From df864712f933306e3a60153795961cf6b0f8b4f4 Mon Sep 17 00:00:00 2001 From: Dargon789 <64915515+Dargon789@users.noreply.github.com> Date: Sat, 25 Oct 2025 18:30:53 +0000 Subject: [PATCH 01/39] 0xsequence/master (#79) * Create fortify.yml * Update issue templates * Update CNAME * fix: upgrade @tanstack/react-query from 5.45.1 to 5.64.2 Snyk has created this PR to upgrade @tanstack/react-query from 5.45.1 to 5.64.2. See this package in npm: @tanstack/react-query See this project in Snyk: https://app.snyk.io/org/dargon789/project/bb845543-cbee-4e11-8cf9-8bfdf9205bf1?utm_source=github&utm_medium=referral&page=upgrade-pr * Create config.yml (#46) Signed-off-by: AU_gdev_19 <64915515+Dargon789@users.noreply.github.com> * Update fortify.yml Signed-off-by: AU_gdev_19 <64915515+Dargon789@users.noreply.github.com> * Update .github/ISSUE_TEMPLATE/bug_report.md Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> * Update .github/ISSUE_TEMPLATE/feature_request.md Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> --------- Signed-off-by: AU_gdev_19 <64915515+Dargon789@users.noreply.github.com> Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> Co-authored-by: snyk-bot Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- .circleci/config.yml | 26 +++++++ .github/ISSUE_TEMPLATE/bug_report.md | 38 ++++++++++ .github/ISSUE_TEMPLATE/custom.md | 10 +++ .github/ISSUE_TEMPLATE/feature_request.md | 20 ++++++ .github/workflows/fortify.yml | 85 +++++++++++++++++++++++ CNAME | 2 +- wagmi-project/package.json | 2 +- 7 files changed, 181 insertions(+), 2 deletions(-) create mode 100644 .circleci/config.yml create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/custom.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md create mode 100644 .github/workflows/fortify.yml diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 000000000..709c9a747 --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,26 @@ +# Use the latest 2.1 version of CircleCI pipeline process engine. +# See: https://circleci.com/docs/configuration-reference + +version: 2.1 +executors: + my-custom-executor: + docker: + - image: cimg/base:stable + auth: + # ensure you have first added these secrets + # visit app.circleci.com/settings/project/github/Dargon789/hardhat-project/environment-variables + username: $DOCKER_HUB_USER + password: $DOCKER_HUB_PASSWORD +jobs: + web3-defi-game-project-: + + executor: my-custom-executor + steps: + - checkout + - run: | + # echo Hello, World! + +workflows: + my-custom-workflow: + jobs: + - web3-defi-game-project- diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 000000000..81c7b58d8 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,38 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: 'bug' +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Desktop (please complete the following information):** + - OS: [e.g. iOS] + - Browser [e.g. chrome, safari] + - Version [e.g. 22] + +**Smartphone (please complete the following information):** + - Device: [e.g. iPhone6] + - OS: [e.g. iOS8.1] + - Browser [e.g. stock browser, safari] + - Version [e.g. 22] + +**Additional context** +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/custom.md b/.github/ISSUE_TEMPLATE/custom.md new file mode 100644 index 000000000..48d5f81fa --- /dev/null +++ b/.github/ISSUE_TEMPLATE/custom.md @@ -0,0 +1,10 @@ +--- +name: Custom issue template +about: Describe this issue template's purpose here. +title: '' +labels: '' +assignees: '' + +--- + + diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 000000000..36014cde5 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,20 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: 'enhancement' +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. diff --git a/.github/workflows/fortify.yml b/.github/workflows/fortify.yml new file mode 100644 index 000000000..ff1a25baf --- /dev/null +++ b/.github/workflows/fortify.yml @@ -0,0 +1,85 @@ +# This workflow uses actions that are not certified by GitHub. +# They are provided by a third-party and are governed by +# separate terms of service, privacy policy, and support +# documentation. + +################################################################################################################################################ +# Fortify Application Security provides your team with solutions to empower DevSecOps practices, enable cloud transformation, and secure your # +# software supply chain. To learn more about Fortify, start a free trial or contact our sales team, visit fortify.com. # +# # +# Use this starter workflow as a basis for integrating Fortify Application Security Testing into your GitHub workflows. This template # +# demonstrates the steps to package the code+dependencies, initiate a scan, and optionally import SAST vulnerabilities into GitHub Security # +# Code Scanning Alerts. Additional information is available in the workflow comments and the Fortify AST Action / fcli / Fortify product # +# documentation. If you need additional assistance, please contact Fortify support. # +################################################################################################################################################ + +name: Fortify AST Scan + +# Customize trigger events based on your DevSecOps process and/or policy +on: + push: + branches: [ "master" ] + pull_request: + # The branches below must be a subset of the branches above + branches: [ "master" ] + schedule: + - cron: '31 12 * * 4' + workflow_dispatch: + +jobs: + Fortify-AST-Scan: + # Use the appropriate runner for building your source code. Ensure dev tools required to build your code are present and configured appropriately (MSBuild, Python, etc). + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + + steps: + # Check out source code + - name: Check Out Source Code + uses: actions/checkout@v4 + + # Java is required to run the various Fortify utilities. Ensuring proper version is installed on the runner. + - name: Setup Java + uses: actions/setup-java@v4 + with: + java-version: 17 + distribution: 'temurin' + + # Perform SAST and optionally SCA scan via Fortify on Demand/Fortify Hosted/Software Security Center, then + # optionally export SAST results to the GitHub code scanning dashboard. In case further customization is + # required, you can use sub-actions like fortify/github-action/setup@v1 to set up the various Fortify tools + # and run them directly from within your pipeline; see https://github.com/fortify/github-action#readme for + # details. + + - name: Run FoD SAST Scan + uses: fortify/github-action@a92347297e02391b857e7015792cd1926a4cd418 + with: + sast-scan: true + env: + ### Required configuration when integrating with Fortify on Demand + FOD_URL: https://ams.fortify.com + FOD_TENANT: ${{secrets.FOD_TENANT}} + FOD_USER: ${{secrets.FOD_USER}} + FOD_PASSWORD: ${{secrets.FOD_PAT}} + ### Optional configuration when integrating with Fortify on Demand + # EXTRA_PACKAGE_OPTS: -oss # Extra 'scancentral package' options, like '-oss'' if + # Debricked SCA scan is enabled on Fortify on Demand + # EXTRA_FOD_LOGIN_OPTS: --socket-timeout=60s # Extra 'fcli fod session login' options + # FOD_RELEASE: MyApp:MyRelease # FoD release name, default: /:; may + # replace app+release name with numeric release ID + # DO_WAIT: true # Wait for scan completion, implied if 'DO_EXPORT: true' + # DO_EXPORT: true # Export SAST results to GitHub code scanning dashboard + ### Required configuration when integrating with Fortify Hosted / Software Security Center & ScanCentral + # SSC_URL: ${{secrets.SSC_URL}} # SSC URL + # SSC_TOKEN: ${{secrets.SSC_TOKEN}} # SSC CIToken or AutomationToken + # SC_SAST_TOKEN: ${{secrets.SC_SAST_TOKEN}} # ScanCentral SAST client auth token + # SC_SAST_SENSOR_VERSION: ${{vars.SC_SAST_SENSOR_VERSION}} # Sensor version on which to run the scan; + # usually defined as organization or repo variable + ### Optional configuration when integrating with Fortify Hosted / Software Security Center & ScanCentral + # EXTRA_SC_SAST_LOGIN_OPTS: --socket-timeout=60s # Extra 'fcli sc-sast session login' options + # SSC_APPVERSION: MyApp:MyVersion # SSC application version, default: /: + # EXTRA_PACKAGE_OPTS: -bv myCustomPom.xml # Extra 'scancentral package' options + # DO_WAIT: true # Wait for scan completion, implied if 'DO_EXPORT: true' + # DO_EXPORT: true # Export SAST results to GitHub code scanning dashboard diff --git a/CNAME b/CNAME index c9903e895..aa0085b19 100644 --- a/CNAME +++ b/CNAME @@ -1 +1 @@ -wagmi-project-two.vercel.app \ No newline at end of file +sequence.app \ No newline at end of file diff --git a/wagmi-project/package.json b/wagmi-project/package.json index 298a76bbc..206445bb3 100644 --- a/wagmi-project/package.json +++ b/wagmi-project/package.json @@ -10,7 +10,7 @@ "preview": "vite preview" }, "dependencies": { - "@tanstack/react-query": "5.45.1", + "@tanstack/react-query": "5.64.2", "react": "^18.3.1", "react-dom": "^18.3.1", "viem": "latest", From ffd17e627c539e2ddc61a77c5cb5350bb88b05b1 Mon Sep 17 00:00:00 2001 From: Dargon789 <64915515+Dargon789@users.noreply.github.com> Date: Fri, 14 Nov 2025 14:18:21 +0700 Subject: [PATCH 02/39] Update tests.yml (#82) Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> --- .github/workflows/tests.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index d49eea949..7d5edbd5f 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -9,6 +9,7 @@ jobs: steps: - uses: actions/checkout@v3 - uses: ./.github/actions/install-dependencies + - run: pnpm install --no-frozen-lockfile build: name: Run build From f3427844b10ece0c3a997657ffb6b49c8f14a77c Mon Sep 17 00:00:00 2001 From: Dargon789 <64915515+Dargon789@users.noreply.github.com> Date: Mon, 17 Nov 2025 19:47:56 +0700 Subject: [PATCH 03/39] Update App.tsx (#92) Summary by Sourcery Overhaul App.tsx to build a comprehensive Sequence Wallet demo application, replacing wagmi with Sequence SDK integration, adding environment/configuration management, rich wallet operations, and a structured UI with console output for interactive testing New Features: Replace wagmi-based hooks with @0xsequence wallet initialization and integration Add environment selection and dynamic wallet URLs via query parameters Implement connect, disconnect, open/close wallet and customizable connection settings Provide extensive demo actions including chain/network switching, account/balance queries, message signing, typed data signing, and transaction sending Introduce a console component and logging for viewing function outputs Add email-based auto-login via modal with validation Enhancements: Refactor UI to use design-system components and group actions thematically Initialize logger and configure default chain/network Memoize and listen to wallet events such as chain changes Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> --- wagmi-project/src/App.tsx | 1380 +++++++++++++++++++++++++++++++++++-- 1 file changed, 1341 insertions(+), 39 deletions(-) diff --git a/wagmi-project/src/App.tsx b/wagmi-project/src/App.tsx index faa8ce1c7..05da5e5b3 100644 --- a/wagmi-project/src/App.tsx +++ b/wagmi-project/src/App.tsx @@ -1,46 +1,1348 @@ -import { useAccount, useConnect, useDisconnect } from 'wagmi' +import { AnimatePresence } from 'framer-motion' +import React, { useState, useEffect, useMemo, SetStateAction } from 'react' +import { ethers } from 'ethers' +import { sequence } from '0xsequence' +import { walletContracts } from '@0xsequence/abi' +import { + Box, + Image, + Text, + Button, + ExternalLinkIcon, + Divider, + Card, + TransactionIcon, + Select, + TokenImage, + TextInput, + Modal +} from '@0xsequence/design-system' +import { ETHAuth } from '@0xsequence/ethauth' +import { configureLogger } from '@0xsequence/utils' +import { ConnectOptions, OpenWalletIntent, Settings } from '@0xsequence/provider' +import { ChainId, NetworkType } from '@0xsequence/network' -function App() { - const account = useAccount() - const { connectors, connect, status, error } = useConnect() - const { disconnect } = useDisconnect() +import { ERC_20_ABI } from './constants/abi' +import { Console } from './components/Console' +import { Group } from './components/Group' +import { getDefaultChainId, toHexString } from './helpers' +import logoUrl from './images/logo.svg' +import skyweaverBannerUrl from './images/skyweaver-banner.png' +import skyweaverBannerLargeUrl from './images/skyweaver-banner-large.png' + +configureLogger({ logLevel: 'DEBUG' }) + +interface Environment { + name: string + walletUrl: string + projectAccessKey: string +} + +const environments: Environment[] = [ + { + name: 'production', + walletUrl: 'https://sequence.app', + projectAccessKey: 'AQAAAAAAAAbvrgpWEC2Aefg5qYStQmwjBpA' + }, + { + name: 'development', + walletUrl: 'https://dev.sequence.app', + //projectAccessKey: 'AQAAAAAAAAVBNfoB30kz7Ph4I_Qs5mkYuDc', + projectAccessKey: 'AQAAAAAAAAVCXiQ9f_57R44MjorZ4SmGdhA' + }, + { + name: 'local', + walletUrl: 'http://localhost:3333', + projectAccessKey: 'AQAAAAAAAAVCXiQ9f_57R44MjorZ4SmGdhA' + }, + { + name: 'custom', + walletUrl: '', + projectAccessKey: '' + } +] + +const DEFAULT_API_URL = 'https://api.sequence.app' + +// Specify your desired default chain id. NOTE: you can communicate to multiple +// chains at the same time without even having to switch the network, but a default +// chain is required. +const defaultChainId = getDefaultChainId() || ChainId.MAINNET +// const defaultChainId = ChainId.POLYGON +// const defaultChainId = ChainId.GOERLI +// const defaultChainId = ChainId.ARBITRUM +// const defaultChainId = ChainId.AVALANCHE +// etc.. see the full list here: https://docs.sequence.xyz/multi-chain-support + +// For Sequence core dev team -- app developers can ignore +// a custom wallet app url can specified in the query string +const urlParams = new URLSearchParams(window.location.search) + +const env = urlParams.get('env') ?? 'production' +const envConfig = environments.find(x => x.name === env) +const walletAppURL = urlParams.get('walletAppURL') ?? envConfig.walletUrl +const projectAccessKey = urlParams.get('projectAccessKey') ?? envConfig.projectAccessKey +const showProhibitedActions = urlParams.has('showProhibitedActions') + +const isCustom = walletAppURL !== envConfig.walletUrl || projectAccessKey !== envConfig.projectAccessKey + +if (walletAppURL && walletAppURL.length > 0) { + // Wallet can point to a custom wallet app url + // NOTICE: this is not needed, unless testing an alpha version of the wallet + sequence.initWallet(projectAccessKey, { defaultNetwork: defaultChainId, transports: { walletAppURL } }) +} else { + // Init the sequence wallet library at the top-level of your project with + // your designed default chain id + sequence.initWallet(projectAccessKey, { defaultNetwork: defaultChainId, transports: { walletAppURL } }) +} + +// App component +const App = () => { + const [consoleMsg, setConsoleMsg] = useState(null) + const [email, setEmail] = useState(null) + const [consoleLoading, setConsoleLoading] = useState(false) + const [isWalletConnected, setIsWalletConnected] = useState(false) + + const wallet = sequence.getWallet().getProvider() + + const [showChainId, setShowChainId] = useState(wallet.getChainId()) + const [isOpen, toggleModal] = useState(false) + const [warning, setWarning] = useState(false) + + useMemo(() => { + wallet.on('chainChanged', (chainId: string) => { + setShowChainId(Number(BigInt(chainId))) + }) + }, []) + + useEffect(() => { + setIsWalletConnected(wallet.isConnected()) + }, [wallet]) + + useEffect(() => { + consoleWelcomeMessage() + // eslint-disable-next-line + }, [isWalletConnected]) + + useEffect(() => { + // Wallet events + wallet.client.onOpen(() => { + console.log('wallet window opened') + }) + + wallet.client.onClose(() => { + console.log('wallet window closed') + }) + }, [wallet]) + + const defaultConnectOptions: ConnectOptions = { + app: 'Demo Dapp', + askForEmail: true + // keepWalletOpened: true, + } + + // Methods + const connect = async (connectOptions: ConnectOptions = { app: 'Demo dapp' }) => { + if (isWalletConnected) { + resetConsole() + appendConsoleLine('Wallet already connected!') + setConsoleLoading(false) + return + } + + connectOptions = { + ...defaultConnectOptions, + ...connectOptions, + settings: { + ...defaultConnectOptions.settings, + ...connectOptions.settings + } + } + + try { + resetConsole() + appendConsoleLine('Connecting') + const wallet = sequence.getWallet() + + const connectDetails = await wallet.connect(connectOptions) + + // Example of how to verify using ETHAuth via Sequence API + if (connectOptions.authorize && connectDetails.connected) { + let apiUrl = urlParams.get('apiUrl') + + if (!apiUrl || apiUrl.length === 0) { + apiUrl = DEFAULT_API_URL + } + + const api = new sequence.api.SequenceAPIClient(apiUrl) + // or just + // const api = new sequence.api.SequenceAPIClient('https://api.sequence.app') + + const { isValid } = await api.isValidETHAuthProof({ + chainId: connectDetails.chainId, + walletAddress: connectDetails.session.accountAddress, + ethAuthProofString: connectDetails.proof!.proofString + }) + + appendConsoleLine(`isValid (API)?: ${isValid}`) + } + + // Example of how to verify using ETHAuth directl on the client + if (connectOptions.authorize) { + const ethAuth = new ETHAuth() + + if (connectDetails.proof) { + const decodedProof = await ethAuth.decodeProof(connectDetails.proof.proofString, true) + + const isValid = await wallet.utils.isValidTypedDataSignature( + wallet.getAddress(), + connectDetails.proof.typedData, + decodedProof.signature, + Number(BigInt(connectDetails.chainId)) + ) + + appendConsoleLine(`connected using chainId: ${BigInt(connectDetails.chainId).toString()}`) + appendConsoleLine(`isValid (client)?: ${isValid}`) + } + } + + setConsoleLoading(false) + if (connectDetails.connected) { + appendConsoleLine('Wallet connected!') + appendConsoleLine(`shared email: ${connectDetails.email}`) + setIsWalletConnected(true) + } else { + appendConsoleLine('Failed to connect wallet - ' + connectDetails.error) + } + } catch (e) { + console.error(e) + consoleErrorMessage() + } + } + + const disconnect = () => { + const wallet = sequence.getWallet() + wallet.disconnect() + consoleWelcomeMessage() + setIsWalletConnected(false) + } + + const openWallet = () => { + const wallet = sequence.getWallet() + wallet.openWallet() + } + + const openWalletWithSettings = () => { + const wallet = sequence.getWallet() + + const settings: Settings = { + theme: 'light', + includedPaymentProviders: ['moonpay', 'ramp'], + defaultFundingCurrency: 'eth', + defaultPurchaseAmount: 400, + lockFundingCurrencyToDefault: false + } + + const intent: OpenWalletIntent = { + type: 'openWithOptions', + options: { + app: 'Demo Dapp', + settings + } + } + + const path = 'wallet/add-funds' + wallet.openWallet(path, intent) + } + + const closeWallet = () => { + const wallet = sequence.getWallet() + wallet.closeWallet() + } + + const isConnected = async () => { + resetConsole() + const wallet = sequence.getWallet() + appendConsoleLine(`isConnected?: ${wallet.isConnected()}`) + setConsoleLoading(false) + } + + const isOpened = async () => { + resetConsole() + const wallet = sequence.getWallet() + appendConsoleLine(`isOpened?: ${wallet.isOpened()}`) + setConsoleLoading(false) + } + + const getChainID = async () => { + try { + resetConsole() + + const topChainId = wallet.getChainId() + appendConsoleLine(`top chainId: ${topChainId}`) + + const provider = wallet.getProvider() + const providerChainId = provider!.getChainId() + appendConsoleLine(`provider.getChainId(): ${providerChainId}`) + + const signer = wallet.getSigner() + const signerChainId = await signer.getChainId() + appendConsoleLine(`signer.getChainId(): ${signerChainId}`) + + setConsoleLoading(false) + } catch (e) { + console.error(e) + consoleErrorMessage() + } + } + + const getAccounts = async () => { + try { + resetConsole() + + const wallet = sequence.getWallet() + const address = wallet.getAddress() + appendConsoleLine(`getAddress(): ${address}`) + + const provider = wallet.getProvider() + const accountList = provider.listAccounts() + appendConsoleLine(`accounts: ${JSON.stringify(accountList)}`) + + setConsoleLoading(false) + } catch (e) { + console.error(e) + consoleErrorMessage() + } + } + + const getBalance = async () => { + try { + resetConsole() + + const wallet = sequence.getWallet() + + const provider = wallet.getProvider() + const account = wallet.getAddress() + const balanceChk1 = await provider!.getBalance(account) + appendConsoleLine(`balance check 1: ${balanceChk1.toString()}`) + + const signer = wallet.getSigner() + const balanceChk2 = await signer.getBalance() + appendConsoleLine(`balance check 2: ${balanceChk2.toString()}`) + + setConsoleLoading(false) + } catch (e) { + console.error(e) + consoleErrorMessage() + } + } + + const getNetworks = async () => { + try { + resetConsole() + + const wallet = sequence.getWallet() + const networks = await wallet.getNetworks() + + appendConsoleLine(`networks: ${JSON.stringify(networks, null, 2)}`) + setConsoleLoading(false) + } catch (e) { + console.error(e) + consoleErrorMessage() + } + } + + const signMessageString = async () => { + try { + resetConsole() + + const wallet = sequence.getWallet() + + appendConsoleLine('signing message...') + const signer = wallet.getSigner() + + const message = `1915 Robert Frost +The Road Not Taken + +Two roads diverged in a yellow wood, +And sorry I could not travel both +And be one traveler, long I stood +And looked down one as far as I could +To where it bent in the undergrowth + +Then took the other, as just as fair, +And having perhaps the better claim, +Because it was grassy and wanted wear +Though as for that the passing there +Had worn them really about the same, + +And both that morning equally lay +In leaves no step had trodden black. +Oh, I kept the first for another day! +Yet knowing how way leads on to way, +I doubted if I should ever come back. + +I shall be telling this with a sigh +Somewhere ages and ages hence: +Two roads diverged in a wood, and I— +I took the one less traveled by, +And that has made all the difference. + +\u2601 \u2600 \u2602` + + // sign + const sig = await signer.signMessage(message) + appendConsoleLine(`signature: ${sig}`) + + const isValid = await wallet.utils.isValidMessageSignature(wallet.getAddress(), message, sig, await signer.getChainId()) + appendConsoleLine(`isValid?: ${isValid}`) + if (!isValid) throw new Error('sig invalid') + + setConsoleLoading(false) + } catch (e) { + console.error(e) + consoleErrorMessage() + } + } + + const signMessageHex = async () => { + try { + resetConsole() + + const wallet = sequence.getWallet() + + appendConsoleLine('signing message...') + const signer = wallet.getSigner() + + // Message in hex + const message = ethers.hexlify(ethers.toUtf8Bytes('Hello, world!')) + + // sign + const sig = await signer.signMessage(message) + appendConsoleLine(`signature: ${sig}`) + + const isValid = await wallet.utils.isValidMessageSignature(wallet.getAddress(), message, sig, await signer.getChainId()) + appendConsoleLine(`isValid?: ${isValid}`) + if (!isValid) throw new Error('sig invalid') + + setConsoleLoading(false) + } catch (e) { + console.error(e) + consoleErrorMessage() + } + } + + const signMessageBytes = async () => { + try { + resetConsole() + + const wallet = sequence.getWallet() + + appendConsoleLine('signing message...') + const signer = wallet.getSigner() + + // Message in hex + const message = ethers.toUtf8Bytes('Hello, world!') + + // sign + const sig = await signer.signMessage(message) + appendConsoleLine(`signature: ${sig}`) + + const isValid = await wallet.utils.isValidMessageSignature(wallet.getAddress(), message, sig, await signer.getChainId()) + appendConsoleLine(`isValid?: ${isValid}`) + if (!isValid) throw new Error('sig invalid') + + setConsoleLoading(false) + } catch (e) { + console.error(e) + consoleErrorMessage() + } + } + + const signTypedData = async () => { + try { + resetConsole() + const wallet = sequence.getWallet() + + appendConsoleLine('signing typedData...') + + const typedData: sequence.utils.TypedData = { + types: { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' } + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'cc', type: 'Person[]' }, + { name: 'contents', type: 'string' }, + { name: 'attachements', type: 'string[]' } + ] + }, + primaryType: 'Mail', + domain: { + name: 'Ether Mail', + version: '1', + chainId: 1, + verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC' + }, + message: { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826' + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB' + }, + cc: [ + { name: 'Dev Team', wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB' }, + { name: 'Accounting', wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB' } + ], + contents: 'Hello, Bob!', + attachements: ['cat.png', 'dog.png'] + } + } + + const signer = wallet.getSigner() + + const sig = await signer.signTypedData(typedData.domain, typedData.types, typedData.message) + appendConsoleLine(`signature: ${sig}`) + + // validate + const isValid = await wallet.utils.isValidTypedDataSignature(wallet.getAddress(), typedData, sig, await signer.getChainId()) + appendConsoleLine(`isValid?: ${isValid}`) + + setConsoleLoading(false) + } catch (e) { + console.error(e) + consoleErrorMessage() + } + } + + const estimateUnwrapGas = async () => { + try { + resetConsole() + + const wallet = sequence.getWallet() + + const wmaticContractAddress = '0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270' + const wmaticInterface = new ethers.Interface(['function withdraw(uint256 amount)']) + + const tx: sequence.transactions.Transaction = { + to: wmaticContractAddress, + data: wmaticInterface.encodeFunctionData('withdraw', ['1000000000000000000']) + } + + const provider = wallet.getProvider() + const estimate = await provider.estimateGas(tx) + + appendConsoleLine(`estimated gas needed for wmatic withdrawal : ${estimate.toString()}`) + + setConsoleLoading(false) + } catch (e) { + console.error(e) + consoleErrorMessage() + } + } + + const sendETH = async (signer?: sequence.provider.SequenceSigner) => { + try { + resetConsole() + const wallet = sequence.getWallet() + + signer = signer || wallet.getSigner() + + appendConsoleLine(`Transfer txn on ${signer.getChainId()} chainId`) + + // NOTE: on mainnet, the balance will be of ETH value + // and on matic, the balance will be of MATIC value + + // Sending the funds to the wallet itself + // so we don't lose any funds ;-) + // (of course, you can send anywhere) + const toAddress = await signer.getAddress() + + const tx1: sequence.transactions.Transaction = { + delegateCall: false, + revertOnError: false, + gasLimit: '0x55555', + to: toAddress, + value: ethers.parseEther('1.234'), + data: '0x' + } + + const tx2: sequence.transactions.Transaction = { + delegateCall: false, + revertOnError: false, + gasLimit: '0x55555', + to: toAddress, + value: ethers.parseEther('0.4242'), + data: '0x' + } + + const provider = signer.provider + + const balance1 = await provider.getBalance(toAddress) + appendConsoleLine(`balance of ${toAddress}, before: ${balance1}`) + + const txnResp = await signer.sendTransaction([tx1, tx2]) + appendConsoleLine(`txnResponse: ${JSON.stringify(txnResp)}`) + + const balance2 = await provider.getBalance(toAddress) + appendConsoleLine(`balance of ${toAddress}, after: ${balance2}`) + + setConsoleLoading(false) + } catch (e) { + console.error(e) + consoleErrorMessage() + } + } + + const sendSepoliaUSDC = async (signer?: sequence.provider.SequenceSigner) => { + try { + resetConsole() + + const wallet = sequence.getWallet() + + signer = signer || wallet.getSigner() // select DefaultChain signer by default + + // Sending the funds to the wallet itself + // so we don't lose any funds ;-) + // (of course, you can send anywhere) + const toAddress = await signer.getAddress() + + const amount = ethers.parseUnits('1', 1) + + // (USDC address on Sepolia) + const usdcAddress = '0x07865c6e87b9f70255377e024ace6630c1eaa37f' + + const tx: sequence.transactions.Transaction = { + delegateCall: false, + revertOnError: false, + gasLimit: '0x55555', + to: usdcAddress, + value: 0, + data: new ethers.Interface(ERC_20_ABI).encodeFunctionData('transfer', [toAddress, toHexString(amount)]) + } + + const txnResp = await signer.sendTransaction([tx], { chainId: ChainId.SEPOLIA }) + appendConsoleLine(`txnResponse: ${JSON.stringify(txnResp)}`) + + setConsoleLoading(false) + } catch (e) { + console.error(e) + consoleErrorMessage() + } + } + + const sendDAI = async (signer?: sequence.provider.SequenceSigner) => { + try { + resetConsole() + + const wallet = sequence.getWallet() + + signer = signer || wallet.getSigner() // select DefaultChain signer by default + + // Sending the funds to the wallet itself + // so we don't lose any funds ;-) + // (of course, you can send anywhere) + const toAddress = await signer.getAddress() + + const amount = ethers.parseUnits('0.05', 18) + const daiContractAddress = '0x8f3Cf7ad23Cd3CaDbD9735AFf958023239c6A063' // (DAI address on Polygon) + + const tx: sequence.transactions.Transaction = { + delegateCall: false, + revertOnError: false, + gasLimit: '0x55555', + to: daiContractAddress, + value: 0, + data: new ethers.Interface(ERC_20_ABI).encodeFunctionData('transfer', [toAddress, toHexString(amount)]) + } + + const txnResp = await signer.sendTransaction([tx]) + appendConsoleLine(`txnResponse: ${JSON.stringify(txnResp)}`) + + setConsoleLoading(false) + } catch (e) { + console.error(e) + consoleErrorMessage() + } + } + + const sendETHSidechain = async () => { + try { + const wallet = sequence.getWallet() + + // Send either to Arbitrum or Optimism + // just pick one that is not the current chainId + const pick = wallet.getChainId() === ChainId.ARBITRUM ? ChainId.OPTIMISM : ChainId.ARBITRUM + sendETH(wallet.getSigner(pick)) + } catch (e) { + console.error(e) + consoleErrorMessage() + } + } + + const send1155Tokens = async () => { + try { + resetConsole() + appendConsoleLine('TODO') + setConsoleLoading(false) + } catch (e) { + console.error(e) + consoleErrorMessage() + } + } + + const contractExample = async (signer?: sequence.provider.SequenceSigner) => { + try { + resetConsole() + + const wallet = sequence.getWallet() + + signer = signer || wallet.getSigner() + + const abi = [ + 'function balanceOf(address owner) view returns (uint256)', + 'function decimals() view returns (uint8)', + 'function symbol() view returns (string)', + 'function transfer(address to, uint amount) returns (bool)', + 'event Transfer(address indexed from, address indexed to, uint amount)' + ] + + // USD Coin (PoS) on Polygon + const address = '0x2791bca1f2de4661ed88a30c99a7a9449aa84174' + + const usdc = new ethers.Contract(address, abi) + + const usdSymbol = await usdc.symbol() + appendConsoleLine(`Token symbol: ${usdSymbol}`) + + const balance = await usdc.balanceOf(await signer.getAddress()) + appendConsoleLine(`Token Balance: ${balance.toString()}`) + + setConsoleLoading(false) + } catch (e) { + console.error(e) + consoleErrorMessage() + } + } + + const fetchTokenBalances = async () => { + try { + resetConsole() + + const wallet = sequence.getWallet() + + const signer = wallet.getSigner() + const accountAddress = await signer.getAddress() + const networks = await wallet.getNetworks() + const network = networks.find(network => network.chainId === ChainId.POLYGON) + + if (!network) { + throw new Error(`Could not find Polygon network in networks list`) + } + + const indexer = new sequence.indexer.SequenceIndexer(network.indexerUrl) + + const tokenBalances = await indexer.getTokenBalances({ + accountAddress: accountAddress, + includeMetadata: true + }) + + appendConsoleLine(`tokens in your account: ${JSON.stringify(tokenBalances)}`) + + // NOTE: you can put any NFT/collectible address in the `contractAddress` field and it will return all of the balances + metadata. + // We use the Skyweaver production contract address here for demo purposes, but try another one :) + const skyweaverCollectibles = await indexer.getTokenBalances({ + accountAddress: accountAddress, + includeMetadata: true, + contractAddress: '0x631998e91476DA5B870D741192fc5Cbc55F5a52E' + }) + appendConsoleLine(`skyweaver collectibles in your account: ${JSON.stringify(skyweaverCollectibles)}`) + + setConsoleLoading(false) + } catch (e) { + console.error(e) + consoleErrorMessage() + } + } + + const updateImplementation = async (signer?: sequence.provider.SequenceSigner) => { + try { + resetConsole() + + const wallet = sequence.getWallet() + + signer = signer || wallet.getSigner() // select DefaultChain signer by default + + const transaction: sequence.transactions.Transaction = { + to: wallet.getAddress(), + data: new ethers.Interface(walletContracts.mainModule.abi).encodeFunctionData('updateImplementation', [ + ethers.ZeroAddress + ]) + } + + const response = await signer.sendTransaction(transaction) + appendConsoleLine(`response: ${JSON.stringify(response)}`) + setConsoleLoading(false) + } catch (e) { + console.error(e) + consoleErrorMessage() + } + } + + const updateImageHash = async (signer?: sequence.provider.SequenceSigner) => { + try { + resetConsole() + + const wallet = sequence.getWallet() + + signer = signer || wallet.getSigner() // select DefaultChain signer by default + + const transaction: sequence.transactions.Transaction = { + to: wallet.getAddress(), + data: new ethers.Interface(walletContracts.mainModuleUpgradable.abi).encodeFunctionData('updateImageHash', [ + ethers.ZeroHash + ]) + } + + const response = await signer.sendTransaction(transaction) + appendConsoleLine(`response: ${JSON.stringify(response)}`) + setConsoleLoading(false) + } catch (e) { + console.error(e) + consoleErrorMessage() + } + } + + const delegateCall = async (signer?: sequence.provider.SequenceSigner) => { + try { + resetConsole() + + const wallet = sequence.getWallet() + + signer = signer || wallet.getSigner() // select DefaultChain signer by default + + const transaction: sequence.transactions.Transaction = { + to: wallet.getAddress(), + delegateCall: true + } + + const response = await signer.sendTransaction(transaction) + appendConsoleLine(`response: ${JSON.stringify(response)}`) + setConsoleLoading(false) + } catch (e) { + console.error(e) + consoleErrorMessage() + } + } + + const addHook = async (signer?: sequence.provider.SequenceSigner) => { + try { + resetConsole() + + const wallet = sequence.getWallet() + + signer = signer || wallet.getSigner() // select DefaultChain signer by default + + const transaction: sequence.transactions.Transaction = { + to: wallet.getAddress(), + data: new ethers.Interface(['function addHook(bytes4 _signature, address _implementation)']).encodeFunctionData( + 'addHook', + ['0x01234567', ethers.ZeroAddress] + ) + } + + const response = await signer.sendTransaction(transaction) + appendConsoleLine(`response: ${JSON.stringify(response)}`) + setConsoleLoading(false) + } catch (e) { + console.error(e) + consoleErrorMessage() + } + } + + const setExtraImageHash = async (signer?: sequence.provider.SequenceSigner) => { + try { + resetConsole() + + const wallet = sequence.getWallet() + + signer = signer || wallet.getSigner() // select DefaultChain signer by default + + const transaction: sequence.transactions.Transaction = { + to: wallet.getAddress(), + data: new ethers.Interface(['function setExtraImageHash(bytes32 _imageHash, uint256 _expiration)']).encodeFunctionData( + 'setExtraImageHash', + [ethers.ZeroHash, ethers.MaxUint256] + ) + } + + const response = await signer.sendTransaction(transaction) + appendConsoleLine(`response: ${JSON.stringify(response)}`) + setConsoleLoading(false) + } catch (e) { + console.error(e) + consoleErrorMessage() + } + } + + const appendConsoleLine = (message: string, clear = false) => { + console.log(message) + + if (clear) { + return setConsoleMsg(message) + } + + return setConsoleMsg(prevState => { + return `${prevState}\n\n${message}` + }) + } + + const resetConsole = () => { + setConsoleLoading(true) + } + + const consoleWelcomeMessage = () => { + setConsoleLoading(false) + + if (isWalletConnected) { + setConsoleMsg('Status: Wallet is connected :)') + } else { + setConsoleMsg('Status: Wallet not connected. Please connect wallet first.') + } + } + + const consoleErrorMessage = () => { + setConsoleLoading(false) + setConsoleMsg('An error occurred') + } + + // networks list, filtered and sorted + const omitNetworks = [ + ChainId.RINKEBY, + ChainId.HARDHAT, + ChainId.HARDHAT_2, + ChainId.KOVAN, + ChainId.ROPSTEN, + ChainId.HOMEVERSE_TESTNET, + ChainId.BASE_GOERLI + ] + + const mainnets = Object.values(sequence.network.networks) + .filter(network => network.type === NetworkType.MAINNET) + .sort((a, b) => a.chainId - b.chainId) + const testnets = Object.values(sequence.network.networks) + .filter(network => network.type === NetworkType.TESTNET) + .sort((a, b) => a.chainId - b.chainId) + const networks = [...mainnets, ...testnets].filter(network => !network.deprecated && !omitNetworks.includes(network.chainId)) + + useEffect(() => { + if (email && !isOpen) { + console.log(email) + connect({ + app: 'Demo Dapp', + authorize: true, + settings: { + // Specify signInWithEmail with an email address to allow user automatically sign in with the email option. + signInWithEmail: email, + theme: 'dark', + bannerUrl: `${window.location.origin}${skyweaverBannerUrl}` + } + }) + setEmail(null) + } + }, [email, isOpen]) + + const sanitizeEmail = (email: string) => { + // Trim unnecessary spaces + email = email.trim() + + // Check if the email matches the pattern of a typical email + const emailRegex = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6}$/ + if (emailRegex.test(email)) { + return true + } + + return false + } return ( - <> -
-

Account

- -
- status: {account.status} -
- addresses: {JSON.stringify(account.addresses)} -
- chainId: {account.chainId} -
- - {account.status === 'connected' && ( - + + + + logo + + + + + + Demo Dapp + + + + + + A dapp example on how to use the Sequence Wallet. This covers how to connect, sign messages and send transctions. + + + + + + + Please open your browser dev inspector to view output of functions below. + + + + + + {!isCustom && ( + + wallet.setDefaultChainId(Number(value))} + value={String(showChainId)} + options={[ + ...Object.values(networks).map(network => ({ + label: ( + + + {network.title!} + + ), + value: String(network.chainId) + })) + ]} + /> + + + +
- -
-

Connect

- {connectors.map((connector) => ( - - ))} -
{status}
-
{error?.message}
-
- + + + ) } -export default App +export default React.memo(App) From 2adc7c5feb25e0e36a6a1dafc9add95167d39667 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 14 Dec 2025 21:30:43 +0100 Subject: [PATCH 04/39] Bump next from 15.5.7 to 15.5.9 (#944) Bumps [next](https://github.com/vercel/next.js) from 15.5.7 to 15.5.9. - [Release notes](https://github.com/vercel/next.js/releases) - [Changelog](https://github.com/vercel/next.js/blob/canary/release.js) - [Commits](https://github.com/vercel/next.js/compare/v15.5.7...v15.5.9) --- updated-dependencies: - dependency-name: next dependency-version: 15.5.9 dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- extras/docs/package.json | 2 +- extras/web/package.json | 2 +- pnpm-lock.yaml | 90 ++++++++++++++++++++-------------------- 3 files changed, 47 insertions(+), 47 deletions(-) diff --git a/extras/docs/package.json b/extras/docs/package.json index f761f0b2d..abadc74fd 100644 --- a/extras/docs/package.json +++ b/extras/docs/package.json @@ -13,7 +13,7 @@ }, "dependencies": { "@repo/ui": "workspace:*", - "next": "^15.5.7", + "next": "^15.5.9", "react": "^19.1.0", "react-dom": "^19.1.0" }, diff --git a/extras/web/package.json b/extras/web/package.json index b5b121c87..3b57fed2b 100644 --- a/extras/web/package.json +++ b/extras/web/package.json @@ -13,7 +13,7 @@ }, "dependencies": { "@repo/ui": "workspace:*", - "next": "^15.5.7", + "next": "^15.5.9", "react": "^19.1.0", "react-dom": "^19.1.0" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a81600c51..a5a389f7d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -39,8 +39,8 @@ importers: specifier: workspace:* version: link:../../repo/ui next: - specifier: ^15.5.7 - version: 15.5.7(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + specifier: ^15.5.9 + version: 15.5.9(react-dom@19.2.0(react@19.2.0))(react@19.2.0) react: specifier: ^19.1.0 version: 19.2.0 @@ -76,8 +76,8 @@ importers: specifier: workspace:* version: link:../../repo/ui next: - specifier: ^15.5.7 - version: 15.5.7(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + specifier: ^15.5.9 + version: 15.5.9(react-dom@19.2.0(react@19.2.0))(react@19.2.0) react: specifier: ^19.1.0 version: 19.2.0 @@ -488,7 +488,7 @@ importers: version: 5.2.0(eslint@9.37.0) eslint-plugin-turbo: specifier: ^2.5.4 - version: 2.5.8(eslint@9.37.0)(turbo@2.6.2) + version: 2.5.8(eslint@9.37.0)(turbo@2.6.3) globals: specifier: ^15.15.0 version: 15.15.0 @@ -1174,8 +1174,8 @@ packages: '@manypkg/get-packages@1.1.3': resolution: {integrity: sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==} - '@next/env@15.5.7': - resolution: {integrity: sha512-4h6Y2NyEkIEN7Z8YxkA27pq6zTkS09bUSYC0xjd0NpwFxjnIKeZEeH591o5WECSmjpUhLn3H2QLJcDye3Uzcvg==} + '@next/env@15.5.9': + resolution: {integrity: sha512-4GlTZ+EJM7WaW2HEZcyU317tIQDjkQIyENDLxYJfSWlfqguN+dHkZgyQTV/7ykvobU7yEH5gKvreNrH4B6QgIg==} '@next/eslint-plugin-next@15.5.5': resolution: {integrity: sha512-FMzm412l9oFB8zdRD+K6HQ1VzlS+sNNsdg0MfvTg0i8lfCyTgP/RFxiu/pGJqZ/IQnzn9xSiLkjOVI7Iv4nbdQ==} @@ -1759,8 +1759,8 @@ packages: camel-case@3.0.0: resolution: {integrity: sha512-+MbKztAYHXPr1jNTSKQF52VpcFjwY5RkR7fxksV8Doo4KAYc5Fl4UJRgthBbTmEx8C54DqahhbLJkDwjI3PI/w==} - caniuse-lite@1.0.30001759: - resolution: {integrity: sha512-Pzfx9fOKoKvevQf8oCXoyNRQ5QyxJj+3O0Rqx2V5oxT61KGx8+n6hV/IUyJeifUci2clnmmKVpvtiqRzgiWjSw==} + caniuse-lite@1.0.30001760: + resolution: {integrity: sha512-7AAMPcueWELt1p3mi13HR/LHH0TJLT11cnwDJEs3xA4+CK/PLKeO9Kl1oru24htkyUKtkGCvAx4ohB0Ttry8Dw==} cbor2@1.12.0: resolution: {integrity: sha512-3Cco8XQhi27DogSp9Ri6LYNZLi/TBY/JVnDe+mj06NkBjW/ZYOtekaEU4wZ4xcRMNrFkDv8KNtOAqHyDfz3lYg==} @@ -2924,8 +2924,8 @@ packages: resolution: {integrity: sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==} engines: {node: '>= 0.4.0'} - next@15.5.7: - resolution: {integrity: sha512-+t2/0jIJ48kUpGKkdlhgkv+zPTEOoXyr60qXe68eB/pl3CMJaLeIGjzp5D6Oqt25hCBiBTt8wEeeAzfJvUKnPQ==} + next@15.5.9: + resolution: {integrity: sha512-agNLK89seZEtC5zUHwtut0+tNrc0Xw4FT/Dg+B/VLEo9pAcS9rtTKpek3V6kVcVwsB2YlqMaHdfZL4eLEVYuCg==} engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0} hasBin: true peerDependencies: @@ -3658,8 +3658,8 @@ packages: cpu: [x64] os: [darwin] - turbo-darwin-64@2.6.2: - resolution: {integrity: sha512-nF9d/YAyrNkyXn9lp3ZtgXPb7fZsik3cUNe/sBvUO0G5YezUS/kDYYw77IdjizDzairz8pL2ITCTUreG2d5iZQ==} + turbo-darwin-64@2.6.3: + resolution: {integrity: sha512-BlJJDc1CQ7SK5Y5qnl7AzpkvKSnpkfPmnA+HeU/sgny3oHZckPV2776ebO2M33CYDSor7+8HQwaodY++IINhYg==} cpu: [x64] os: [darwin] @@ -3668,8 +3668,8 @@ packages: cpu: [arm64] os: [darwin] - turbo-darwin-arm64@2.6.2: - resolution: {integrity: sha512-mmm0jFaVramST26XE1Lk2qjkjvLJHOe9f3TFjqY+aByjMK/ZmKE5WFPuCWo4L3xhwx+16T37rdPP//76loB3oA==} + turbo-darwin-arm64@2.6.3: + resolution: {integrity: sha512-MwVt7rBKiOK7zdYerenfCRTypefw4kZCue35IJga9CH1+S50+KTiCkT6LBqo0hHeoH2iKuI0ldTF2a0aB72z3w==} cpu: [arm64] os: [darwin] @@ -3678,8 +3678,8 @@ packages: cpu: [x64] os: [linux] - turbo-linux-64@2.6.2: - resolution: {integrity: sha512-IUMHjkVRJDUABGpi+iS1Le59aOl5DX88U5UT/mKaE7nNEjG465+a8UtYno56cZnLP+C6BkX4I93LFgYf9syjGQ==} + turbo-linux-64@2.6.3: + resolution: {integrity: sha512-cqpcw+dXxbnPtNnzeeSyWprjmuFVpHJqKcs7Jym5oXlu/ZcovEASUIUZVN3OGEM6Y/OTyyw0z09tOHNt5yBAVg==} cpu: [x64] os: [linux] @@ -3688,8 +3688,8 @@ packages: cpu: [arm64] os: [linux] - turbo-linux-arm64@2.6.2: - resolution: {integrity: sha512-0qQdZiimMUZj2Gfq87thYu0E02NaNcsB3lcEK/TD70Zzi7AxQoxye664Gis0Uao2j2L9/+05wC2btZ7SoFX3Gw==} + turbo-linux-arm64@2.6.3: + resolution: {integrity: sha512-MterpZQmjXyr4uM7zOgFSFL3oRdNKeflY7nsjxJb2TklsYqiu3Z9pQ4zRVFFH8n0mLGna7MbQMZuKoWqqHb45w==} cpu: [arm64] os: [linux] @@ -3698,8 +3698,8 @@ packages: cpu: [x64] os: [win32] - turbo-windows-64@2.6.2: - resolution: {integrity: sha512-BmMfFmt0VaoZL4NbtDq/dzGfjHsPoGU2+vFiZtkiYsttHY3fd/Dmgnu9PuRyJN1pv2M22q88rXO+dqYRHztLMw==} + turbo-windows-64@2.6.3: + resolution: {integrity: sha512-biDU70v9dLwnBdLf+daoDlNJVvqOOP8YEjqNipBHzgclbQlXbsi6Gqqelp5er81Qo3BiRgmTNx79oaZQTPb07Q==} cpu: [x64] os: [win32] @@ -3708,8 +3708,8 @@ packages: cpu: [arm64] os: [win32] - turbo-windows-arm64@2.6.2: - resolution: {integrity: sha512-0r4s4M/FgLxfjrdLPdqQUur8vZAtaWEi4jhkQ6wCIN2xzA9aee9IKwM53w7CQcjaLvWhT0AU7LTQHjFaHwxiKw==} + turbo-windows-arm64@2.6.3: + resolution: {integrity: sha512-dDHVKpSeukah3VsI/xMEKeTnV9V9cjlpFSUs4bmsUiLu3Yv2ENlgVEZv65wxbeE0bh0jjpmElDT+P1KaCxArQQ==} cpu: [arm64] os: [win32] @@ -3717,8 +3717,8 @@ packages: resolution: {integrity: sha512-qBwXXuDT3rA53kbNafGbT5r++BrhRgx3sAo0cHoDAeG9g1ItTmUMgltz3Hy7Hazy1ODqNpR+C7QwqL6DYB52yA==} hasBin: true - turbo@2.6.2: - resolution: {integrity: sha512-LiQAFS6iWvnY8ViGtoPgduWBeuGH9B32XR4p8H8jxU5PudwyHiiyf1jQW0fCC8gCCTz9itkIbqZLIyUu5AG33w==} + turbo@2.6.3: + resolution: {integrity: sha512-bf6YKUv11l5Xfcmg76PyWoy/e2vbkkxFNBGJSnfdSXQC33ZiUfutYh6IXidc5MhsnrFkWfdNNLyaRk+kHMLlwA==} hasBin: true type-check@0.4.0: @@ -4548,7 +4548,7 @@ snapshots: globby: 11.1.0 read-yaml-file: 1.1.0 - '@next/env@15.5.7': {} + '@next/env@15.5.9': {} '@next/eslint-plugin-next@15.5.5': dependencies: @@ -5151,7 +5151,7 @@ snapshots: no-case: 2.3.2 upper-case: 1.1.3 - caniuse-lite@1.0.30001759: {} + caniuse-lite@1.0.30001760: {} cbor2@1.12.0: {} @@ -5620,11 +5620,11 @@ snapshots: string.prototype.matchall: 4.0.12 string.prototype.repeat: 1.0.0 - eslint-plugin-turbo@2.5.8(eslint@9.37.0)(turbo@2.6.2): + eslint-plugin-turbo@2.5.8(eslint@9.37.0)(turbo@2.6.3): dependencies: dotenv: 16.0.3 eslint: 9.37.0 - turbo: 2.6.2 + turbo: 2.6.3 eslint-scope@8.4.0: dependencies: @@ -6489,11 +6489,11 @@ snapshots: netmask@2.0.2: {} - next@15.5.7(react-dom@19.2.0(react@19.2.0))(react@19.2.0): + next@15.5.9(react-dom@19.2.0(react@19.2.0))(react@19.2.0): dependencies: - '@next/env': 15.5.7 + '@next/env': 15.5.9 '@swc/helpers': 0.5.15 - caniuse-lite: 1.0.30001759 + caniuse-lite: 1.0.30001760 postcss: 8.4.31 react: 19.2.0 react-dom: 19.2.0(react@19.2.0) @@ -7376,37 +7376,37 @@ snapshots: turbo-darwin-64@2.6.1: optional: true - turbo-darwin-64@2.6.2: + turbo-darwin-64@2.6.3: optional: true turbo-darwin-arm64@2.6.1: optional: true - turbo-darwin-arm64@2.6.2: + turbo-darwin-arm64@2.6.3: optional: true turbo-linux-64@2.6.1: optional: true - turbo-linux-64@2.6.2: + turbo-linux-64@2.6.3: optional: true turbo-linux-arm64@2.6.1: optional: true - turbo-linux-arm64@2.6.2: + turbo-linux-arm64@2.6.3: optional: true turbo-windows-64@2.6.1: optional: true - turbo-windows-64@2.6.2: + turbo-windows-64@2.6.3: optional: true turbo-windows-arm64@2.6.1: optional: true - turbo-windows-arm64@2.6.2: + turbo-windows-arm64@2.6.3: optional: true turbo@2.6.1: @@ -7418,14 +7418,14 @@ snapshots: turbo-windows-64: 2.6.1 turbo-windows-arm64: 2.6.1 - turbo@2.6.2: + turbo@2.6.3: optionalDependencies: - turbo-darwin-64: 2.6.2 - turbo-darwin-arm64: 2.6.2 - turbo-linux-64: 2.6.2 - turbo-linux-arm64: 2.6.2 - turbo-windows-64: 2.6.2 - turbo-windows-arm64: 2.6.2 + turbo-darwin-64: 2.6.3 + turbo-darwin-arm64: 2.6.3 + turbo-linux-64: 2.6.3 + turbo-linux-arm64: 2.6.3 + turbo-windows-64: 2.6.3 + turbo-windows-arm64: 2.6.3 type-check@0.4.0: dependencies: From ccdafe66ac8f86c79868765a15000f92a5a435fc Mon Sep 17 00:00:00 2001 From: Taylan Pince Date: Tue, 16 Dec 2025 08:38:33 +0100 Subject: [PATCH 05/39] Pin foundry to v1.5.0 instead of nightly (#947) --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 3003e531e..20d477729 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -30,7 +30,7 @@ jobs: - name: Install Foundry uses: foundry-rs/foundry-toolchain@v1 with: - version: nightly + version: v1.5.0 - name: Start Anvil in background run: anvil --fork-url https://nodes.sequence.app/arbitrum & - run: pnpm build From ee064420adbc3bee6f191df64f427f8036c7983d Mon Sep 17 00:00:00 2001 From: Corban Riley Date: Tue, 16 Dec 2025 09:51:33 -0500 Subject: [PATCH 06/39] Include repo and extras in syncpack config to ensure deps are synced (#945) * Include repo and extras in syncpack config to ensure deps are synced across all * Updating support deps * Updating deps * Updating pnpm lock * Fixing type errors within wdk tests --- extras/docs/package.json | 18 +- extras/web/package.json | 18 +- package.json | 12 +- packages/services/api/package.json | 2 +- packages/services/builder/package.json | 2 +- packages/services/guard/package.json | 4 +- .../services/identity-instrument/package.json | 4 +- packages/services/indexer/package.json | 2 +- packages/services/marketplace/package.json | 2 +- packages/services/metadata/package.json | 2 +- packages/services/relayer/package.json | 4 +- packages/services/userdata/package.json | 2 +- packages/utils/abi/package.json | 2 +- packages/wallet/core/package.json | 6 +- packages/wallet/dapp-client/package.json | 8 +- packages/wallet/primitives-cli/package.json | 6 +- packages/wallet/primitives/package.json | 4 +- packages/wallet/wdk/package.json | 8 +- packages/wallet/wdk/src/sequence/manager.ts | 1 + .../wallet/wdk/test/authcode-pkce.test.ts | 8 +- packages/wallet/wdk/test/authcode.test.ts | 28 +- packages/wallet/wdk/test/constants.ts | 15 +- packages/wallet/wdk/test/guard.test.ts | 16 +- .../wallet/wdk/test/identity-auth-dbs.test.ts | 8 +- .../wallet/wdk/test/identity-signer.test.ts | 32 +- packages/wallet/wdk/test/messages.test.ts | 30 +- packages/wallet/wdk/test/otp.test.ts | 16 +- packages/wallet/wdk/test/passkeys.test.ts | 8 +- packages/wallet/wdk/test/recovery.test.ts | 12 +- packages/wallet/wdk/test/sessions.test.ts | 4 +- packages/wallet/wdk/test/setup.ts | 2 +- packages/wallet/wdk/test/transactions.test.ts | 78 +- packages/wallet/wdk/test/wallets.test.ts | 80 +- pnpm-lock.yaml | 2168 ++++++++--------- repo/eslint-config/package.json | 18 +- repo/ui/package.json | 14 +- 36 files changed, 1284 insertions(+), 1360 deletions(-) diff --git a/extras/docs/package.json b/extras/docs/package.json index abadc74fd..29fbc4bc7 100644 --- a/extras/docs/package.json +++ b/extras/docs/package.json @@ -12,18 +12,18 @@ "clean": "rimraf .next" }, "dependencies": { - "@repo/ui": "workspace:*", + "@repo/ui": "workspace:^", "next": "^15.5.9", - "react": "^19.1.0", - "react-dom": "^19.1.0" + "react": "^19.2.3", + "react-dom": "^19.2.3" }, "devDependencies": { - "@repo/eslint-config": "workspace:*", - "@repo/typescript-config": "workspace:*", - "@types/node": "^20.17.57", - "@types/react": "^19.2.6", + "@repo/eslint-config": "workspace:^", + "@repo/typescript-config": "workspace:^", + "@types/node": "^25.0.2", + "@types/react": "^19.2.7", "@types/react-dom": "^19.2.3", - "eslint": "^9.28.0", - "typescript": "^5.8.3" + "eslint": "^9.39.2", + "typescript": "^5.9.3" } } diff --git a/extras/web/package.json b/extras/web/package.json index 3b57fed2b..b0b621e95 100644 --- a/extras/web/package.json +++ b/extras/web/package.json @@ -12,18 +12,18 @@ "clean": "rimraf .next" }, "dependencies": { - "@repo/ui": "workspace:*", + "@repo/ui": "workspace:^", "next": "^15.5.9", - "react": "^19.1.0", - "react-dom": "^19.1.0" + "react": "^19.2.3", + "react-dom": "^19.2.3" }, "devDependencies": { - "@repo/eslint-config": "workspace:*", - "@repo/typescript-config": "workspace:*", - "@types/node": "^20.17.57", - "@types/react": "^19.2.6", + "@repo/eslint-config": "workspace:^", + "@repo/typescript-config": "workspace:^", + "@types/node": "^25.0.2", + "@types/react": "^19.2.7", "@types/react-dom": "^19.2.3", - "eslint": "^9.28.0", - "typescript": "^5.8.3" + "eslint": "^9.39.2", + "typescript": "^5.9.3" } } diff --git a/package.json b/package.json index 483cd0936..53a8caae3 100644 --- a/package.json +++ b/package.json @@ -20,12 +20,12 @@ "deps:fix": "syncpack fix-mismatches" }, "devDependencies": { - "@changesets/cli": "^2.29.4", - "lefthook": "^2.0.4", - "prettier": "^3.5.3", + "@changesets/cli": "^2.29.8", + "lefthook": "^2.0.12", + "prettier": "^3.7.4", "rimraf": "^6.1.2", "syncpack": "^13.0.4", - "turbo": "^2.6.1", + "turbo": "^2.6.3", "typescript": "^5.9.3" }, "pnpm": { @@ -40,7 +40,9 @@ "syncpack": { "source": [ "package.json", - "packages/**/package.json" + "packages/**/package.json", + "extras/**/package.json", + "repo/**/package.json" ], "versionGroups": [ { diff --git a/packages/services/api/package.json b/packages/services/api/package.json index 20fc284b0..dda4d0fd7 100644 --- a/packages/services/api/package.json +++ b/packages/services/api/package.json @@ -22,7 +22,7 @@ }, "devDependencies": { "@repo/typescript-config": "workspace:^", - "@types/node": "^24.10.1", + "@types/node": "^25.0.2", "typescript": "^5.9.3" } } diff --git a/packages/services/builder/package.json b/packages/services/builder/package.json index 5f20f458b..a6da87826 100644 --- a/packages/services/builder/package.json +++ b/packages/services/builder/package.json @@ -22,7 +22,7 @@ }, "devDependencies": { "@repo/typescript-config": "workspace:^", - "@types/node": "^24.10.1", + "@types/node": "^25.0.2", "typescript": "^5.9.3" } } diff --git a/packages/services/guard/package.json b/packages/services/guard/package.json index 225211817..542b9ee55 100644 --- a/packages/services/guard/package.json +++ b/packages/services/guard/package.json @@ -25,9 +25,9 @@ }, "devDependencies": { "@repo/typescript-config": "workspace:^", - "@types/node": "^24.10.1", + "@types/node": "^25.0.2", "typescript": "^5.9.3", - "vitest": "^4.0.14" + "vitest": "^4.0.15" }, "dependencies": { "ox": "^0.9.17" diff --git a/packages/services/identity-instrument/package.json b/packages/services/identity-instrument/package.json index b025b75c8..dfdd56b3e 100644 --- a/packages/services/identity-instrument/package.json +++ b/packages/services/identity-instrument/package.json @@ -20,9 +20,9 @@ }, "devDependencies": { "@repo/typescript-config": "workspace:^", - "@types/node": "^24.10.1", + "@types/node": "^25.0.2", "typescript": "^5.9.3", - "vitest": "^4.0.14" + "vitest": "^4.0.15" }, "dependencies": { "json-canonicalize": "^2.0.0", diff --git a/packages/services/indexer/package.json b/packages/services/indexer/package.json index 03ec99a79..bb4ea0b6f 100644 --- a/packages/services/indexer/package.json +++ b/packages/services/indexer/package.json @@ -22,7 +22,7 @@ }, "devDependencies": { "@repo/typescript-config": "workspace:^", - "@types/node": "^24.10.1", + "@types/node": "^25.0.2", "typescript": "^5.9.3" } } diff --git a/packages/services/marketplace/package.json b/packages/services/marketplace/package.json index b454b44ae..47905f591 100644 --- a/packages/services/marketplace/package.json +++ b/packages/services/marketplace/package.json @@ -22,7 +22,7 @@ }, "devDependencies": { "@repo/typescript-config": "workspace:^", - "@types/node": "^24.10.1", + "@types/node": "^25.0.2", "typescript": "^5.9.3" } } diff --git a/packages/services/metadata/package.json b/packages/services/metadata/package.json index b31905d3a..5f30c7600 100644 --- a/packages/services/metadata/package.json +++ b/packages/services/metadata/package.json @@ -22,7 +22,7 @@ }, "devDependencies": { "@repo/typescript-config": "workspace:^", - "@types/node": "^24.10.1", + "@types/node": "^25.0.2", "typescript": "^5.9.3" } } diff --git a/packages/services/relayer/package.json b/packages/services/relayer/package.json index 9778d1e8e..e87885932 100644 --- a/packages/services/relayer/package.json +++ b/packages/services/relayer/package.json @@ -27,9 +27,9 @@ }, "devDependencies": { "@repo/typescript-config": "workspace:^", - "@types/node": "^24.10.1", + "@types/node": "^25.0.2", "typescript": "^5.9.3", - "vitest": "^4.0.14" + "vitest": "^4.0.15" }, "dependencies": { "@0xsequence/wallet-primitives": "workspace:^", diff --git a/packages/services/userdata/package.json b/packages/services/userdata/package.json index dedb4e953..36237bc95 100644 --- a/packages/services/userdata/package.json +++ b/packages/services/userdata/package.json @@ -22,7 +22,7 @@ }, "devDependencies": { "@repo/typescript-config": "workspace:^", - "@types/node": "^24.10.1", + "@types/node": "^25.0.2", "typescript": "^5.9.3" } } diff --git a/packages/utils/abi/package.json b/packages/utils/abi/package.json index ac07e0f0a..d2df92de1 100644 --- a/packages/utils/abi/package.json +++ b/packages/utils/abi/package.json @@ -22,7 +22,7 @@ }, "devDependencies": { "@repo/typescript-config": "workspace:^", - "@types/node": "^24.10.1", + "@types/node": "^25.0.2", "typescript": "^5.9.3" } } diff --git a/packages/wallet/core/package.json b/packages/wallet/core/package.json index 682ed0d06..8e58e5641 100644 --- a/packages/wallet/core/package.json +++ b/packages/wallet/core/package.json @@ -23,12 +23,12 @@ }, "devDependencies": { "@repo/typescript-config": "workspace:^", - "@types/node": "^24.10.1", - "@vitest/coverage-v8": "^4.0.14", + "@types/node": "^25.0.2", + "@vitest/coverage-v8": "^4.0.15", "dotenv": "^17.2.3", "fake-indexeddb": "^6.2.5", "typescript": "^5.9.3", - "vitest": "^4.0.14" + "vitest": "^4.0.15" }, "dependencies": { "@0xsequence/guard": "workspace:^", diff --git a/packages/wallet/dapp-client/package.json b/packages/wallet/dapp-client/package.json index d67d1ea7d..7ce4dae81 100644 --- a/packages/wallet/dapp-client/package.json +++ b/packages/wallet/dapp-client/package.json @@ -21,13 +21,13 @@ }, "devDependencies": { "@repo/typescript-config": "workspace:^", - "@types/node": "^24.10.1", - "@vitest/coverage-v8": "^4.0.14", + "@types/node": "^25.0.2", + "@vitest/coverage-v8": "^4.0.15", "dotenv": "^17.2.3", "fake-indexeddb": "^6.2.5", - "happy-dom": "^20.0.10", + "happy-dom": "^20.0.11", "typescript": "^5.9.3", - "vitest": "^4.0.14" + "vitest": "^4.0.15" }, "dependencies": { "@0xsequence/guard": "workspace:^", diff --git a/packages/wallet/primitives-cli/package.json b/packages/wallet/primitives-cli/package.json index ee00f2a2a..0a8c978d4 100644 --- a/packages/wallet/primitives-cli/package.json +++ b/packages/wallet/primitives-cli/package.json @@ -21,12 +21,12 @@ } }, "devDependencies": { - "@repo/eslint-config": "workspace:*", + "@repo/eslint-config": "workspace:^", "@repo/typescript-config": "workspace:^", - "@types/node": "^24.10.1", + "@types/node": "^25.0.2", "@types/yargs": "^17.0.35", "concurrently": "^9.2.1", - "esbuild": "^0.27.0", + "esbuild": "^0.27.1", "nodemon": "^3.1.11", "typescript": "^5.9.3" }, diff --git a/packages/wallet/primitives/package.json b/packages/wallet/primitives/package.json index 83f97b33c..3b1ffdbec 100644 --- a/packages/wallet/primitives/package.json +++ b/packages/wallet/primitives/package.json @@ -23,9 +23,9 @@ }, "devDependencies": { "@repo/typescript-config": "workspace:^", - "@vitest/coverage-v8": "^4.0.14", + "@vitest/coverage-v8": "^4.0.15", "typescript": "^5.9.3", - "vitest": "^4.0.14" + "vitest": "^4.0.15" }, "dependencies": { "ox": "^0.9.17" diff --git a/packages/wallet/wdk/package.json b/packages/wallet/wdk/package.json index 87d1a45a5..2c0dc66e3 100644 --- a/packages/wallet/wdk/package.json +++ b/packages/wallet/wdk/package.json @@ -24,13 +24,13 @@ }, "devDependencies": { "@repo/typescript-config": "workspace:^", - "@types/node": "^24.10.1", - "@vitest/coverage-v8": "^4.0.14", + "@types/node": "^25.0.2", + "@vitest/coverage-v8": "^4.0.15", "dotenv": "^17.2.3", "fake-indexeddb": "^6.2.5", - "happy-dom": "^20.0.10", + "happy-dom": "^20.0.11", "typescript": "^5.9.3", - "vitest": "^4.0.14" + "vitest": "^4.0.15" }, "dependencies": { "@0xsequence/guard": "workspace:^", diff --git a/packages/wallet/wdk/src/sequence/manager.ts b/packages/wallet/wdk/src/sequence/manager.ts index 9fe04d13c..a55059cbf 100644 --- a/packages/wallet/wdk/src/sequence/manager.ts +++ b/packages/wallet/wdk/src/sequence/manager.ts @@ -37,6 +37,7 @@ export type ManagerOptions = { extensions?: Extensions.Extensions context?: Context.Context + context4337?: Context.Context guest?: Address.Address encryptedPksDb?: CoreSigners.Pk.Encrypted.EncryptedPksDb diff --git a/packages/wallet/wdk/test/authcode-pkce.test.ts b/packages/wallet/wdk/test/authcode-pkce.test.ts index 2e62b8afd..c69e66d71 100644 --- a/packages/wallet/wdk/test/authcode-pkce.test.ts +++ b/packages/wallet/wdk/test/authcode-pkce.test.ts @@ -1,10 +1,10 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' import { Address, Hex, Bytes } from 'ox' import * as Identity from '@0xsequence/identity-instrument' -import { AuthCodePkceHandler } from '../src/sequence/handlers/authcode-pkce' -import { Signatures } from '../src/sequence/signatures' -import * as Db from '../src/dbs' -import { IdentitySigner } from '../src/identity/signer' +import { AuthCodePkceHandler } from '../src/sequence/handlers/authcode-pkce.js' +import { Signatures } from '../src/sequence/signatures.js' +import * as Db from '../src/dbs/index.js' +import { IdentitySigner } from '../src/identity/signer.js' describe('AuthCodePkceHandler', () => { let handler: AuthCodePkceHandler diff --git a/packages/wallet/wdk/test/authcode.test.ts b/packages/wallet/wdk/test/authcode.test.ts index 121a03348..4874e475b 100644 --- a/packages/wallet/wdk/test/authcode.test.ts +++ b/packages/wallet/wdk/test/authcode.test.ts @@ -2,11 +2,11 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' import { Address, Hex, Bytes } from 'ox' import { Network, Payload } from '@0xsequence/wallet-primitives' import { IdentityInstrument, IdentityType, KeyType, AuthCodeChallenge } from '@0xsequence/identity-instrument' -import { AuthCodeHandler } from '../src/sequence/handlers/authcode' -import { Signatures } from '../src/sequence/signatures' -import * as Db from '../src/dbs' -import { IdentitySigner } from '../src/identity/signer' -import { BaseSignatureRequest } from '../src/sequence/types/signature-request' +import { AuthCodeHandler } from '../src/sequence/handlers/authcode.js' +import { Signatures } from '../src/sequence/signatures.js' +import * as Db from '../src/dbs/index.js' +import { IdentitySigner } from '../src/identity/signer.js' +import { BaseSignatureRequest } from '../src/sequence/types/signature-request.js' // Mock the global crypto API const mockCryptoSubtle = { @@ -254,7 +254,7 @@ describe('AuthCodeHandler', () => { // Verify commitment was saved expect(mockAuthCommitmentsSet).toHaveBeenCalledOnce() - const commitmentCall = mockAuthCommitmentsSet.mock.calls[0][0] + const commitmentCall = mockAuthCommitmentsSet.mock.calls[0]![0]! expect(commitmentCall.kind).toBe('google-pkce') expect(commitmentCall.signer).toBe(signer) @@ -279,7 +279,7 @@ describe('AuthCodeHandler', () => { const result = await authCodeHandler.commitAuth('/target', false, customState) // Verify commitment uses custom state - const commitmentCall = mockAuthCommitmentsSet.mock.calls[0][0] + const commitmentCall = mockAuthCommitmentsSet.mock.calls[0]![0]! expect(commitmentCall.id).toBe(customState) expect(result).toContain(`state=${customState}`) }) @@ -287,7 +287,7 @@ describe('AuthCodeHandler', () => { it('Should generate random state when not provided', async () => { const result = await authCodeHandler.commitAuth('/target', false) - const commitmentCall = mockAuthCommitmentsSet.mock.calls[0][0] + const commitmentCall = mockAuthCommitmentsSet.mock.calls[0]![0]! expect(commitmentCall.id).toBeDefined() expect(typeof commitmentCall.id).toBe('string') expect(commitmentCall.id.startsWith('0x')).toBe(true) @@ -316,7 +316,7 @@ describe('AuthCodeHandler', () => { it('Should create commitment without signer', async () => { const result = await authCodeHandler.commitAuth('/target', true) - const commitmentCall = mockAuthCommitmentsSet.mock.calls[0][0] + const commitmentCall = mockAuthCommitmentsSet.mock.calls[0]![0]! expect(commitmentCall.signer).toBeUndefined() expect(commitmentCall.isSignUp).toBe(true) }) @@ -348,12 +348,12 @@ describe('AuthCodeHandler', () => { // Verify commitVerifier was called expect(mockCommitVerifier).toHaveBeenCalledOnce() - const commitVerifierCall = mockCommitVerifier.mock.calls[0] + const commitVerifierCall = mockCommitVerifier.mock.calls[0]! expect(commitVerifierCall[1]).toBeInstanceOf(AuthCodeChallenge) // Verify completeAuth was called expect(mockCompleteAuth).toHaveBeenCalledOnce() - const completeAuthCall = mockCompleteAuth.mock.calls[0] + const completeAuthCall = mockCompleteAuth.mock.calls[0]! expect(completeAuthCall[1]).toBeInstanceOf(AuthCodeChallenge) // Verify results @@ -490,7 +490,7 @@ describe('AuthCodeHandler', () => { expect(window.location.href).toContain('https://accounts.google.com/o/oauth2/v2/auth') expect(mockAuthCommitmentsSet).toHaveBeenCalledOnce() - const commitmentCall = mockAuthCommitmentsSet.mock.calls[0][0] + const commitmentCall = mockAuthCommitmentsSet.mock.calls[0]![0]! expect(commitmentCall.target).toBe(window.location.pathname) expect(commitmentCall.isSignUp).toBe(false) expect(commitmentCall.signer).toBe(testWallet) @@ -711,14 +711,14 @@ describe('AuthCodeHandler', () => { // Test signup flow await authCodeHandler.commitAuth('/signup-target', true, 'signup-state') - const signupCall = mockAuthCommitmentsSet.mock.calls[0][0] + const signupCall = mockAuthCommitmentsSet.mock.calls[0]![0]! expect(signupCall.isSignUp).toBe(true) expect(signupCall.target).toBe('/signup-target') // Test login flow await authCodeHandler.commitAuth('/login-target', false, 'login-state') - const loginCall = mockAuthCommitmentsSet.mock.calls[1][0] + const loginCall = mockAuthCommitmentsSet.mock.calls[1]![0]! expect(loginCall.isSignUp).toBe(false) expect(loginCall.target).toBe('/login-target') }) diff --git a/packages/wallet/wdk/test/constants.ts b/packages/wallet/wdk/test/constants.ts index 14b099614..01dff3b50 100644 --- a/packages/wallet/wdk/test/constants.ts +++ b/packages/wallet/wdk/test/constants.ts @@ -1,9 +1,10 @@ import { config as dotenvConfig } from 'dotenv' import { Abi, Address, Provider, RpcTransport } from 'ox' -import { Manager, ManagerOptions, ManagerOptionsDefaults } from '../src/sequence' -import { mockEthereum } from './setup' -import { Signers as CoreSigners, State, Relayer } from '@0xsequence/wallet-core' -import * as Db from '../src/dbs' +import { Manager, ManagerOptions, ManagerOptionsDefaults } from '../src/sequence/index.js' +import { mockEthereum } from './setup.js' +import { Signers as CoreSigners, State, Bundler } from '@0xsequence/wallet-core' +import { Relayer } from '@0xsequence/relayer' +import * as Db from '../src/dbs/index.js' import { Network } from '@0xsequence/wallet-primitives' const envFile = process.env.CI ? '.env.test' : '.env.test.local' @@ -81,16 +82,16 @@ export function newRemoteManager( : `_testrun_${testIdCounter}` let relayers: Relayer.Relayer[] = [] - let bundlers: Relayer.Bundler[] = [] + let bundlers: Bundler.Bundler[] = [] if (remoteManagerOptions.network.relayerPk) { const provider = Provider.from(RpcTransport.fromHttp(remoteManagerOptions.network.rpcUrl)) - relayers.push(new Relayer.Standard.PkRelayer(remoteManagerOptions.network.relayerPk as `0x${string}`, provider)) + relayers.push(new Relayer.PkRelayer(remoteManagerOptions.network.relayerPk as `0x${string}`, provider)) } if (remoteManagerOptions.network.bundlerUrl) { bundlers.push( - new Relayer.Bundlers.PimlicoBundler( + new Bundler.Bundlers.PimlicoBundler( remoteManagerOptions.network.bundlerUrl, Provider.from(RpcTransport.fromHttp(remoteManagerOptions.network.rpcUrl)), ), diff --git a/packages/wallet/wdk/test/guard.test.ts b/packages/wallet/wdk/test/guard.test.ts index 44e7e2cb5..8614de6c2 100644 --- a/packages/wallet/wdk/test/guard.test.ts +++ b/packages/wallet/wdk/test/guard.test.ts @@ -1,11 +1,11 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import { Manager } from '../src/sequence' -import { GuardHandler } from '../src/sequence/handlers/guard' +import { Manager } from '../src/sequence/index.js' +import { GuardHandler } from '../src/sequence/handlers/guard.js' import { Address, Bytes, Hex, TypedData } from 'ox' import { Config, Constants, Network, Payload } from '@0xsequence/wallet-primitives' -import { Kinds } from '../src/sequence/types/signer' -import { newManager } from './constants' -import { GuardRole, Guards } from '../src/sequence/guards' +import { Kinds } from '../src/sequence/types/signer.js' +import { newManager } from './constants.js' +import { GuardRole, Guards } from '../src/sequence/guards.js' // Mock fetch globally for guard API calls const mockFetch = vi.fn() @@ -163,7 +163,7 @@ describe('GuardHandler', () => { expect(result).toBe(true) expect(mockAddSignature).toHaveBeenCalledOnce() - const [requestId, signatureData] = mockAddSignature.mock.calls[0] + const [requestId, signatureData] = mockAddSignature.mock.calls[0]! expect(requestId).toBe('test-request-id') expect(signatureData.address).toBe(guards.getByRole('wallet').address) expect(signatureData.signature).toBeDefined() @@ -247,7 +247,7 @@ describe('GuardHandler', () => { expect(mockCallback).toHaveBeenCalledOnce() expect(mockAddSignature).toHaveBeenCalledOnce() - const [requestId, signatureData] = mockAddSignature.mock.calls[0] + const [requestId, signatureData] = mockAddSignature.mock.calls[0]! expect(requestId).toBe('test-request-id') expect(signatureData.address).toBe(guards.getByRole('wallet').address) expect(signatureData.signature).toBeDefined() @@ -300,7 +300,7 @@ describe('GuardHandler', () => { signatures: [], }) - expect(mockFetch.mock.calls[0][0]).toContain(customGuardUrl) + expect(mockFetch.mock.calls[0]![0]).toContain(customGuardUrl) await customManager.stop() }) diff --git a/packages/wallet/wdk/test/identity-auth-dbs.test.ts b/packages/wallet/wdk/test/identity-auth-dbs.test.ts index 43f6e0b5b..eccc8b885 100644 --- a/packages/wallet/wdk/test/identity-auth-dbs.test.ts +++ b/packages/wallet/wdk/test/identity-auth-dbs.test.ts @@ -1,9 +1,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import { Manager } from '../src/sequence' -import { Address, Hex, Bytes } from 'ox' -import { IdentityInstrument } from '@0xsequence/identity-instrument' -import * as Db from '../src/dbs' -import { LOCAL_RPC_URL } from './constants' +import { Manager } from '../src/sequence/index.js' +import * as Db from '../src/dbs/index.js' +import { LOCAL_RPC_URL } from './constants.js' import { State } from '@0xsequence/wallet-core' import { Network } from '@0xsequence/wallet-primitives' diff --git a/packages/wallet/wdk/test/identity-signer.test.ts b/packages/wallet/wdk/test/identity-signer.test.ts index 5eb9c42b4..9d62f5719 100644 --- a/packages/wallet/wdk/test/identity-signer.test.ts +++ b/packages/wallet/wdk/test/identity-signer.test.ts @@ -1,10 +1,10 @@ -import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import { Address, Hex, Bytes } from 'ox' +import { afterEach, beforeEach, describe, expect, it, Mock, vi } from 'vitest' +import { Address, Bytes, Hex } from 'ox' import { Network, Payload } from '@0xsequence/wallet-primitives' import { IdentityInstrument, KeyType } from '@0xsequence/identity-instrument' import { State } from '@0xsequence/wallet-core' -import { IdentitySigner, toIdentityAuthKey } from '../src/identity/signer' -import { AuthKey } from '../src/dbs/auth-keys' +import { IdentitySigner, toIdentityAuthKey } from '../src/identity/signer.js' +import { AuthKey } from '../src/dbs/auth-keys.js' // Mock the global crypto API const mockCryptoSubtle = { @@ -31,7 +31,7 @@ describe('Identity Signer', () => { let testAuthKey: AuthKey let testWallet: Address.Address let mockStateWriter: State.Writer - let mockSignFn: ReturnType + let mockSignFn: Mock beforeEach(() => { vi.clearAllMocks() @@ -179,7 +179,7 @@ describe('Identity Signer', () => { // Verify that identityInstrument.sign was called with correct parameters expect(mockSignFn).toHaveBeenCalledOnce() - const [authKeyArg, digestArg] = mockSignFn.mock.calls[0] + const [authKeyArg, digestArg] = mockSignFn.mock.calls[0]! expect(authKeyArg.address).toBe(testAuthKey.address) expect(authKeyArg.signer).toBe(testAuthKey.identitySigner) expect(digestArg).toBeDefined() @@ -196,7 +196,7 @@ describe('Identity Signer', () => { expect(mockSignFn).toHaveBeenCalledOnce() // The digest should be different for different chainIds - const [, digestArg] = mockSignFn.mock.calls[0] + const [, digestArg] = mockSignFn.mock.calls[0]! expect(digestArg).toBeDefined() }) @@ -255,7 +255,7 @@ describe('Identity Signer', () => { } expect(mockSignFn).toHaveBeenCalledOnce() - const [authKeyArg, digestArg] = mockSignFn.mock.calls[0] + const [authKeyArg, digestArg] = mockSignFn.mock.calls[0]! expect(authKeyArg.address).toBe(testAuthKey.address) expect(digestArg).toBe(digest) }) @@ -295,7 +295,7 @@ describe('Identity Signer', () => { it('Should handle malformed signature from identity instrument', async () => { const digest = Hex.toBytes('0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef') - mockSignFn.mockResolvedValueOnce('invalid-signature') + mockSignFn.mockResolvedValueOnce('invalid-signature' as any) await expect(identitySigner.signDigest(digest)).rejects.toThrow() // Should throw when Signature.fromHex fails }) @@ -317,7 +317,7 @@ describe('Identity Signer', () => { // Verify witness was saved expect(mockSaveWitnesses).toHaveBeenCalledOnce() - const [wallet, chainId, payload, witness] = mockSaveWitnesses.mock.calls[0] + const [wallet, chainId, payload, witness] = mockSaveWitnesses.mock.calls[0]! expect(wallet).toBe(testWallet) expect(chainId).toBe(0) // Witness signatures use chainId 0 @@ -338,7 +338,7 @@ describe('Identity Signer', () => { await identitySigner.witness(mockStateWriter, testWallet) // Extract the payload that was signed - const [, , payload] = mockSaveWitnesses.mock.calls[0] + const [, , payload] = mockSaveWitnesses.mock.calls[0]! // Parse the message content to verify consent structure const messageHex = payload.message @@ -367,7 +367,7 @@ describe('Identity Signer', () => { await identitySigner.witness(mockStateWriter, testWallet, extraData) // Extract and verify extra data was included - const [, , payload] = mockSaveWitnesses.mock.calls[0] + const [, , payload] = mockSaveWitnesses.mock.calls[0]! const messageString = Hex.toString(payload.message) const consentData = JSON.parse(messageString) @@ -435,7 +435,7 @@ describe('Identity Signer', () => { expect(mockSaveWitnesses).toHaveBeenCalledOnce() // Verify witness payload includes extra context - const [, , witnessPayload] = mockSaveWitnesses.mock.calls[0] + const [, , witnessPayload] = mockSaveWitnesses.mock.calls[0]! const witnessMessage = JSON.parse(Hex.toString(witnessPayload.message)) expect(witnessMessage.signatureId).toBe('sig-123') expect(witnessMessage.purpose).toBe('authentication') @@ -469,8 +469,8 @@ describe('Identity Signer', () => { expect(mockSignFn).toHaveBeenCalledTimes(2) // Verify different payloads produce different hashes - const [, messageDigest] = mockSignFn.mock.calls[0] - const [, transactionDigest] = mockSignFn.mock.calls[1] + const [, messageDigest] = mockSignFn.mock.calls[0]! + const [, transactionDigest] = mockSignFn.mock.calls[1]! expect(messageDigest).not.toEqual(transactionDigest) }) }) @@ -500,7 +500,7 @@ describe('Identity Signer', () => { it('Should handle malformed hex signatures', async () => { const digest = Hex.toBytes('0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef') - mockSignFn.mockResolvedValueOnce('not-a-hex-string') + mockSignFn.mockResolvedValueOnce('not-a-hex-string' as any) await expect(identitySigner.signDigest(digest)).rejects.toThrow() }) diff --git a/packages/wallet/wdk/test/messages.test.ts b/packages/wallet/wdk/test/messages.test.ts index 9420ca000..32d68ffe5 100644 --- a/packages/wallet/wdk/test/messages.test.ts +++ b/packages/wallet/wdk/test/messages.test.ts @@ -1,7 +1,7 @@ import { afterEach, beforeEach, describe, expect, it } from 'vitest' -import { Manager, SignerActionable } from '../src/sequence' +import { Manager, SignerActionable } from '../src/sequence/index.js' import { Mnemonic } from 'ox' -import { newManager } from './constants' +import { newManager } from './constants.js' import { Network } from '@0xsequence/wallet-primitives' describe('Messages', () => { @@ -41,12 +41,13 @@ describe('Messages', () => { // Verify message appears in list const messages = await manager.messages.list() expect(messages.length).toBe(1) - expect(messages[0].wallet).toBe(wallet) - expect(messages[0].message).toBe(testMessage) - expect(messages[0].status).toBe('requested') - expect(messages[0].signatureId).toBe(signatureId) - expect(messages[0].source).toBe('unknown') - expect(messages[0].id).toBeDefined() + const message = messages[0]! + expect(message.wallet).toBe(wallet) + expect(message.message).toBe(testMessage) + expect(message.status).toBe('requested') + expect(message.signatureId).toBe(signatureId) + expect(message.source).toBe('unknown') + expect(message.id).toBeDefined() }) it('Should create message request with custom source', async () => { @@ -63,8 +64,11 @@ describe('Messages', () => { const messages = await manager.messages.list() expect(messages.length).toBe(1) - expect(messages[0].source).toBe(customSource) - expect(messages[0].message).toBe(testMessage) + + const message = messages[0]! + + expect(message.source).toBe(customSource) + expect(message.message).toBe(testMessage) }) it('Should get message by ID', async () => { @@ -79,7 +83,7 @@ describe('Messages', () => { const messages = await manager.messages.list() expect(messages.length).toBe(1) - const messageId = messages[0].id + const messageId = messages[0]!.id // Get by message ID const retrievedMessage = await manager.messages.get(messageId) @@ -269,7 +273,7 @@ describe('Messages', () => { const signatureId = await manager.messages.request(wallet!, testMessage) const messages = await manager.messages.list() - const messageId = messages[0].id + const messageId = messages[0]!.id let updateCallCount = 0 let lastMessage: any @@ -315,7 +319,7 @@ describe('Messages', () => { await manager.messages.request(wallet!, testMessage) const messages = await manager.messages.list() - const messageId = messages[0].id + const messageId = messages[0]!.id let callCount = 0 let receivedMessage: any diff --git a/packages/wallet/wdk/test/otp.test.ts b/packages/wallet/wdk/test/otp.test.ts index 1ad450227..f3ae45209 100644 --- a/packages/wallet/wdk/test/otp.test.ts +++ b/packages/wallet/wdk/test/otp.test.ts @@ -1,13 +1,13 @@ -import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' +import { afterEach, beforeEach, describe, expect, it, Mock, vi } from 'vitest' import { Address, Hex } from 'ox' import { Network, Payload } from '@0xsequence/wallet-primitives' import { IdentityInstrument, IdentityType, KeyType, OtpChallenge } from '@0xsequence/identity-instrument' -import { OtpHandler } from '../src/sequence/handlers/otp' -import { Signatures } from '../src/sequence/signatures' -import * as Db from '../src/dbs' -import { IdentitySigner } from '../src/identity/signer' -import { BaseSignatureRequest } from '../src/sequence/types/signature-request' -import { Kinds } from '../src/sequence/types/signer' +import { OtpHandler, PromptOtpHandler } from '../src/sequence/handlers/otp.js' +import { Signatures } from '../src/sequence/signatures.js' +import * as Db from '../src/dbs/index.js' +import { IdentitySigner } from '../src/identity/signer.js' +import { BaseSignatureRequest } from '../src/sequence/types/signature-request.js' +import { Kinds } from '../src/sequence/types/signer.js' // Mock the global crypto API const mockCryptoSubtle = { @@ -69,7 +69,7 @@ describe('OtpHandler', () => { let otpHandler: OtpHandler let testWallet: Address.Address let testRequest: BaseSignatureRequest - let mockPromptOtp: ReturnType + let mockPromptOtp: Mock beforeEach(() => { vi.clearAllMocks() diff --git a/packages/wallet/wdk/test/passkeys.test.ts b/packages/wallet/wdk/test/passkeys.test.ts index 857258c23..199265822 100644 --- a/packages/wallet/wdk/test/passkeys.test.ts +++ b/packages/wallet/wdk/test/passkeys.test.ts @@ -3,10 +3,10 @@ import { Address, Hex } from 'ox' import { Network, Payload } from '@0xsequence/wallet-primitives' import { Signers, State } from '@0xsequence/wallet-core' import { Extensions } from '@0xsequence/wallet-primitives' -import { PasskeysHandler } from '../src/sequence/handlers/passkeys' -import { Signatures } from '../src/sequence/signatures' -import { BaseSignatureRequest } from '../src/sequence/types/signature-request' -import { Kinds } from '../src/sequence/types/signer' +import { PasskeysHandler } from '../src/sequence/handlers/passkeys.js' +import { Signatures } from '../src/sequence/signatures.js' +import { BaseSignatureRequest } from '../src/sequence/types/signature-request.js' +import { Kinds } from '../src/sequence/types/signer.js' // Mock dependencies with proper vi.fn() types const mockAddSignature = vi.fn() diff --git a/packages/wallet/wdk/test/recovery.test.ts b/packages/wallet/wdk/test/recovery.test.ts index 9401260ab..3ca6da075 100644 --- a/packages/wallet/wdk/test/recovery.test.ts +++ b/packages/wallet/wdk/test/recovery.test.ts @@ -1,8 +1,8 @@ import { describe, expect, it } from 'vitest' -import { Manager, QueuedRecoveryPayload, SignerReady, TransactionDefined } from '../src/sequence' +import { QueuedRecoveryPayload, SignerReady, TransactionDefined } from '../src/sequence/index.js' import { Bytes, Hex, Mnemonic, Provider, RpcTransport } from 'ox' import { Network, Payload } from '@0xsequence/wallet-primitives' -import { LOCAL_RPC_URL, newManager } from './constants' +import { LOCAL_RPC_URL, newManager } from './constants.js' describe('Recovery', () => { it('Should execute a recovery', async () => { @@ -159,7 +159,7 @@ describe('Recovery', () => { expect(tx.status).toBe('defined') expect((tx as TransactionDefined).relayerOptions.length).toBe(1) - const localRelayer = (tx as TransactionDefined).relayerOptions[0] + const localRelayer = (tx as TransactionDefined).relayerOptions[0]! expect(localRelayer).toBeDefined() expect(localRelayer.relayerId).toBe('local') @@ -332,7 +332,7 @@ describe('Recovery', () => { expect(Array.isArray(fetchedPayloads)).toBeTruthy() expect(fetchedPayloads.length).toBe(1) - const fetchedPayload = fetchedPayloads[0] + const fetchedPayload = fetchedPayloads[0]! expect(fetchedPayload).toBeDefined() expect(fetchedPayload.wallet).toBe(wallet) expect(fetchedPayload.chainId).toBe(Network.ChainId.ARBITRUM) @@ -390,8 +390,8 @@ describe('Recovery', () => { expect(updatedPayloads.length).toBe(fetchedPayloads2.length) if (updatedPayloads.length > 0 && fetchedPayloads.length > 0) { - const updated = updatedPayloads[0] - const fetched = fetchedPayloads[0] + const updated = updatedPayloads[0]! + const fetched = fetchedPayloads[0]! expect(updated.id).toBe(fetched.id) expect(updated.wallet).toBe(fetched.wallet) diff --git a/packages/wallet/wdk/test/sessions.test.ts b/packages/wallet/wdk/test/sessions.test.ts index 4e3c9a2ca..98a762d3e 100644 --- a/packages/wallet/wdk/test/sessions.test.ts +++ b/packages/wallet/wdk/test/sessions.test.ts @@ -4,7 +4,7 @@ import { Signers as CoreSigners, Wallet as CoreWallet, Envelope, State } from '. import { ExplicitSession } from '../../core/src/utils/session/types.js' import { Context, Extensions, Network, Payload, Permission } from '../../primitives/src/index.js' import { Sequence } from '../src/index.js' -import { EMITTER_ABI, EMITTER_ADDRESS, LOCAL_RPC_URL } from './constants' +import { EMITTER_ABI, EMITTER_ADDRESS, LOCAL_RPC_URL } from './constants.js' const ALL_EXTENSIONS: { name: string @@ -402,7 +402,7 @@ for (const extension of ALL_EXTENSIONS) { // Now we modify the permissions target contract to zero address // This should cause any session call to the EMITTER_ADDRESS contract to fail - explicitSession.permissions[0].target = '0x0000000000000000000000000000000000000000' + explicitSession.permissions[0]!.target = '0x0000000000000000000000000000000000000000' await setupExplicitSession(explicitSession, true) diff --git a/packages/wallet/wdk/test/setup.ts b/packages/wallet/wdk/test/setup.ts index 70482040c..4aa336a55 100644 --- a/packages/wallet/wdk/test/setup.ts +++ b/packages/wallet/wdk/test/setup.ts @@ -14,7 +14,7 @@ import { } from 'fake-indexeddb' import { Provider, RpcTransport } from 'ox' import { vi } from 'vitest' -import { LOCAL_RPC_URL } from './constants' +import { LOCAL_RPC_URL } from './constants.js' // Add IndexedDB support to the test environment using fake-indexeddb global.indexedDB = indexedDB diff --git a/packages/wallet/wdk/test/transactions.test.ts b/packages/wallet/wdk/test/transactions.test.ts index 91bffa56a..910511e7a 100644 --- a/packages/wallet/wdk/test/transactions.test.ts +++ b/packages/wallet/wdk/test/transactions.test.ts @@ -1,7 +1,13 @@ import { afterEach, describe, expect, it, vi } from 'vitest' -import { Manager, SignerActionable, Transaction, TransactionDefined, TransactionRelayed } from '../src/sequence' +import { + Manager, + SignerActionable, + Transaction, + TransactionDefined, + TransactionRelayed, +} from '../src/sequence/index.js' import { Address, Hex, Mnemonic, Provider, RpcTransport } from 'ox' -import { LOCAL_RPC_URL, newManager } from './constants' +import { LOCAL_RPC_URL, newManager } from './constants.js' import { Payload, Network } from '@0xsequence/wallet-primitives' describe('Transactions', () => { @@ -48,9 +54,9 @@ describe('Transactions', () => { } expect(tx.relayerOptions.length).toBe(1) - expect(tx.relayerOptions[0].id).toBeDefined() + expect(tx.relayerOptions[0]!.id).toBeDefined() - const sigId = await manager.transactions.selectRelayer(txId!, tx.relayerOptions[0].id) + const sigId = await manager.transactions.selectRelayer(txId!, tx.relayerOptions[0]!.id) expect(sigId).toBeDefined() tx = await manager.transactions.get(txId!) @@ -161,9 +167,9 @@ describe('Transactions', () => { } expect(tx.relayerOptions.length).toBe(1) - expect(tx.relayerOptions[0].id).toBeDefined() + expect(tx.relayerOptions[0]!.id).toBeDefined() - const sigId = await manager.transactions.selectRelayer(txId!, tx.relayerOptions[0].id) + const sigId = await manager.transactions.selectRelayer(txId!, tx.relayerOptions[0]!.id) expect(sigId).toBeDefined() tx = await manager.transactions.get(txId!) @@ -230,11 +236,12 @@ describe('Transactions', () => { expect(calledTimes).toBe(1) expect(transactions.length).toBe(1) - expect(transactions[0].status).toBe('requested') - expect(transactions[0].wallet).toBe(wallet!) - expect(transactions[0].requests.length).toBe(1) - expect(transactions[0].requests[0].to).toEqual(to) - expect(transactions[0].requests[0].value).toEqual(9n) + const tx = transactions[0]! + expect(tx.status).toBe('requested') + expect(tx.wallet).toBe(wallet!) + expect(tx.requests.length).toBe(1) + expect(tx.requests[0]!.to).toEqual(to) + expect(tx.requests[0]!.value).toEqual(9n) }) it('Should call onTransactionUpdate when a transaction is defined, relayer selected and relayed', async () => { @@ -273,12 +280,12 @@ describe('Transactions', () => { expect(tx!.status).toBe('defined') expect(tx!.wallet).toBe(wallet!) expect(tx!.requests.length).toBe(1) - expect(tx!.requests[0].to).toEqual(to) - expect(tx!.requests[0].value).toBeUndefined() - expect(tx!.requests[0].gasLimit).toBeUndefined() - expect(tx!.requests[0].data).toBeUndefined() + expect(tx!.requests[0]!.to).toEqual(to) + expect(tx!.requests[0]!.value).toBeUndefined() + expect(tx!.requests[0]!.gasLimit).toBeUndefined() + expect(tx!.requests[0]!.data).toBeUndefined() - const sigId = await manager.transactions.selectRelayer(txId!, (tx as TransactionDefined).relayerOptions[0].id) + const sigId = await manager.transactions.selectRelayer(txId!, (tx as TransactionDefined).relayerOptions[0]!.id) expect(sigId).toBeDefined() while (calledTimes < 2) { @@ -374,7 +381,7 @@ describe('Transactions', () => { expect(tx).toBeDefined() expect(tx!.status).toBe('defined') - const sigId = await manager.transactions.selectRelayer(txId!, (tx as TransactionDefined).relayerOptions[0].id) + const sigId = await manager.transactions.selectRelayer(txId!, (tx as TransactionDefined).relayerOptions[0]!.id) expect(sigId).toBeDefined() await manager.transactions.delete(txId!) @@ -433,12 +440,12 @@ describe('Transactions', () => { // The first call should be to the random address // and the second one should be a call to self - const call1 = (tx.envelope.payload as Payload.Calls).calls[0] - const call2 = (tx.envelope.payload as Payload.Calls).calls[1] + const call1 = (tx.envelope.payload as Payload.Calls).calls[0]! + const call2 = (tx.envelope.payload as Payload.Calls).calls[1]! expect(call1.to).toEqual(randomAddress) expect(call2.to).toEqual(wallet) - const sigId = await manager.transactions.selectRelayer(txId!, (tx as TransactionDefined).relayerOptions[0].id) + const sigId = await manager.transactions.selectRelayer(txId!, (tx as TransactionDefined).relayerOptions[0]!.id) expect(sigId).toBeDefined() tx = await manager.transactions.get(txId!) @@ -540,9 +547,10 @@ describe('Transactions', () => { // Should now have one transaction expect(transactionsList.length).toBe(1) - expect(transactionsList[0].id).toBe(txId) - expect(transactionsList[0].status).toBe('requested') - expect(transactionsList[0].wallet).toBe(wallet) + const tx = transactionsList[0]! + expect(tx.id).toBe(txId) + expect(tx.status).toBe('requested') + expect(tx.wallet).toBe(wallet) unsubscribe() }) @@ -577,7 +585,7 @@ describe('Transactions', () => { expect(callCount).toBe(1) expect(receivedTransactions.length).toBe(1) - expect(receivedTransactions[0].id).toBe(txId) + expect(receivedTransactions[0]!.id).toBe(txId) unsubscribe() }) @@ -697,8 +705,8 @@ describe('Transactions', () => { const tx = await manager.transactions.get(txId) expect(tx.status).toBe('defined') - expect(tx.envelope.payload.calls[0].gasLimit).toBe(50000n) - expect(tx.envelope.payload.calls[1].gasLimit).toBe(75000n) + expect(tx.envelope.payload.calls[0]!.gasLimit).toBe(50000n) + expect(tx.envelope.payload.calls[1]!.gasLimit).toBe(75000n) }) it('Should throw error when defining transaction not in requested state', async () => { @@ -780,8 +788,8 @@ describe('Transactions', () => { expect(tx.status).toBe('requested') expect(tx.source).toBe('test-dapp') expect(tx.envelope.payload.space).toBe(customSpace) - expect(tx.requests[0].data).toBe('0x1234') - expect(tx.requests[0].gasLimit).toBe(21000n) + expect(tx.requests[0]!.data).toBe('0x1234') + expect(tx.requests[0]!.gasLimit).toBe(21000n) }) it('Should throw error for unknown network', async () => { @@ -820,12 +828,12 @@ describe('Transactions', () => { const tx = await manager.transactions.get(txId) expect(tx.status).toBe('requested') - expect(tx.envelope.payload.calls[0].value).toBe(0n) - expect(tx.envelope.payload.calls[0].data).toBe('0x') - expect(tx.envelope.payload.calls[0].gasLimit).toBe(0n) - expect(tx.envelope.payload.calls[0].delegateCall).toBe(false) - expect(tx.envelope.payload.calls[0].onlyFallback).toBe(false) - expect(tx.envelope.payload.calls[0].behaviorOnError).toBe('revert') + expect(tx.envelope.payload.calls[0]!.value).toBe(0n) + expect(tx.envelope.payload.calls[0]!.data).toBe('0x') + expect(tx.envelope.payload.calls[0]!.gasLimit).toBe(0n) + expect(tx.envelope.payload.calls[0]!.delegateCall).toBe(false) + expect(tx.envelope.payload.calls[0]!.onlyFallback).toBe(false) + expect(tx.envelope.payload.calls[0]!.behaviorOnError).toBe('revert') }) it('Should handle relay with signature ID instead of transaction ID', async () => { @@ -856,7 +864,7 @@ describe('Transactions', () => { throw new Error('Transaction not defined') } - const sigId = await manager.transactions.selectRelayer(txId, tx.relayerOptions[0].id) + const sigId = await manager.transactions.selectRelayer(txId, tx.relayerOptions[0]!.id) // Sign the transaction const sigRequest = await manager.signatures.get(sigId) diff --git a/packages/wallet/wdk/test/wallets.test.ts b/packages/wallet/wdk/test/wallets.test.ts index ec3265b50..99e71d73d 100644 --- a/packages/wallet/wdk/test/wallets.test.ts +++ b/packages/wallet/wdk/test/wallets.test.ts @@ -1,7 +1,7 @@ import { afterEach, describe, expect, it } from 'vitest' -import { Manager, SignerActionable, SignerReady } from '../src/sequence' +import { Manager, SignerActionable, SignerReady } from '../src/sequence/index.js' import { Mnemonic, Address } from 'ox' -import { newManager } from './constants' +import { newManager } from './constants.js' import { Config, Constants, Network } from '@0xsequence/wallet-primitives' describe('Wallets', () => { @@ -65,7 +65,7 @@ describe('Wallets', () => { const walletsAfterFirst = await manager.wallets.list() expect(walletsAfterFirst.length).toBe(1) - expect(walletsAfterFirst[0].address).toBe(wallet1) + expect(walletsAfterFirst[0]!.address).toBe(wallet1) }) // === WALLET SELECTOR REGISTRATION === @@ -283,14 +283,14 @@ describe('Wallets', () => { expect(config.devices).toBeDefined() expect(config.devices.length).toBe(1) - expect(config.devices[0].kind).toBe('local-device') - expect(config.devices[0].address).toBeDefined() + expect(config.devices[0]!.kind).toBe('local-device') + expect(config.devices[0]!.address).toBeDefined() expect(config.login).toBeDefined() expect(config.login.length).toBe(1) - expect(config.login[0].kind).toBe('login-mnemonic') + expect(config.login[0]!.kind).toBe('login-mnemonic') - expect(config.guard).not.toBeDefined() // No guard for noGuard: true + expect(config.walletGuard).not.toBeDefined() // No guard for noGuard: true expect(config.raw).toBeDefined() expect(config.raw.loginTopology).toBeDefined() @@ -319,7 +319,9 @@ describe('Wallets', () => { Config.findSignerLeaf(config.raw.guardTopology!, Constants.PlaceholderAddress as Address.Address), ).toBeUndefined() - const sessionsModule = config.raw.modules.find((m) => Address.isEqual(m.sapientLeaf.address, sessionsModuleAddress)) + const sessionsModule = config.raw.modules.find((m: any) => + Address.isEqual(m.sapientLeaf.address, sessionsModuleAddress), + ) expect(sessionsModule?.guardLeaf).toBeDefined() expect(Config.findSignerLeaf(sessionsModule!.guardLeaf!, sessionsGuardAddress)).toBeDefined() expect( @@ -360,7 +362,9 @@ describe('Wallets', () => { ).toBeUndefined() const sessionsModuleAddress = (manager as any).shared.sequence.extensions.sessions - const sessionsModule = config.raw.modules.find((m) => Address.isEqual(m.sapientLeaf.address, sessionsModuleAddress)) + const sessionsModule = config.raw.modules.find((m: any) => + Address.isEqual(m.sapientLeaf.address, sessionsModuleAddress), + ) expect(sessionsModule?.guardLeaf).toBeDefined() expect(Config.findSignerLeaf(sessionsModule!.guardLeaf!, sessionsGuardAddress)).toBeDefined() }) @@ -406,7 +410,7 @@ describe('Wallets', () => { const mnemonic = Mnemonic.random(Mnemonic.english) await manager.wallets.signUp({ mnemonic, kind: 'mnemonic', noGuard: true }) - await manager.wallets.logout(await manager.wallets.list().then((w) => w[0].address), { skipRemoveDevice: true }) + await manager.wallets.logout(await manager.wallets.list().then((w) => w[0]!.address), { skipRemoveDevice: true }) const invalidSelector = async () => 'invalid-result' as any manager.wallets.registerWalletSelector(invalidSelector) @@ -426,7 +430,7 @@ describe('Wallets', () => { const wallets = await manager.wallets.list() expect(wallets.length).toBe(1) - expect(wallets[0].address).toBe(wallet!) + expect(wallets[0]!.address).toBe(wallet!) const requestId = await manager.wallets.logout(wallet!) expect(requestId).toBeDefined() @@ -466,16 +470,16 @@ describe('Wallets', () => { const wallets = await manager.wallets.list() expect(wallets.length).toBe(1) - expect(wallets[0].address).toBe(wallet!) - expect(wallets[0].status).toBe('ready') + expect(wallets[0]!.address).toBe(wallet!) + expect(wallets[0]!.status).toBe('ready') const requestId = await manager.wallets.logout(wallet!) expect(requestId).toBeDefined() const wallets2 = await manager.wallets.list() expect(wallets2.length).toBe(1) - expect(wallets2[0].address).toBe(wallet!) - expect(wallets2[0].status).toBe('logging-out') + expect(wallets2[0]!.address).toBe(wallet!) + expect(wallets2[0]!.status).toBe('logging-out') const request = await manager.signatures.get(requestId) expect(request).toBeDefined() @@ -511,8 +515,8 @@ describe('Wallets', () => { const wallets = await manager.wallets.list() expect(wallets.length).toBe(1) - expect(wallets[0].address).toBe(wallet!) - expect(wallets[0].status).toBe('logging-in') + expect(wallets[0]!.address).toBe(wallet!) + expect(wallets[0]!.status).toBe('logging-in') let signRequests = 0 const unregistedUI = manager.registerMnemonicUI(async (respond) => { @@ -539,8 +543,8 @@ describe('Wallets', () => { expect((await manager.signatures.get(requestId1!))?.status).toBe('completed') const wallets2 = await manager.wallets.list() expect(wallets2.length).toBe(1) - expect(wallets2[0].address).toBe(wallet!) - expect(wallets2[0].status).toBe('ready') + expect(wallets2[0]!.address).toBe(wallet!) + expect(wallets2[0]!.status).toBe('ready') // The wallet should have 2 device keys and 2 recovery keys const config = await manager.wallets.getConfiguration(wallet!) @@ -560,7 +564,7 @@ describe('Wallets', () => { const wallets = await manager.wallets.list() expect(wallets.length).toBe(1) - expect(wallets[0].address).toBe(wallet!) + expect(wallets[0]!.address).toBe(wallet!) const requestId = await manager.wallets.logout(wallet!) expect(requestId).toBeDefined() @@ -609,7 +613,7 @@ describe('Wallets', () => { expect((await manager.signatures.get(requestId2!))?.status).toBe('completed') const wallets3 = await manager.wallets.list() expect(wallets3.length).toBe(1) - expect(wallets3[0].address).toBe(wallet!) + expect(wallets3[0]!.address).toBe(wallet!) // The wallet should have a single device key and a single recovery key const config = await manager.wallets.getConfiguration(wallet!) @@ -618,10 +622,10 @@ describe('Wallets', () => { expect(recovery?.length).toBe(1) // The kind of the device key should be 'local-device' - expect(config.devices[0].kind).toBe('local-device') + expect(config.devices[0]!.kind).toBe('local-device') // The kind of the recovery key should be 'local-recovery' - expect(recovery?.[0].kind).toBe('local-device') + expect(recovery?.[0]!.kind).toBe('local-device') }) it('Should fail to logout from a non-existent wallet', async () => { @@ -672,8 +676,8 @@ describe('Wallets', () => { const wallets = await manager.wallets.list() expect(wallets.length).toBe(1) - expect(wallets[0].address).toBe(wallet!) - expect(wallets[0].status).toBe('logging-in') + expect(wallets[0]!.address).toBe(wallet!) + expect(wallets[0]!.status).toBe('logging-in') const request = await manager.signatures.get(requestId!) expect(request).toBeDefined() @@ -695,8 +699,8 @@ describe('Wallets', () => { expect((await manager.signatures.get(requestId!))?.status).toBe('completed') const wallets2 = await manager.wallets.list() expect(wallets2.length).toBe(1) - expect(wallets2[0].address).toBe(wallet!) - expect(wallets2[0].status).toBe('ready') + expect(wallets2[0]!.address).toBe(wallet!) + expect(wallets2[0]!.status).toBe('ready') }) it('Should trigger an update when a wallet is logged in', async () => { @@ -711,8 +715,8 @@ describe('Wallets', () => { unregisterCallback = manager.wallets.onWalletsUpdate((wallets) => { callbackCalls++ expect(wallets.length).toBe(1) - expect(wallets[0].address).toBe(wallet!) - expect(wallets[0].status).toBe('ready') + expect(wallets[0]!.address).toBe(wallet!) + expect(wallets[0]!.status).toBe('ready') resolve() }) }) @@ -773,8 +777,8 @@ describe('Wallets', () => { unregisterCallback = manager.wallets.onWalletsUpdate((wallets) => { callbackCalls++ expect(wallets.length).toBe(1) - expect(wallets[0].address).toBe(wallet!) - expect(wallets[0].status).toBe('logging-out') + expect(wallets[0]!.address).toBe(wallet!) + expect(wallets[0]!.status).toBe('logging-out') resolve() }) }) @@ -796,9 +800,9 @@ describe('Wallets', () => { const devices = await manager.wallets.listDevices(wallet!) expect(devices.length).toBe(1) - expect(devices[0].address).not.toBe(wallet) - expect(devices[0].isLocal).toBe(true) expect(devices[0]).toBeDefined() + expect(devices[0]!.address).not.toBe(wallet) + expect(devices[0]!.isLocal).toBe(true) }) it('Should list all active devices for a wallet, including a new remote device', async () => { @@ -816,8 +820,8 @@ describe('Wallets', () => { // Verify initial state from Device 1's perspective const devices1 = await managerDevice1.wallets.listDevices(wallet!) expect(devices1.length).toBe(1) - expect(devices1[0].isLocal).toBe(true) - const device1Address = devices1[0].address + expect(devices1[0]!.isLocal).toBe(true) + const device1Address = devices1[0]!.address // Wallet logs in on device 2 const managerDevice2 = newManager(undefined, undefined, 'device-2') @@ -934,8 +938,8 @@ describe('Wallets', () => { const finalDevices = await managerDevice1.wallets.listDevices(wallet!) console.log('Final devices', finalDevices) expect(finalDevices.length).toBe(1) - expect(finalDevices[0].isLocal).toBe(true) - expect(finalDevices[0].address).not.toBe(device2Address) + expect(finalDevices[0]!.isLocal).toBe(true) + expect(finalDevices[0]!.address).not.toBe(device2Address) await managerDevice1.stop() await managerDevice2.stop() @@ -952,7 +956,7 @@ describe('Wallets', () => { const devices = await manager.wallets.listDevices(wallet!) expect(devices.length).toBe(1) - const localDeviceAddress = devices[0].address + const localDeviceAddress = devices[0]!.address const remoteLogoutPromise = manager.wallets.remoteLogout(wallet!, localDeviceAddress) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a5a389f7d..fdbb822b8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -12,14 +12,14 @@ importers: .: devDependencies: '@changesets/cli': - specifier: ^2.29.4 - version: 2.29.7(@types/node@24.10.1) + specifier: ^2.29.8 + version: 2.29.8(@types/node@25.0.2) lefthook: - specifier: ^2.0.4 - version: 2.0.4 + specifier: ^2.0.12 + version: 2.0.12 prettier: - specifier: ^3.5.3 - version: 3.6.2 + specifier: ^3.7.4 + version: 3.7.4 rimraf: specifier: ^6.1.2 version: 6.1.2 @@ -27,8 +27,8 @@ importers: specifier: ^13.0.4 version: 13.0.4(typescript@5.9.3) turbo: - specifier: ^2.6.1 - version: 2.6.1 + specifier: ^2.6.3 + version: 2.6.3 typescript: specifier: ^5.9.3 version: 5.9.3 @@ -36,76 +36,76 @@ importers: extras/docs: dependencies: '@repo/ui': - specifier: workspace:* + specifier: workspace:^ version: link:../../repo/ui next: specifier: ^15.5.9 - version: 15.5.9(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + version: 15.5.9(react-dom@19.2.3(react@19.2.3))(react@19.2.3) react: - specifier: ^19.1.0 - version: 19.2.0 + specifier: ^19.2.3 + version: 19.2.3 react-dom: - specifier: ^19.1.0 - version: 19.2.0(react@19.2.0) + specifier: ^19.2.3 + version: 19.2.3(react@19.2.3) devDependencies: '@repo/eslint-config': - specifier: workspace:* + specifier: workspace:^ version: link:../../repo/eslint-config '@repo/typescript-config': - specifier: workspace:* + specifier: workspace:^ version: link:../../repo/typescript-config '@types/node': - specifier: ^20.17.57 - version: 20.19.21 + specifier: ^25.0.2 + version: 25.0.2 '@types/react': - specifier: ^19.2.6 - version: 19.2.6 + specifier: ^19.2.7 + version: 19.2.7 '@types/react-dom': specifier: ^19.2.3 - version: 19.2.3(@types/react@19.2.6) + version: 19.2.3(@types/react@19.2.7) eslint: - specifier: ^9.28.0 - version: 9.37.0 + specifier: ^9.39.2 + version: 9.39.2 typescript: - specifier: ^5.8.3 - version: 5.8.3 + specifier: ^5.9.3 + version: 5.9.3 extras/web: dependencies: '@repo/ui': - specifier: workspace:* + specifier: workspace:^ version: link:../../repo/ui next: specifier: ^15.5.9 - version: 15.5.9(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + version: 15.5.9(react-dom@19.2.3(react@19.2.3))(react@19.2.3) react: - specifier: ^19.1.0 - version: 19.2.0 + specifier: ^19.2.3 + version: 19.2.3 react-dom: - specifier: ^19.1.0 - version: 19.2.0(react@19.2.0) + specifier: ^19.2.3 + version: 19.2.3(react@19.2.3) devDependencies: '@repo/eslint-config': - specifier: workspace:* + specifier: workspace:^ version: link:../../repo/eslint-config '@repo/typescript-config': - specifier: workspace:* + specifier: workspace:^ version: link:../../repo/typescript-config '@types/node': - specifier: ^20.17.57 - version: 20.19.21 + specifier: ^25.0.2 + version: 25.0.2 '@types/react': - specifier: ^19.2.6 - version: 19.2.6 + specifier: ^19.2.7 + version: 19.2.7 '@types/react-dom': specifier: ^19.2.3 - version: 19.2.3(@types/react@19.2.6) + version: 19.2.3(@types/react@19.2.7) eslint: - specifier: ^9.28.0 - version: 9.37.0 + specifier: ^9.39.2 + version: 9.39.2 typescript: - specifier: ^5.8.3 - version: 5.8.3 + specifier: ^5.9.3 + version: 5.9.3 packages/services/api: devDependencies: @@ -113,8 +113,8 @@ importers: specifier: workspace:^ version: link:../../../repo/typescript-config '@types/node': - specifier: ^24.10.1 - version: 24.10.1 + specifier: ^25.0.2 + version: 25.0.2 typescript: specifier: ^5.9.3 version: 5.9.3 @@ -125,8 +125,8 @@ importers: specifier: workspace:^ version: link:../../../repo/typescript-config '@types/node': - specifier: ^24.10.1 - version: 24.10.1 + specifier: ^25.0.2 + version: 25.0.2 typescript: specifier: ^5.9.3 version: 5.9.3 @@ -135,20 +135,20 @@ importers: dependencies: ox: specifier: ^0.9.17 - version: 0.9.17(typescript@5.9.3) + version: 0.9.17(typescript@5.9.3)(zod@4.2.0) devDependencies: '@repo/typescript-config': specifier: workspace:^ version: link:../../../repo/typescript-config '@types/node': - specifier: ^24.10.1 - version: 24.10.1 + specifier: ^25.0.2 + version: 25.0.2 typescript: specifier: ^5.9.3 version: 5.9.3 vitest: - specifier: ^4.0.14 - version: 4.0.14(@types/node@24.10.1)(happy-dom@20.0.10) + specifier: ^4.0.15 + version: 4.0.15(@types/node@25.0.2)(happy-dom@20.0.11) packages/services/identity-instrument: dependencies: @@ -160,20 +160,20 @@ importers: version: 4.0.0 ox: specifier: ^0.9.17 - version: 0.9.17(typescript@5.9.3) + version: 0.9.17(typescript@5.9.3)(zod@4.2.0) devDependencies: '@repo/typescript-config': specifier: workspace:^ version: link:../../../repo/typescript-config '@types/node': - specifier: ^24.10.1 - version: 24.10.1 + specifier: ^25.0.2 + version: 25.0.2 typescript: specifier: ^5.9.3 version: 5.9.3 vitest: - specifier: ^4.0.14 - version: 4.0.14(@types/node@24.10.1)(happy-dom@20.0.10) + specifier: ^4.0.15 + version: 4.0.15(@types/node@25.0.2)(happy-dom@20.0.11) packages/services/indexer: devDependencies: @@ -181,8 +181,8 @@ importers: specifier: workspace:^ version: link:../../../repo/typescript-config '@types/node': - specifier: ^24.10.1 - version: 24.10.1 + specifier: ^25.0.2 + version: 25.0.2 typescript: specifier: ^5.9.3 version: 5.9.3 @@ -193,8 +193,8 @@ importers: specifier: workspace:^ version: link:../../../repo/typescript-config '@types/node': - specifier: ^24.10.1 - version: 24.10.1 + specifier: ^25.0.2 + version: 25.0.2 typescript: specifier: ^5.9.3 version: 5.9.3 @@ -205,8 +205,8 @@ importers: specifier: workspace:^ version: link:../../../repo/typescript-config '@types/node': - specifier: ^24.10.1 - version: 24.10.1 + specifier: ^25.0.2 + version: 25.0.2 typescript: specifier: ^5.9.3 version: 5.9.3 @@ -221,23 +221,23 @@ importers: version: 0.0.7(typescript@5.9.3) ox: specifier: ^0.9.17 - version: 0.9.17(typescript@5.9.3) + version: 0.9.17(typescript@5.9.3)(zod@4.2.0) viem: specifier: ^2.40.3 - version: 2.40.3(typescript@5.9.3) + version: 2.42.1(typescript@5.9.3)(zod@4.2.0) devDependencies: '@repo/typescript-config': specifier: workspace:^ version: link:../../../repo/typescript-config '@types/node': - specifier: ^24.10.1 - version: 24.10.1 + specifier: ^25.0.2 + version: 25.0.2 typescript: specifier: ^5.9.3 version: 5.9.3 vitest: - specifier: ^4.0.14 - version: 4.0.14(@types/node@24.10.1)(happy-dom@20.0.10) + specifier: ^4.0.15 + version: 4.0.15(@types/node@25.0.2)(happy-dom@20.0.11) packages/services/userdata: devDependencies: @@ -245,8 +245,8 @@ importers: specifier: workspace:^ version: link:../../../repo/typescript-config '@types/node': - specifier: ^24.10.1 - version: 24.10.1 + specifier: ^25.0.2 + version: 25.0.2 typescript: specifier: ^5.9.3 version: 5.9.3 @@ -257,8 +257,8 @@ importers: specifier: workspace:^ version: link:../../../repo/typescript-config '@types/node': - specifier: ^24.10.1 - version: 24.10.1 + specifier: ^25.0.2 + version: 25.0.2 typescript: specifier: ^5.9.3 version: 5.9.3 @@ -279,20 +279,20 @@ importers: version: 0.0.7(typescript@5.9.3) ox: specifier: ^0.9.17 - version: 0.9.17(typescript@5.9.3) + version: 0.9.17(typescript@5.9.3)(zod@4.2.0) viem: specifier: ^2.40.3 - version: 2.40.3(typescript@5.9.3) + version: 2.42.1(typescript@5.9.3)(zod@4.2.0) devDependencies: '@repo/typescript-config': specifier: workspace:^ version: link:../../../repo/typescript-config '@types/node': - specifier: ^24.10.1 - version: 24.10.1 + specifier: ^25.0.2 + version: 25.0.2 '@vitest/coverage-v8': - specifier: ^4.0.14 - version: 4.0.14(vitest@4.0.14(@types/node@24.10.1)(happy-dom@20.0.10)) + specifier: ^4.0.15 + version: 4.0.15(vitest@4.0.15(@types/node@25.0.2)(happy-dom@20.0.11)) dotenv: specifier: ^17.2.3 version: 17.2.3 @@ -303,8 +303,8 @@ importers: specifier: ^5.9.3 version: 5.9.3 vitest: - specifier: ^4.0.14 - version: 4.0.14(@types/node@24.10.1)(happy-dom@20.0.10) + specifier: ^4.0.15 + version: 4.0.15(@types/node@25.0.2)(happy-dom@20.0.11) packages/wallet/dapp-client: dependencies: @@ -322,17 +322,17 @@ importers: version: link:../primitives ox: specifier: ^0.9.17 - version: 0.9.17(typescript@5.9.3) + version: 0.9.17(typescript@5.9.3)(zod@4.2.0) devDependencies: '@repo/typescript-config': specifier: workspace:^ version: link:../../../repo/typescript-config '@types/node': - specifier: ^24.10.1 - version: 24.10.1 + specifier: ^25.0.2 + version: 25.0.2 '@vitest/coverage-v8': - specifier: ^4.0.14 - version: 4.0.14(vitest@4.0.14(@types/node@24.10.1)(happy-dom@20.0.10)) + specifier: ^4.0.15 + version: 4.0.15(vitest@4.0.15(@types/node@25.0.2)(happy-dom@20.0.11)) dotenv: specifier: ^17.2.3 version: 17.2.3 @@ -340,33 +340,33 @@ importers: specifier: ^6.2.5 version: 6.2.5 happy-dom: - specifier: ^20.0.10 - version: 20.0.10 + specifier: ^20.0.11 + version: 20.0.11 typescript: specifier: ^5.9.3 version: 5.9.3 vitest: - specifier: ^4.0.14 - version: 4.0.14(@types/node@24.10.1)(happy-dom@20.0.10) + specifier: ^4.0.15 + version: 4.0.15(@types/node@25.0.2)(happy-dom@20.0.11) packages/wallet/primitives: dependencies: ox: specifier: ^0.9.17 - version: 0.9.17(typescript@5.9.3) + version: 0.9.17(typescript@5.9.3)(zod@4.2.0) devDependencies: '@repo/typescript-config': specifier: workspace:^ version: link:../../../repo/typescript-config '@vitest/coverage-v8': - specifier: ^4.0.14 - version: 4.0.14(vitest@4.0.14(@types/node@24.10.1)(happy-dom@20.0.10)) + specifier: ^4.0.15 + version: 4.0.15(vitest@4.0.15(@types/node@25.0.2)(happy-dom@20.0.11)) typescript: specifier: ^5.9.3 version: 5.9.3 vitest: - specifier: ^4.0.14 - version: 4.0.14(@types/node@24.10.1)(happy-dom@20.0.10) + specifier: ^4.0.15 + version: 4.0.15(@types/node@25.0.2)(happy-dom@20.0.11) packages/wallet/primitives-cli: dependencies: @@ -375,20 +375,20 @@ importers: version: link:../primitives ox: specifier: ^0.9.17 - version: 0.9.17(typescript@5.9.3) + version: 0.9.17(typescript@5.9.3)(zod@4.2.0) yargs: specifier: ^18.0.0 version: 18.0.0 devDependencies: '@repo/eslint-config': - specifier: workspace:* + specifier: workspace:^ version: link:../../../repo/eslint-config '@repo/typescript-config': specifier: workspace:^ version: link:../../../repo/typescript-config '@types/node': - specifier: ^24.10.1 - version: 24.10.1 + specifier: ^25.0.2 + version: 25.0.2 '@types/yargs': specifier: ^17.0.35 version: 17.0.35 @@ -396,8 +396,8 @@ importers: specifier: ^9.2.1 version: 9.2.1 esbuild: - specifier: ^0.27.0 - version: 0.27.0 + specifier: ^0.27.1 + version: 0.27.1 nodemon: specifier: ^3.1.11 version: 3.1.11 @@ -433,7 +433,7 @@ importers: version: 4.0.0 ox: specifier: ^0.9.17 - version: 0.9.17(typescript@5.9.3) + version: 0.9.17(typescript@5.9.3)(zod@4.2.0) uuid: specifier: ^13.0.0 version: 13.0.0 @@ -442,11 +442,11 @@ importers: specifier: workspace:^ version: link:../../../repo/typescript-config '@types/node': - specifier: ^24.10.1 - version: 24.10.1 + specifier: ^25.0.2 + version: 25.0.2 '@vitest/coverage-v8': - specifier: ^4.0.14 - version: 4.0.14(vitest@4.0.14(@types/node@24.10.1)(happy-dom@20.0.10)) + specifier: ^4.0.15 + version: 4.0.15(vitest@4.0.15(@types/node@25.0.2)(happy-dom@20.0.11)) dotenv: specifier: ^17.2.3 version: 17.2.3 @@ -454,83 +454,83 @@ importers: specifier: ^6.2.5 version: 6.2.5 happy-dom: - specifier: ^20.0.10 - version: 20.0.10 + specifier: ^20.0.11 + version: 20.0.11 typescript: specifier: ^5.9.3 version: 5.9.3 vitest: - specifier: ^4.0.14 - version: 4.0.14(@types/node@24.10.1)(happy-dom@20.0.10) + specifier: ^4.0.15 + version: 4.0.15(@types/node@25.0.2)(happy-dom@20.0.11) repo/eslint-config: devDependencies: '@eslint/js': - specifier: ^9.28.0 - version: 9.37.0 + specifier: ^9.39.2 + version: 9.39.2 '@next/eslint-plugin-next': - specifier: ^15.3.3 - version: 15.5.5 + specifier: ^15.5.9 + version: 15.5.9 eslint: - specifier: ^9.28.0 - version: 9.37.0 + specifier: ^9.39.2 + version: 9.39.2 eslint-config-prettier: - specifier: ^9.1.0 - version: 9.1.2(eslint@9.37.0) + specifier: ^10.1.8 + version: 10.1.8(eslint@9.39.2) eslint-plugin-only-warn: specifier: ^1.1.0 version: 1.1.0 eslint-plugin-react: specifier: ^7.37.5 - version: 7.37.5(eslint@9.37.0) + version: 7.37.5(eslint@9.39.2) eslint-plugin-react-hooks: - specifier: ^5.2.0 - version: 5.2.0(eslint@9.37.0) + specifier: ^7.0.1 + version: 7.0.1(eslint@9.39.2) eslint-plugin-turbo: - specifier: ^2.5.4 - version: 2.5.8(eslint@9.37.0)(turbo@2.6.3) + specifier: ^2.6.3 + version: 2.6.3(eslint@9.39.2)(turbo@2.6.3) globals: - specifier: ^15.15.0 - version: 15.15.0 + specifier: ^16.5.0 + version: 16.5.0 typescript: - specifier: ^5.8.3 - version: 5.8.3 + specifier: ^5.9.3 + version: 5.9.3 typescript-eslint: - specifier: ^8.33.1 - version: 8.46.1(eslint@9.37.0)(typescript@5.8.3) + specifier: ^8.49.0 + version: 8.50.0(eslint@9.39.2)(typescript@5.9.3) repo/typescript-config: {} repo/ui: dependencies: react: - specifier: ^19.1.0 - version: 19.2.0 + specifier: ^19.2.3 + version: 19.2.3 react-dom: - specifier: ^19.1.0 - version: 19.2.0(react@19.2.0) + specifier: ^19.2.3 + version: 19.2.3(react@19.2.3) devDependencies: '@repo/eslint-config': - specifier: workspace:* + specifier: workspace:^ version: link:../eslint-config '@repo/typescript-config': - specifier: workspace:* + specifier: workspace:^ version: link:../typescript-config '@turbo/gen': specifier: ^1.13.4 - version: 1.13.4(@types/node@20.19.21)(typescript@5.8.3) + version: 1.13.4(@types/node@25.0.2)(typescript@5.9.3) '@types/node': - specifier: ^20.17.57 - version: 20.19.21 + specifier: ^25.0.2 + version: 25.0.2 '@types/react': - specifier: ^19.2.6 - version: 19.2.6 + specifier: ^19.2.7 + version: 19.2.7 '@types/react-dom': specifier: ^19.2.3 - version: 19.2.3(@types/react@19.2.6) + version: 19.2.3(@types/react@19.2.7) typescript: - specifier: ^5.8.3 - version: 5.8.3 + specifier: ^5.9.3 + version: 5.9.3 packages: @@ -544,6 +544,36 @@ packages: resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} engines: {node: '>=6.9.0'} + '@babel/compat-data@7.28.5': + resolution: {integrity: sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.28.5': + resolution: {integrity: sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.28.5': + resolution: {integrity: sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-compilation-targets@7.27.2': + resolution: {integrity: sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-globals@7.28.0': + resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@7.27.1': + resolution: {integrity: sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-transforms@7.28.3': + resolution: {integrity: sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + '@babel/helper-string-parser@7.27.1': resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} engines: {node: '>=6.9.0'} @@ -552,6 +582,14 @@ packages: resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} engines: {node: '>=6.9.0'} + '@babel/helper-validator-option@7.27.1': + resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} + engines: {node: '>=6.9.0'} + + '@babel/helpers@7.28.4': + resolution: {integrity: sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==} + engines: {node: '>=6.9.0'} + '@babel/parser@7.28.5': resolution: {integrity: sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==} engines: {node: '>=6.0.0'} @@ -565,6 +603,14 @@ packages: resolution: {integrity: sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==} engines: {node: '>=6.9.0'} + '@babel/template@7.27.2': + resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.28.5': + resolution: {integrity: sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==} + engines: {node: '>=6.9.0'} + '@babel/types@7.28.5': resolution: {integrity: sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==} engines: {node: '>=6.9.0'} @@ -573,8 +619,8 @@ packages: resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==} engines: {node: '>=18'} - '@changesets/apply-release-plan@7.0.13': - resolution: {integrity: sha512-BIW7bofD2yAWoE8H4V40FikC+1nNFEKBisMECccS16W1rt6qqhNTBDmIw5HaqmMgtLNz9e7oiALiEUuKrQ4oHg==} + '@changesets/apply-release-plan@7.0.14': + resolution: {integrity: sha512-ddBvf9PHdy2YY0OUiEl3TV78mH9sckndJR14QAt87KLEbIov81XO0q0QAmvooBxXlqRRP8I9B7XOzZwQG7JkWA==} '@changesets/assemble-release-plan@6.0.9': resolution: {integrity: sha512-tPgeeqCHIwNo8sypKlS3gOPmsS3wP0zHt67JDuL20P4QcXiw/O4Hl7oXiuLnP9yg+rXLQ2sScdV1Kkzde61iSQ==} @@ -582,12 +628,12 @@ packages: '@changesets/changelog-git@0.2.1': resolution: {integrity: sha512-x/xEleCFLH28c3bQeQIyeZf8lFXyDFVn1SgcBiR2Tw/r4IAWlk1fzxCEZ6NxQAjF2Nwtczoen3OA2qR+UawQ8Q==} - '@changesets/cli@2.29.7': - resolution: {integrity: sha512-R7RqWoaksyyKXbKXBTbT4REdy22yH81mcFK6sWtqSanxUCbUi9Uf+6aqxZtDQouIqPdem2W56CdxXgsxdq7FLQ==} + '@changesets/cli@2.29.8': + resolution: {integrity: sha512-1weuGZpP63YWUYjay/E84qqwcnt5yJMM0tep10Up7Q5cS/DGe2IZ0Uj3HNMxGhCINZuR7aO9WBMdKnPit5ZDPA==} hasBin: true - '@changesets/config@3.1.1': - resolution: {integrity: sha512-bd+3Ap2TKXxljCggI0mKPfzCQKeV/TU4yO2h2C6vAihIo8tzseAn2e7klSuiyYYXvgu53zMN1OeYMIQkaQoWnA==} + '@changesets/config@3.1.2': + resolution: {integrity: sha512-CYiRhA4bWKemdYi/uwImjPxqWNpqGPNbEBdX1BdONALFIDK7MCUj6FPkzD+z9gJcvDFUQJn9aDVf4UG7OT6Kog==} '@changesets/errors@0.2.0': resolution: {integrity: sha512-6BLOQUscTpZeGljvyQXlWOItQyU71kCdGz7Pi8H8zdw6BI0g3m43iL4xKUVPWtG+qrrL9DTjpdn8eYuCQSRpow==} @@ -595,8 +641,8 @@ packages: '@changesets/get-dependents-graph@2.1.3': resolution: {integrity: sha512-gphr+v0mv2I3Oxt19VdWRRUxq3sseyUpX9DaHpTUmLj92Y10AGy+XOtV+kbM6L/fDcpx7/ISDFK6T8A/P3lOdQ==} - '@changesets/get-release-plan@4.0.13': - resolution: {integrity: sha512-DWG1pus72FcNeXkM12tx+xtExyH/c9I1z+2aXlObH3i9YA7+WZEVaiHzHl03thpvAgWTRaH64MpfHxozfF7Dvg==} + '@changesets/get-release-plan@4.0.14': + resolution: {integrity: sha512-yjZMHpUHgl4Xl5gRlolVuxDkm4HgSJqT93Ri1Uz8kGrQb+5iJ8dkXJ20M2j/Y4iV5QzS2c5SeTxVSKX+2eMI0g==} '@changesets/get-version-range-type@0.4.0': resolution: {integrity: sha512-hwawtob9DryoGTpixy1D3ZXbGgJu1Rhr+ySH2PvTLHvkZuQ7sRT4oQwMh0hbqZH1weAooedEjRsbrWcGLCeyVQ==} @@ -607,14 +653,14 @@ packages: '@changesets/logger@0.1.1': resolution: {integrity: sha512-OQtR36ZlnuTxKqoW4Sv6x5YIhOmClRd5pWsjZsddYxpWs517R0HkyiefQPIytCVh4ZcC5x9XaG8KTdd5iRQUfg==} - '@changesets/parse@0.4.1': - resolution: {integrity: sha512-iwksMs5Bf/wUItfcg+OXrEpravm5rEd9Bf4oyIPL4kVTmJQ7PNDSd6MDYkpSJR1pn7tz/k8Zf2DhTCqX08Ou+Q==} + '@changesets/parse@0.4.2': + resolution: {integrity: sha512-Uo5MC5mfg4OM0jU3up66fmSn6/NE9INK+8/Vn/7sMVcdWg46zfbvvUSjD9EMonVqPi9fbrJH9SXHn48Tr1f2yA==} '@changesets/pre@2.0.2': resolution: {integrity: sha512-HaL/gEyFVvkf9KFg6484wR9s0qjAXlZ8qWPDkTyKF6+zqjBe/I2mygg3MbpZ++hdi0ToqNUF8cjj7fBy0dg8Ug==} - '@changesets/read@0.6.5': - resolution: {integrity: sha512-UPzNGhsSjHD3Veb0xO/MwvasGe8eMyNrR/sT9gR8Q3DhOQZirgKhhXv/8hVsI0QpPjR004Z9iFxoJU6in3uGMg==} + '@changesets/read@0.6.6': + resolution: {integrity: sha512-P5QaN9hJSQQKJShzzpBT13FzOSPyHbqdoIBUd2DJdgvnECCyO6LmAOWSV+O8se2TaZJVwSXjL+v9yhb+a9JeJg==} '@changesets/should-skip-package@0.1.2': resolution: {integrity: sha512-qAK/WrqWLNCP22UDdBTMPH5f41elVDlsNyat180A33dWxuUDyNpg6fPi/FyTZwRriVjg0L8gnjJn2F9XAoF0qw==} @@ -635,314 +681,158 @@ packages: '@emnapi/runtime@1.7.1': resolution: {integrity: sha512-PVtJr5CmLwYAU9PZDMITZoR5iAOShYREoR45EyyLrbntV50mdePTgUn4AmOw90Ifcj+x2kRjdzr1HP3RrNiHGA==} - '@esbuild/aix-ppc64@0.25.11': - resolution: {integrity: sha512-Xt1dOL13m8u0WE8iplx9Ibbm+hFAO0GsU2P34UNoDGvZYkY8ifSiy6Zuc1lYxfG7svWE2fzqCUmFp5HCn51gJg==} + '@esbuild/aix-ppc64@0.27.1': + resolution: {integrity: sha512-HHB50pdsBX6k47S4u5g/CaLjqS3qwaOVE5ILsq64jyzgMhLuCuZ8rGzM9yhsAjfjkbgUPMzZEPa7DAp7yz6vuA==} engines: {node: '>=18'} cpu: [ppc64] os: [aix] - '@esbuild/aix-ppc64@0.27.0': - resolution: {integrity: sha512-KuZrd2hRjz01y5JK9mEBSD3Vj3mbCvemhT466rSuJYeE/hjuBrHfjjcjMdTm/sz7au+++sdbJZJmuBwQLuw68A==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [aix] - - '@esbuild/android-arm64@0.25.11': - resolution: {integrity: sha512-9slpyFBc4FPPz48+f6jyiXOx/Y4v34TUeDDXJpZqAWQn/08lKGeD8aDp9TMn9jDz2CiEuHwfhRmGBvpnd/PWIQ==} - engines: {node: '>=18'} - cpu: [arm64] - os: [android] - - '@esbuild/android-arm64@0.27.0': - resolution: {integrity: sha512-CC3vt4+1xZrs97/PKDkl0yN7w8edvU2vZvAFGD16n9F0Cvniy5qvzRXjfO1l94efczkkQE6g1x0i73Qf5uthOQ==} + '@esbuild/android-arm64@0.27.1': + resolution: {integrity: sha512-45fuKmAJpxnQWixOGCrS+ro4Uvb4Re9+UTieUY2f8AEc+t7d4AaZ6eUJ3Hva7dtrxAAWHtlEFsXFMAgNnGU9uQ==} engines: {node: '>=18'} cpu: [arm64] os: [android] - '@esbuild/android-arm@0.25.11': - resolution: {integrity: sha512-uoa7dU+Dt3HYsethkJ1k6Z9YdcHjTrSb5NUy66ZfZaSV8hEYGD5ZHbEMXnqLFlbBflLsl89Zke7CAdDJ4JI+Gg==} + '@esbuild/android-arm@0.27.1': + resolution: {integrity: sha512-kFqa6/UcaTbGm/NncN9kzVOODjhZW8e+FRdSeypWe6j33gzclHtwlANs26JrupOntlcWmB0u8+8HZo8s7thHvg==} engines: {node: '>=18'} cpu: [arm] os: [android] - '@esbuild/android-arm@0.27.0': - resolution: {integrity: sha512-j67aezrPNYWJEOHUNLPj9maeJte7uSMM6gMoxfPC9hOg8N02JuQi/T7ewumf4tNvJadFkvLZMlAq73b9uwdMyQ==} - engines: {node: '>=18'} - cpu: [arm] - os: [android] - - '@esbuild/android-x64@0.25.11': - resolution: {integrity: sha512-Sgiab4xBjPU1QoPEIqS3Xx+R2lezu0LKIEcYe6pftr56PqPygbB7+szVnzoShbx64MUupqoE0KyRlN7gezbl8g==} - engines: {node: '>=18'} - cpu: [x64] - os: [android] - - '@esbuild/android-x64@0.27.0': - resolution: {integrity: sha512-wurMkF1nmQajBO1+0CJmcN17U4BP6GqNSROP8t0X/Jiw2ltYGLHpEksp9MpoBqkrFR3kv2/te6Sha26k3+yZ9Q==} + '@esbuild/android-x64@0.27.1': + resolution: {integrity: sha512-LBEpOz0BsgMEeHgenf5aqmn/lLNTFXVfoWMUox8CtWWYK9X4jmQzWjoGoNb8lmAYml/tQ/Ysvm8q7szu7BoxRQ==} engines: {node: '>=18'} cpu: [x64] os: [android] - '@esbuild/darwin-arm64@0.25.11': - resolution: {integrity: sha512-VekY0PBCukppoQrycFxUqkCojnTQhdec0vevUL/EDOCnXd9LKWqD/bHwMPzigIJXPhC59Vd1WFIL57SKs2mg4w==} - engines: {node: '>=18'} - cpu: [arm64] - os: [darwin] - - '@esbuild/darwin-arm64@0.27.0': - resolution: {integrity: sha512-uJOQKYCcHhg07DL7i8MzjvS2LaP7W7Pn/7uA0B5S1EnqAirJtbyw4yC5jQ5qcFjHK9l6o/MX9QisBg12kNkdHg==} + '@esbuild/darwin-arm64@0.27.1': + resolution: {integrity: sha512-veg7fL8eMSCVKL7IW4pxb54QERtedFDfY/ASrumK/SbFsXnRazxY4YykN/THYqFnFwJ0aVjiUrVG2PwcdAEqQQ==} engines: {node: '>=18'} cpu: [arm64] os: [darwin] - '@esbuild/darwin-x64@0.25.11': - resolution: {integrity: sha512-+hfp3yfBalNEpTGp9loYgbknjR695HkqtY3d3/JjSRUyPg/xd6q+mQqIb5qdywnDxRZykIHs3axEqU6l1+oWEQ==} + '@esbuild/darwin-x64@0.27.1': + resolution: {integrity: sha512-+3ELd+nTzhfWb07Vol7EZ+5PTbJ/u74nC6iv4/lwIU99Ip5uuY6QoIf0Hn4m2HoV0qcnRivN3KSqc+FyCHjoVQ==} engines: {node: '>=18'} cpu: [x64] os: [darwin] - '@esbuild/darwin-x64@0.27.0': - resolution: {integrity: sha512-8mG6arH3yB/4ZXiEnXof5MK72dE6zM9cDvUcPtxhUZsDjESl9JipZYW60C3JGreKCEP+p8P/72r69m4AZGJd5g==} - engines: {node: '>=18'} - cpu: [x64] - os: [darwin] - - '@esbuild/freebsd-arm64@0.25.11': - resolution: {integrity: sha512-CmKjrnayyTJF2eVuO//uSjl/K3KsMIeYeyN7FyDBjsR3lnSJHaXlVoAK8DZa7lXWChbuOk7NjAc7ygAwrnPBhA==} - engines: {node: '>=18'} - cpu: [arm64] - os: [freebsd] - - '@esbuild/freebsd-arm64@0.27.0': - resolution: {integrity: sha512-9FHtyO988CwNMMOE3YIeci+UV+x5Zy8fI2qHNpsEtSF83YPBmE8UWmfYAQg6Ux7Gsmd4FejZqnEUZCMGaNQHQw==} + '@esbuild/freebsd-arm64@0.27.1': + resolution: {integrity: sha512-/8Rfgns4XD9XOSXlzUDepG8PX+AVWHliYlUkFI3K3GB6tqbdjYqdhcb4BKRd7C0BhZSoaCxhv8kTcBrcZWP+xg==} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-x64@0.25.11': - resolution: {integrity: sha512-Dyq+5oscTJvMaYPvW3x3FLpi2+gSZTCE/1ffdwuM6G1ARang/mb3jvjxs0mw6n3Lsw84ocfo9CrNMqc5lTfGOw==} - engines: {node: '>=18'} - cpu: [x64] - os: [freebsd] - - '@esbuild/freebsd-x64@0.27.0': - resolution: {integrity: sha512-zCMeMXI4HS/tXvJz8vWGexpZj2YVtRAihHLk1imZj4efx1BQzN76YFeKqlDr3bUWI26wHwLWPd3rwh6pe4EV7g==} + '@esbuild/freebsd-x64@0.27.1': + resolution: {integrity: sha512-GITpD8dK9C+r+5yRT/UKVT36h/DQLOHdwGVwwoHidlnA168oD3uxA878XloXebK4Ul3gDBBIvEdL7go9gCUFzQ==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] - '@esbuild/linux-arm64@0.25.11': - resolution: {integrity: sha512-Qr8AzcplUhGvdyUF08A1kHU3Vr2O88xxP0Tm8GcdVOUm25XYcMPp2YqSVHbLuXzYQMf9Bh/iKx7YPqECs6ffLA==} + '@esbuild/linux-arm64@0.27.1': + resolution: {integrity: sha512-W9//kCrh/6in9rWIBdKaMtuTTzNj6jSeG/haWBADqLLa9P8O5YSRDzgD5y9QBok4AYlzS6ARHifAb75V6G670Q==} engines: {node: '>=18'} cpu: [arm64] os: [linux] - '@esbuild/linux-arm64@0.27.0': - resolution: {integrity: sha512-AS18v0V+vZiLJyi/4LphvBE+OIX682Pu7ZYNsdUHyUKSoRwdnOsMf6FDekwoAFKej14WAkOef3zAORJgAtXnlQ==} - engines: {node: '>=18'} - cpu: [arm64] - os: [linux] - - '@esbuild/linux-arm@0.25.11': - resolution: {integrity: sha512-TBMv6B4kCfrGJ8cUPo7vd6NECZH/8hPpBHHlYI3qzoYFvWu2AdTvZNuU/7hsbKWqu/COU7NIK12dHAAqBLLXgw==} - engines: {node: '>=18'} - cpu: [arm] - os: [linux] - - '@esbuild/linux-arm@0.27.0': - resolution: {integrity: sha512-t76XLQDpxgmq2cNXKTVEB7O7YMb42atj2Re2Haf45HkaUpjM2J0UuJZDuaGbPbamzZ7bawyGFUkodL+zcE+jvQ==} + '@esbuild/linux-arm@0.27.1': + resolution: {integrity: sha512-ieMID0JRZY/ZeCrsFQ3Y3NlHNCqIhTprJfDgSB3/lv5jJZ8FX3hqPyXWhe+gvS5ARMBJ242PM+VNz/ctNj//eA==} engines: {node: '>=18'} cpu: [arm] os: [linux] - '@esbuild/linux-ia32@0.25.11': - resolution: {integrity: sha512-TmnJg8BMGPehs5JKrCLqyWTVAvielc615jbkOirATQvWWB1NMXY77oLMzsUjRLa0+ngecEmDGqt5jiDC6bfvOw==} - engines: {node: '>=18'} - cpu: [ia32] - os: [linux] - - '@esbuild/linux-ia32@0.27.0': - resolution: {integrity: sha512-Mz1jxqm/kfgKkc/KLHC5qIujMvnnarD9ra1cEcrs7qshTUSksPihGrWHVG5+osAIQ68577Zpww7SGapmzSt4Nw==} + '@esbuild/linux-ia32@0.27.1': + resolution: {integrity: sha512-VIUV4z8GD8rtSVMfAj1aXFahsi/+tcoXXNYmXgzISL+KB381vbSTNdeZHHHIYqFyXcoEhu9n5cT+05tRv13rlw==} engines: {node: '>=18'} cpu: [ia32] os: [linux] - '@esbuild/linux-loong64@0.25.11': - resolution: {integrity: sha512-DIGXL2+gvDaXlaq8xruNXUJdT5tF+SBbJQKbWy/0J7OhU8gOHOzKmGIlfTTl6nHaCOoipxQbuJi7O++ldrxgMw==} + '@esbuild/linux-loong64@0.27.1': + resolution: {integrity: sha512-l4rfiiJRN7sTNI//ff65zJ9z8U+k6zcCg0LALU5iEWzY+a1mVZ8iWC1k5EsNKThZ7XCQ6YWtsZ8EWYm7r1UEsg==} engines: {node: '>=18'} cpu: [loong64] os: [linux] - '@esbuild/linux-loong64@0.27.0': - resolution: {integrity: sha512-QbEREjdJeIreIAbdG2hLU1yXm1uu+LTdzoq1KCo4G4pFOLlvIspBm36QrQOar9LFduavoWX2msNFAAAY9j4BDg==} - engines: {node: '>=18'} - cpu: [loong64] - os: [linux] - - '@esbuild/linux-mips64el@0.25.11': - resolution: {integrity: sha512-Osx1nALUJu4pU43o9OyjSCXokFkFbyzjXb6VhGIJZQ5JZi8ylCQ9/LFagolPsHtgw6himDSyb5ETSfmp4rpiKQ==} - engines: {node: '>=18'} - cpu: [mips64el] - os: [linux] - - '@esbuild/linux-mips64el@0.27.0': - resolution: {integrity: sha512-sJz3zRNe4tO2wxvDpH/HYJilb6+2YJxo/ZNbVdtFiKDufzWq4JmKAiHy9iGoLjAV7r/W32VgaHGkk35cUXlNOg==} + '@esbuild/linux-mips64el@0.27.1': + resolution: {integrity: sha512-U0bEuAOLvO/DWFdygTHWY8C067FXz+UbzKgxYhXC0fDieFa0kDIra1FAhsAARRJbvEyso8aAqvPdNxzWuStBnA==} engines: {node: '>=18'} cpu: [mips64el] os: [linux] - '@esbuild/linux-ppc64@0.25.11': - resolution: {integrity: sha512-nbLFgsQQEsBa8XSgSTSlrnBSrpoWh7ioFDUmwo158gIm5NNP+17IYmNWzaIzWmgCxq56vfr34xGkOcZ7jX6CPw==} + '@esbuild/linux-ppc64@0.27.1': + resolution: {integrity: sha512-NzdQ/Xwu6vPSf/GkdmRNsOfIeSGnh7muundsWItmBsVpMoNPVpM61qNzAVY3pZ1glzzAxLR40UyYM23eaDDbYQ==} engines: {node: '>=18'} cpu: [ppc64] os: [linux] - '@esbuild/linux-ppc64@0.27.0': - resolution: {integrity: sha512-z9N10FBD0DCS2dmSABDBb5TLAyF1/ydVb+N4pi88T45efQ/w4ohr/F/QYCkxDPnkhkp6AIpIcQKQ8F0ANoA2JA==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [linux] - - '@esbuild/linux-riscv64@0.25.11': - resolution: {integrity: sha512-HfyAmqZi9uBAbgKYP1yGuI7tSREXwIb438q0nqvlpxAOs3XnZ8RsisRfmVsgV486NdjD7Mw2UrFSw51lzUk1ww==} + '@esbuild/linux-riscv64@0.27.1': + resolution: {integrity: sha512-7zlw8p3IApcsN7mFw0O1Z1PyEk6PlKMu18roImfl3iQHTnr/yAfYv6s4hXPidbDoI2Q0pW+5xeoM4eTCC0UdrQ==} engines: {node: '>=18'} cpu: [riscv64] os: [linux] - '@esbuild/linux-riscv64@0.27.0': - resolution: {integrity: sha512-pQdyAIZ0BWIC5GyvVFn5awDiO14TkT/19FTmFcPdDec94KJ1uZcmFs21Fo8auMXzD4Tt+diXu1LW1gHus9fhFQ==} - engines: {node: '>=18'} - cpu: [riscv64] - os: [linux] - - '@esbuild/linux-s390x@0.25.11': - resolution: {integrity: sha512-HjLqVgSSYnVXRisyfmzsH6mXqyvj0SA7pG5g+9W7ESgwA70AXYNpfKBqh1KbTxmQVaYxpzA/SvlB9oclGPbApw==} + '@esbuild/linux-s390x@0.27.1': + resolution: {integrity: sha512-cGj5wli+G+nkVQdZo3+7FDKC25Uh4ZVwOAK6A06Hsvgr8WqBBuOy/1s+PUEd/6Je+vjfm6stX0kmib5b/O2Ykw==} engines: {node: '>=18'} cpu: [s390x] os: [linux] - '@esbuild/linux-s390x@0.27.0': - resolution: {integrity: sha512-hPlRWR4eIDDEci953RI1BLZitgi5uqcsjKMxwYfmi4LcwyWo2IcRP+lThVnKjNtk90pLS8nKdroXYOqW+QQH+w==} - engines: {node: '>=18'} - cpu: [s390x] - os: [linux] - - '@esbuild/linux-x64@0.25.11': - resolution: {integrity: sha512-HSFAT4+WYjIhrHxKBwGmOOSpphjYkcswF449j6EjsjbinTZbp8PJtjsVK1XFJStdzXdy/jaddAep2FGY+wyFAQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [linux] - - '@esbuild/linux-x64@0.27.0': - resolution: {integrity: sha512-1hBWx4OUJE2cab++aVZ7pObD6s+DK4mPGpemtnAORBvb5l/g5xFGk0vc0PjSkrDs0XaXj9yyob3d14XqvnQ4gw==} + '@esbuild/linux-x64@0.27.1': + resolution: {integrity: sha512-z3H/HYI9MM0HTv3hQZ81f+AKb+yEoCRlUby1F80vbQ5XdzEMyY/9iNlAmhqiBKw4MJXwfgsh7ERGEOhrM1niMA==} engines: {node: '>=18'} cpu: [x64] os: [linux] - '@esbuild/netbsd-arm64@0.25.11': - resolution: {integrity: sha512-hr9Oxj1Fa4r04dNpWr3P8QKVVsjQhqrMSUzZzf+LZcYjZNqhA3IAfPQdEh1FLVUJSiu6sgAwp3OmwBfbFgG2Xg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [netbsd] - - '@esbuild/netbsd-arm64@0.27.0': - resolution: {integrity: sha512-6m0sfQfxfQfy1qRuecMkJlf1cIzTOgyaeXaiVaaki8/v+WB+U4hc6ik15ZW6TAllRlg/WuQXxWj1jx6C+dfy3w==} + '@esbuild/netbsd-arm64@0.27.1': + resolution: {integrity: sha512-wzC24DxAvk8Em01YmVXyjl96Mr+ecTPyOuADAvjGg+fyBpGmxmcr2E5ttf7Im8D0sXZihpxzO1isus8MdjMCXQ==} engines: {node: '>=18'} cpu: [arm64] os: [netbsd] - '@esbuild/netbsd-x64@0.25.11': - resolution: {integrity: sha512-u7tKA+qbzBydyj0vgpu+5h5AeudxOAGncb8N6C9Kh1N4n7wU1Xw1JDApsRjpShRpXRQlJLb9wY28ELpwdPcZ7A==} + '@esbuild/netbsd-x64@0.27.1': + resolution: {integrity: sha512-1YQ8ybGi2yIXswu6eNzJsrYIGFpnlzEWRl6iR5gMgmsrR0FcNoV1m9k9sc3PuP5rUBLshOZylc9nqSgymI+TYg==} engines: {node: '>=18'} cpu: [x64] os: [netbsd] - '@esbuild/netbsd-x64@0.27.0': - resolution: {integrity: sha512-xbbOdfn06FtcJ9d0ShxxvSn2iUsGd/lgPIO2V3VZIPDbEaIj1/3nBBe1AwuEZKXVXkMmpr6LUAgMkLD/4D2PPA==} - engines: {node: '>=18'} - cpu: [x64] - os: [netbsd] - - '@esbuild/openbsd-arm64@0.25.11': - resolution: {integrity: sha512-Qq6YHhayieor3DxFOoYM1q0q1uMFYb7cSpLD2qzDSvK1NAvqFi8Xgivv0cFC6J+hWVw2teCYltyy9/m/14ryHg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openbsd] - - '@esbuild/openbsd-arm64@0.27.0': - resolution: {integrity: sha512-fWgqR8uNbCQ/GGv0yhzttj6sU/9Z5/Sv/VGU3F5OuXK6J6SlriONKrQ7tNlwBrJZXRYk5jUhuWvF7GYzGguBZQ==} + '@esbuild/openbsd-arm64@0.27.1': + resolution: {integrity: sha512-5Z+DzLCrq5wmU7RDaMDe2DVXMRm2tTDvX2KU14JJVBN2CT/qov7XVix85QoJqHltpvAOZUAc3ndU56HSMWrv8g==} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] - '@esbuild/openbsd-x64@0.25.11': - resolution: {integrity: sha512-CN+7c++kkbrckTOz5hrehxWN7uIhFFlmS/hqziSFVWpAzpWrQoAG4chH+nN3Be+Kzv/uuo7zhX716x3Sn2Jduw==} - engines: {node: '>=18'} - cpu: [x64] - os: [openbsd] - - '@esbuild/openbsd-x64@0.27.0': - resolution: {integrity: sha512-aCwlRdSNMNxkGGqQajMUza6uXzR/U0dIl1QmLjPtRbLOx3Gy3otfFu/VjATy4yQzo9yFDGTxYDo1FfAD9oRD2A==} + '@esbuild/openbsd-x64@0.27.1': + resolution: {integrity: sha512-Q73ENzIdPF5jap4wqLtsfh8YbYSZ8Q0wnxplOlZUOyZy7B4ZKW8DXGWgTCZmF8VWD7Tciwv5F4NsRf6vYlZtqg==} engines: {node: '>=18'} cpu: [x64] os: [openbsd] - '@esbuild/openharmony-arm64@0.25.11': - resolution: {integrity: sha512-rOREuNIQgaiR+9QuNkbkxubbp8MSO9rONmwP5nKncnWJ9v5jQ4JxFnLu4zDSRPf3x4u+2VN4pM4RdyIzDty/wQ==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openharmony] - - '@esbuild/openharmony-arm64@0.27.0': - resolution: {integrity: sha512-nyvsBccxNAsNYz2jVFYwEGuRRomqZ149A39SHWk4hV0jWxKM0hjBPm3AmdxcbHiFLbBSwG6SbpIcUbXjgyECfA==} + '@esbuild/openharmony-arm64@0.27.1': + resolution: {integrity: sha512-ajbHrGM/XiK+sXM0JzEbJAen+0E+JMQZ2l4RR4VFwvV9JEERx+oxtgkpoKv1SevhjavK2z2ReHk32pjzktWbGg==} engines: {node: '>=18'} cpu: [arm64] os: [openharmony] - '@esbuild/sunos-x64@0.25.11': - resolution: {integrity: sha512-nq2xdYaWxyg9DcIyXkZhcYulC6pQ2FuCgem3LI92IwMgIZ69KHeY8T4Y88pcwoLIjbed8n36CyKoYRDygNSGhA==} - engines: {node: '>=18'} - cpu: [x64] - os: [sunos] - - '@esbuild/sunos-x64@0.27.0': - resolution: {integrity: sha512-Q1KY1iJafM+UX6CFEL+F4HRTgygmEW568YMqDA5UV97AuZSm21b7SXIrRJDwXWPzr8MGr75fUZPV67FdtMHlHA==} + '@esbuild/sunos-x64@0.27.1': + resolution: {integrity: sha512-IPUW+y4VIjuDVn+OMzHc5FV4GubIwPnsz6ubkvN8cuhEqH81NovB53IUlrlBkPMEPxvNnf79MGBoz8rZ2iW8HA==} engines: {node: '>=18'} cpu: [x64] os: [sunos] - '@esbuild/win32-arm64@0.25.11': - resolution: {integrity: sha512-3XxECOWJq1qMZ3MN8srCJ/QfoLpL+VaxD/WfNRm1O3B4+AZ/BnLVgFbUV3eiRYDMXetciH16dwPbbHqwe1uU0Q==} - engines: {node: '>=18'} - cpu: [arm64] - os: [win32] - - '@esbuild/win32-arm64@0.27.0': - resolution: {integrity: sha512-W1eyGNi6d+8kOmZIwi/EDjrL9nxQIQ0MiGqe/AWc6+IaHloxHSGoeRgDRKHFISThLmsewZ5nHFvGFWdBYlgKPg==} + '@esbuild/win32-arm64@0.27.1': + resolution: {integrity: sha512-RIVRWiljWA6CdVu8zkWcRmGP7iRRIIwvhDKem8UMBjPql2TXM5PkDVvvrzMtj1V+WFPB4K7zkIGM7VzRtFkjdg==} engines: {node: '>=18'} cpu: [arm64] os: [win32] - '@esbuild/win32-ia32@0.25.11': - resolution: {integrity: sha512-3ukss6gb9XZ8TlRyJlgLn17ecsK4NSQTmdIXRASVsiS2sQ6zPPZklNJT5GR5tE/MUarymmy8kCEf5xPCNCqVOA==} + '@esbuild/win32-ia32@0.27.1': + resolution: {integrity: sha512-2BR5M8CPbptC1AK5JbJT1fWrHLvejwZidKx3UMSF0ecHMa+smhi16drIrCEggkgviBwLYd5nwrFLSl5Kho96RQ==} engines: {node: '>=18'} cpu: [ia32] os: [win32] - '@esbuild/win32-ia32@0.27.0': - resolution: {integrity: sha512-30z1aKL9h22kQhilnYkORFYt+3wp7yZsHWus+wSKAJR8JtdfI76LJ4SBdMsCopTR3z/ORqVu5L1vtnHZWVj4cQ==} - engines: {node: '>=18'} - cpu: [ia32] - os: [win32] - - '@esbuild/win32-x64@0.25.11': - resolution: {integrity: sha512-D7Hpz6A2L4hzsRpPaCYkQnGOotdUpDzSGRIv9I+1ITdHROSFUWW95ZPZWQmGka1Fg7W3zFJowyn9WGwMJ0+KPA==} - engines: {node: '>=18'} - cpu: [x64] - os: [win32] - - '@esbuild/win32-x64@0.27.0': - resolution: {integrity: sha512-aIitBcjQeyOhMTImhLZmtxfdOcuNRpwlPNmlFKPcHQYPhEssw75Cl1TSXJXpMkzaua9FUetx/4OQKq7eJul5Cg==} + '@esbuild/win32-x64@0.27.1': + resolution: {integrity: sha512-d5X6RMYv6taIymSk8JBP+nxv8DQAMY6A51GPgusqLdK9wBz5wWIXy1KjTck6HnjE9hqJzJRdk+1p/t5soSbCtw==} engines: {node: '>=18'} cpu: [x64] os: [win32] @@ -953,36 +843,36 @@ packages: peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - '@eslint-community/regexpp@4.12.1': - resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} + '@eslint-community/regexpp@4.12.2': + resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - '@eslint/config-array@0.21.0': - resolution: {integrity: sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==} + '@eslint/config-array@0.21.1': + resolution: {integrity: sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/config-helpers@0.4.0': - resolution: {integrity: sha512-WUFvV4WoIwW8Bv0KeKCIIEgdSiFOsulyN0xrMu+7z43q/hkOLXjvb5u7UC9jDxvRzcrbEmuZBX5yJZz1741jog==} + '@eslint/config-helpers@0.4.2': + resolution: {integrity: sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/core@0.16.0': - resolution: {integrity: sha512-nmC8/totwobIiFcGkDza3GIKfAw1+hLiYVrh3I1nIomQ8PEr5cxg34jnkmGawul/ep52wGRAcyeDCNtWKSOj4Q==} + '@eslint/core@0.17.0': + resolution: {integrity: sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/eslintrc@3.3.1': - resolution: {integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==} + '@eslint/eslintrc@3.3.3': + resolution: {integrity: sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/js@9.37.0': - resolution: {integrity: sha512-jaS+NJ+hximswBG6pjNX0uEJZkrT0zwpVi3BA3vX22aFGjJjmgSTSmPpZCRKmoBL5VY/M6p0xsSJx7rk7sy5gg==} + '@eslint/js@9.39.2': + resolution: {integrity: sha512-q1mjIoW1VX4IvSocvM/vbTiveKC4k9eLrajNEuSsmjymSDEbpGddtpfOoN7YGAqBK3NG+uqo8ia4PDTt8buCYA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/object-schema@2.1.6': - resolution: {integrity: sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==} + '@eslint/object-schema@2.1.7': + resolution: {integrity: sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/plugin-kit@0.4.0': - resolution: {integrity: sha512-sB5uyeq+dwCWyPi31B2gQlVlo+j5brPlWx4yZBrEaRo/nhdDE8Xke1gsGgtiBdaBTxuTkceLVuVt/pclrasb0A==} + '@eslint/plugin-kit@0.4.1': + resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@humanfs/core@0.19.1': @@ -1138,8 +1028,8 @@ packages: cpu: [x64] os: [win32] - '@inquirer/external-editor@1.0.2': - resolution: {integrity: sha512-yy9cOoBnx58TlsPrIxauKIFQTiyH+0MK4e97y4sV9ERbI+zDxw7i2hxHLCIEGIE/8PPvDxGhgzIOTSOWcs6/MQ==} + '@inquirer/external-editor@1.0.3': + resolution: {integrity: sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' @@ -1155,6 +1045,12 @@ packages: resolution: {integrity: sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==} engines: {node: 20 || >=22} + '@jridgewell/gen-mapping@0.3.13': + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + + '@jridgewell/remapping@2.3.5': + resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} + '@jridgewell/resolve-uri@3.1.2': resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} engines: {node: '>=6.0.0'} @@ -1177,8 +1073,8 @@ packages: '@next/env@15.5.9': resolution: {integrity: sha512-4GlTZ+EJM7WaW2HEZcyU317tIQDjkQIyENDLxYJfSWlfqguN+dHkZgyQTV/7ykvobU7yEH5gKvreNrH4B6QgIg==} - '@next/eslint-plugin-next@15.5.5': - resolution: {integrity: sha512-FMzm412l9oFB8zdRD+K6HQ1VzlS+sNNsdg0MfvTg0i8lfCyTgP/RFxiu/pGJqZ/IQnzn9xSiLkjOVI7Iv4nbdQ==} + '@next/eslint-plugin-next@15.5.9': + resolution: {integrity: sha512-kUzXx0iFiXw27cQAViE1yKWnz/nF8JzRmwgMRTMh8qMY90crNsdXJRh2e+R0vBpFR3kk1yvAR7wev7+fCCb79Q==} '@next/swc-darwin-arm64@15.5.7': resolution: {integrity: sha512-IZwtxCEpI91HVU/rAUOOobWSZv4P2DeTtNaCdHqLcTJU4wdNXgAySvKa/qJCgR5m6KI8UsKDXtO2B31jcaw1Yw==} @@ -1236,10 +1132,6 @@ packages: resolution: {integrity: sha512-k11yZxZg+t+gWvBbIswW0yoJlu8cHOC7dhunwOzoWH/mXGBiYyR4YY6hAEK/3EUs4UpB8la1RfdRpeGsFHkWsA==} engines: {node: ^14.21.3 || >=16} - '@noble/curves@1.9.7': - resolution: {integrity: sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw==} - engines: {node: ^14.21.3 || >=16} - '@noble/hashes@1.4.0': resolution: {integrity: sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==} engines: {node: '>= 16'} @@ -1260,113 +1152,113 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} - '@rollup/rollup-android-arm-eabi@4.52.4': - resolution: {integrity: sha512-BTm2qKNnWIQ5auf4deoetINJm2JzvihvGb9R6K/ETwKLql/Bb3Eg2H1FBp1gUb4YGbydMA3jcmQTR73q7J+GAA==} + '@rollup/rollup-android-arm-eabi@4.53.4': + resolution: {integrity: sha512-PWU3Y92H4DD0bOqorEPp1Y0tbzwAurFmIYpjcObv5axGVOtcTlB0b2UKMd2echo08MgN7jO8WQZSSysvfisFSQ==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.52.4': - resolution: {integrity: sha512-P9LDQiC5vpgGFgz7GSM6dKPCiqR3XYN1WwJKA4/BUVDjHpYsf3iBEmVz62uyq20NGYbiGPR5cNHI7T1HqxNs2w==} + '@rollup/rollup-android-arm64@4.53.4': + resolution: {integrity: sha512-Gw0/DuVm3rGsqhMGYkSOXXIx20cC3kTlivZeuaGt4gEgILivykNyBWxeUV5Cf2tDA2nPLah26vq3emlRrWVbng==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.52.4': - resolution: {integrity: sha512-QRWSW+bVccAvZF6cbNZBJwAehmvG9NwfWHwMy4GbWi/BQIA/laTIktebT2ipVjNncqE6GLPxOok5hsECgAxGZg==} + '@rollup/rollup-darwin-arm64@4.53.4': + resolution: {integrity: sha512-+w06QvXsgzKwdVg5qRLZpTHh1bigHZIqoIUPtiqh05ZiJVUQ6ymOxaPkXTvRPRLH88575ZCRSRM3PwIoNma01Q==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.52.4': - resolution: {integrity: sha512-hZgP05pResAkRJxL1b+7yxCnXPGsXU0fG9Yfd6dUaoGk+FhdPKCJ5L1Sumyxn8kvw8Qi5PvQ8ulenUbRjzeCTw==} + '@rollup/rollup-darwin-x64@4.53.4': + resolution: {integrity: sha512-EB4Na9G2GsrRNRNFPuxfwvDRDUwQEzJPpiK1vo2zMVhEeufZ1k7J1bKnT0JYDfnPC7RNZ2H5YNQhW6/p2QKATw==} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.52.4': - resolution: {integrity: sha512-xmc30VshuBNUd58Xk4TKAEcRZHaXlV+tCxIXELiE9sQuK3kG8ZFgSPi57UBJt8/ogfhAF5Oz4ZSUBN77weM+mQ==} + '@rollup/rollup-freebsd-arm64@4.53.4': + resolution: {integrity: sha512-bldA8XEqPcs6OYdknoTMaGhjytnwQ0NClSPpWpmufOuGPN5dDmvIa32FygC2gneKK4A1oSx86V1l55hyUWUYFQ==} cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.52.4': - resolution: {integrity: sha512-WdSLpZFjOEqNZGmHflxyifolwAiZmDQzuOzIq9L27ButpCVpD7KzTRtEG1I0wMPFyiyUdOO+4t8GvrnBLQSwpw==} + '@rollup/rollup-freebsd-x64@4.53.4': + resolution: {integrity: sha512-3T8GPjH6mixCd0YPn0bXtcuSXi1Lj+15Ujw2CEb7dd24j9thcKscCf88IV7n76WaAdorOzAgSSbuVRg4C8V8Qw==} cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.52.4': - resolution: {integrity: sha512-xRiOu9Of1FZ4SxVbB0iEDXc4ddIcjCv2aj03dmW8UrZIW7aIQ9jVJdLBIhxBI+MaTnGAKyvMwPwQnoOEvP7FgQ==} + '@rollup/rollup-linux-arm-gnueabihf@4.53.4': + resolution: {integrity: sha512-UPMMNeC4LXW7ZSHxeP3Edv09aLsFUMaD1TSVW6n1CWMECnUIJMFFB7+XC2lZTdPtvB36tYC0cJWc86mzSsaviw==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.52.4': - resolution: {integrity: sha512-FbhM2p9TJAmEIEhIgzR4soUcsW49e9veAQCziwbR+XWB2zqJ12b4i/+hel9yLiD8pLncDH4fKIPIbt5238341Q==} + '@rollup/rollup-linux-arm-musleabihf@4.53.4': + resolution: {integrity: sha512-H8uwlV0otHs5Q7WAMSoyvjV9DJPiy5nJ/xnHolY0QptLPjaSsuX7tw+SPIfiYH6cnVx3fe4EWFafo6gH6ekZKA==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.52.4': - resolution: {integrity: sha512-4n4gVwhPHR9q/g8lKCyz0yuaD0MvDf7dV4f9tHt0C73Mp8h38UCtSCSE6R9iBlTbXlmA8CjpsZoujhszefqueg==} + '@rollup/rollup-linux-arm64-gnu@4.53.4': + resolution: {integrity: sha512-BLRwSRwICXz0TXkbIbqJ1ibK+/dSBpTJqDClF61GWIrxTXZWQE78ROeIhgl5MjVs4B4gSLPCFeD4xML9vbzvCQ==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-musl@4.52.4': - resolution: {integrity: sha512-u0n17nGA0nvi/11gcZKsjkLj1QIpAuPFQbR48Subo7SmZJnGxDpspyw2kbpuoQnyK+9pwf3pAoEXerJs/8Mi9g==} + '@rollup/rollup-linux-arm64-musl@4.53.4': + resolution: {integrity: sha512-6bySEjOTbmVcPJAywjpGLckK793A0TJWSbIa0sVwtVGfe/Nz6gOWHOwkshUIAp9j7wg2WKcA4Snu7Y1nUZyQew==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-loong64-gnu@4.52.4': - resolution: {integrity: sha512-0G2c2lpYtbTuXo8KEJkDkClE/+/2AFPdPAbmaHoE870foRFs4pBrDehilMcrSScrN/fB/1HTaWO4bqw+ewBzMQ==} + '@rollup/rollup-linux-loong64-gnu@4.53.4': + resolution: {integrity: sha512-U0ow3bXYJZ5MIbchVusxEycBw7bO6C2u5UvD31i5IMTrnt2p4Fh4ZbHSdc/31TScIJQYHwxbj05BpevB3201ug==} cpu: [loong64] os: [linux] - '@rollup/rollup-linux-ppc64-gnu@4.52.4': - resolution: {integrity: sha512-teSACug1GyZHmPDv14VNbvZFX779UqWTsd7KtTM9JIZRDI5NUwYSIS30kzI8m06gOPB//jtpqlhmraQ68b5X2g==} + '@rollup/rollup-linux-ppc64-gnu@4.53.4': + resolution: {integrity: sha512-iujDk07ZNwGLVn0YIWM80SFN039bHZHCdCCuX9nyx3Jsa2d9V/0Y32F+YadzwbvDxhSeVo9zefkoPnXEImnM5w==} cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.52.4': - resolution: {integrity: sha512-/MOEW3aHjjs1p4Pw1Xk4+3egRevx8Ji9N6HUIA1Ifh8Q+cg9dremvFCUbOX2Zebz80BwJIgCBUemjqhU5XI5Eg==} + '@rollup/rollup-linux-riscv64-gnu@4.53.4': + resolution: {integrity: sha512-MUtAktiOUSu+AXBpx1fkuG/Bi5rhlorGs3lw5QeJ2X3ziEGAq7vFNdWVde6XGaVqi0LGSvugwjoxSNJfHFTC0g==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-riscv64-musl@4.52.4': - resolution: {integrity: sha512-1HHmsRyh845QDpEWzOFtMCph5Ts+9+yllCrREuBR/vg2RogAQGGBRC8lDPrPOMnrdOJ+mt1WLMOC2Kao/UwcvA==} + '@rollup/rollup-linux-riscv64-musl@4.53.4': + resolution: {integrity: sha512-btm35eAbDfPtcFEgaXCI5l3c2WXyzwiE8pArhd66SDtoLWmgK5/M7CUxmUglkwtniPzwvWioBKKl6IXLbPf2sQ==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.52.4': - resolution: {integrity: sha512-seoeZp4L/6D1MUyjWkOMRU6/iLmCU2EjbMTyAG4oIOs1/I82Y5lTeaxW0KBfkUdHAWN7j25bpkt0rjnOgAcQcA==} + '@rollup/rollup-linux-s390x-gnu@4.53.4': + resolution: {integrity: sha512-uJlhKE9ccUTCUlK+HUz/80cVtx2RayadC5ldDrrDUFaJK0SNb8/cCmC9RhBhIWuZ71Nqj4Uoa9+xljKWRogdhA==} cpu: [s390x] os: [linux] - '@rollup/rollup-linux-x64-gnu@4.52.4': - resolution: {integrity: sha512-Wi6AXf0k0L7E2gteNsNHUs7UMwCIhsCTs6+tqQ5GPwVRWMaflqGec4Sd8n6+FNFDw9vGcReqk2KzBDhCa1DLYg==} + '@rollup/rollup-linux-x64-gnu@4.53.4': + resolution: {integrity: sha512-jjEMkzvASQBbzzlzf4os7nzSBd/cvPrpqXCUOqoeCh1dQ4BP3RZCJk8XBeik4MUln3m+8LeTJcY54C/u8wb3DQ==} cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.52.4': - resolution: {integrity: sha512-dtBZYjDmCQ9hW+WgEkaffvRRCKm767wWhxsFW3Lw86VXz/uJRuD438/XvbZT//B96Vs8oTA8Q4A0AfHbrxP9zw==} + '@rollup/rollup-linux-x64-musl@4.53.4': + resolution: {integrity: sha512-lu90KG06NNH19shC5rBPkrh6mrTpq5kviFylPBXQVpdEu0yzb0mDgyxLr6XdcGdBIQTH/UAhDJnL+APZTBu1aQ==} cpu: [x64] os: [linux] - '@rollup/rollup-openharmony-arm64@4.52.4': - resolution: {integrity: sha512-1ox+GqgRWqaB1RnyZXL8PD6E5f7YyRUJYnCqKpNzxzP0TkaUh112NDrR9Tt+C8rJ4x5G9Mk8PQR3o7Ku2RKqKA==} + '@rollup/rollup-openharmony-arm64@4.53.4': + resolution: {integrity: sha512-dFDcmLwsUzhAm/dn0+dMOQZoONVYBtgik0VuY/d5IJUUb787L3Ko/ibvTvddqhb3RaB7vFEozYevHN4ox22R/w==} cpu: [arm64] os: [openharmony] - '@rollup/rollup-win32-arm64-msvc@4.52.4': - resolution: {integrity: sha512-8GKr640PdFNXwzIE0IrkMWUNUomILLkfeHjXBi/nUvFlpZP+FA8BKGKpacjW6OUUHaNI6sUURxR2U2g78FOHWQ==} + '@rollup/rollup-win32-arm64-msvc@4.53.4': + resolution: {integrity: sha512-WvUpUAWmUxZKtRnQWpRKnLW2DEO8HB/l8z6oFFMNuHndMzFTJEXzaYJ5ZAmzNw0L21QQJZsUQFt2oPf3ykAD/w==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.52.4': - resolution: {integrity: sha512-AIy/jdJ7WtJ/F6EcfOb2GjR9UweO0n43jNObQMb6oGxkYTfLcnN7vYYpG+CN3lLxrQkzWnMOoNSHTW54pgbVxw==} + '@rollup/rollup-win32-ia32-msvc@4.53.4': + resolution: {integrity: sha512-JGbeF2/FDU0x2OLySw/jgvkwWUo05BSiJK0dtuI4LyuXbz3wKiC1xHhLB1Tqm5VU6ZZDmAorj45r/IgWNWku5g==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-gnu@4.52.4': - resolution: {integrity: sha512-UF9KfsH9yEam0UjTwAgdK0anlQ7c8/pWPU2yVjyWcF1I1thABt6WXE47cI71pGiZ8wGvxohBoLnxM04L/wj8mQ==} + '@rollup/rollup-win32-x64-gnu@4.53.4': + resolution: {integrity: sha512-zuuC7AyxLWLubP+mlUwEyR8M1ixW1ERNPHJfXm8x7eQNP4Pzkd7hS3qBuKBR70VRiQ04Kw8FNfRMF5TNxuZq2g==} cpu: [x64] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.52.4': - resolution: {integrity: sha512-bf9PtUa0u8IXDVxzRToFQKsNCRz9qLYfR/MpECxl4mRoWYjAeFjgxj1XdZr2M/GNVpT05p+LgQOHopYDlUu6/w==} + '@rollup/rollup-win32-x64-msvc@4.53.4': + resolution: {integrity: sha512-Sbx45u/Lbb5RyptSbX7/3deP+/lzEmZ0BTSHxwxN/IMOZDZf8S0AGo0hJD5n/LQssxb5Z3B4og4P2X6Dd8acCA==} cpu: [x64] os: [win32] @@ -1392,8 +1284,8 @@ packages: '@tootallnate/quickjs-emscripten@0.23.0': resolution: {integrity: sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==} - '@tsconfig/node10@1.0.11': - resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==} + '@tsconfig/node10@1.0.12': + resolution: {integrity: sha512-UCYBaeFvM11aU2y3YPZ//O5Rhj+xKyzy7mvcIoAjASbigy8mHMryP5cK7dgjlz2hWxh1g5pLw084E0a/wlUSFQ==} '@tsconfig/node12@1.0.11': resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} @@ -1412,8 +1304,8 @@ packages: resolution: {integrity: sha512-3uYg2b5TWCiupetbDFMbBFMHl33xQTvp5DNg0fZSYal73Z9AlFH9yWabHWMYw6ywmwM1evkYRpTVA2n7GgqT5A==} hasBin: true - '@types/chai@5.2.2': - resolution: {integrity: sha512-8kB30R7Hwqf40JPiKhVzodJs2Qc1ZJ5zuT3uzw5Hq/dhNCl3G3l83jfpdI1e20BP348+fV7VIL/+FxaXkqBmWg==} + '@types/chai@5.2.3': + resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} '@types/deep-eql@4.0.2': resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} @@ -1437,19 +1329,19 @@ packages: '@types/node@12.20.55': resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} - '@types/node@20.19.21': - resolution: {integrity: sha512-CsGG2P3I5y48RPMfprQGfy4JPRZ6csfC3ltBZSRItG3ngggmNY/qs2uZKp4p9VbrpqNNSMzUZNFZKzgOGnd/VA==} + '@types/node@20.19.27': + resolution: {integrity: sha512-N2clP5pJhB2YnZJ3PIHFk5RkygRX5WO/5f0WC08tp0wd+sv0rsJk3MqWn3CbNmT2J505a5336jaQj4ph1AdMug==} - '@types/node@24.10.1': - resolution: {integrity: sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ==} + '@types/node@25.0.2': + resolution: {integrity: sha512-gWEkeiyYE4vqjON/+Obqcoeffmk0NF15WSBwSs7zwVA2bAbTaE0SJ7P0WNGoJn8uE7fiaV5a7dKYIJriEqOrmA==} '@types/react-dom@19.2.3': resolution: {integrity: sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==} peerDependencies: '@types/react': ^19.2.0 - '@types/react@19.2.6': - resolution: {integrity: sha512-p/jUvulfgU7oKtj6Xpk8cA2Y1xKTtICGpJYeJXz2YVO2UcvjQgeRMLDGfDeqeRW2Ta+0QNFwcc8X3GH8SxZz6w==} + '@types/react@19.2.7': + resolution: {integrity: sha512-MWtvHrGZLFttgeEj28VXHxpmwYbor/ATPYbBfSFZEIRK0ecCFLl2Qo55z52Hss+UV9CRN7trSeq1zbgx7YDWWg==} '@types/through@0.0.33': resolution: {integrity: sha512-HsJ+z3QuETzP3cswwtzt2vEIiHBk/dCcHGhbmG5X3ecnwFD/lPrMpliGXxSCg03L9AhrdwA4Oz/qfspkDW+xGQ==} @@ -1466,79 +1358,79 @@ packages: '@types/yargs@17.0.35': resolution: {integrity: sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==} - '@typescript-eslint/eslint-plugin@8.46.1': - resolution: {integrity: sha512-rUsLh8PXmBjdiPY+Emjz9NX2yHvhS11v0SR6xNJkm5GM1MO9ea/1GoDKlHHZGrOJclL/cZ2i/vRUYVtjRhrHVQ==} + '@typescript-eslint/eslint-plugin@8.50.0': + resolution: {integrity: sha512-O7QnmOXYKVtPrfYzMolrCTfkezCJS9+ljLdKW/+DCvRsc3UAz+sbH6Xcsv7p30+0OwUbeWfUDAQE0vpabZ3QLg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.46.1 + '@typescript-eslint/parser': ^8.50.0 eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/parser@8.46.1': - resolution: {integrity: sha512-6JSSaBZmsKvEkbRUkf7Zj7dru/8ZCrJxAqArcLaVMee5907JdtEbKGsZ7zNiIm/UAkpGUkaSMZEXShnN2D1HZA==} + '@typescript-eslint/parser@8.50.0': + resolution: {integrity: sha512-6/cmF2piao+f6wSxUsJLZjck7OQsYyRtcOZS02k7XINSNlz93v6emM8WutDQSXnroG2xwYlEVHJI+cPA7CPM3Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/project-service@8.46.1': - resolution: {integrity: sha512-FOIaFVMHzRskXr5J4Jp8lFVV0gz5ngv3RHmn+E4HYxSJ3DgDzU7fVI1/M7Ijh1zf6S7HIoaIOtln1H5y8V+9Zg==} + '@typescript-eslint/project-service@8.50.0': + resolution: {integrity: sha512-Cg/nQcL1BcoTijEWyx4mkVC56r8dj44bFDvBdygifuS20f3OZCHmFbjF34DPSi07kwlFvqfv/xOLnJ5DquxSGQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/scope-manager@8.46.1': - resolution: {integrity: sha512-weL9Gg3/5F0pVQKiF8eOXFZp8emqWzZsOJuWRUNtHT+UNV2xSJegmpCNQHy37aEQIbToTq7RHKhWvOsmbM680A==} + '@typescript-eslint/scope-manager@8.50.0': + resolution: {integrity: sha512-xCwfuCZjhIqy7+HKxBLrDVT5q/iq7XBVBXLn57RTIIpelLtEIZHXAF/Upa3+gaCpeV1NNS5Z9A+ID6jn50VD4A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/tsconfig-utils@8.46.1': - resolution: {integrity: sha512-X88+J/CwFvlJB+mK09VFqx5FE4H5cXD+H/Bdza2aEWkSb8hnWIQorNcscRl4IEo1Cz9VI/+/r/jnGWkbWPx54g==} + '@typescript-eslint/tsconfig-utils@8.50.0': + resolution: {integrity: sha512-vxd3G/ybKTSlm31MOA96gqvrRGv9RJ7LGtZCn2Vrc5htA0zCDvcMqUkifcjrWNNKXHUU3WCkYOzzVSFBd0wa2w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/type-utils@8.46.1': - resolution: {integrity: sha512-+BlmiHIiqufBxkVnOtFwjah/vrkF4MtKKvpXrKSPLCkCtAp8H01/VV43sfqA98Od7nJpDcFnkwgyfQbOG0AMvw==} + '@typescript-eslint/type-utils@8.50.0': + resolution: {integrity: sha512-7OciHT2lKCewR0mFoBrvZJ4AXTMe/sYOe87289WAViOocEmDjjv8MvIOT2XESuKj9jp8u3SZYUSh89QA4S1kQw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/types@8.46.1': - resolution: {integrity: sha512-C+soprGBHwWBdkDpbaRC4paGBrkIXxVlNohadL5o0kfhsXqOC6GYH2S/Obmig+I0HTDl8wMaRySwrfrXVP8/pQ==} + '@typescript-eslint/types@8.50.0': + resolution: {integrity: sha512-iX1mgmGrXdANhhITbpp2QQM2fGehBse9LbTf0sidWK6yg/NE+uhV5dfU1g6EYPlcReYmkE9QLPq/2irKAmtS9w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@8.46.1': - resolution: {integrity: sha512-uIifjT4s8cQKFQ8ZBXXyoUODtRoAd7F7+G8MKmtzj17+1UbdzFl52AzRyZRyKqPHhgzvXunnSckVu36flGy8cg==} + '@typescript-eslint/typescript-estree@8.50.0': + resolution: {integrity: sha512-W7SVAGBR/IX7zm1t70Yujpbk+zdPq/u4soeFSknWFdXIFuWsBGBOUu/Tn/I6KHSKvSh91OiMuaSnYp3mtPt5IQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/utils@8.46.1': - resolution: {integrity: sha512-vkYUy6LdZS7q1v/Gxb2Zs7zziuXN0wxqsetJdeZdRe/f5dwJFglmuvZBfTUivCtjH725C1jWCDfpadadD95EDQ==} + '@typescript-eslint/utils@8.50.0': + resolution: {integrity: sha512-87KgUXET09CRjGCi2Ejxy3PULXna63/bMYv72tCAlDJC3Yqwln0HiFJ3VJMst2+mEtNtZu5oFvX4qJGjKsnAgg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/visitor-keys@8.46.1': - resolution: {integrity: sha512-ptkmIf2iDkNUjdeu2bQqhFPV1m6qTnFFjg7PPDjxKWaMaP0Z6I9l30Jr3g5QqbZGdw8YdYvLp+XnqnWWZOg/NA==} + '@typescript-eslint/visitor-keys@8.50.0': + resolution: {integrity: sha512-Xzmnb58+Db78gT/CCj/PVCvK+zxbnsw6F+O1oheYszJbBSdEjVhQi3C/Xttzxgi/GLmpvOggRs1RFpiJ8+c34Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@vitest/coverage-v8@4.0.14': - resolution: {integrity: sha512-EYHLqN/BY6b47qHH7gtMxAg++saoGmsjWmAq9MlXxAz4M0NcHh9iOyKhBZyU4yxZqOd8Xnqp80/5saeitz4Cng==} + '@vitest/coverage-v8@4.0.15': + resolution: {integrity: sha512-FUJ+1RkpTFW7rQITdgTi93qOCWJobWhBirEPCeXh2SW2wsTlFxy51apDz5gzG+ZEYt/THvWeNmhdAoS9DTwpCw==} peerDependencies: - '@vitest/browser': 4.0.14 - vitest: 4.0.14 + '@vitest/browser': 4.0.15 + vitest: 4.0.15 peerDependenciesMeta: '@vitest/browser': optional: true - '@vitest/expect@4.0.14': - resolution: {integrity: sha512-RHk63V3zvRiYOWAV0rGEBRO820ce17hz7cI2kDmEdfQsBjT2luEKB5tCOc91u1oSQoUOZkSv3ZyzkdkSLD7lKw==} + '@vitest/expect@4.0.15': + resolution: {integrity: sha512-Gfyva9/GxPAWXIWjyGDli9O+waHDC0Q0jaLdFP1qPAUUfo1FEXPXUfUkp3eZA0sSq340vPycSyOlYUeM15Ft1w==} - '@vitest/mocker@4.0.14': - resolution: {integrity: sha512-RzS5NujlCzeRPF1MK7MXLiEFpkIXeMdQ+rN3Kk3tDI9j0mtbr7Nmuq67tpkOJQpgyClbOltCXMjLZicJHsH5Cg==} + '@vitest/mocker@4.0.15': + resolution: {integrity: sha512-CZ28GLfOEIFkvCFngN8Sfx5h+Se0zN+h4B7yOsPVCcgtiO7t5jt9xQh2E1UkFep+eb9fjyMfuC5gBypwb07fvQ==} peerDependencies: msw: ^2.4.9 vite: ^6.0.0 || ^7.0.0-0 @@ -1548,20 +1440,20 @@ packages: vite: optional: true - '@vitest/pretty-format@4.0.14': - resolution: {integrity: sha512-SOYPgujB6TITcJxgd3wmsLl+wZv+fy3av2PpiPpsWPZ6J1ySUYfScfpIt2Yv56ShJXR2MOA6q2KjKHN4EpdyRQ==} + '@vitest/pretty-format@4.0.15': + resolution: {integrity: sha512-SWdqR8vEv83WtZcrfLNqlqeQXlQLh2iilO1Wk1gv4eiHKjEzvgHb2OVc3mIPyhZE6F+CtfYjNlDJwP5MN6Km7A==} - '@vitest/runner@4.0.14': - resolution: {integrity: sha512-BsAIk3FAqxICqREbX8SetIteT8PiaUL/tgJjmhxJhCsigmzzH8xeadtp7LRnTpCVzvf0ib9BgAfKJHuhNllKLw==} + '@vitest/runner@4.0.15': + resolution: {integrity: sha512-+A+yMY8dGixUhHmNdPUxOh0la6uVzun86vAbuMT3hIDxMrAOmn5ILBHm8ajrqHE0t8R9T1dGnde1A5DTnmi3qw==} - '@vitest/snapshot@4.0.14': - resolution: {integrity: sha512-aQVBfT1PMzDSA16Y3Fp45a0q8nKexx6N5Amw3MX55BeTeZpoC08fGqEZqVmPcqN0ueZsuUQ9rriPMhZ3Mu19Ag==} + '@vitest/snapshot@4.0.15': + resolution: {integrity: sha512-A7Ob8EdFZJIBjLjeO0DZF4lqR6U7Ydi5/5LIZ0xcI+23lYlsYJAfGn8PrIWTYdZQRNnSRlzhg0zyGu37mVdy5g==} - '@vitest/spy@4.0.14': - resolution: {integrity: sha512-JmAZT1UtZooO0tpY3GRyiC/8W7dCs05UOq9rfsUUgEZEdq+DuHLmWhPsrTt0TiW7WYeL/hXpaE07AZ2RCk44hg==} + '@vitest/spy@4.0.15': + resolution: {integrity: sha512-+EIjOJmnY6mIfdXtE/bnozKEvTC4Uczg19yeZ2vtCz5Yyb0QQ31QWVQ8hswJ3Ysx/K2EqaNsVanjr//2+P3FHw==} - '@vitest/utils@4.0.14': - resolution: {integrity: sha512-hLqXZKAWNg8pI+SQXyXxWCTOpA3MvsqcbVeNgSi8x/CSN2wi26dSzn1wrOhmCmFjEvN9p8/kLFRHa6PI8jHazw==} + '@vitest/utils@4.0.15': + resolution: {integrity: sha512-HXjPW2w5dxhTD0dLwtYHDnelK3j8sR8cWIaLxr22evTyY6q8pRCjZSmhRWVjBaOVXChQd6AwMzi9pucorXCPZA==} abitype@1.1.0: resolution: {integrity: sha512-6Vh4HcRxNMLA0puzPjM5GBgT4aAcFGKZzSgAXvuZ27shJP6NEpielTuqbBmZILR5/xd0PizkBGy5hReKz9jl5A==} @@ -1574,8 +1466,8 @@ packages: zod: optional: true - abitype@1.1.1: - resolution: {integrity: sha512-Loe5/6tAgsBukY95eGaPSDmQHIjRZYQq8PB1MpsNccDIK8WiV+Uw6WzaIXipvaxTEL2yEB0OpEaQv3gs8pkS9Q==} + abitype@1.2.2: + resolution: {integrity: sha512-4DOIMWscIB3j8hboLAUjLZCE8TMLdgecBpHFumfU4PdO/C1SBCVx4Nu1wPYXaL2iK8B0Jk3tiwnDLCpUtm3fZg==} peerDependencies: typescript: '>=5.0.4' zod: ^3.22.0 || ^4.0.0 @@ -1683,10 +1575,14 @@ packages: resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==} engines: {node: '>= 0.4'} - asn1js@3.0.6: - resolution: {integrity: sha512-UOCGPYbl0tv8+006qks/dTgV9ajs97X2p0FAbyS2iyCRrmLSRolDaHdp+v/CLgnzHc3fVB+CwYiUmei7ndFcgA==} + asn1js@3.0.7: + resolution: {integrity: sha512-uLvq6KJu04qoQM6gvBfKFjlh6Gl0vOKQuR5cJMDHQkmwfMOQeN3F3SHCv9SNYSL+CRoHvOGFfllDlVz03GQjvQ==} engines: {node: '>=12.0.0'} + assertion-error@2.0.1: + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} + engines: {node: '>=12'} + ast-types@0.13.4: resolution: {integrity: sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==} engines: {node: '>=4'} @@ -1708,6 +1604,10 @@ packages: base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + baseline-browser-mapping@2.9.7: + resolution: {integrity: sha512-k9xFKplee6KIio3IDbwj+uaCLpqzOwakOgmqzPezM0sFJlFKcg30vk2wOiAJtkTSfx0SSQDSe8q+mWA/fSH5Zg==} + hasBin: true + basic-ftp@5.0.5: resolution: {integrity: sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==} engines: {node: '>=10.0.0'} @@ -1733,6 +1633,11 @@ packages: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} + browserslist@4.28.1: + resolution: {integrity: sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + buffer@5.7.1: resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} @@ -1796,8 +1701,8 @@ packages: chardet@0.7.0: resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} - chardet@2.1.0: - resolution: {integrity: sha512-bNFETTG/pM5ryzQ9Ad0lJOTa6HWD/YsScAR3EnCPZRPlQh77JocYktSHOUHelyhm8IARL+o4c4F1bP5KVOjiRA==} + chardet@2.1.1: + resolution: {integrity: sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==} chokidar@3.6.0: resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} @@ -1874,8 +1779,11 @@ packages: constant-case@2.0.0: resolution: {integrity: sha512-eS0N9WwmjTqrOmR3o83F5vW8Z+9R1HnVz3xmzT2PMFug9ly+Au/fxRWlEBSb6LcZwspSsEn9Xs1uw9YgzAg1EQ==} - core-js-pure@3.46.0: - resolution: {integrity: sha512-NMCW30bHNofuhwLhYPt66OLOKTMbOhgTTatKVbaQC3KRHpTCiRIBYvtshr+NBYSnBxwAFhjW/RfJ0XbIjS16rw==} + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + + core-js-pure@3.47.0: + resolution: {integrity: sha512-BcxeDbzUrRnXGYIVAGFtcGQVNpFcUhVjr6W7F8XktvQW2iJP9e66GP6xdKotCRFlrxBvNIBrhwKteRXqMV86Nw==} cosmiconfig@9.0.0: resolution: {integrity: sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==} @@ -1982,8 +1890,11 @@ packages: resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} engines: {node: '>= 0.4'} - effect@3.19.6: - resolution: {integrity: sha512-Eh1E/CI+xCAcMSDC5DtyE29yWJINC0zwBbwHappQPorjKyS69rCA8qzpsHpfhKnPDYgxdg8zkknii8mZ+6YMQA==} + effect@3.19.12: + resolution: {integrity: sha512-7F9RGTrCTC3D7nh9Zw+3VlJWwZgo5k33KA+476BAaD0rKIXKZsY/jQ+ipyhR/Avo239Fi6GqAVFs1mqM1IJ7yg==} + + electron-to-chromium@1.5.267: + resolution: {integrity: sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==} emoji-regex@10.6.0: resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==} @@ -2002,8 +1913,8 @@ packages: error-ex@1.3.4: resolution: {integrity: sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==} - es-abstract@1.24.0: - resolution: {integrity: sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg==} + es-abstract@1.24.1: + resolution: {integrity: sha512-zHXBLhP+QehSSbsS9Pt23Gg964240DPd6QCf8WpkqEXxQ7fhdZzYsocOr5u7apWonsS5EjZDmTF+/slGMyasvw==} engines: {node: '>= 0.4'} es-define-property@1.0.1: @@ -2014,8 +1925,8 @@ packages: resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} engines: {node: '>= 0.4'} - es-iterator-helpers@1.2.1: - resolution: {integrity: sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w==} + es-iterator-helpers@1.2.2: + resolution: {integrity: sha512-BrUQ0cPTB/IwXj23HtwHjS9n7O4h9FX94b4xc5zlTHxeLgTAdzYUDyy6KdExAl9lbN5rtfe44xpjpmj9grxs5w==} engines: {node: '>= 0.4'} es-module-lexer@1.7.0: @@ -2037,13 +1948,8 @@ packages: resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==} engines: {node: '>= 0.4'} - esbuild@0.25.11: - resolution: {integrity: sha512-KohQwyzrKTQmhXDW1PjCv3Tyspn9n5GcY2RTDqeORIdIJY8yKIF7sTSopFmn/wpMPW4rdPXI0UE5LJLuq3bx0Q==} - engines: {node: '>=18'} - hasBin: true - - esbuild@0.27.0: - resolution: {integrity: sha512-jd0f4NHbD6cALCyGElNpGAOtWxSq46l9X/sWB0Nzd5er4Kz2YTm+Vl0qKFT9KUJvD8+fiO8AvoHhFvEatfVixA==} + esbuild@0.27.1: + resolution: {integrity: sha512-yY35KZckJJuVVPXpvjgxiCuVEJT67F6zDeVTv4rizyPrfGBUpZQsvmxnN+C371c2esD/hNMjj4tpBhuueLN7aA==} engines: {node: '>=18'} hasBin: true @@ -2064,8 +1970,8 @@ packages: engines: {node: '>=6.0'} hasBin: true - eslint-config-prettier@9.1.2: - resolution: {integrity: sha512-iI1f+D2ViGn+uvv5HuHVUamg8ll4tN+JRHGc6IJi4TP9Kl976C57fzPXgseXNs8v0iA8aSJpHsTWjDb9QJamGQ==} + eslint-config-prettier@10.1.8: + resolution: {integrity: sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==} hasBin: true peerDependencies: eslint: '>=7.0.0' @@ -2074,9 +1980,9 @@ packages: resolution: {integrity: sha512-2tktqUAT+Q3hCAU0iSf4xAN1k9zOpjK5WO8104mB0rT/dGhOa09582HN5HlbxNbPRZ0THV7nLGvzugcNOSjzfA==} engines: {node: '>=6'} - eslint-plugin-react-hooks@5.2.0: - resolution: {integrity: sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg==} - engines: {node: '>=10'} + eslint-plugin-react-hooks@7.0.1: + resolution: {integrity: sha512-O0d0m04evaNzEPoSW+59Mezf8Qt0InfgGIBJnpC0h3NH/WjUAR7BIKUfysC6todmtiZ/A0oUVS8Gce0WhBrHsA==} + engines: {node: '>=18'} peerDependencies: eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 @@ -2086,8 +1992,8 @@ packages: peerDependencies: eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7 - eslint-plugin-turbo@2.5.8: - resolution: {integrity: sha512-bVjx4vTH0oTKIyQ7EGFAXnuhZMrKIfu17qlex/dps7eScPnGQLJ3r1/nFq80l8xA+8oYjsSirSQ2tXOKbz3kEw==} + eslint-plugin-turbo@2.6.3: + resolution: {integrity: sha512-91WZ+suhT/pk+qNS0/rqT43xLUlUblsa3a8jKmAStGhkJCmR2uX0oWo/e0Edb+It8MdnteXuYpCkvsK4Vw8FtA==} peerDependencies: eslint: '>6.6.0' turbo: '>2.0.0' @@ -2104,8 +2010,8 @@ packages: resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - eslint@9.37.0: - resolution: {integrity: sha512-XyLmROnACWqSxiGYArdef1fItQd47weqB7iwtfr9JHwRrqIXZdcFMvvEcL9xHCmL0SNsOvF0c42lWyM1U5dgig==} + eslint@9.39.2: + resolution: {integrity: sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} hasBin: true peerDependencies: @@ -2149,8 +2055,8 @@ packages: resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} engines: {node: '>=10'} - expect-type@1.2.2: - resolution: {integrity: sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA==} + expect-type@1.3.0: + resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==} engines: {node: '>=12.0.0'} extendable-error@0.1.7: @@ -2262,6 +2168,10 @@ packages: resolution: {integrity: sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==} engines: {node: '>= 0.4'} + gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + get-caller-file@2.0.5: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} @@ -2310,8 +2220,8 @@ packages: resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} engines: {node: '>=18'} - globals@15.15.0: - resolution: {integrity: sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==} + globals@16.5.0: + resolution: {integrity: sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ==} engines: {node: '>=18'} globalthis@1.0.4: @@ -2341,16 +2251,13 @@ packages: resolution: {integrity: sha512-rEDCuqUQ4tbD78TpzsMtt5OIf0cBCSDWSJtUDaF6JsAh+k0v9r++NzxNEG87oDZx9ZwGhD8DaezR2L/yrw0Jdw==} engines: {node: '>=10'} - graphemer@1.4.0: - resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} - handlebars@4.7.8: resolution: {integrity: sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==} engines: {node: '>=0.4.7'} hasBin: true - happy-dom@20.0.10: - resolution: {integrity: sha512-6umCCHcjQrhP5oXhrHQQvLB0bwb1UzHAHdsXy+FjtKoYjUhmNZsQL8NivwM1vDvNEChJabVrUYxUnp/ZdYmy2g==} + happy-dom@20.0.11: + resolution: {integrity: sha512-QsCdAUHAmiDeKeaNojb1OHOPF7NjcWPBR7obdu3NwH2a/oyQaLg5d0aaCy/9My6CdPChYF07dvz5chaXBGaD4g==} engines: {node: '>=20.0.0'} has-bigints@1.1.0: @@ -2387,6 +2294,12 @@ packages: header-case@1.0.1: resolution: {integrity: sha512-i0q9mkOeSuhXw6bGgiQCCBgY/jlZuV/7dZXyZ9c6LcBrqwvT8eT719E9uxE5LiZftdl+z81Ugbg/VvXV4OJOeQ==} + hermes-estree@0.25.1: + resolution: {integrity: sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw==} + + hermes-parser@0.25.1: + resolution: {integrity: sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA==} + hosted-git-info@8.1.0: resolution: {integrity: sha512-Rw/B2DNQaPBICNXEm8balFz9a6WpZrkCGpcWFpy7nCj+NyhSdqXipmfvtmWt9xGfp0wZnBxB+iVpLmQMYt47Tw==} engines: {node: ^18.17.0 || >=20.5.0} @@ -2402,8 +2315,8 @@ packages: resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} engines: {node: '>= 14'} - human-id@4.1.2: - resolution: {integrity: sha512-v/J+4Z/1eIJovEBdlV5TYj1IR+ZiohcYGRY+qN/oC9dAfKzVT023N/Bgw37hrKCoVRBvk3bqyzpr2PP5YeTMSg==} + human-id@4.1.3: + resolution: {integrity: sha512-tsYlhAYpjCKa//8rXZ9DqKEawhPoSytweBC2eNvcaDK+57RZLHGqNs3PZTQO6yekLFSuvA6AlnAfrw1uBvtb+Q==} hasBin: true human-signals@2.1.0: @@ -2414,8 +2327,8 @@ packages: resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} engines: {node: '>=0.10.0'} - iconv-lite@0.7.0: - resolution: {integrity: sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==} + iconv-lite@0.7.1: + resolution: {integrity: sha512-2Tth85cXwGFHfvRgZWszZSvdo+0Xsqmw8k8ZwxScfcBneNUraK+dxRxRm24nszx80Y0TVio8kKLt5sLE7ZCLlw==} engines: {node: '>=0.10.0'} idb@8.0.3: @@ -2469,8 +2382,8 @@ packages: resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} engines: {node: '>= 0.4'} - ip-address@10.0.1: - resolution: {integrity: sha512-NWv9YLW4PoW2B7xtzaS3NCot75m6nK7Icdv0o3lfMceJVRfSoQwqD4wEH5rLwoKJwUiZ/rfpiVBhnaF0FK4HoA==} + ip-address@10.1.0: + resolution: {integrity: sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==} engines: {node: '>= 12'} is-array-buffer@3.0.5: @@ -2671,12 +2584,17 @@ packages: js-tokens@9.0.1: resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==} - js-yaml@3.14.1: - resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} + js-yaml@3.14.2: + resolution: {integrity: sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==} hasBin: true - js-yaml@4.1.0: - resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + js-yaml@4.1.1: + resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} + hasBin: true + + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} hasBin: true json-buffer@3.0.1: @@ -2694,6 +2612,11 @@ packages: json-stable-stringify-without-jsonify@1.0.1: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + jsonc-parser@3.3.1: resolution: {integrity: sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==} @@ -2718,58 +2641,58 @@ packages: resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} engines: {node: '>=6'} - lefthook-darwin-arm64@2.0.4: - resolution: {integrity: sha512-AR63/O5UkM7Sc6x5PhP4vTuztTYRBeBroXApeWGM/8e5uZyoQug/7KTh7xhbCMDf8WJv6vdFeXAQCPSmDyPU3Q==} + lefthook-darwin-arm64@2.0.12: + resolution: {integrity: sha512-tuBz1sNLien+nKKb8BDopKjS6EnbXU8rQzhMVBY+bnVfsTiYDfbBr4wo/IzA5TcwoTL/b5somCJhljEw6DvSyg==} cpu: [arm64] os: [darwin] - lefthook-darwin-x64@2.0.4: - resolution: {integrity: sha512-618DVUttSzV9egQiqTQoxGfnR240JoPWYmqRVHhiegnQKZ2lp5XJ+7NMxeRk/ih93VVOLzFO5ky3PbpxTmJgjQ==} + lefthook-darwin-x64@2.0.12: + resolution: {integrity: sha512-FnuUMPPRMJyTEPXg6PotSrFJ8qf8FDLhhD1zLh74D+9Cye5j9n3lcrCQEjXubPT8du/GZLxMBjjffRbcZ8eYDA==} cpu: [x64] os: [darwin] - lefthook-freebsd-arm64@2.0.4: - resolution: {integrity: sha512-mTAQym1BK38fKglHBQ/0GXPznVC4LoStHO5lAI3ZxaEC0FQetqGHYFzhWbIH5sde9JhztE2rL/aBzMHDoAtzSw==} + lefthook-freebsd-arm64@2.0.12: + resolution: {integrity: sha512-DXElB0qR5e6a8cXkFNYakhwCieypbfh6Y4QG39pzMnLsG03g/nhe093o6owfiUZ4mUFyDM6+0xmy0steOooF2g==} cpu: [arm64] os: [freebsd] - lefthook-freebsd-x64@2.0.4: - resolution: {integrity: sha512-sy02aSxd8UMd6XmiPFVl/Em0b78jdZcDSsLwg+bweJQQk0l+vJhOfqFiG11mbnpo+EBIZmRe6OH5LkxeSU36+w==} + lefthook-freebsd-x64@2.0.12: + resolution: {integrity: sha512-iJN1ZxFeaDi4Fi3b9jcW9wgyNl19LOv2NaVOaAi/tG6mlIn196cmSdXkOA3+943ZbqbdfV9I+bBcIKwneXDA3Q==} cpu: [x64] os: [freebsd] - lefthook-linux-arm64@2.0.4: - resolution: {integrity: sha512-W0Nlr/Cz2QTH9n4k5zNrk3LSsg1C4wHiJi8hrAiQVTaAV/N1XrKqd0DevqQuouuapG6pw/6B1xCgiNPebv9oyw==} + lefthook-linux-arm64@2.0.12: + resolution: {integrity: sha512-byvmO4Iri6P0COwM8c3lGgeCV3Q0hh1XJpRfrcZDr4Wslq9O63t6J3T6i87oOtY+UjC9pXLl6xGk6hlUcHZ3BQ==} cpu: [arm64] os: [linux] - lefthook-linux-x64@2.0.4: - resolution: {integrity: sha512-N6ySVCtB/DrOZ1ZgPL8WBZTgtoVHvcPKI+LV5wbcGrvA/dzDZFvniadrbDWZg7Tm705efiQzyENjwhhqNkwiww==} + lefthook-linux-x64@2.0.12: + resolution: {integrity: sha512-KBaiinmf336rA+/dmYs7H7TTeAOByB0CyLA7k8IecTCuaiuKr6ez7ktSjht19poa5G+V0mts4GgEGcx6HViR0w==} cpu: [x64] os: [linux] - lefthook-openbsd-arm64@2.0.4: - resolution: {integrity: sha512-VmOhJO3pYzZ/1C2WFXtL/n5pq4/eYOroqJJpwTJfmCHyw4ceLACu8MDyU5AMJhGMkbL8mPxGInJKxg5xhYgGRw==} + lefthook-openbsd-arm64@2.0.12: + resolution: {integrity: sha512-1QBMXX1UW5rtgC4TB52OKWB7Rz/kCBRB+bKKLT/gDD79aPzLgJANTitQQzgFNIWoa7aM9UvzvIAJzOo6FcFIbg==} cpu: [arm64] os: [openbsd] - lefthook-openbsd-x64@2.0.4: - resolution: {integrity: sha512-U8MZz1xlHUdflkQQ2hkMQsei6fSZbs8tuE4EjCIHWnNdnAF4V8sZ6n1KbxsJcoZXPyBZqxZSMu1o/Ye8IAMVKg==} + lefthook-openbsd-x64@2.0.12: + resolution: {integrity: sha512-zPcvUzs65GexRA37UHmaZqWuEGSU/zpBaPIY98MybXzzcJfCIf+O0oUQe2riMllwYGvNW0B1y3NOYRziDNe/vA==} cpu: [x64] os: [openbsd] - lefthook-windows-arm64@2.0.4: - resolution: {integrity: sha512-543H3y2JAwNdvwUQ6nlNBG7rdKgoOUgzAa6pYcl6EoqicCRrjRmGhkJu7vUudkkrD2Wjm7tr9hU9poP2g5fRFQ==} + lefthook-windows-arm64@2.0.12: + resolution: {integrity: sha512-kgwxguS2GssoHM4SMTp+ArD/Gjg9q5MinD6iI5vSFpuJygD13ZWiXQQfESMHq9y/v1XkD0BdHTJej49dx8P+Vw==} cpu: [arm64] os: [win32] - lefthook-windows-x64@2.0.4: - resolution: {integrity: sha512-UDEPK9RWKm60xsNOdS/DQOdFba0SFa4w3tpFMXK1AJzmRHhosoKrorXGhtTr6kcM0MGKOtYi8GHsm++ArZ9wvQ==} + lefthook-windows-x64@2.0.12: + resolution: {integrity: sha512-Tf/VtSOtF3rBTc9dzRWROa+HuhqaiIV+Xp+1gzlx5+uCueLM0m87Rz6yd4IN5mL7TrDaNkiRXI3FvjCp0dUE4Q==} cpu: [x64] os: [win32] - lefthook@2.0.4: - resolution: {integrity: sha512-GNCU2vQWM/UWjiEF23601aILi1aMbPke6viortH7wIO/oVGOCW0H6FdLez4XZDyqnHL9XkTnd0BBVrBbYVMLpA==} + lefthook@2.0.12: + resolution: {integrity: sha512-I2FdA9cdnq1icwlNz4RADs7exuqe47q1N9+p2LmcP/WfchWh16mvTB82OAD7w7zK9GxblS9GpF7pASaOSl4c7A==} hasBin: true levn@0.4.1: @@ -2825,10 +2748,13 @@ packages: lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} - lru-cache@11.2.2: - resolution: {integrity: sha512-F9ODfyqML2coTIsQpSkRHnLSZMtkU8Q+mSfcaIyKwy58u+8k5nvAYeiNhsyMARvzNcXJ9QfWVrcPsC9e9rAxtg==} + lru-cache@11.2.4: + resolution: {integrity: sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==} engines: {node: 20 || >=22} + lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + lru-cache@7.18.3: resolution: {integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==} engines: {node: '>=12'} @@ -2952,6 +2878,9 @@ packages: resolution: {integrity: sha512-Cov028YhBZ5aB7MdMWJEmwyBig43aGL5WT4vdoB28Oitau1zZAcHUn8Sgfk9HM33TqhtLJ9PlM/O0Mv+QpV/4Q==} engines: {node: '>=8.9.4'} + node-releases@2.0.27: + resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==} + nodemon@3.1.11: resolution: {integrity: sha512-is96t8F/1//UHAjNPHpbsNY46ELPpftGUoSVNXwUfMk/qdjSylYrWSu1XavVTBOn526kFiOR733ATgNBCQyH0g==} engines: {node: '>=10'} @@ -3124,8 +3053,8 @@ packages: path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} - path-scurry@2.0.0: - resolution: {integrity: sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==} + path-scurry@2.0.1: + resolution: {integrity: sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==} engines: {node: 20 || >=22} path-type@4.0.0: @@ -3154,9 +3083,9 @@ packages: resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} engines: {node: '>=6'} - pkijs@3.3.0: - resolution: {integrity: sha512-SVUpr7uqRNuR6w417k0aM8YrHWWhvMh4P0paIA+wWdOxPOLd7PCDZgt3/nooAyrrO1cjwPP2I1hd3h2P6hUQZQ==} - engines: {node: '>=12.0.0'} + pkijs@3.3.3: + resolution: {integrity: sha512-+KD8hJtqQMYoTuL1bbGOqxb4z+nZkTAwVdNtWwe8Tc2xNbEmdJYIYoc6Qt0uF55e6YW6KuTHw1DjQ18gMhzepw==} + engines: {node: '>=16.0.0'} possible-typed-array-names@1.1.0: resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} @@ -3179,8 +3108,8 @@ packages: engines: {node: '>=10.13.0'} hasBin: true - prettier@3.6.2: - resolution: {integrity: sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==} + prettier@3.7.4: + resolution: {integrity: sha512-v6UNi1+3hSlVvv8fSaoUbggEM5VErKmmpGA7Pl3HF8V6uKY7rvClBOJlH6yNwQtfTueNkGVpOv/mtWL9L4bgRA==} engines: {node: '>=14'} hasBin: true @@ -3215,9 +3144,9 @@ packages: pvtsutils@1.3.6: resolution: {integrity: sha512-PLgQXQ6H2FWCaeRak8vvk1GW462lMxB5s3Jm673N82zI4vqtVUPuZdffdZbPDFRoU8kAhItWFtPCWiPpp4/EDg==} - pvutils@1.1.3: - resolution: {integrity: sha512-pMpnA0qRdFp32b1sJl1wOJNxZLQ2cbQx+k6tjNtZ8CpvVhNqEPRgivZ2WOUev2YMajecdH7ctUPDvEe87nariQ==} - engines: {node: '>=6.0.0'} + pvutils@1.1.5: + resolution: {integrity: sha512-KTqnxsgGiQ6ZAzZCVlJH5eOjSnvlyEgx1m8bkRJfOhmGRqfo5KLvmAlACQkrjEtOQ4B7wF9TdSLIs9O90MX9xA==} + engines: {node: '>=16.0.0'} quansync@0.2.11: resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==} @@ -3229,16 +3158,16 @@ packages: resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} hasBin: true - react-dom@19.2.0: - resolution: {integrity: sha512-UlbRu4cAiGaIewkPyiRGJk0imDN2T3JjieT6spoL2UeSf5od4n5LB/mQ4ejmxhCFT1tYe8IvaFulzynWovsEFQ==} + react-dom@19.2.3: + resolution: {integrity: sha512-yELu4WmLPw5Mr/lmeEpox5rw3RETacE++JgHqQzd2dg+YbJuat3jH4ingc+WPZhxaoFzdv9y33G+F7Nl5O0GBg==} peerDependencies: - react: ^19.2.0 + react: ^19.2.3 react-is@16.13.1: resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} - react@19.2.0: - resolution: {integrity: sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ==} + react@19.2.3: + resolution: {integrity: sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA==} engines: {node: '>=0.10.0'} read-yaml-file@1.1.0: @@ -3284,8 +3213,8 @@ packages: resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} engines: {node: '>=8'} - resolve@1.22.10: - resolution: {integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==} + resolve@1.22.11: + resolution: {integrity: sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==} engines: {node: '>= 0.4'} hasBin: true @@ -3315,8 +3244,8 @@ packages: engines: {node: 20 || >=22} hasBin: true - rollup@4.52.4: - resolution: {integrity: sha512-CLEVl+MnPAiKh5pl4dEWSyMTpuflgNQiLGhMv8ezD5W/qP8AKvmYpCOKRRNOh7oRKnauBZ4SyeYkMS+1VSyKwQ==} + rollup@4.53.4: + resolution: {integrity: sha512-YpXaaArg0MvrnJpvduEDYIp7uGOqKXbH9NsHGQ6SxKCOsNAjZF018MmxefFUulVP2KLtiGw1UvZbr+/ekjvlDg==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -3591,8 +3520,9 @@ packages: tinycolor2@1.6.0: resolution: {integrity: sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==} - tinyexec@0.3.2: - resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} + tinyexec@1.0.2: + resolution: {integrity: sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==} + engines: {node: '>=18'} tinyglobby@0.2.15: resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} @@ -3653,70 +3583,36 @@ packages: tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} - turbo-darwin-64@2.6.1: - resolution: {integrity: sha512-Dm0HwhyZF4J0uLqkhUyCVJvKM9Rw7M03v3J9A7drHDQW0qAbIGBrUijQ8g4Q9Cciw/BXRRd8Uzkc3oue+qn+ZQ==} - cpu: [x64] - os: [darwin] - turbo-darwin-64@2.6.3: resolution: {integrity: sha512-BlJJDc1CQ7SK5Y5qnl7AzpkvKSnpkfPmnA+HeU/sgny3oHZckPV2776ebO2M33CYDSor7+8HQwaodY++IINhYg==} cpu: [x64] os: [darwin] - turbo-darwin-arm64@2.6.1: - resolution: {integrity: sha512-U0PIPTPyxdLsrC3jN7jaJUwgzX5sVUBsKLO7+6AL+OASaa1NbT1pPdiZoTkblBAALLP76FM0LlnsVQOnmjYhyw==} - cpu: [arm64] - os: [darwin] - turbo-darwin-arm64@2.6.3: resolution: {integrity: sha512-MwVt7rBKiOK7zdYerenfCRTypefw4kZCue35IJga9CH1+S50+KTiCkT6LBqo0hHeoH2iKuI0ldTF2a0aB72z3w==} cpu: [arm64] os: [darwin] - turbo-linux-64@2.6.1: - resolution: {integrity: sha512-eM1uLWgzv89bxlK29qwQEr9xYWBhmO/EGiH22UGfq+uXr+QW1OvNKKMogSN65Ry8lElMH4LZh0aX2DEc7eC0Mw==} - cpu: [x64] - os: [linux] - turbo-linux-64@2.6.3: resolution: {integrity: sha512-cqpcw+dXxbnPtNnzeeSyWprjmuFVpHJqKcs7Jym5oXlu/ZcovEASUIUZVN3OGEM6Y/OTyyw0z09tOHNt5yBAVg==} cpu: [x64] os: [linux] - turbo-linux-arm64@2.6.1: - resolution: {integrity: sha512-MFFh7AxAQAycXKuZDrbeutfWM5Ep0CEZ9u7zs4Hn2FvOViTCzIfEhmuJou3/a5+q5VX1zTxQrKGy+4Lf5cdpsA==} - cpu: [arm64] - os: [linux] - turbo-linux-arm64@2.6.3: resolution: {integrity: sha512-MterpZQmjXyr4uM7zOgFSFL3oRdNKeflY7nsjxJb2TklsYqiu3Z9pQ4zRVFFH8n0mLGna7MbQMZuKoWqqHb45w==} cpu: [arm64] os: [linux] - turbo-windows-64@2.6.1: - resolution: {integrity: sha512-buq7/VAN7KOjMYi4tSZT5m+jpqyhbRU2EUTTvp6V0Ii8dAkY2tAAjQN1q5q2ByflYWKecbQNTqxmVploE0LVwQ==} - cpu: [x64] - os: [win32] - turbo-windows-64@2.6.3: resolution: {integrity: sha512-biDU70v9dLwnBdLf+daoDlNJVvqOOP8YEjqNipBHzgclbQlXbsi6Gqqelp5er81Qo3BiRgmTNx79oaZQTPb07Q==} cpu: [x64] os: [win32] - turbo-windows-arm64@2.6.1: - resolution: {integrity: sha512-7w+AD5vJp3R+FB0YOj1YJcNcOOvBior7bcHTodqp90S3x3bLgpr7tE6xOea1e8JkP7GK6ciKVUpQvV7psiwU5Q==} - cpu: [arm64] - os: [win32] - turbo-windows-arm64@2.6.3: resolution: {integrity: sha512-dDHVKpSeukah3VsI/xMEKeTnV9V9cjlpFSUs4bmsUiLu3Yv2ENlgVEZv65wxbeE0bh0jjpmElDT+P1KaCxArQQ==} cpu: [arm64] os: [win32] - turbo@2.6.1: - resolution: {integrity: sha512-qBwXXuDT3rA53kbNafGbT5r++BrhRgx3sAo0cHoDAeG9g1ItTmUMgltz3Hy7Hazy1ODqNpR+C7QwqL6DYB52yA==} - hasBin: true - turbo@2.6.3: resolution: {integrity: sha512-bf6YKUv11l5Xfcmg76PyWoy/e2vbkkxFNBGJSnfdSXQC33ZiUfutYh6IXidc5MhsnrFkWfdNNLyaRk+kHMLlwA==} hasBin: true @@ -3745,18 +3641,13 @@ packages: resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==} engines: {node: '>= 0.4'} - typescript-eslint@8.46.1: - resolution: {integrity: sha512-VHgijW803JafdSsDO8I761r3SHrgk4T00IdyQ+/UsthtgPRsBWQLqoSxOolxTpxRKi1kGXK0bSz4CoAc9ObqJA==} + typescript-eslint@8.50.0: + resolution: {integrity: sha512-Q1/6yNUmCpH94fbgMUMg2/BSAr/6U7GBk61kZTv1/asghQOWOjTlp9K8mixS5NcJmm2creY+UFfGeW/+OcA64A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - typescript@5.8.3: - resolution: {integrity: sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==} - engines: {node: '>=14.17'} - hasBin: true - typescript@5.9.3: resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} engines: {node: '>=14.17'} @@ -3792,6 +3683,12 @@ packages: resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} engines: {node: '>= 10.0.0'} + update-browserslist-db@1.2.2: + resolution: {integrity: sha512-E85pfNzMQ9jpKkA7+TJAi4TJN+tBCuWh5rUcS/sv6cFi+1q9LYDwDI5dpUL0u/73EElyQ8d3TEaeW4sPedBqYA==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + update-check@1.5.4: resolution: {integrity: sha512-5YHsflzHP4t1G+8WGPlvKbJEbAJGCgw+Em+dGR1KmBUbr1J36SJBqlHLjR7oob7sco5hWHGQVcr9B2poIVDDTQ==} @@ -3822,16 +3719,16 @@ packages: resolution: {integrity: sha512-IUoow1YUtvoBBC06dXs8bR8B9vuA3aJfmQNKMoaPG/OFsPmoQvw8xh+6Ye25Gx9DQhoEom3Pcu9MKHerm/NpUQ==} engines: {node: ^18.17.0 || >=20.5.0} - viem@2.40.3: - resolution: {integrity: sha512-feYfEpbgjRkZYQpwcgxqkWzjxHI5LSDAjcGetHHwDRuX9BRQHUdV8ohrCosCYpdEhus/RknD3/bOd4qLYVPPuA==} + viem@2.42.1: + resolution: {integrity: sha512-NzT/f54jT+b0Um6pYzN/uAGMLg+3twhricAzXS+XH8pVIREzPEh7P25rlhPQnLYiPWzQd9mrFcvnm73Sc8bx+A==} peerDependencies: typescript: '>=5.0.4' peerDependenciesMeta: typescript: optional: true - vite@7.1.10: - resolution: {integrity: sha512-CmuvUBzVJ/e3HGxhg6cYk88NGgTnBoOo7ogtfJJ0fefUWAxN/WDSUa50o+oVBxuIhO8FoEZW0j2eW7sfjs5EtA==} + vite@7.3.0: + resolution: {integrity: sha512-dZwN5L1VlUBewiP6H9s2+B3e3Jg96D0vzN+Ry73sOefebhYr9f94wwkMNN/9ouoU8pV1BqA1d1zGk8928cx0rg==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: @@ -3870,18 +3767,18 @@ packages: yaml: optional: true - vitest@4.0.14: - resolution: {integrity: sha512-d9B2J9Cm9dN9+6nxMnnNJKJCtcyKfnHj15N6YNJfaFHRLua/d3sRKU9RuKmO9mB0XdFtUizlxfz/VPbd3OxGhw==} + vitest@4.0.15: + resolution: {integrity: sha512-n1RxDp8UJm6N0IbJLQo+yzLZ2sQCDyl1o0LeugbPWf8+8Fttp29GghsQBjYJVmWq3gBFfe9Hs1spR44vovn2wA==} engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@opentelemetry/api': ^1.9.0 '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0 - '@vitest/browser-playwright': 4.0.14 - '@vitest/browser-preview': 4.0.14 - '@vitest/browser-webdriverio': 4.0.14 - '@vitest/ui': 4.0.14 + '@vitest/browser-playwright': 4.0.15 + '@vitest/browser-preview': 4.0.15 + '@vitest/browser-webdriverio': 4.0.15 + '@vitest/ui': 4.0.15 happy-dom: '*' jsdom: '*' peerDependenciesMeta: @@ -3975,6 +3872,9 @@ packages: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} + yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + yargs-parser@21.1.1: resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} engines: {node: '>=12'} @@ -3999,12 +3899,21 @@ packages: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} + zod-validation-error@4.0.2: + resolution: {integrity: sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ==} + engines: {node: '>=18.0.0'} + peerDependencies: + zod: ^3.25.0 || ^4.0.0 + + zod@4.2.0: + resolution: {integrity: sha512-Bd5fw9wlIhtqCCxotZgdTOMwGm1a0u75wARVEY9HMs1X17trvA/lMi4+MGK5EUfYkXVTbX8UDiDKW4OgzHVUZw==} + snapshots: '@0xsequence/tee-verifier@0.1.2': dependencies: cbor2: 1.12.0 - pkijs: 3.3.0 + pkijs: 3.3.3 '@adraffy/ens-normalize@1.11.1': {} @@ -4014,20 +3923,101 @@ snapshots: js-tokens: 4.0.0 picocolors: 1.1.1 + '@babel/compat-data@7.28.5': {} + + '@babel/core@7.28.5': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.28.5 + '@babel/helper-compilation-targets': 7.27.2 + '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.5) + '@babel/helpers': 7.28.4 + '@babel/parser': 7.28.5 + '@babel/template': 7.27.2 + '@babel/traverse': 7.28.5 + '@babel/types': 7.28.5 + '@jridgewell/remapping': 2.3.5 + convert-source-map: 2.0.0 + debug: 4.4.3(supports-color@5.5.0) + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/generator@7.28.5': + dependencies: + '@babel/parser': 7.28.5 + '@babel/types': 7.28.5 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + jsesc: 3.1.0 + + '@babel/helper-compilation-targets@7.27.2': + dependencies: + '@babel/compat-data': 7.28.5 + '@babel/helper-validator-option': 7.27.1 + browserslist: 4.28.1 + lru-cache: 5.1.1 + semver: 6.3.1 + + '@babel/helper-globals@7.28.0': {} + + '@babel/helper-module-imports@7.27.1': + dependencies: + '@babel/traverse': 7.28.5 + '@babel/types': 7.28.5 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-transforms@7.28.3(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-module-imports': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 + '@babel/traverse': 7.28.5 + transitivePeerDependencies: + - supports-color + '@babel/helper-string-parser@7.27.1': {} '@babel/helper-validator-identifier@7.28.5': {} + '@babel/helper-validator-option@7.27.1': {} + + '@babel/helpers@7.28.4': + dependencies: + '@babel/template': 7.27.2 + '@babel/types': 7.28.5 + '@babel/parser@7.28.5': dependencies: '@babel/types': 7.28.5 '@babel/runtime-corejs3@7.28.4': dependencies: - core-js-pure: 3.46.0 + core-js-pure: 3.47.0 '@babel/runtime@7.28.4': {} + '@babel/template@7.27.2': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/parser': 7.28.5 + '@babel/types': 7.28.5 + + '@babel/traverse@7.28.5': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.28.5 + '@babel/helper-globals': 7.28.0 + '@babel/parser': 7.28.5 + '@babel/template': 7.27.2 + '@babel/types': 7.28.5 + debug: 4.4.3(supports-color@5.5.0) + transitivePeerDependencies: + - supports-color + '@babel/types@7.28.5': dependencies: '@babel/helper-string-parser': 7.27.1 @@ -4035,9 +4025,9 @@ snapshots: '@bcoe/v8-coverage@1.0.2': {} - '@changesets/apply-release-plan@7.0.13': + '@changesets/apply-release-plan@7.0.14': dependencies: - '@changesets/config': 3.1.1 + '@changesets/config': 3.1.2 '@changesets/get-version-range-type': 0.4.0 '@changesets/git': 3.0.4 '@changesets/should-skip-package': 0.1.2 @@ -4064,23 +4054,23 @@ snapshots: dependencies: '@changesets/types': 6.1.0 - '@changesets/cli@2.29.7(@types/node@24.10.1)': + '@changesets/cli@2.29.8(@types/node@25.0.2)': dependencies: - '@changesets/apply-release-plan': 7.0.13 + '@changesets/apply-release-plan': 7.0.14 '@changesets/assemble-release-plan': 6.0.9 '@changesets/changelog-git': 0.2.1 - '@changesets/config': 3.1.1 + '@changesets/config': 3.1.2 '@changesets/errors': 0.2.0 '@changesets/get-dependents-graph': 2.1.3 - '@changesets/get-release-plan': 4.0.13 + '@changesets/get-release-plan': 4.0.14 '@changesets/git': 3.0.4 '@changesets/logger': 0.1.1 '@changesets/pre': 2.0.2 - '@changesets/read': 0.6.5 + '@changesets/read': 0.6.6 '@changesets/should-skip-package': 0.1.2 '@changesets/types': 6.1.0 '@changesets/write': 0.4.0 - '@inquirer/external-editor': 1.0.2(@types/node@24.10.1) + '@inquirer/external-editor': 1.0.3(@types/node@25.0.2) '@manypkg/get-packages': 1.1.3 ansi-colors: 4.1.3 ci-info: 3.9.0 @@ -4097,7 +4087,7 @@ snapshots: transitivePeerDependencies: - '@types/node' - '@changesets/config@3.1.1': + '@changesets/config@3.1.2': dependencies: '@changesets/errors': 0.2.0 '@changesets/get-dependents-graph': 2.1.3 @@ -4118,12 +4108,12 @@ snapshots: picocolors: 1.1.1 semver: 7.7.3 - '@changesets/get-release-plan@4.0.13': + '@changesets/get-release-plan@4.0.14': dependencies: '@changesets/assemble-release-plan': 6.0.9 - '@changesets/config': 3.1.1 + '@changesets/config': 3.1.2 '@changesets/pre': 2.0.2 - '@changesets/read': 0.6.5 + '@changesets/read': 0.6.6 '@changesets/types': 6.1.0 '@manypkg/get-packages': 1.1.3 @@ -4141,10 +4131,10 @@ snapshots: dependencies: picocolors: 1.1.1 - '@changesets/parse@0.4.1': + '@changesets/parse@0.4.2': dependencies: '@changesets/types': 6.1.0 - js-yaml: 3.14.1 + js-yaml: 4.1.1 '@changesets/pre@2.0.2': dependencies: @@ -4153,11 +4143,11 @@ snapshots: '@manypkg/get-packages': 1.1.3 fs-extra: 7.0.1 - '@changesets/read@0.6.5': + '@changesets/read@0.6.6': dependencies: '@changesets/git': 3.0.4 '@changesets/logger': 0.1.1 - '@changesets/parse': 0.4.1 + '@changesets/parse': 0.4.2 '@changesets/types': 6.1.0 fs-extra: 7.0.1 p-filter: 2.1.0 @@ -4176,7 +4166,7 @@ snapshots: dependencies: '@changesets/types': 6.1.0 fs-extra: 7.0.1 - human-id: 4.1.2 + human-id: 4.1.3 prettier: 2.8.8 '@cspotcode/source-map-support@0.8.1': @@ -4188,186 +4178,108 @@ snapshots: tslib: 2.8.1 optional: true - '@esbuild/aix-ppc64@0.25.11': - optional: true - - '@esbuild/aix-ppc64@0.27.0': - optional: true - - '@esbuild/android-arm64@0.25.11': - optional: true - - '@esbuild/android-arm64@0.27.0': - optional: true - - '@esbuild/android-arm@0.25.11': - optional: true - - '@esbuild/android-arm@0.27.0': - optional: true - - '@esbuild/android-x64@0.25.11': - optional: true - - '@esbuild/android-x64@0.27.0': - optional: true - - '@esbuild/darwin-arm64@0.25.11': - optional: true - - '@esbuild/darwin-arm64@0.27.0': - optional: true - - '@esbuild/darwin-x64@0.25.11': - optional: true - - '@esbuild/darwin-x64@0.27.0': - optional: true - - '@esbuild/freebsd-arm64@0.25.11': - optional: true - - '@esbuild/freebsd-arm64@0.27.0': - optional: true - - '@esbuild/freebsd-x64@0.25.11': - optional: true - - '@esbuild/freebsd-x64@0.27.0': - optional: true - - '@esbuild/linux-arm64@0.25.11': - optional: true - - '@esbuild/linux-arm64@0.27.0': - optional: true - - '@esbuild/linux-arm@0.25.11': - optional: true - - '@esbuild/linux-arm@0.27.0': - optional: true - - '@esbuild/linux-ia32@0.25.11': - optional: true - - '@esbuild/linux-ia32@0.27.0': + '@esbuild/aix-ppc64@0.27.1': optional: true - '@esbuild/linux-loong64@0.25.11': + '@esbuild/android-arm64@0.27.1': optional: true - '@esbuild/linux-loong64@0.27.0': + '@esbuild/android-arm@0.27.1': optional: true - '@esbuild/linux-mips64el@0.25.11': + '@esbuild/android-x64@0.27.1': optional: true - '@esbuild/linux-mips64el@0.27.0': + '@esbuild/darwin-arm64@0.27.1': optional: true - '@esbuild/linux-ppc64@0.25.11': + '@esbuild/darwin-x64@0.27.1': optional: true - '@esbuild/linux-ppc64@0.27.0': + '@esbuild/freebsd-arm64@0.27.1': optional: true - '@esbuild/linux-riscv64@0.25.11': + '@esbuild/freebsd-x64@0.27.1': optional: true - '@esbuild/linux-riscv64@0.27.0': + '@esbuild/linux-arm64@0.27.1': optional: true - '@esbuild/linux-s390x@0.25.11': + '@esbuild/linux-arm@0.27.1': optional: true - '@esbuild/linux-s390x@0.27.0': + '@esbuild/linux-ia32@0.27.1': optional: true - '@esbuild/linux-x64@0.25.11': + '@esbuild/linux-loong64@0.27.1': optional: true - '@esbuild/linux-x64@0.27.0': + '@esbuild/linux-mips64el@0.27.1': optional: true - '@esbuild/netbsd-arm64@0.25.11': + '@esbuild/linux-ppc64@0.27.1': optional: true - '@esbuild/netbsd-arm64@0.27.0': + '@esbuild/linux-riscv64@0.27.1': optional: true - '@esbuild/netbsd-x64@0.25.11': + '@esbuild/linux-s390x@0.27.1': optional: true - '@esbuild/netbsd-x64@0.27.0': + '@esbuild/linux-x64@0.27.1': optional: true - '@esbuild/openbsd-arm64@0.25.11': + '@esbuild/netbsd-arm64@0.27.1': optional: true - '@esbuild/openbsd-arm64@0.27.0': + '@esbuild/netbsd-x64@0.27.1': optional: true - '@esbuild/openbsd-x64@0.25.11': + '@esbuild/openbsd-arm64@0.27.1': optional: true - '@esbuild/openbsd-x64@0.27.0': + '@esbuild/openbsd-x64@0.27.1': optional: true - '@esbuild/openharmony-arm64@0.25.11': + '@esbuild/openharmony-arm64@0.27.1': optional: true - '@esbuild/openharmony-arm64@0.27.0': + '@esbuild/sunos-x64@0.27.1': optional: true - '@esbuild/sunos-x64@0.25.11': + '@esbuild/win32-arm64@0.27.1': optional: true - '@esbuild/sunos-x64@0.27.0': + '@esbuild/win32-ia32@0.27.1': optional: true - '@esbuild/win32-arm64@0.25.11': + '@esbuild/win32-x64@0.27.1': optional: true - '@esbuild/win32-arm64@0.27.0': - optional: true - - '@esbuild/win32-ia32@0.25.11': - optional: true - - '@esbuild/win32-ia32@0.27.0': - optional: true - - '@esbuild/win32-x64@0.25.11': - optional: true - - '@esbuild/win32-x64@0.27.0': - optional: true - - '@eslint-community/eslint-utils@4.9.0(eslint@9.37.0)': + '@eslint-community/eslint-utils@4.9.0(eslint@9.39.2)': dependencies: - eslint: 9.37.0 + eslint: 9.39.2 eslint-visitor-keys: 3.4.3 - '@eslint-community/regexpp@4.12.1': {} + '@eslint-community/regexpp@4.12.2': {} - '@eslint/config-array@0.21.0': + '@eslint/config-array@0.21.1': dependencies: - '@eslint/object-schema': 2.1.6 + '@eslint/object-schema': 2.1.7 debug: 4.4.3(supports-color@5.5.0) minimatch: 3.1.2 transitivePeerDependencies: - supports-color - '@eslint/config-helpers@0.4.0': + '@eslint/config-helpers@0.4.2': dependencies: - '@eslint/core': 0.16.0 + '@eslint/core': 0.17.0 - '@eslint/core@0.16.0': + '@eslint/core@0.17.0': dependencies: '@types/json-schema': 7.0.15 - '@eslint/eslintrc@3.3.1': + '@eslint/eslintrc@3.3.3': dependencies: ajv: 6.12.6 debug: 4.4.3(supports-color@5.5.0) @@ -4375,19 +4287,19 @@ snapshots: globals: 14.0.0 ignore: 5.3.2 import-fresh: 3.3.1 - js-yaml: 4.1.0 + js-yaml: 4.1.1 minimatch: 3.1.2 strip-json-comments: 3.1.1 transitivePeerDependencies: - supports-color - '@eslint/js@9.37.0': {} + '@eslint/js@9.39.2': {} - '@eslint/object-schema@2.1.6': {} + '@eslint/object-schema@2.1.7': {} - '@eslint/plugin-kit@0.4.0': + '@eslint/plugin-kit@0.4.1': dependencies: - '@eslint/core': 0.16.0 + '@eslint/core': 0.17.0 levn: 0.4.1 '@humanfs/core@0.19.1': {} @@ -4498,19 +4410,12 @@ snapshots: '@img/sharp-win32-x64@0.34.5': optional: true - '@inquirer/external-editor@1.0.2(@types/node@20.19.21)': + '@inquirer/external-editor@1.0.3(@types/node@25.0.2)': dependencies: - chardet: 2.1.0 - iconv-lite: 0.7.0 + chardet: 2.1.1 + iconv-lite: 0.7.1 optionalDependencies: - '@types/node': 20.19.21 - - '@inquirer/external-editor@1.0.2(@types/node@24.10.1)': - dependencies: - chardet: 2.1.0 - iconv-lite: 0.7.0 - optionalDependencies: - '@types/node': 24.10.1 + '@types/node': 25.0.2 '@isaacs/balanced-match@4.0.1': {} @@ -4518,6 +4423,16 @@ snapshots: dependencies: '@isaacs/balanced-match': 4.0.1 + '@jridgewell/gen-mapping@0.3.13': + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/remapping@2.3.5': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + '@jridgewell/resolve-uri@3.1.2': {} '@jridgewell/sourcemap-codec@1.5.5': {} @@ -4550,7 +4465,7 @@ snapshots: '@next/env@15.5.9': {} - '@next/eslint-plugin-next@15.5.5': + '@next/eslint-plugin-next@15.5.9': dependencies: fast-glob: 3.3.1 @@ -4584,10 +4499,6 @@ snapshots: dependencies: '@noble/hashes': 1.8.0 - '@noble/curves@1.9.7': - dependencies: - '@noble/hashes': 1.8.0 - '@noble/hashes@1.4.0': {} '@noble/hashes@1.8.0': {} @@ -4604,77 +4515,77 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.19.1 - '@rollup/rollup-android-arm-eabi@4.52.4': + '@rollup/rollup-android-arm-eabi@4.53.4': optional: true - '@rollup/rollup-android-arm64@4.52.4': + '@rollup/rollup-android-arm64@4.53.4': optional: true - '@rollup/rollup-darwin-arm64@4.52.4': + '@rollup/rollup-darwin-arm64@4.53.4': optional: true - '@rollup/rollup-darwin-x64@4.52.4': + '@rollup/rollup-darwin-x64@4.53.4': optional: true - '@rollup/rollup-freebsd-arm64@4.52.4': + '@rollup/rollup-freebsd-arm64@4.53.4': optional: true - '@rollup/rollup-freebsd-x64@4.52.4': + '@rollup/rollup-freebsd-x64@4.53.4': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.52.4': + '@rollup/rollup-linux-arm-gnueabihf@4.53.4': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.52.4': + '@rollup/rollup-linux-arm-musleabihf@4.53.4': optional: true - '@rollup/rollup-linux-arm64-gnu@4.52.4': + '@rollup/rollup-linux-arm64-gnu@4.53.4': optional: true - '@rollup/rollup-linux-arm64-musl@4.52.4': + '@rollup/rollup-linux-arm64-musl@4.53.4': optional: true - '@rollup/rollup-linux-loong64-gnu@4.52.4': + '@rollup/rollup-linux-loong64-gnu@4.53.4': optional: true - '@rollup/rollup-linux-ppc64-gnu@4.52.4': + '@rollup/rollup-linux-ppc64-gnu@4.53.4': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.52.4': + '@rollup/rollup-linux-riscv64-gnu@4.53.4': optional: true - '@rollup/rollup-linux-riscv64-musl@4.52.4': + '@rollup/rollup-linux-riscv64-musl@4.53.4': optional: true - '@rollup/rollup-linux-s390x-gnu@4.52.4': + '@rollup/rollup-linux-s390x-gnu@4.53.4': optional: true - '@rollup/rollup-linux-x64-gnu@4.52.4': + '@rollup/rollup-linux-x64-gnu@4.53.4': optional: true - '@rollup/rollup-linux-x64-musl@4.52.4': + '@rollup/rollup-linux-x64-musl@4.53.4': optional: true - '@rollup/rollup-openharmony-arm64@4.52.4': + '@rollup/rollup-openharmony-arm64@4.53.4': optional: true - '@rollup/rollup-win32-arm64-msvc@4.52.4': + '@rollup/rollup-win32-arm64-msvc@4.53.4': optional: true - '@rollup/rollup-win32-ia32-msvc@4.52.4': + '@rollup/rollup-win32-ia32-msvc@4.53.4': optional: true - '@rollup/rollup-win32-x64-gnu@4.52.4': + '@rollup/rollup-win32-x64-gnu@4.53.4': optional: true - '@rollup/rollup-win32-x64-msvc@4.52.4': + '@rollup/rollup-win32-x64-msvc@4.53.4': optional: true '@scure/base@1.2.6': {} '@scure/bip32@1.7.0': dependencies: - '@noble/curves': 1.9.7 + '@noble/curves': 1.9.1 '@noble/hashes': 1.8.0 '@scure/base': 1.2.6 @@ -4693,7 +4604,7 @@ snapshots: '@tootallnate/quickjs-emscripten@0.23.0': {} - '@tsconfig/node10@1.0.11': {} + '@tsconfig/node10@1.0.12': {} '@tsconfig/node12@1.0.11': {} @@ -4701,17 +4612,17 @@ snapshots: '@tsconfig/node16@1.0.4': {} - '@turbo/gen@1.13.4(@types/node@20.19.21)(typescript@5.8.3)': + '@turbo/gen@1.13.4(@types/node@25.0.2)(typescript@5.9.3)': dependencies: - '@turbo/workspaces': 1.13.4(@types/node@20.19.21) + '@turbo/workspaces': 1.13.4(@types/node@25.0.2) chalk: 2.4.2 commander: 10.0.1 fs-extra: 10.1.0 - inquirer: 8.2.7(@types/node@20.19.21) + inquirer: 8.2.7(@types/node@25.0.2) minimatch: 9.0.5 node-plop: 0.26.3 proxy-agent: 6.5.0 - ts-node: 10.9.2(@types/node@20.19.21)(typescript@5.8.3) + ts-node: 10.9.2(@types/node@25.0.2)(typescript@5.9.3) update-check: 1.5.4 validate-npm-package-name: 5.0.1 transitivePeerDependencies: @@ -4721,7 +4632,7 @@ snapshots: - supports-color - typescript - '@turbo/workspaces@1.13.4(@types/node@20.19.21)': + '@turbo/workspaces@1.13.4(@types/node@25.0.2)': dependencies: chalk: 2.4.2 commander: 10.0.1 @@ -4729,8 +4640,8 @@ snapshots: fast-glob: 3.3.3 fs-extra: 10.1.0 gradient-string: 2.0.2 - inquirer: 8.2.7(@types/node@20.19.21) - js-yaml: 4.1.0 + inquirer: 8.2.7(@types/node@25.0.2) + js-yaml: 4.1.1 ora: 4.1.1 rimraf: 3.0.2 semver: 7.7.3 @@ -4738,9 +4649,10 @@ snapshots: transitivePeerDependencies: - '@types/node' - '@types/chai@5.2.2': + '@types/chai@5.2.3': dependencies: '@types/deep-eql': 4.0.2 + assertion-error: 2.0.1 '@types/deep-eql@4.0.2': {} @@ -4749,7 +4661,7 @@ snapshots: '@types/glob@7.2.0': dependencies: '@types/minimatch': 6.0.0 - '@types/node': 24.10.1 + '@types/node': 25.0.2 '@types/inquirer@6.5.0': dependencies: @@ -4760,29 +4672,29 @@ snapshots: '@types/minimatch@6.0.0': dependencies: - minimatch: 10.1.1 + minimatch: 9.0.5 '@types/node@12.20.55': {} - '@types/node@20.19.21': + '@types/node@20.19.27': dependencies: undici-types: 6.21.0 - '@types/node@24.10.1': + '@types/node@25.0.2': dependencies: undici-types: 7.16.0 - '@types/react-dom@19.2.3(@types/react@19.2.6)': + '@types/react-dom@19.2.3(@types/react@19.2.7)': dependencies: - '@types/react': 19.2.6 + '@types/react': 19.2.7 - '@types/react@19.2.6': + '@types/react@19.2.7': dependencies: csstype: 3.2.3 '@types/through@0.0.33': dependencies: - '@types/node': 24.10.1 + '@types/node': 25.0.2 '@types/tinycolor2@1.4.6': {} @@ -4794,103 +4706,101 @@ snapshots: dependencies: '@types/yargs-parser': 21.0.3 - '@typescript-eslint/eslint-plugin@8.46.1(@typescript-eslint/parser@8.46.1(eslint@9.37.0)(typescript@5.8.3))(eslint@9.37.0)(typescript@5.8.3)': + '@typescript-eslint/eslint-plugin@8.50.0(@typescript-eslint/parser@8.50.0(eslint@9.39.2)(typescript@5.9.3))(eslint@9.39.2)(typescript@5.9.3)': dependencies: - '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 8.46.1(eslint@9.37.0)(typescript@5.8.3) - '@typescript-eslint/scope-manager': 8.46.1 - '@typescript-eslint/type-utils': 8.46.1(eslint@9.37.0)(typescript@5.8.3) - '@typescript-eslint/utils': 8.46.1(eslint@9.37.0)(typescript@5.8.3) - '@typescript-eslint/visitor-keys': 8.46.1 - eslint: 9.37.0 - graphemer: 1.4.0 + '@eslint-community/regexpp': 4.12.2 + '@typescript-eslint/parser': 8.50.0(eslint@9.39.2)(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.50.0 + '@typescript-eslint/type-utils': 8.50.0(eslint@9.39.2)(typescript@5.9.3) + '@typescript-eslint/utils': 8.50.0(eslint@9.39.2)(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.50.0 + eslint: 9.39.2 ignore: 7.0.5 natural-compare: 1.4.0 - ts-api-utils: 2.1.0(typescript@5.8.3) - typescript: 5.8.3 + ts-api-utils: 2.1.0(typescript@5.9.3) + typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.46.1(eslint@9.37.0)(typescript@5.8.3)': + '@typescript-eslint/parser@8.50.0(eslint@9.39.2)(typescript@5.9.3)': dependencies: - '@typescript-eslint/scope-manager': 8.46.1 - '@typescript-eslint/types': 8.46.1 - '@typescript-eslint/typescript-estree': 8.46.1(typescript@5.8.3) - '@typescript-eslint/visitor-keys': 8.46.1 + '@typescript-eslint/scope-manager': 8.50.0 + '@typescript-eslint/types': 8.50.0 + '@typescript-eslint/typescript-estree': 8.50.0(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.50.0 debug: 4.4.3(supports-color@5.5.0) - eslint: 9.37.0 - typescript: 5.8.3 + eslint: 9.39.2 + typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.46.1(typescript@5.8.3)': + '@typescript-eslint/project-service@8.50.0(typescript@5.9.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.46.1(typescript@5.8.3) - '@typescript-eslint/types': 8.46.1 + '@typescript-eslint/tsconfig-utils': 8.50.0(typescript@5.9.3) + '@typescript-eslint/types': 8.50.0 debug: 4.4.3(supports-color@5.5.0) - typescript: 5.8.3 + typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@8.46.1': + '@typescript-eslint/scope-manager@8.50.0': dependencies: - '@typescript-eslint/types': 8.46.1 - '@typescript-eslint/visitor-keys': 8.46.1 + '@typescript-eslint/types': 8.50.0 + '@typescript-eslint/visitor-keys': 8.50.0 - '@typescript-eslint/tsconfig-utils@8.46.1(typescript@5.8.3)': + '@typescript-eslint/tsconfig-utils@8.50.0(typescript@5.9.3)': dependencies: - typescript: 5.8.3 + typescript: 5.9.3 - '@typescript-eslint/type-utils@8.46.1(eslint@9.37.0)(typescript@5.8.3)': + '@typescript-eslint/type-utils@8.50.0(eslint@9.39.2)(typescript@5.9.3)': dependencies: - '@typescript-eslint/types': 8.46.1 - '@typescript-eslint/typescript-estree': 8.46.1(typescript@5.8.3) - '@typescript-eslint/utils': 8.46.1(eslint@9.37.0)(typescript@5.8.3) + '@typescript-eslint/types': 8.50.0 + '@typescript-eslint/typescript-estree': 8.50.0(typescript@5.9.3) + '@typescript-eslint/utils': 8.50.0(eslint@9.39.2)(typescript@5.9.3) debug: 4.4.3(supports-color@5.5.0) - eslint: 9.37.0 - ts-api-utils: 2.1.0(typescript@5.8.3) - typescript: 5.8.3 + eslint: 9.39.2 + ts-api-utils: 2.1.0(typescript@5.9.3) + typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/types@8.46.1': {} + '@typescript-eslint/types@8.50.0': {} - '@typescript-eslint/typescript-estree@8.46.1(typescript@5.8.3)': + '@typescript-eslint/typescript-estree@8.50.0(typescript@5.9.3)': dependencies: - '@typescript-eslint/project-service': 8.46.1(typescript@5.8.3) - '@typescript-eslint/tsconfig-utils': 8.46.1(typescript@5.8.3) - '@typescript-eslint/types': 8.46.1 - '@typescript-eslint/visitor-keys': 8.46.1 + '@typescript-eslint/project-service': 8.50.0(typescript@5.9.3) + '@typescript-eslint/tsconfig-utils': 8.50.0(typescript@5.9.3) + '@typescript-eslint/types': 8.50.0 + '@typescript-eslint/visitor-keys': 8.50.0 debug: 4.4.3(supports-color@5.5.0) - fast-glob: 3.3.3 - is-glob: 4.0.3 minimatch: 9.0.5 semver: 7.7.3 - ts-api-utils: 2.1.0(typescript@5.8.3) - typescript: 5.8.3 + tinyglobby: 0.2.15 + ts-api-utils: 2.1.0(typescript@5.9.3) + typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.46.1(eslint@9.37.0)(typescript@5.8.3)': + '@typescript-eslint/utils@8.50.0(eslint@9.39.2)(typescript@5.9.3)': dependencies: - '@eslint-community/eslint-utils': 4.9.0(eslint@9.37.0) - '@typescript-eslint/scope-manager': 8.46.1 - '@typescript-eslint/types': 8.46.1 - '@typescript-eslint/typescript-estree': 8.46.1(typescript@5.8.3) - eslint: 9.37.0 - typescript: 5.8.3 + '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.2) + '@typescript-eslint/scope-manager': 8.50.0 + '@typescript-eslint/types': 8.50.0 + '@typescript-eslint/typescript-estree': 8.50.0(typescript@5.9.3) + eslint: 9.39.2 + typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/visitor-keys@8.46.1': + '@typescript-eslint/visitor-keys@8.50.0': dependencies: - '@typescript-eslint/types': 8.46.1 + '@typescript-eslint/types': 8.50.0 eslint-visitor-keys: 4.2.1 - '@vitest/coverage-v8@4.0.14(vitest@4.0.14(@types/node@24.10.1)(happy-dom@20.0.10))': + '@vitest/coverage-v8@4.0.15(vitest@4.0.15(@types/node@25.0.2)(happy-dom@20.0.11))': dependencies: '@bcoe/v8-coverage': 1.0.2 - '@vitest/utils': 4.0.14 + '@vitest/utils': 4.0.15 ast-v8-to-istanbul: 0.3.8 istanbul-lib-coverage: 3.2.2 istanbul-lib-report: 3.0.1 @@ -4900,56 +4810,58 @@ snapshots: obug: 2.1.1 std-env: 3.10.0 tinyrainbow: 3.0.3 - vitest: 4.0.14(@types/node@24.10.1)(happy-dom@20.0.10) + vitest: 4.0.15(@types/node@25.0.2)(happy-dom@20.0.11) transitivePeerDependencies: - supports-color - '@vitest/expect@4.0.14': + '@vitest/expect@4.0.15': dependencies: '@standard-schema/spec': 1.0.0 - '@types/chai': 5.2.2 - '@vitest/spy': 4.0.14 - '@vitest/utils': 4.0.14 + '@types/chai': 5.2.3 + '@vitest/spy': 4.0.15 + '@vitest/utils': 4.0.15 chai: 6.2.1 tinyrainbow: 3.0.3 - '@vitest/mocker@4.0.14(vite@7.1.10(@types/node@24.10.1))': + '@vitest/mocker@4.0.15(vite@7.3.0(@types/node@25.0.2))': dependencies: - '@vitest/spy': 4.0.14 + '@vitest/spy': 4.0.15 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 7.1.10(@types/node@24.10.1) + vite: 7.3.0(@types/node@25.0.2) - '@vitest/pretty-format@4.0.14': + '@vitest/pretty-format@4.0.15': dependencies: tinyrainbow: 3.0.3 - '@vitest/runner@4.0.14': + '@vitest/runner@4.0.15': dependencies: - '@vitest/utils': 4.0.14 + '@vitest/utils': 4.0.15 pathe: 2.0.3 - '@vitest/snapshot@4.0.14': + '@vitest/snapshot@4.0.15': dependencies: - '@vitest/pretty-format': 4.0.14 + '@vitest/pretty-format': 4.0.15 magic-string: 0.30.21 pathe: 2.0.3 - '@vitest/spy@4.0.14': {} + '@vitest/spy@4.0.15': {} - '@vitest/utils@4.0.14': + '@vitest/utils@4.0.15': dependencies: - '@vitest/pretty-format': 4.0.14 + '@vitest/pretty-format': 4.0.15 tinyrainbow: 3.0.3 - abitype@1.1.0(typescript@5.9.3): + abitype@1.1.0(typescript@5.9.3)(zod@4.2.0): optionalDependencies: typescript: 5.9.3 + zod: 4.2.0 - abitype@1.1.1(typescript@5.9.3): + abitype@1.2.2(typescript@5.9.3)(zod@4.2.0): optionalDependencies: typescript: 5.9.3 + zod: 4.2.0 acorn-jsx@5.3.2(acorn@8.15.0): dependencies: @@ -5018,7 +4930,7 @@ snapshots: call-bind: 1.0.8 call-bound: 1.0.4 define-properties: 1.2.1 - es-abstract: 1.24.0 + es-abstract: 1.24.1 es-object-atoms: 1.1.1 get-intrinsic: 1.3.0 is-string: 1.1.1 @@ -5030,7 +4942,7 @@ snapshots: dependencies: call-bind: 1.0.8 define-properties: 1.2.1 - es-abstract: 1.24.0 + es-abstract: 1.24.1 es-errors: 1.3.0 es-object-atoms: 1.1.1 es-shim-unscopables: 1.1.0 @@ -5039,21 +4951,21 @@ snapshots: dependencies: call-bind: 1.0.8 define-properties: 1.2.1 - es-abstract: 1.24.0 + es-abstract: 1.24.1 es-shim-unscopables: 1.1.0 array.prototype.flatmap@1.3.3: dependencies: call-bind: 1.0.8 define-properties: 1.2.1 - es-abstract: 1.24.0 + es-abstract: 1.24.1 es-shim-unscopables: 1.1.0 array.prototype.tosorted@1.1.4: dependencies: call-bind: 1.0.8 define-properties: 1.2.1 - es-abstract: 1.24.0 + es-abstract: 1.24.1 es-errors: 1.3.0 es-shim-unscopables: 1.1.0 @@ -5062,17 +4974,19 @@ snapshots: array-buffer-byte-length: 1.0.2 call-bind: 1.0.8 define-properties: 1.2.1 - es-abstract: 1.24.0 + es-abstract: 1.24.1 es-errors: 1.3.0 get-intrinsic: 1.3.0 is-array-buffer: 3.0.5 - asn1js@3.0.6: + asn1js@3.0.7: dependencies: pvtsutils: 1.3.6 - pvutils: 1.1.3 + pvutils: 1.1.5 tslib: 2.8.1 + assertion-error@2.0.1: {} + ast-types@0.13.4: dependencies: tslib: 2.8.1 @@ -5093,6 +5007,8 @@ snapshots: base64-js@1.5.1: {} + baseline-browser-mapping@2.9.7: {} + basic-ftp@5.0.5: {} better-path-resolve@1.0.0: @@ -5120,6 +5036,14 @@ snapshots: dependencies: fill-range: 7.1.1 + browserslist@4.28.1: + dependencies: + baseline-browser-mapping: 2.9.7 + caniuse-lite: 1.0.30001760 + electron-to-chromium: 1.5.267 + node-releases: 2.0.27 + update-browserslist-db: 1.2.2(browserslist@4.28.1) + buffer@5.7.1: dependencies: base64-js: 1.5.1 @@ -5202,7 +5126,7 @@ snapshots: chardet@0.7.0: {} - chardet@2.1.0: {} + chardet@2.1.1: {} chokidar@3.6.0: dependencies: @@ -5280,13 +5204,15 @@ snapshots: snake-case: 2.1.0 upper-case: 1.1.3 - core-js-pure@3.46.0: {} + convert-source-map@2.0.0: {} + + core-js-pure@3.47.0: {} cosmiconfig@9.0.0(typescript@5.9.3): dependencies: env-paths: 2.2.1 import-fresh: 3.3.1 - js-yaml: 4.1.0 + js-yaml: 4.1.1 parse-json: 5.2.0 optionalDependencies: typescript: 5.9.3 @@ -5393,11 +5319,13 @@ snapshots: es-errors: 1.3.0 gopd: 1.2.0 - effect@3.19.6: + effect@3.19.12: dependencies: '@standard-schema/spec': 1.0.0 fast-check: 3.23.2 + electron-to-chromium@1.5.267: {} + emoji-regex@10.6.0: {} emoji-regex@8.0.0: {} @@ -5413,7 +5341,7 @@ snapshots: dependencies: is-arrayish: 0.2.1 - es-abstract@1.24.0: + es-abstract@1.24.1: dependencies: array-buffer-byte-length: 1.0.2 arraybuffer.prototype.slice: 1.0.4 @@ -5474,12 +5402,12 @@ snapshots: es-errors@1.3.0: {} - es-iterator-helpers@1.2.1: + es-iterator-helpers@1.2.2: dependencies: call-bind: 1.0.8 call-bound: 1.0.4 define-properties: 1.2.1 - es-abstract: 1.24.0 + es-abstract: 1.24.1 es-errors: 1.3.0 es-set-tostringtag: 2.1.0 function-bind: 1.1.2 @@ -5516,63 +5444,34 @@ snapshots: is-date-object: 1.1.0 is-symbol: 1.1.1 - esbuild@0.25.11: - optionalDependencies: - '@esbuild/aix-ppc64': 0.25.11 - '@esbuild/android-arm': 0.25.11 - '@esbuild/android-arm64': 0.25.11 - '@esbuild/android-x64': 0.25.11 - '@esbuild/darwin-arm64': 0.25.11 - '@esbuild/darwin-x64': 0.25.11 - '@esbuild/freebsd-arm64': 0.25.11 - '@esbuild/freebsd-x64': 0.25.11 - '@esbuild/linux-arm': 0.25.11 - '@esbuild/linux-arm64': 0.25.11 - '@esbuild/linux-ia32': 0.25.11 - '@esbuild/linux-loong64': 0.25.11 - '@esbuild/linux-mips64el': 0.25.11 - '@esbuild/linux-ppc64': 0.25.11 - '@esbuild/linux-riscv64': 0.25.11 - '@esbuild/linux-s390x': 0.25.11 - '@esbuild/linux-x64': 0.25.11 - '@esbuild/netbsd-arm64': 0.25.11 - '@esbuild/netbsd-x64': 0.25.11 - '@esbuild/openbsd-arm64': 0.25.11 - '@esbuild/openbsd-x64': 0.25.11 - '@esbuild/openharmony-arm64': 0.25.11 - '@esbuild/sunos-x64': 0.25.11 - '@esbuild/win32-arm64': 0.25.11 - '@esbuild/win32-ia32': 0.25.11 - '@esbuild/win32-x64': 0.25.11 - - esbuild@0.27.0: + esbuild@0.27.1: optionalDependencies: - '@esbuild/aix-ppc64': 0.27.0 - '@esbuild/android-arm': 0.27.0 - '@esbuild/android-arm64': 0.27.0 - '@esbuild/android-x64': 0.27.0 - '@esbuild/darwin-arm64': 0.27.0 - '@esbuild/darwin-x64': 0.27.0 - '@esbuild/freebsd-arm64': 0.27.0 - '@esbuild/freebsd-x64': 0.27.0 - '@esbuild/linux-arm': 0.27.0 - '@esbuild/linux-arm64': 0.27.0 - '@esbuild/linux-ia32': 0.27.0 - '@esbuild/linux-loong64': 0.27.0 - '@esbuild/linux-mips64el': 0.27.0 - '@esbuild/linux-ppc64': 0.27.0 - '@esbuild/linux-riscv64': 0.27.0 - '@esbuild/linux-s390x': 0.27.0 - '@esbuild/linux-x64': 0.27.0 - '@esbuild/netbsd-arm64': 0.27.0 - '@esbuild/netbsd-x64': 0.27.0 - '@esbuild/openbsd-arm64': 0.27.0 - '@esbuild/openbsd-x64': 0.27.0 - '@esbuild/openharmony-arm64': 0.27.0 - '@esbuild/sunos-x64': 0.27.0 - '@esbuild/win32-arm64': 0.27.0 - '@esbuild/win32-ia32': 0.27.0 - '@esbuild/win32-x64': 0.27.0 + '@esbuild/aix-ppc64': 0.27.1 + '@esbuild/android-arm': 0.27.1 + '@esbuild/android-arm64': 0.27.1 + '@esbuild/android-x64': 0.27.1 + '@esbuild/darwin-arm64': 0.27.1 + '@esbuild/darwin-x64': 0.27.1 + '@esbuild/freebsd-arm64': 0.27.1 + '@esbuild/freebsd-x64': 0.27.1 + '@esbuild/linux-arm': 0.27.1 + '@esbuild/linux-arm64': 0.27.1 + '@esbuild/linux-ia32': 0.27.1 + '@esbuild/linux-loong64': 0.27.1 + '@esbuild/linux-mips64el': 0.27.1 + '@esbuild/linux-ppc64': 0.27.1 + '@esbuild/linux-riscv64': 0.27.1 + '@esbuild/linux-s390x': 0.27.1 + '@esbuild/linux-x64': 0.27.1 + '@esbuild/netbsd-arm64': 0.27.1 + '@esbuild/netbsd-x64': 0.27.1 + '@esbuild/openbsd-arm64': 0.27.1 + '@esbuild/openbsd-x64': 0.27.1 + '@esbuild/openharmony-arm64': 0.27.1 + '@esbuild/sunos-x64': 0.27.1 + '@esbuild/win32-arm64': 0.27.1 + '@esbuild/win32-ia32': 0.27.1 + '@esbuild/win32-x64': 0.27.1 escalade@3.2.0: {} @@ -5588,25 +5487,32 @@ snapshots: optionalDependencies: source-map: 0.6.1 - eslint-config-prettier@9.1.2(eslint@9.37.0): + eslint-config-prettier@10.1.8(eslint@9.39.2): dependencies: - eslint: 9.37.0 + eslint: 9.39.2 eslint-plugin-only-warn@1.1.0: {} - eslint-plugin-react-hooks@5.2.0(eslint@9.37.0): + eslint-plugin-react-hooks@7.0.1(eslint@9.39.2): dependencies: - eslint: 9.37.0 + '@babel/core': 7.28.5 + '@babel/parser': 7.28.5 + eslint: 9.39.2 + hermes-parser: 0.25.1 + zod: 4.2.0 + zod-validation-error: 4.0.2(zod@4.2.0) + transitivePeerDependencies: + - supports-color - eslint-plugin-react@7.37.5(eslint@9.37.0): + eslint-plugin-react@7.37.5(eslint@9.39.2): dependencies: array-includes: 3.1.9 array.prototype.findlast: 1.2.5 array.prototype.flatmap: 1.3.3 array.prototype.tosorted: 1.1.4 doctrine: 2.1.0 - es-iterator-helpers: 1.2.1 - eslint: 9.37.0 + es-iterator-helpers: 1.2.2 + eslint: 9.39.2 estraverse: 5.3.0 hasown: 2.0.2 jsx-ast-utils: 3.3.5 @@ -5620,10 +5526,10 @@ snapshots: string.prototype.matchall: 4.0.12 string.prototype.repeat: 1.0.0 - eslint-plugin-turbo@2.5.8(eslint@9.37.0)(turbo@2.6.3): + eslint-plugin-turbo@2.6.3(eslint@9.39.2)(turbo@2.6.3): dependencies: dotenv: 16.0.3 - eslint: 9.37.0 + eslint: 9.39.2 turbo: 2.6.3 eslint-scope@8.4.0: @@ -5635,21 +5541,20 @@ snapshots: eslint-visitor-keys@4.2.1: {} - eslint@9.37.0: + eslint@9.39.2: dependencies: - '@eslint-community/eslint-utils': 4.9.0(eslint@9.37.0) - '@eslint-community/regexpp': 4.12.1 - '@eslint/config-array': 0.21.0 - '@eslint/config-helpers': 0.4.0 - '@eslint/core': 0.16.0 - '@eslint/eslintrc': 3.3.1 - '@eslint/js': 9.37.0 - '@eslint/plugin-kit': 0.4.0 + '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.2) + '@eslint-community/regexpp': 4.12.2 + '@eslint/config-array': 0.21.1 + '@eslint/config-helpers': 0.4.2 + '@eslint/core': 0.17.0 + '@eslint/eslintrc': 3.3.3 + '@eslint/js': 9.39.2 + '@eslint/plugin-kit': 0.4.1 '@humanfs/node': 0.16.7 '@humanwhocodes/module-importer': 1.0.1 '@humanwhocodes/retry': 0.4.3 '@types/estree': 1.0.8 - '@types/json-schema': 7.0.15 ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.6 @@ -5713,7 +5618,7 @@ snapshots: signal-exit: 3.0.7 strip-final-newline: 2.0.0 - expect-type@1.2.2: {} + expect-type@1.3.0: {} extendable-error@0.1.7: {} @@ -5830,6 +5735,8 @@ snapshots: generator-function@2.0.1: {} + gensync@1.0.0-beta.2: {} + get-caller-file@2.0.5: {} get-east-asian-width@1.4.0: {} @@ -5880,7 +5787,7 @@ snapshots: dependencies: minimatch: 10.1.1 minipass: 7.1.2 - path-scurry: 2.0.0 + path-scurry: 2.0.1 glob@7.2.3: dependencies: @@ -5893,7 +5800,7 @@ snapshots: globals@14.0.0: {} - globals@15.15.0: {} + globals@16.5.0: {} globalthis@1.0.4: dependencies: @@ -5938,8 +5845,6 @@ snapshots: chalk: 4.1.2 tinygradient: 1.1.5 - graphemer@1.4.0: {} - handlebars@4.7.8: dependencies: minimist: 1.2.8 @@ -5949,9 +5854,9 @@ snapshots: optionalDependencies: uglify-js: 3.19.3 - happy-dom@20.0.10: + happy-dom@20.0.11: dependencies: - '@types/node': 20.19.21 + '@types/node': 20.19.27 '@types/whatwg-mimetype': 3.0.2 whatwg-mimetype: 3.0.0 @@ -5984,6 +5889,12 @@ snapshots: no-case: 2.3.2 upper-case: 1.1.3 + hermes-estree@0.25.1: {} + + hermes-parser@0.25.1: + dependencies: + hermes-estree: 0.25.1 + hosted-git-info@8.1.0: dependencies: lru-cache: 10.4.3 @@ -6004,7 +5915,7 @@ snapshots: transitivePeerDependencies: - supports-color - human-id@4.1.2: {} + human-id@4.1.3: {} human-signals@2.1.0: {} @@ -6012,7 +5923,7 @@ snapshots: dependencies: safer-buffer: 2.1.2 - iconv-lite@0.7.0: + iconv-lite@0.7.1: dependencies: safer-buffer: 2.1.2 @@ -6060,9 +5971,9 @@ snapshots: strip-ansi: 6.0.1 through: 2.3.8 - inquirer@8.2.7(@types/node@20.19.21): + inquirer@8.2.7(@types/node@25.0.2): dependencies: - '@inquirer/external-editor': 1.0.2(@types/node@20.19.21) + '@inquirer/external-editor': 1.0.3(@types/node@25.0.2) ansi-escapes: 4.3.2 chalk: 4.1.2 cli-cursor: 3.1.0 @@ -6086,7 +5997,7 @@ snapshots: hasown: 2.0.2 side-channel: 1.1.0 - ip-address@10.0.1: {} + ip-address@10.1.0: {} is-array-buffer@3.0.5: dependencies: @@ -6278,15 +6189,17 @@ snapshots: js-tokens@9.0.1: {} - js-yaml@3.14.1: + js-yaml@3.14.2: dependencies: argparse: 1.0.10 esprima: 4.0.1 - js-yaml@4.1.0: + js-yaml@4.1.1: dependencies: argparse: 2.0.1 + jsesc@3.1.0: {} + json-buffer@3.0.1: {} json-canonicalize@2.0.0: {} @@ -6297,6 +6210,8 @@ snapshots: json-stable-stringify-without-jsonify@1.0.1: {} + json5@2.2.3: {} + jsonc-parser@3.3.1: {} jsonfile@4.0.0: @@ -6324,48 +6239,48 @@ snapshots: kleur@3.0.3: {} - lefthook-darwin-arm64@2.0.4: + lefthook-darwin-arm64@2.0.12: optional: true - lefthook-darwin-x64@2.0.4: + lefthook-darwin-x64@2.0.12: optional: true - lefthook-freebsd-arm64@2.0.4: + lefthook-freebsd-arm64@2.0.12: optional: true - lefthook-freebsd-x64@2.0.4: + lefthook-freebsd-x64@2.0.12: optional: true - lefthook-linux-arm64@2.0.4: + lefthook-linux-arm64@2.0.12: optional: true - lefthook-linux-x64@2.0.4: + lefthook-linux-x64@2.0.12: optional: true - lefthook-openbsd-arm64@2.0.4: + lefthook-openbsd-arm64@2.0.12: optional: true - lefthook-openbsd-x64@2.0.4: + lefthook-openbsd-x64@2.0.12: optional: true - lefthook-windows-arm64@2.0.4: + lefthook-windows-arm64@2.0.12: optional: true - lefthook-windows-x64@2.0.4: + lefthook-windows-x64@2.0.12: optional: true - lefthook@2.0.4: + lefthook@2.0.12: optionalDependencies: - lefthook-darwin-arm64: 2.0.4 - lefthook-darwin-x64: 2.0.4 - lefthook-freebsd-arm64: 2.0.4 - lefthook-freebsd-x64: 2.0.4 - lefthook-linux-arm64: 2.0.4 - lefthook-linux-x64: 2.0.4 - lefthook-openbsd-arm64: 2.0.4 - lefthook-openbsd-x64: 2.0.4 - lefthook-windows-arm64: 2.0.4 - lefthook-windows-x64: 2.0.4 + lefthook-darwin-arm64: 2.0.12 + lefthook-darwin-x64: 2.0.12 + lefthook-freebsd-arm64: 2.0.12 + lefthook-freebsd-x64: 2.0.12 + lefthook-linux-arm64: 2.0.12 + lefthook-linux-x64: 2.0.12 + lefthook-openbsd-arm64: 2.0.12 + lefthook-openbsd-x64: 2.0.12 + lefthook-windows-arm64: 2.0.12 + lefthook-windows-x64: 2.0.12 levn@0.4.1: dependencies: @@ -6416,7 +6331,11 @@ snapshots: lru-cache@10.4.3: {} - lru-cache@11.2.2: {} + lru-cache@11.2.4: {} + + lru-cache@5.1.1: + dependencies: + yallist: 3.1.1 lru-cache@7.18.3: {} @@ -6489,15 +6408,15 @@ snapshots: netmask@2.0.2: {} - next@15.5.9(react-dom@19.2.0(react@19.2.0))(react@19.2.0): + next@15.5.9(react-dom@19.2.3(react@19.2.3))(react@19.2.3): dependencies: '@next/env': 15.5.9 '@swc/helpers': 0.5.15 caniuse-lite: 1.0.30001760 postcss: 8.4.31 - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - styled-jsx: 5.1.6(react@19.2.0) + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + styled-jsx: 5.1.6(react@19.2.3) optionalDependencies: '@next/swc-darwin-arm64': 15.5.7 '@next/swc-darwin-x64': 15.5.7 @@ -6528,7 +6447,9 @@ snapshots: isbinaryfile: 4.0.10 lodash.get: 4.4.2 mkdirp: 0.5.6 - resolve: 1.22.10 + resolve: 1.22.11 + + node-releases@2.0.27: {} nodemon@3.1.11: dependencies: @@ -6582,7 +6503,7 @@ snapshots: dependencies: call-bind: 1.0.8 define-properties: 1.2.1 - es-abstract: 1.24.0 + es-abstract: 1.24.1 es-object-atoms: 1.1.1 object.values@1.2.1: @@ -6660,7 +6581,7 @@ snapshots: object-keys: 1.1.1 safe-push-apply: 1.0.0 - ox@0.9.17(typescript@5.9.3): + ox@0.9.17(typescript@5.9.3)(zod@4.2.0): dependencies: '@adraffy/ens-normalize': 1.11.1 '@noble/ciphers': 1.3.0 @@ -6668,7 +6589,7 @@ snapshots: '@noble/hashes': 1.8.0 '@scure/bip32': 1.7.0 '@scure/bip39': 1.6.0 - abitype: 1.1.1(typescript@5.9.3) + abitype: 1.2.2(typescript@5.9.3)(zod@4.2.0) eventemitter3: 5.0.1 optionalDependencies: typescript: 5.9.3 @@ -6759,9 +6680,9 @@ snapshots: path-parse@1.0.7: {} - path-scurry@2.0.0: + path-scurry@2.0.1: dependencies: - lru-cache: 11.2.2 + lru-cache: 11.2.4 minipass: 7.1.2 path-type@4.0.0: {} @@ -6778,13 +6699,13 @@ snapshots: pify@4.0.1: {} - pkijs@3.3.0: + pkijs@3.3.3: dependencies: '@noble/hashes': 1.4.0 - asn1js: 3.0.6 + asn1js: 3.0.7 bytestreamjs: 2.0.1 pvtsutils: 1.3.6 - pvutils: 1.1.3 + pvutils: 1.1.5 tslib: 2.8.1 possible-typed-array-names@1.1.0: {} @@ -6805,7 +6726,7 @@ snapshots: prettier@2.8.8: {} - prettier@3.6.2: {} + prettier@3.7.4: {} proc-log@5.0.0: {} @@ -6845,7 +6766,7 @@ snapshots: dependencies: tslib: 2.8.1 - pvutils@1.1.3: {} + pvutils@1.1.5: {} quansync@0.2.11: {} @@ -6858,25 +6779,25 @@ snapshots: minimist: 1.2.8 strip-json-comments: 2.0.1 - react-dom@19.2.0(react@19.2.0): + react-dom@19.2.3(react@19.2.3): dependencies: - react: 19.2.0 + react: 19.2.3 scheduler: 0.27.0 react-is@16.13.1: {} - react@19.2.0: {} + react@19.2.3: {} read-yaml-file@1.1.0: dependencies: graceful-fs: 4.2.11 - js-yaml: 3.14.1 + js-yaml: 3.14.2 pify: 4.0.1 strip-bom: 3.0.0 read-yaml-file@2.1.0: dependencies: - js-yaml: 4.1.0 + js-yaml: 4.1.1 strip-bom: 4.0.0 readable-stream@3.6.2: @@ -6893,7 +6814,7 @@ snapshots: dependencies: call-bind: 1.0.8 define-properties: 1.2.1 - es-abstract: 1.24.0 + es-abstract: 1.24.1 es-errors: 1.3.0 es-object-atoms: 1.1.1 get-intrinsic: 1.3.0 @@ -6924,7 +6845,7 @@ snapshots: resolve-from@5.0.0: {} - resolve@1.22.10: + resolve@1.22.11: dependencies: is-core-module: 2.16.1 path-parse: 1.0.7 @@ -6957,32 +6878,32 @@ snapshots: glob: 13.0.0 package-json-from-dist: 1.0.1 - rollup@4.52.4: + rollup@4.53.4: dependencies: '@types/estree': 1.0.8 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.52.4 - '@rollup/rollup-android-arm64': 4.52.4 - '@rollup/rollup-darwin-arm64': 4.52.4 - '@rollup/rollup-darwin-x64': 4.52.4 - '@rollup/rollup-freebsd-arm64': 4.52.4 - '@rollup/rollup-freebsd-x64': 4.52.4 - '@rollup/rollup-linux-arm-gnueabihf': 4.52.4 - '@rollup/rollup-linux-arm-musleabihf': 4.52.4 - '@rollup/rollup-linux-arm64-gnu': 4.52.4 - '@rollup/rollup-linux-arm64-musl': 4.52.4 - '@rollup/rollup-linux-loong64-gnu': 4.52.4 - '@rollup/rollup-linux-ppc64-gnu': 4.52.4 - '@rollup/rollup-linux-riscv64-gnu': 4.52.4 - '@rollup/rollup-linux-riscv64-musl': 4.52.4 - '@rollup/rollup-linux-s390x-gnu': 4.52.4 - '@rollup/rollup-linux-x64-gnu': 4.52.4 - '@rollup/rollup-linux-x64-musl': 4.52.4 - '@rollup/rollup-openharmony-arm64': 4.52.4 - '@rollup/rollup-win32-arm64-msvc': 4.52.4 - '@rollup/rollup-win32-ia32-msvc': 4.52.4 - '@rollup/rollup-win32-x64-gnu': 4.52.4 - '@rollup/rollup-win32-x64-msvc': 4.52.4 + '@rollup/rollup-android-arm-eabi': 4.53.4 + '@rollup/rollup-android-arm64': 4.53.4 + '@rollup/rollup-darwin-arm64': 4.53.4 + '@rollup/rollup-darwin-x64': 4.53.4 + '@rollup/rollup-freebsd-arm64': 4.53.4 + '@rollup/rollup-freebsd-x64': 4.53.4 + '@rollup/rollup-linux-arm-gnueabihf': 4.53.4 + '@rollup/rollup-linux-arm-musleabihf': 4.53.4 + '@rollup/rollup-linux-arm64-gnu': 4.53.4 + '@rollup/rollup-linux-arm64-musl': 4.53.4 + '@rollup/rollup-linux-loong64-gnu': 4.53.4 + '@rollup/rollup-linux-ppc64-gnu': 4.53.4 + '@rollup/rollup-linux-riscv64-gnu': 4.53.4 + '@rollup/rollup-linux-riscv64-musl': 4.53.4 + '@rollup/rollup-linux-s390x-gnu': 4.53.4 + '@rollup/rollup-linux-x64-gnu': 4.53.4 + '@rollup/rollup-linux-x64-musl': 4.53.4 + '@rollup/rollup-openharmony-arm64': 4.53.4 + '@rollup/rollup-win32-arm64-msvc': 4.53.4 + '@rollup/rollup-win32-ia32-msvc': 4.53.4 + '@rollup/rollup-win32-x64-gnu': 4.53.4 + '@rollup/rollup-win32-x64-msvc': 4.53.4 fsevents: 2.3.3 run-async@2.4.1: {} @@ -7155,7 +7076,7 @@ snapshots: socks@2.8.7: dependencies: - ip-address: 10.0.1 + ip-address: 10.1.0 smart-buffer: 4.2.0 source-map-js@1.2.1: {} @@ -7197,7 +7118,7 @@ snapshots: call-bind: 1.0.8 call-bound: 1.0.4 define-properties: 1.2.1 - es-abstract: 1.24.0 + es-abstract: 1.24.1 es-errors: 1.3.0 es-object-atoms: 1.1.1 get-intrinsic: 1.3.0 @@ -7211,7 +7132,7 @@ snapshots: string.prototype.repeat@1.0.0: dependencies: define-properties: 1.2.1 - es-abstract: 1.24.0 + es-abstract: 1.24.1 string.prototype.trim@1.2.10: dependencies: @@ -7219,7 +7140,7 @@ snapshots: call-bound: 1.0.4 define-data-property: 1.1.4 define-properties: 1.2.1 - es-abstract: 1.24.0 + es-abstract: 1.24.1 es-object-atoms: 1.1.1 has-property-descriptors: 1.0.2 @@ -7258,10 +7179,10 @@ snapshots: strip-json-comments@3.1.1: {} - styled-jsx@5.1.6(react@19.2.0): + styled-jsx@5.1.6(react@19.2.3): dependencies: client-only: 0.0.1 - react: 19.2.0 + react: 19.2.3 supports-color@5.5.0: dependencies: @@ -7288,7 +7209,7 @@ snapshots: chalk-template: 1.1.2 commander: 13.1.0 cosmiconfig: 9.0.0(typescript@5.9.3) - effect: 3.19.6 + effect: 3.19.12 enquirer: 2.4.1 fast-check: 3.23.2 globby: 14.1.0 @@ -7314,7 +7235,7 @@ snapshots: tinycolor2@1.6.0: {} - tinyexec@0.3.2: {} + tinyexec@1.0.2: {} tinyglobby@0.2.15: dependencies: @@ -7345,25 +7266,25 @@ snapshots: tree-kill@1.2.2: {} - ts-api-utils@2.1.0(typescript@5.8.3): + ts-api-utils@2.1.0(typescript@5.9.3): dependencies: - typescript: 5.8.3 + typescript: 5.9.3 - ts-node@10.9.2(@types/node@20.19.21)(typescript@5.8.3): + ts-node@10.9.2(@types/node@25.0.2)(typescript@5.9.3): dependencies: '@cspotcode/source-map-support': 0.8.1 - '@tsconfig/node10': 1.0.11 + '@tsconfig/node10': 1.0.12 '@tsconfig/node12': 1.0.11 '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.4 - '@types/node': 20.19.21 + '@types/node': 25.0.2 acorn: 8.15.0 acorn-walk: 8.3.4 arg: 4.1.3 create-require: 1.1.1 diff: 4.0.2 make-error: 1.3.6 - typescript: 5.8.3 + typescript: 5.9.3 v8-compile-cache-lib: 3.0.1 yn: 3.1.1 @@ -7373,51 +7294,24 @@ snapshots: tslib@2.8.1: {} - turbo-darwin-64@2.6.1: - optional: true - turbo-darwin-64@2.6.3: optional: true - turbo-darwin-arm64@2.6.1: - optional: true - turbo-darwin-arm64@2.6.3: optional: true - turbo-linux-64@2.6.1: - optional: true - turbo-linux-64@2.6.3: optional: true - turbo-linux-arm64@2.6.1: - optional: true - turbo-linux-arm64@2.6.3: optional: true - turbo-windows-64@2.6.1: - optional: true - turbo-windows-64@2.6.3: optional: true - turbo-windows-arm64@2.6.1: - optional: true - turbo-windows-arm64@2.6.3: optional: true - turbo@2.6.1: - optionalDependencies: - turbo-darwin-64: 2.6.1 - turbo-darwin-arm64: 2.6.1 - turbo-linux-64: 2.6.1 - turbo-linux-arm64: 2.6.1 - turbo-windows-64: 2.6.1 - turbo-windows-arm64: 2.6.1 - turbo@2.6.3: optionalDependencies: turbo-darwin-64: 2.6.3 @@ -7466,19 +7360,17 @@ snapshots: possible-typed-array-names: 1.1.0 reflect.getprototypeof: 1.0.10 - typescript-eslint@8.46.1(eslint@9.37.0)(typescript@5.8.3): + typescript-eslint@8.50.0(eslint@9.39.2)(typescript@5.9.3): dependencies: - '@typescript-eslint/eslint-plugin': 8.46.1(@typescript-eslint/parser@8.46.1(eslint@9.37.0)(typescript@5.8.3))(eslint@9.37.0)(typescript@5.8.3) - '@typescript-eslint/parser': 8.46.1(eslint@9.37.0)(typescript@5.8.3) - '@typescript-eslint/typescript-estree': 8.46.1(typescript@5.8.3) - '@typescript-eslint/utils': 8.46.1(eslint@9.37.0)(typescript@5.8.3) - eslint: 9.37.0 - typescript: 5.8.3 + '@typescript-eslint/eslint-plugin': 8.50.0(@typescript-eslint/parser@8.50.0(eslint@9.39.2)(typescript@5.9.3))(eslint@9.39.2)(typescript@5.9.3) + '@typescript-eslint/parser': 8.50.0(eslint@9.39.2)(typescript@5.9.3) + '@typescript-eslint/typescript-estree': 8.50.0(typescript@5.9.3) + '@typescript-eslint/utils': 8.50.0(eslint@9.39.2)(typescript@5.9.3) + eslint: 9.39.2 + typescript: 5.9.3 transitivePeerDependencies: - supports-color - typescript@5.8.3: {} - typescript@5.9.3: {} uglify-js@3.19.3: @@ -7503,6 +7395,12 @@ snapshots: universalify@2.0.1: {} + update-browserslist-db@1.2.2(browserslist@4.28.1): + dependencies: + browserslist: 4.28.1 + escalade: 3.2.0 + picocolors: 1.1.1 + update-check@1.5.4: dependencies: registry-auth-token: 3.3.2 @@ -7528,15 +7426,15 @@ snapshots: validate-npm-package-name@6.0.2: {} - viem@2.40.3(typescript@5.9.3): + viem@2.42.1(typescript@5.9.3)(zod@4.2.0): dependencies: '@noble/curves': 1.9.1 '@noble/hashes': 1.8.0 '@scure/bip32': 1.7.0 '@scure/bip39': 1.6.0 - abitype: 1.1.0(typescript@5.9.3) + abitype: 1.1.0(typescript@5.9.3)(zod@4.2.0) isows: 1.0.7(ws@8.18.3) - ox: 0.9.17(typescript@5.9.3) + ox: 0.9.17(typescript@5.9.3)(zod@4.2.0) ws: 8.18.3 optionalDependencies: typescript: 5.9.3 @@ -7545,43 +7443,43 @@ snapshots: - utf-8-validate - zod - vite@7.1.10(@types/node@24.10.1): + vite@7.3.0(@types/node@25.0.2): dependencies: - esbuild: 0.25.11 + esbuild: 0.27.1 fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 postcss: 8.5.6 - rollup: 4.52.4 + rollup: 4.53.4 tinyglobby: 0.2.15 optionalDependencies: - '@types/node': 24.10.1 + '@types/node': 25.0.2 fsevents: 2.3.3 - vitest@4.0.14(@types/node@24.10.1)(happy-dom@20.0.10): + vitest@4.0.15(@types/node@25.0.2)(happy-dom@20.0.11): dependencies: - '@vitest/expect': 4.0.14 - '@vitest/mocker': 4.0.14(vite@7.1.10(@types/node@24.10.1)) - '@vitest/pretty-format': 4.0.14 - '@vitest/runner': 4.0.14 - '@vitest/snapshot': 4.0.14 - '@vitest/spy': 4.0.14 - '@vitest/utils': 4.0.14 + '@vitest/expect': 4.0.15 + '@vitest/mocker': 4.0.15(vite@7.3.0(@types/node@25.0.2)) + '@vitest/pretty-format': 4.0.15 + '@vitest/runner': 4.0.15 + '@vitest/snapshot': 4.0.15 + '@vitest/spy': 4.0.15 + '@vitest/utils': 4.0.15 es-module-lexer: 1.7.0 - expect-type: 1.2.2 + expect-type: 1.3.0 magic-string: 0.30.21 obug: 2.1.1 pathe: 2.0.3 picomatch: 4.0.3 std-env: 3.10.0 tinybench: 2.9.0 - tinyexec: 0.3.2 + tinyexec: 1.0.2 tinyglobby: 0.2.15 tinyrainbow: 3.0.3 - vite: 7.1.10(@types/node@24.10.1) + vite: 7.3.0(@types/node@25.0.2) why-is-node-running: 2.3.0 optionalDependencies: - '@types/node': 24.10.1 - happy-dom: 20.0.10 + '@types/node': 25.0.2 + happy-dom: 20.0.11 transitivePeerDependencies: - jiti - less @@ -7679,6 +7577,8 @@ snapshots: y18n@5.0.8: {} + yallist@3.1.1: {} + yargs-parser@21.1.1: {} yargs-parser@22.0.0: {} @@ -7705,3 +7605,9 @@ snapshots: yn@3.1.1: {} yocto-queue@0.1.0: {} + + zod-validation-error@4.0.2(zod@4.2.0): + dependencies: + zod: 4.2.0 + + zod@4.2.0: {} diff --git a/repo/eslint-config/package.json b/repo/eslint-config/package.json index 7fa53be38..5625bc699 100644 --- a/repo/eslint-config/package.json +++ b/repo/eslint-config/package.json @@ -9,16 +9,16 @@ "./react-internal": "./react-internal.js" }, "devDependencies": { - "@eslint/js": "^9.28.0", - "@next/eslint-plugin-next": "^15.3.3", - "eslint": "^9.28.0", - "eslint-config-prettier": "^9.1.0", + "@eslint/js": "^9.39.2", + "@next/eslint-plugin-next": "^15.5.9", + "eslint": "^9.39.2", + "eslint-config-prettier": "^10.1.8", "eslint-plugin-only-warn": "^1.1.0", "eslint-plugin-react": "^7.37.5", - "eslint-plugin-react-hooks": "^5.2.0", - "eslint-plugin-turbo": "^2.5.4", - "globals": "^15.15.0", - "typescript": "^5.8.3", - "typescript-eslint": "^8.33.1" + "eslint-plugin-react-hooks": "^7.0.1", + "eslint-plugin-turbo": "^2.6.3", + "globals": "^16.5.0", + "typescript": "^5.9.3", + "typescript-eslint": "^8.49.0" } } diff --git a/repo/ui/package.json b/repo/ui/package.json index 226eed0d9..6b380862e 100644 --- a/repo/ui/package.json +++ b/repo/ui/package.json @@ -13,16 +13,16 @@ "typecheck": "tsc --noEmit" }, "devDependencies": { - "@repo/eslint-config": "workspace:*", - "@repo/typescript-config": "workspace:*", + "@repo/eslint-config": "workspace:^", + "@repo/typescript-config": "workspace:^", "@turbo/gen": "^1.13.4", - "@types/node": "^20.17.57", - "@types/react": "^19.2.6", + "@types/node": "^25.0.2", + "@types/react": "^19.2.7", "@types/react-dom": "^19.2.3", - "typescript": "^5.8.3" + "typescript": "^5.9.3" }, "dependencies": { - "react": "^19.1.0", - "react-dom": "^19.1.0" + "react": "^19.2.3", + "react-dom": "^19.2.3" } } From a7744910e6c182a0023856d14cdd7040fa008a9b Mon Sep 17 00:00:00 2001 From: Agusx1211 Date: Thu, 18 Dec 2025 20:27:26 +0100 Subject: [PATCH 07/39] Short circuit 404s (#949) * skip witness on signers that don't support it * add passkey to test --- packages/wallet/wdk/src/sequence/manager.ts | 42 ++++++++++++++++++- packages/wallet/wdk/src/sequence/signers.ts | 13 ++++++ .../wallet/wdk/test/signers-kindof.test.ts | 40 ++++++++++++++++++ 3 files changed, 94 insertions(+), 1 deletion(-) create mode 100644 packages/wallet/wdk/test/signers-kindof.test.ts diff --git a/packages/wallet/wdk/src/sequence/manager.ts b/packages/wallet/wdk/src/sequence/manager.ts index a55059cbf..ba27116cf 100644 --- a/packages/wallet/wdk/src/sequence/manager.ts +++ b/packages/wallet/wdk/src/sequence/manager.ts @@ -59,6 +59,8 @@ export type ManagerOptions = { guardUrl?: string guardAddresses?: Record + nonWitnessableSigners?: Address.Address[] + // The default guard topology MUST have a placeholder address for the guard address defaultGuardTopology?: Config.Topology defaultRecoverySettings?: RecoverySettings @@ -123,6 +125,8 @@ export const ManagerOptionsDefaults = { }, bundlers: [], + nonWitnessableSigners: [] as Address.Address[], + guardUrl: 'https://guard.sequence.app', guardAddresses: { wallet: '0x26f3D30F41FA897309Ae804A2AFf15CEb1dA5742', @@ -183,11 +187,41 @@ export const CreateWalletOptionsDefaults = { } export function applyManagerOptionsDefaults(options?: ManagerOptions) { - return { + const merged = { ...ManagerOptionsDefaults, ...options, identity: { ...ManagerOptionsDefaults.identity, ...options?.identity }, } + + // Merge and normalize non-witnessable signers. + // We always include the sessions extension address for the active extensions set. + const nonWitnessable = new Set() + for (const address of ManagerOptionsDefaults.nonWitnessableSigners ?? []) { + nonWitnessable.add(address.toLowerCase()) + } + for (const address of options?.nonWitnessableSigners ?? []) { + nonWitnessable.add(address.toLowerCase()) + } + nonWitnessable.add(merged.extensions.sessions.toLowerCase()) + + // Include static signer leaves from the guard topology (e.g. recovery guard signer), + // but ignore the placeholder address that is later replaced per-role. + if (merged.defaultGuardTopology) { + const guardTopologySigners = Config.getSigners(merged.defaultGuardTopology) + for (const signer of guardTopologySigners.signers) { + if (Address.isEqual(signer, Constants.PlaceholderAddress)) { + continue + } + nonWitnessable.add(signer.toLowerCase()) + } + for (const signer of guardTopologySigners.sapientSigners) { + nonWitnessable.add(signer.address.toLowerCase()) + } + } + + merged.nonWitnessableSigners = Array.from(nonWitnessable) as Address.Address[] + + return merged } export type RecoverySettings = { @@ -221,6 +255,8 @@ export type Sequence = { readonly relayers: Relayer.Relayer[] readonly bundlers: Bundler.Bundler[] + readonly nonWitnessableSigners: ReadonlySet + readonly defaultGuardTopology: Config.Topology readonly defaultRecoverySettings: RecoverySettings @@ -408,6 +444,10 @@ export class Manager { relayers, bundlers: ops.bundlers, + nonWitnessableSigners: new Set( + (ops.nonWitnessableSigners ?? []).map((address) => address.toLowerCase() as Address.Address), + ), + defaultGuardTopology: ops.defaultGuardTopology, defaultRecoverySettings: ops.defaultRecoverySettings, diff --git a/packages/wallet/wdk/src/sequence/signers.ts b/packages/wallet/wdk/src/sequence/signers.ts index cf79c43c7..c2002d2d9 100644 --- a/packages/wallet/wdk/src/sequence/signers.ts +++ b/packages/wallet/wdk/src/sequence/signers.ts @@ -48,6 +48,19 @@ export class Signers { return Kinds.Guard } + // Passkeys are a sapient signer module: the address alone identifies the kind. + // Metadata (credential id, public key, etc.) is loaded later by the PasskeysHandler + // via the witness payload, so we can skip the witness probe here. + if (Address.isEqual(this.shared.sequence.extensions.passkeys, address)) { + return Kinds.LoginPasskey + } + + // Some signers are known to never publish a witness record (e.g. module signers). + // Skip probing the Sessions/Witness endpoint for them. + if (this.shared.sequence.nonWitnessableSigners.has(address.toLowerCase() as Address.Address)) { + return undefined + } + // We need to use the state provider (and witness) this will tell us the kind of signer // NOTICE: This looks expensive, but this operation should be cached by the state provider const witness = await (imageHash diff --git a/packages/wallet/wdk/test/signers-kindof.test.ts b/packages/wallet/wdk/test/signers-kindof.test.ts new file mode 100644 index 000000000..4e5f83aad --- /dev/null +++ b/packages/wallet/wdk/test/signers-kindof.test.ts @@ -0,0 +1,40 @@ +import { describe, expect, it, vi } from 'vitest' + +import { Kinds } from '../src/sequence/index.js' +import { newManager } from './constants.js' + +describe('Signers.kindOf', () => { + it('does not probe Sessions/Witness for non-witnessable signers', async () => { + const getWitnessFor = vi.fn().mockResolvedValue(undefined) + const getWitnessForSapient = vi.fn().mockResolvedValue(undefined) + + const manager = newManager({ + stateProvider: { + getWitnessFor, + getWitnessForSapient, + } as any, + }) + + const signers = (manager as any).shared.modules.signers + const extensions = (manager as any).shared.sequence.extensions + + const wallet = '0x1111111111111111111111111111111111111111' + const imageHash = ('0x' + '00'.repeat(32)) as `0x${string}` + + // Sessions extension signer (sapient leaf) never publishes a witness. + await signers.kindOf(wallet, extensions.sessions, imageHash) + + // Passkeys module is a known sapient signer kind. + expect(await signers.kindOf(wallet, extensions.passkeys, imageHash)).toBe(Kinds.LoginPasskey) + + // Sequence dev multisig (default guard topology leaf) never publishes a witness. + await signers.kindOf(wallet, '0x007a47e6BF40C1e0ed5c01aE42fDC75879140bc4') + + expect(getWitnessFor).not.toHaveBeenCalled() + expect(getWitnessForSapient).not.toHaveBeenCalled() + + // Unknown signers still rely on a witness probe. + await signers.kindOf(wallet, '0x2222222222222222222222222222222222222222') + expect(getWitnessFor).toHaveBeenCalledTimes(1) + }) +}) From e7de3b1073fcea54a41e65b00b3cdecdd8e60eb0 Mon Sep 17 00:00:00 2001 From: Taylan Pince Date: Thu, 18 Dec 2025 20:37:52 +0100 Subject: [PATCH 08/39] 3.0.0-beta.6 --- .changeset/cyan-radios-relax.md | 18 ++++++++ .changeset/pre.json | 43 +++++++++++-------- packages/services/api/CHANGELOG.md | 6 +++ packages/services/api/package.json | 2 +- packages/services/builder/CHANGELOG.md | 6 +++ packages/services/builder/package.json | 2 +- packages/services/guard/CHANGELOG.md | 6 +++ packages/services/guard/package.json | 2 +- .../services/identity-instrument/CHANGELOG.md | 6 +++ .../services/identity-instrument/package.json | 2 +- packages/services/indexer/CHANGELOG.md | 6 +++ packages/services/indexer/package.json | 2 +- packages/services/marketplace/CHANGELOG.md | 6 +++ packages/services/marketplace/package.json | 2 +- packages/services/metadata/CHANGELOG.md | 6 +++ packages/services/metadata/package.json | 2 +- packages/services/relayer/CHANGELOG.md | 8 ++++ packages/services/relayer/package.json | 2 +- packages/services/userdata/CHANGELOG.md | 6 +++ packages/services/userdata/package.json | 2 +- packages/utils/abi/CHANGELOG.md | 6 +++ packages/utils/abi/package.json | 2 +- packages/wallet/core/CHANGELOG.md | 10 +++++ packages/wallet/core/package.json | 2 +- packages/wallet/dapp-client/CHANGELOG.md | 11 +++++ packages/wallet/dapp-client/package.json | 2 +- packages/wallet/primitives/CHANGELOG.md | 6 +++ packages/wallet/primitives/package.json | 2 +- packages/wallet/wdk/CHANGELOG.md | 12 ++++++ packages/wallet/wdk/package.json | 2 +- 30 files changed, 158 insertions(+), 32 deletions(-) create mode 100644 .changeset/cyan-radios-relax.md diff --git a/.changeset/cyan-radios-relax.md b/.changeset/cyan-radios-relax.md new file mode 100644 index 000000000..ec408d6cd --- /dev/null +++ b/.changeset/cyan-radios-relax.md @@ -0,0 +1,18 @@ +--- +'@0xsequence/api': patch +'@0xsequence/builder': patch +'@0xsequence/guard': patch +'@0xsequence/identity-instrument': patch +'@0xsequence/indexer': patch +'@0xsequence/marketplace': patch +'@0xsequence/metadata': patch +'@0xsequence/relayer': patch +'@0xsequence/userdata': patch +'@0xsequence/abi': patch +'@0xsequence/wallet-core': patch +'@0xsequence/dapp-client': patch +'@0xsequence/wallet-primitives': patch +'@0xsequence/wallet-wdk': patch +--- + +Fix signer 404 error, minor fixes diff --git a/.changeset/pre.json b/.changeset/pre.json index a92fc72b5..73184ae44 100644 --- a/.changeset/pre.json +++ b/.changeset/pre.json @@ -4,23 +4,30 @@ "initialVersions": { "docs": "0.1.0", "web": "0.1.0", - "@0xsequence/api": "3.0.0-beta.4", - "@0xsequence/builder": "3.0.0-beta.4", - "@0xsequence/guard": "3.0.0-beta.4", - "@0xsequence/identity-instrument": "3.0.0-beta.4", - "@0xsequence/indexer": "3.0.0-beta.4", - "@0xsequence/marketplace": "3.0.0-beta.4", - "@0xsequence/metadata": "3.0.0-beta.4", - "@0xsequence/relayer": "3.0.0-beta.4", - "@0xsequence/userdata": "3.0.0-beta.4", - "@0xsequence/abi": "3.0.0-beta.4", - "@0xsequence/wallet-core": "3.0.0-beta.4", - "@0xsequence/dapp-client": "3.0.0-beta.4", - "@0xsequence/wallet-primitives": "3.0.0-beta.4", - "@0xsequence/wallet-wdk": "3.0.0-beta.4", - "@repo/eslint-config": "0.0.1-beta.0", - "@repo/typescript-config": "0.0.1-beta.0", - "@repo/ui": "0.0.1-beta.0" + "@0xsequence/api": "3.0.0-beta.5", + "@0xsequence/builder": "3.0.0-beta.5", + "@0xsequence/guard": "3.0.0-beta.5", + "@0xsequence/identity-instrument": "3.0.0-beta.5", + "@0xsequence/indexer": "3.0.0-beta.5", + "@0xsequence/marketplace": "3.0.0-beta.5", + "@0xsequence/metadata": "3.0.0-beta.5", + "@0xsequence/relayer": "3.0.0-beta.5", + "@0xsequence/userdata": "3.0.0-beta.5", + "@0xsequence/abi": "3.0.0-beta.5", + "@0xsequence/wallet-core": "3.0.0-beta.5", + "@0xsequence/dapp-client": "3.0.0-beta.5", + "@0xsequence/wallet-primitives": "3.0.0-beta.5", + "@0xsequence/wallet-wdk": "3.0.0-beta.5", + "@repo/eslint-config": "0.0.1-beta.1", + "@repo/typescript-config": "0.0.1-beta.1", + "@repo/ui": "0.0.1-beta.1" }, - "changesets": ["goofy-laws-serve", "open-toes-marry", "plain-feet-stare", "wild-feet-carry", "wise-heads-buy"] + "changesets": [ + "cyan-radios-relax", + "goofy-laws-serve", + "open-toes-marry", + "plain-feet-stare", + "wild-feet-carry", + "wise-heads-buy" + ] } diff --git a/packages/services/api/CHANGELOG.md b/packages/services/api/CHANGELOG.md index 610642b4c..11007faa9 100644 --- a/packages/services/api/CHANGELOG.md +++ b/packages/services/api/CHANGELOG.md @@ -1,5 +1,11 @@ # @0xsequence/api +## 3.0.0-beta.6 + +### Patch Changes + +- Fix signer 404 error, minor fixes + ## 3.0.0-beta.5 ### Patch Changes diff --git a/packages/services/api/package.json b/packages/services/api/package.json index dda4d0fd7..6191c7940 100644 --- a/packages/services/api/package.json +++ b/packages/services/api/package.json @@ -1,6 +1,6 @@ { "name": "@0xsequence/api", - "version": "3.0.0-beta.5", + "version": "3.0.0-beta.6", "description": "api sub-package for Sequence", "repository": "https://github.com/0xsequence/sequence.js/tree/master/packages/services/api", "author": "Sequence Platforms Inc.", diff --git a/packages/services/builder/CHANGELOG.md b/packages/services/builder/CHANGELOG.md index 9dda5364d..2877d5538 100644 --- a/packages/services/builder/CHANGELOG.md +++ b/packages/services/builder/CHANGELOG.md @@ -1,5 +1,11 @@ # @0xsequence/builder +## 3.0.0-beta.6 + +### Patch Changes + +- Fix signer 404 error, minor fixes + ## 3.0.0-beta.5 ### Patch Changes diff --git a/packages/services/builder/package.json b/packages/services/builder/package.json index a6da87826..de33fd730 100644 --- a/packages/services/builder/package.json +++ b/packages/services/builder/package.json @@ -1,6 +1,6 @@ { "name": "@0xsequence/builder", - "version": "3.0.0-beta.5", + "version": "3.0.0-beta.6", "description": "builder sub-package for Sequence", "repository": "https://github.com/0xsequence/sequence.js/tree/master/packages/services/builder", "author": "Sequence Platforms Inc.", diff --git a/packages/services/guard/CHANGELOG.md b/packages/services/guard/CHANGELOG.md index 9ba2ad5f4..7adaddd55 100644 --- a/packages/services/guard/CHANGELOG.md +++ b/packages/services/guard/CHANGELOG.md @@ -1,5 +1,11 @@ # @0xsequence/guard +## 3.0.0-beta.6 + +### Patch Changes + +- Fix signer 404 error, minor fixes + ## 3.0.0-beta.5 ### Patch Changes diff --git a/packages/services/guard/package.json b/packages/services/guard/package.json index 542b9ee55..5c93bdfc1 100644 --- a/packages/services/guard/package.json +++ b/packages/services/guard/package.json @@ -1,6 +1,6 @@ { "name": "@0xsequence/guard", - "version": "3.0.0-beta.5", + "version": "3.0.0-beta.6", "description": "guard sub-package for Sequence", "repository": "https://github.com/0xsequence/sequence.js/tree/master/packages/services/guard", "author": "Sequence Platforms Inc.", diff --git a/packages/services/identity-instrument/CHANGELOG.md b/packages/services/identity-instrument/CHANGELOG.md index 3ecd8814c..866782714 100644 --- a/packages/services/identity-instrument/CHANGELOG.md +++ b/packages/services/identity-instrument/CHANGELOG.md @@ -1,5 +1,11 @@ # @0xsequence/identity-instrument +## 3.0.0-beta.6 + +### Patch Changes + +- Fix signer 404 error, minor fixes + ## 3.0.0-beta.5 ### Patch Changes diff --git a/packages/services/identity-instrument/package.json b/packages/services/identity-instrument/package.json index dfdd56b3e..026b8c291 100644 --- a/packages/services/identity-instrument/package.json +++ b/packages/services/identity-instrument/package.json @@ -1,6 +1,6 @@ { "name": "@0xsequence/identity-instrument", - "version": "3.0.0-beta.5", + "version": "3.0.0-beta.6", "license": "Apache-2.0", "type": "module", "publishConfig": { diff --git a/packages/services/indexer/CHANGELOG.md b/packages/services/indexer/CHANGELOG.md index 3978b95ac..e320c4307 100644 --- a/packages/services/indexer/CHANGELOG.md +++ b/packages/services/indexer/CHANGELOG.md @@ -1,5 +1,11 @@ # @0xsequence/indexer +## 3.0.0-beta.6 + +### Patch Changes + +- Fix signer 404 error, minor fixes + ## 3.0.0-beta.5 ### Patch Changes diff --git a/packages/services/indexer/package.json b/packages/services/indexer/package.json index bb4ea0b6f..cb91b590c 100644 --- a/packages/services/indexer/package.json +++ b/packages/services/indexer/package.json @@ -1,6 +1,6 @@ { "name": "@0xsequence/indexer", - "version": "3.0.0-beta.5", + "version": "3.0.0-beta.6", "description": "indexer sub-package for Sequence", "repository": "https://github.com/0xsequence/sequence.js/tree/master/packages/services/indexer", "author": "Sequence Platforms Inc.", diff --git a/packages/services/marketplace/CHANGELOG.md b/packages/services/marketplace/CHANGELOG.md index 2b450ab82..6e33420f0 100644 --- a/packages/services/marketplace/CHANGELOG.md +++ b/packages/services/marketplace/CHANGELOG.md @@ -1,5 +1,11 @@ # @0xsequence/marketplace +## 3.0.0-beta.6 + +### Patch Changes + +- Fix signer 404 error, minor fixes + ## 3.0.0-beta.5 ### Patch Changes diff --git a/packages/services/marketplace/package.json b/packages/services/marketplace/package.json index 47905f591..58959af0d 100644 --- a/packages/services/marketplace/package.json +++ b/packages/services/marketplace/package.json @@ -1,6 +1,6 @@ { "name": "@0xsequence/marketplace", - "version": "3.0.0-beta.5", + "version": "3.0.0-beta.6", "description": "marketplace sub-package for Sequence", "repository": "https://github.com/0xsequence/sequence.js/tree/master/packages/services/marketplace", "author": "Sequence Platforms Inc.", diff --git a/packages/services/metadata/CHANGELOG.md b/packages/services/metadata/CHANGELOG.md index f783d7ba3..4fc3e61cc 100644 --- a/packages/services/metadata/CHANGELOG.md +++ b/packages/services/metadata/CHANGELOG.md @@ -1,5 +1,11 @@ # @0xsequence/metadata +## 3.0.0-beta.6 + +### Patch Changes + +- Fix signer 404 error, minor fixes + ## 3.0.0-beta.5 ### Patch Changes diff --git a/packages/services/metadata/package.json b/packages/services/metadata/package.json index 5f30c7600..9218059ef 100644 --- a/packages/services/metadata/package.json +++ b/packages/services/metadata/package.json @@ -1,6 +1,6 @@ { "name": "@0xsequence/metadata", - "version": "3.0.0-beta.5", + "version": "3.0.0-beta.6", "publishConfig": { "access": "public" }, diff --git a/packages/services/relayer/CHANGELOG.md b/packages/services/relayer/CHANGELOG.md index c4e639bfd..00efdf828 100644 --- a/packages/services/relayer/CHANGELOG.md +++ b/packages/services/relayer/CHANGELOG.md @@ -1,5 +1,13 @@ # @0xsequence/relayer +## 3.0.0-beta.6 + +### Patch Changes + +- Fix signer 404 error, minor fixes +- Updated dependencies + - @0xsequence/wallet-primitives@3.0.0-beta.6 + ## 3.0.0-beta.5 ### Patch Changes diff --git a/packages/services/relayer/package.json b/packages/services/relayer/package.json index e87885932..9e49fe299 100644 --- a/packages/services/relayer/package.json +++ b/packages/services/relayer/package.json @@ -1,6 +1,6 @@ { "name": "@0xsequence/relayer", - "version": "3.0.0-beta.5", + "version": "3.0.0-beta.6", "type": "module", "publishConfig": { "access": "public" diff --git a/packages/services/userdata/CHANGELOG.md b/packages/services/userdata/CHANGELOG.md index 0079ca325..b28ab5220 100644 --- a/packages/services/userdata/CHANGELOG.md +++ b/packages/services/userdata/CHANGELOG.md @@ -1,5 +1,11 @@ # @0xsequence/userdata +## 3.0.0-beta.6 + +### Patch Changes + +- Fix signer 404 error, minor fixes + ## 3.0.0-beta.5 ### Patch Changes diff --git a/packages/services/userdata/package.json b/packages/services/userdata/package.json index 36237bc95..3d2fd79e9 100644 --- a/packages/services/userdata/package.json +++ b/packages/services/userdata/package.json @@ -1,6 +1,6 @@ { "name": "@0xsequence/userdata", - "version": "3.0.0-beta.5", + "version": "3.0.0-beta.6", "description": "userdata sub-package for Sequence", "repository": "https://github.com/0xsequence/sequence.js/tree/master/packages/services/userdata", "author": "Sequence Platforms Inc.", diff --git a/packages/utils/abi/CHANGELOG.md b/packages/utils/abi/CHANGELOG.md index 447d70ed1..92b0978a1 100644 --- a/packages/utils/abi/CHANGELOG.md +++ b/packages/utils/abi/CHANGELOG.md @@ -1,5 +1,11 @@ # @0xsequence/abi +## 3.0.0-beta.6 + +### Patch Changes + +- Fix signer 404 error, minor fixes + ## 3.0.0-beta.5 ### Patch Changes diff --git a/packages/utils/abi/package.json b/packages/utils/abi/package.json index d2df92de1..fdf2e38c2 100644 --- a/packages/utils/abi/package.json +++ b/packages/utils/abi/package.json @@ -1,6 +1,6 @@ { "name": "@0xsequence/abi", - "version": "3.0.0-beta.5", + "version": "3.0.0-beta.6", "description": "abi sub-package for Sequence", "repository": "https://github.com/0xsequence/sequence.js/tree/master/packages/utils/abi", "author": "Sequence Platforms Inc.", diff --git a/packages/wallet/core/CHANGELOG.md b/packages/wallet/core/CHANGELOG.md index 940b7e413..0ff25b21a 100644 --- a/packages/wallet/core/CHANGELOG.md +++ b/packages/wallet/core/CHANGELOG.md @@ -1,5 +1,15 @@ # @0xsequence/wallet-core +## 3.0.0-beta.6 + +### Patch Changes + +- Fix signer 404 error, minor fixes +- Updated dependencies + - @0xsequence/guard@3.0.0-beta.6 + - @0xsequence/relayer@3.0.0-beta.6 + - @0xsequence/wallet-primitives@3.0.0-beta.6 + ## 3.0.0-beta.5 ### Patch Changes diff --git a/packages/wallet/core/package.json b/packages/wallet/core/package.json index 8e58e5641..b7e7b463f 100644 --- a/packages/wallet/core/package.json +++ b/packages/wallet/core/package.json @@ -1,6 +1,6 @@ { "name": "@0xsequence/wallet-core", - "version": "3.0.0-beta.5", + "version": "3.0.0-beta.6", "license": "Apache-2.0", "type": "module", "publishConfig": { diff --git a/packages/wallet/dapp-client/CHANGELOG.md b/packages/wallet/dapp-client/CHANGELOG.md index 3c4d46618..e7feb8989 100644 --- a/packages/wallet/dapp-client/CHANGELOG.md +++ b/packages/wallet/dapp-client/CHANGELOG.md @@ -1,5 +1,16 @@ # @0xsequence/dapp-client +## 3.0.0-beta.6 + +### Patch Changes + +- Fix signer 404 error, minor fixes +- Updated dependencies + - @0xsequence/guard@3.0.0-beta.6 + - @0xsequence/relayer@3.0.0-beta.6 + - @0xsequence/wallet-core@3.0.0-beta.6 + - @0xsequence/wallet-primitives@3.0.0-beta.6 + ## 3.0.0-beta.5 ### Patch Changes diff --git a/packages/wallet/dapp-client/package.json b/packages/wallet/dapp-client/package.json index 7ce4dae81..40a6659c5 100644 --- a/packages/wallet/dapp-client/package.json +++ b/packages/wallet/dapp-client/package.json @@ -1,6 +1,6 @@ { "name": "@0xsequence/dapp-client", - "version": "3.0.0-beta.5", + "version": "3.0.0-beta.6", "license": "Apache-2.0", "type": "module", "publishConfig": { diff --git a/packages/wallet/primitives/CHANGELOG.md b/packages/wallet/primitives/CHANGELOG.md index 5e9e2c183..c98111672 100644 --- a/packages/wallet/primitives/CHANGELOG.md +++ b/packages/wallet/primitives/CHANGELOG.md @@ -1,5 +1,11 @@ # @0xsequence/wallet-primitives +## 3.0.0-beta.6 + +### Patch Changes + +- Fix signer 404 error, minor fixes + ## 3.0.0-beta.5 ### Patch Changes diff --git a/packages/wallet/primitives/package.json b/packages/wallet/primitives/package.json index 3b1ffdbec..08e2b41ba 100644 --- a/packages/wallet/primitives/package.json +++ b/packages/wallet/primitives/package.json @@ -1,6 +1,6 @@ { "name": "@0xsequence/wallet-primitives", - "version": "3.0.0-beta.5", + "version": "3.0.0-beta.6", "license": "Apache-2.0", "type": "module", "publishConfig": { diff --git a/packages/wallet/wdk/CHANGELOG.md b/packages/wallet/wdk/CHANGELOG.md index ea802f9c4..6f2094f85 100644 --- a/packages/wallet/wdk/CHANGELOG.md +++ b/packages/wallet/wdk/CHANGELOG.md @@ -1,5 +1,17 @@ # @0xsequence/wallet-wdk +## 3.0.0-beta.6 + +### Patch Changes + +- Fix signer 404 error, minor fixes +- Updated dependencies + - @0xsequence/guard@3.0.0-beta.6 + - @0xsequence/identity-instrument@3.0.0-beta.6 + - @0xsequence/relayer@3.0.0-beta.6 + - @0xsequence/wallet-core@3.0.0-beta.6 + - @0xsequence/wallet-primitives@3.0.0-beta.6 + ## 3.0.0-beta.5 ### Patch Changes diff --git a/packages/wallet/wdk/package.json b/packages/wallet/wdk/package.json index 2c0dc66e3..069ea2491 100644 --- a/packages/wallet/wdk/package.json +++ b/packages/wallet/wdk/package.json @@ -1,6 +1,6 @@ { "name": "@0xsequence/wallet-wdk", - "version": "3.0.0-beta.5", + "version": "3.0.0-beta.6", "license": "Apache-2.0", "type": "module", "publishConfig": { From 95cbf4906efe56faba64a8d771d7bc64d834f021 Mon Sep 17 00:00:00 2001 From: Dargon789 <64915515+Dargon789@users.noreply.github.com> Date: Fri, 19 Dec 2025 21:34:22 +0700 Subject: [PATCH 09/39] Update tests.yml (#119) Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> From 5c2bfd5b056c0a96edbaa5783991b6c066e82b07 Mon Sep 17 00:00:00 2001 From: Dargon789 <64915515+Dargon789@users.noreply.github.com> Date: Fri, 19 Dec 2025 22:37:33 +0700 Subject: [PATCH 10/39] Update config.yml (#120) Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 709c9a747..ad53a8e49 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -8,7 +8,7 @@ executors: - image: cimg/base:stable auth: # ensure you have first added these secrets - # visit app.circleci.com/settings/project/github/Dargon789/hardhat-project/environment-variables + # visit app.circleci.com/settings/project/github/Dargon789/foundry/environment-variables username: $DOCKER_HUB_USER password: $DOCKER_HUB_PASSWORD jobs: From 85324163804380abf8808edb390d5368fdfcb5af Mon Sep 17 00:00:00 2001 From: Dargon789 <64915515+Dargon789@users.noreply.github.com> Date: Mon, 22 Dec 2025 02:03:57 +0700 Subject: [PATCH 11/39] Update packages/services/identity-instrument/src/index.ts Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> --- packages/services/identity-instrument/src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/services/identity-instrument/src/index.ts b/packages/services/identity-instrument/src/index.ts index f7b477b6c..12eb0f0ff 100644 --- a/packages/services/identity-instrument/src/index.ts +++ b/packages/services/identity-instrument/src/index.ts @@ -65,7 +65,7 @@ export class IdentityInstrument { keyType: KeyType.Ethereum_Secp256k1, }, digest: Hex.fromBytes(digest), - nonce: Hex.fromNumber(Date.now()), + nonce: Hex.random(16), } const res = await this.rpc.sign({ params, From 62954a37adf87309b882e544848d23769d209470 Mon Sep 17 00:00:00 2001 From: Dargon789 <64915515+Dargon789@users.noreply.github.com> Date: Mon, 22 Dec 2025 02:18:10 +0700 Subject: [PATCH 12/39] feat: upgrade @wagmi/cli from 0.1.15 to 2.8.0 (#126) Snyk has created this PR to upgrade @wagmi/cli from 0.1.15 to 2.8.0. See this package in npm: @wagmi/cli See this project in Snyk: https://app.snyk.io/org/dargon789/project/bb845543-cbee-4e11-8cf9-8bfdf9205bf1?utm_source=github&utm_medium=referral&page=upgrade-pr Co-authored-by: snyk-bot --- wagmi-project/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wagmi-project/package.json b/wagmi-project/package.json index fb48d8e6a..b3a2bc03e 100644 --- a/wagmi-project/package.json +++ b/wagmi-project/package.json @@ -21,7 +21,7 @@ "@types/react": "^18.3.1", "@types/react-dom": "^18.3.0", "@vitejs/plugin-react": "^4.2.1", - "@wagmi/cli": "~0.x.x", + "@wagmi/cli": "~2.8.0", "buffer": "^6.0.3", "typescript": "^5.4.5", "vite": "^5.2.11" From 666c383b8c5a33537974ad512582df43799d0123 Mon Sep 17 00:00:00 2001 From: Dargon789 <64915515+Dargon789@users.noreply.github.com> Date: Mon, 22 Dec 2025 20:50:35 +0700 Subject: [PATCH 13/39] Potential fix for code scanning alert no. 82: Workflow does not contain permissions Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> --- .github/workflows/on_pr_pnpm-format-label.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/on_pr_pnpm-format-label.yml b/.github/workflows/on_pr_pnpm-format-label.yml index 84fb27cb3..83f23775a 100644 --- a/.github/workflows/on_pr_pnpm-format-label.yml +++ b/.github/workflows/on_pr_pnpm-format-label.yml @@ -1,5 +1,9 @@ name: pnpm-format-label +permissions: + contents: read + issues: write + on: pull_request: types: [labeled] From 4257ad54d6469593cf65a7dcdb52cd970e60b30c Mon Sep 17 00:00:00 2001 From: Dargon789 <64915515+Dargon789@users.noreply.github.com> Date: Mon, 22 Dec 2025 20:51:18 +0700 Subject: [PATCH 14/39] Potential fix for code scanning alert no. 62: Information exposure through a stack trace Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> --- packages/wallet/primitives-cli/src/subcommands/server.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/wallet/primitives-cli/src/subcommands/server.ts b/packages/wallet/primitives-cli/src/subcommands/server.ts index 29c5e1118..ab999c454 100644 --- a/packages/wallet/primitives-cli/src/subcommands/server.ts +++ b/packages/wallet/primitives-cli/src/subcommands/server.ts @@ -327,7 +327,8 @@ async function handleHttpRequest(req: IncomingMessage, res: ServerResponse, debu } catch (error) { if (!silent) console.log(`[${new Date().toISOString()}] JSON parse error:`, error) res.statusCode = 400 - res.end(JSON.stringify(errorResponse(undefined, -32700, 'Parse error', String(error)))) + // Return a generic parse error without exposing internal error details to the client + res.end(JSON.stringify(errorResponse(undefined, -32700, 'Parse error'))) return } From edc0b099ba1656df208735e7af1df8805c6a686f Mon Sep 17 00:00:00 2001 From: Dargon789 <64915515+Dargon789@users.noreply.github.com> Date: Mon, 22 Dec 2025 21:30:38 +0700 Subject: [PATCH 15/39] [Snyk] Upgrade @tanstack/react-query from 5.64.2 to 5.90.11 (#125) * fix: upgrade @tanstack/react-query from 5.64.2 to 5.90.11 Snyk has created this PR to upgrade @tanstack/react-query from 5.64.2 to 5.90.11. See this package in npm: @tanstack/react-query See this project in Snyk: https://app.snyk.io/org/dargon789/project/bb845543-cbee-4e11-8cf9-8bfdf9205bf1?utm_source=github&utm_medium=referral&page=upgrade-pr * Update wagmi-project/package.json Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> --------- Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> Co-authored-by: snyk-bot Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- wagmi-project/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wagmi-project/package.json b/wagmi-project/package.json index b3a2bc03e..a076f4533 100644 --- a/wagmi-project/package.json +++ b/wagmi-project/package.json @@ -10,7 +10,7 @@ "preview": "vite preview" }, "dependencies": { - "@tanstack/react-query": "5.64.2", + "@tanstack/react-query": "^5.90.11", "react": "^18.3.1", "react-dom": "^18.3.1", "viem": "^2.x", From cbb6c14f5413d6d6ad7b4bedecad12b4c4cec69e Mon Sep 17 00:00:00 2001 From: Dargon789 <64915515+Dargon789@users.noreply.github.com> Date: Mon, 22 Dec 2025 21:34:15 +0700 Subject: [PATCH 16/39] feat: upgrade vite from 5.4.21 to 7.2.4 (#124) Snyk has created this PR to upgrade vite from 5.4.21 to 7.2.4. See this package in npm: vite See this project in Snyk: https://app.snyk.io/org/dargon789/project/bb845543-cbee-4e11-8cf9-8bfdf9205bf1?utm_source=github&utm_medium=referral&page=upgrade-pr Co-authored-by: snyk-bot --- wagmi-project/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wagmi-project/package.json b/wagmi-project/package.json index a076f4533..4d2695f99 100644 --- a/wagmi-project/package.json +++ b/wagmi-project/package.json @@ -24,6 +24,6 @@ "@wagmi/cli": "~2.8.0", "buffer": "^6.0.3", "typescript": "^5.4.5", - "vite": "^5.2.11" + "vite": "^7.2.4" } } From 095c4b3a5fa231d01a57178aedc1eb082f4a6a12 Mon Sep 17 00:00:00 2001 From: Dargon789 <64915515+Dargon789@users.noreply.github.com> Date: Mon, 22 Dec 2025 21:35:50 +0700 Subject: [PATCH 17/39] feat: upgrade wagmi from 0.12.19 to 3.0.2 (#123) Snyk has created this PR to upgrade wagmi from 0.12.19 to 3.0.2. See this package in npm: wagmi See this project in Snyk: https://app.snyk.io/org/dargon789/project/bb845543-cbee-4e11-8cf9-8bfdf9205bf1?utm_source=github&utm_medium=referral&page=upgrade-pr Co-authored-by: snyk-bot --- wagmi-project/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wagmi-project/package.json b/wagmi-project/package.json index 4d2695f99..1256f02c7 100644 --- a/wagmi-project/package.json +++ b/wagmi-project/package.json @@ -14,7 +14,7 @@ "react": "^18.3.1", "react-dom": "^18.3.1", "viem": "^2.x", - "wagmi": "~0.x.x" + "wagmi": "~3.0.2" }, "devDependencies": { "@biomejs/biome": "^1.8.0", From 3c73b56250894a34906f06f24e8abd00675bf4b8 Mon Sep 17 00:00:00 2001 From: Dargon789 <64915515+Dargon789@users.noreply.github.com> Date: Mon, 22 Dec 2025 21:38:12 +0700 Subject: [PATCH 18/39] feat: upgrade react-dom from 18.3.1 to 19.2.0 (#122) Snyk has created this PR to upgrade react-dom from 18.3.1 to 19.2.0. See this package in npm: react-dom See this project in Snyk: https://app.snyk.io/org/dargon789/project/bb845543-cbee-4e11-8cf9-8bfdf9205bf1?utm_source=github&utm_medium=referral&page=upgrade-pr Co-authored-by: snyk-bot --- wagmi-project/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wagmi-project/package.json b/wagmi-project/package.json index 1256f02c7..e08226928 100644 --- a/wagmi-project/package.json +++ b/wagmi-project/package.json @@ -12,7 +12,7 @@ "dependencies": { "@tanstack/react-query": "^5.90.11", "react": "^18.3.1", - "react-dom": "^18.3.1", + "react-dom": "^19.2.0", "viem": "^2.x", "wagmi": "~3.0.2" }, From 186f8430583884d1fdc66101093b89ca7141ab6f Mon Sep 17 00:00:00 2001 From: Dargon789 <64915515+Dargon789@users.noreply.github.com> Date: Mon, 22 Dec 2025 22:36:16 +0700 Subject: [PATCH 19/39] fix: extras/docs/package.json to reduce vulnerabilities (#136) The following vulnerabilities are fixed with an upgrade: - https://snyk.io/vuln/SNYK-JS-NEXT-14173355 Co-authored-by: snyk-io[bot] <141718529+snyk-io[bot]@users.noreply.github.com> From b56f318e043ef11831fab9c65d345bc6bddf588a Mon Sep 17 00:00:00 2001 From: Dargon789 <64915515+Dargon789@users.noreply.github.com> Date: Mon, 22 Dec 2025 23:34:35 +0700 Subject: [PATCH 20/39] [Snyk] Upgrade @types/react from 18.3.27 to 19.2.7 (#127) * feat: upgrade @types/react from 18.3.27 to 19.2.7 Snyk has created this PR to upgrade @types/react from 18.3.27 to 19.2.7. See this package in npm: @types/react See this project in Snyk: https://app.snyk.io/org/dargon789/project/bb845543-cbee-4e11-8cf9-8bfdf9205bf1?utm_source=github&utm_medium=referral&page=upgrade-pr * Update wagmi-project/package.json Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> --------- Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> Co-authored-by: snyk-bot Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> From bc418b171da95091d834f3a21141780169818db3 Mon Sep 17 00:00:00 2001 From: Dargon789 <64915515+Dargon789@users.noreply.github.com> Date: Tue, 23 Dec 2025 00:27:24 +0700 Subject: [PATCH 21/39] Master ceb95d4 (#129) * Update issue templates (#128) * Bump the npm_and_yarn group across 1 directory with 1 update Bumps the npm_and_yarn group with 1 update in the / directory: [express](https://github.com/expressjs/express). Updates `express` from 4.18.2 to 4.19.2 - [Release notes](https://github.com/expressjs/express/releases) - [Changelog](https://github.com/expressjs/express/blob/master/History.md) - [Commits](https://github.com/expressjs/express/compare/4.18.2...4.19.2) --- updated-dependencies: - dependency-name: express dependency-type: direct:development dependency-group: npm_and_yarn-security-group ... Signed-off-by: dependabot[bot] * Create SECURITY.md * Set up CI with Azure Pipelines [skip ci] * Create CNAME * Create fortify.yml * Update issue templates * Update CNAME * fix: upgrade @tanstack/react-query from 5.45.1 to 5.64.2 Snyk has created this PR to upgrade @tanstack/react-query from 5.45.1 to 5.64.2. See this package in npm: @tanstack/react-query See this project in Snyk: https://app.snyk.io/org/dargon789/project/bb845543-cbee-4e11-8cf9-8bfdf9205bf1?utm_source=github&utm_medium=referral&page=upgrade-pr * Create config.yml (#46) Signed-off-by: AU_gdev_19 <64915515+Dargon789@users.noreply.github.com> * Support multiple identity signers in sessions configuration * Device signers can approve implicit sessions * Remove invalid test * Fix recursion * Fix comment * Improve test stability by reducing race conditions * Do not set passkey signer as identity signer * Use length checks * Throw on missing identity signer * Encoding requires identity signer to encode * Fix test * Refactor/types namings tsdoc redundant code (#880) * refactor types, namings, ts doc * fix session response payload * change parameter name * change parameter name * change type in tests * improve types and dapp client methods * fix session test to use new types * refactor * refactor implicit sessions array in chain session manager * remove unused types * remove unused types and add ConnectionError * update pnpm lock * move reusable session types to wallet-core * Update some imports and update some response type names --------- Co-authored-by: Tolgahan Arikan * Fix check for explicit session for the updated type in dapp-client * Update api.gen.ts and relayer.gen.ts * Add missing chainId for dapp client event * Fix initializing new chain session manager on redirect * Add support for non-viem, custom Sequence chains (#882) * Provider sent to prepareBlankEnvelope * Update fortify.yml Signed-off-by: AU_gdev_19 <64915515+Dargon789@users.noreply.github.com> * Add session signature decoding * Add feeTokens endpoint to relayer (#885) * const for node length * Clearer blacklist size encoding * identity signer node length * add getFeeTokens to dapp client (#889) * add getFeeTokens to dapp client * fix typo * make getFeeTokens independent of chain session manager and initialize state (#890) * make getFeeTokens independent of chain session manager and initialized state * remove getFeeTokens from chain session manager * Throw specific error when trying to sign with an expired session (#887) * Throw when supported session signer is expired * Fix tests * Make dapp-client implicit sessions chain agnostic (#893) * Add Monad, remove LAOS and Root Network * Add support for sessionless dapp connection (#896) * Refactor relayer package & update dependant packages (#891) * refactor exports for relayer (#900) * Add Arc Testnet * Fix changelog config * Sessionless connection upgrade and error handling in DappClient (#902) * dapp-client: add sessionless snapshot restore flow * Bump the npm_and_yarn group across 3 directories with 1 update Bumps the npm_and_yarn group with 1 update in the / directory: [happy-dom](https://github.com/capricorn86/happy-dom). Bumps the npm_and_yarn group with 1 update in the /packages/wallet/dapp-client directory: [happy-dom](https://github.com/capricorn86/happy-dom). Bumps the npm_and_yarn group with 1 update in the /packages/wallet/wdk directory: [happy-dom](https://github.com/capricorn86/happy-dom). Updates `happy-dom` from 17.6.3 to 20.0.2 - [Release notes](https://github.com/capricorn86/happy-dom/releases) - [Commits](https://github.com/capricorn86/happy-dom/compare/v17.6.3...v20.0.2) Updates `happy-dom` from 17.6.3 to 20.0.2 - [Release notes](https://github.com/capricorn86/happy-dom/releases) - [Commits](https://github.com/capricorn86/happy-dom/compare/v17.6.3...v20.0.2) Updates `happy-dom` from 17.6.3 to 20.0.2 - [Release notes](https://github.com/capricorn86/happy-dom/releases) - [Commits](https://github.com/capricorn86/happy-dom/compare/v17.6.3...v20.0.2) --- updated-dependencies: - dependency-name: happy-dom dependency-version: 20.0.2 dependency-type: direct:development dependency-group: npm_and_yarn - dependency-name: happy-dom dependency-version: 20.0.2 dependency-type: direct:development dependency-group: npm_and_yarn - dependency-name: happy-dom dependency-version: 20.0.2 dependency-type: direct:development dependency-group: npm_and_yarn ... Signed-off-by: dependabot[bot] * Allow to logout a wallet with skipRemoveDevice even if the wallet is not in a ready state to allow force removing of wallets (#906) * Pass request to PromptCodeHandler in guard registerUI (#909) * Pass request to PromptCodeHandler in guard registerUI * Fixing guard registerUI test * guard: allow using recovery code as 2FA token (#910) * guard: allow using recovery code as 2FA token * Cleanup types of ResponseFn --------- Co-authored-by: Corban Riley * Add a way to reset 2fa when using a backup code (#911) * Add a way to reset 2fa when using a backup code * use the GuardToken type instead of breaking out the props * Update package.json Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> * Update SECURITY.md Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> * Update wagmi-project/package.json Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> * Update wagmi-project/package.json Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> * Update wagmi-project/src/App.tsx Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> * Create FUNDING.json (#90) Enhancements: Include FUNDING.json to display GitHub sponsorship options in the repository Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> * Create config.yml (#91) Add initial CircleCI configuration to enable automated builds using a custom Docker executor and a defined workflow. Build: Add .circleci/config.yml with version 2.1 specification and custom Docker executor. CI: Define web3-defi-game-project job with checkout step. Set up my-custom-workflow to run the job. Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> * Add rc4 contracts * Set rc4 as default and add it to lists * Session enhanced replay protection * New sessions replay protection hashes payload * Use the 4337 factory wrapper * Update keymachine url in dapp-client constants * Update keymachine url in Provider constructor * SSR safety (#915) * SSR safety test * Fix CI job * Guard dapp-client for SSR (lazy transport, browser checks, gated storage) * Fix guard topology (#918) * Use proper guard topology * Test and fixes * login and setup tests * Switch prod manager settings (#917) * Add prod guard and identity instrument info * Remove completed TODOs * Small JS tweaks (#919) * Fix type exports to built declarations * Update repository links to current package paths * Improve Next app tooling and React typings * Expose primitives CLI bin and use base lint config * Update relayer.gen.ts and TransactionPrecondition interface * Update api.gen.ts * Update metadata.gen.ts * Update marketplace.gen.ts * Update guard.gen.ts * Support multiple identity signers in sessions configuration * Device signers can approve implicit sessions * Remove invalid test * Fix recursion * Fix comment * Improve test stability by reducing race conditions * Do not set passkey signer as identity signer * Use length checks * Throw on missing identity signer * Encoding requires identity signer to encode * Fix test * Refactor/types namings tsdoc redundant code (#880) * refactor types, namings, ts doc * fix session response payload * change parameter name * change parameter name * change type in tests * improve types and dapp client methods * fix session test to use new types * refactor * refactor implicit sessions array in chain session manager * remove unused types * remove unused types and add ConnectionError * update pnpm lock * move reusable session types to wallet-core * Update some imports and update some response type names --------- Co-authored-by: Tolgahan Arikan * Fix check for explicit session for the updated type in dapp-client * Update api.gen.ts and relayer.gen.ts * Add missing chainId for dapp client event * Fix initializing new chain session manager on redirect * Add support for non-viem, custom Sequence chains (#882) * Provider sent to prepareBlankEnvelope * Add session signature decoding * const for node length * Clearer blacklist size encoding * identity signer node length * Add feeTokens endpoint to relayer (#885) * add getFeeTokens to dapp client (#889) * add getFeeTokens to dapp client * fix typo * make getFeeTokens independent of chain session manager and initialize state (#890) * make getFeeTokens independent of chain session manager and initialized state * remove getFeeTokens from chain session manager * Throw specific error when trying to sign with an expired session (#887) * Throw when supported session signer is expired * Fix tests * Make dapp-client implicit sessions chain agnostic (#893) * Add Monad, remove LAOS and Root Network * Add support for sessionless dapp connection (#896) * Refactor relayer package & update dependant packages (#891) * refactor exports for relayer (#900) * Add Arc Testnet * Fix changelog config * Sessionless connection upgrade and error handling in DappClient (#902) * dapp-client: add sessionless snapshot restore flow * Allow to logout a wallet with skipRemoveDevice even if the wallet is not in a ready state to allow force removing of wallets (#906) * Pass request to PromptCodeHandler in guard registerUI (#909) * Pass request to PromptCodeHandler in guard registerUI * Fixing guard registerUI test * guard: allow using recovery code as 2FA token (#910) * guard: allow using recovery code as 2FA token * Cleanup types of ResponseFn --------- Co-authored-by: Corban Riley * Add a way to reset 2fa when using a backup code (#911) * Add a way to reset 2fa when using a backup code * use the GuardToken type instead of breaking out the props * Add rc4 contracts * Set rc4 as default and add it to lists * Session enhanced replay protection * New sessions replay protection hashes payload * Use the 4337 factory wrapper * Update keymachine url in dapp-client constants * Update keymachine url in Provider constructor * SSR safety (#915) * Guard dapp-client for SSR (lazy transport, browser checks, gated storage) * Fix guard topology (#918) * Use proper guard topology * Test and fixes * login and setup tests * Switch prod manager settings (#917) * Add prod guard and identity instrument info * Remove completed TODOs * Small JS tweaks (#919) * Fix type exports to built declarations * Update repository links to current package paths * Improve Next app tooling and React typings * Expose primitives CLI bin and use base lint config * Update relayer.gen.ts and TransactionPrecondition interface * Update relayer.gen.ts and TransactionPrecondition interface (#920) * 3.0.0-beta.1 * identity-instrument: generate nonce from current time (#921) * Remove publish-dists.yml github action (#923) * 3.0.0-beta.2 * Clean up changeset config * Improve test stability by removing race conditions * Ensure build before test * Updating happy-dom to 20.0.10 (#926) * Add support for custom auth providers (authcode & authcode-pkce only) (#894) * Add support for custom auth providers (authcode & authcode-pkce only) * fix authcode tests * Updating Deps November 2025 (#927) * Updating deps for the workspace root * Updating deps for wallet/wdk * Fixing sessions test for latest vitest * Lets not upgrade to the latest typescript quite yet * Updating to latest vitest * Updating deps for wallet/core * Updating deps for wallet/primitives-cli * Updating deps for wallet/dapp-client * Adding syncpack to check for dep version inconsistencies * Setup syncpack versionGroups for pnpm workspace:^ * Fixing dep versions mismatches * Fixing @types/node mismatches * Adding syncpack to pre commit hook * Remove the syncpack format script. * Update ox to v9.17.0 (#928) * Upgrading ox to 9.17.0 * WrappedSignature renamed to SignatureErc6492 * Fixing PasskeySignatureValidator interface * Lock ox lib dep to use the same version with pnpm overrides and update viem to latest * Fix explicitSessionRequested check in dapp client * Typescript 5.9.3 (#930) * Upgrading to typescript v5.9.3 * Fix type errors that arose from typescript upgrade related to Bytes and Buffer source typings. * Don't catch errors thrown by Guard 2FA or reject early to allow multiple attempts on incorrect TOTP (#931) * Update pnpm * Mark @0xsequence/wallet-primitives-cli as private * 3.0.0-beta.3 * changeset cleanup * Fix rc4 4337 factory (#933) * Add rc5 and set it as default (#934) * 3.0.0-beta.4 * Update SECURITY.md Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> * Update wagmi-project/package.json Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> * Update wagmi-project/package.json Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> * Bump next from 15.5.5 to 15.5.7 (#936) Bumps [next](https://github.com/vercel/next.js) from 15.5.5 to 15.5.7. - [Release notes](https://github.com/vercel/next.js/releases) - [Changelog](https://github.com/vercel/next.js/blob/canary/release.js) - [Commits](https://github.com/vercel/next.js/compare/v15.5.5...v15.5.7) --- updated-dependencies: - dependency-name: next dependency-version: 15.5.7 dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * add userdata service client (#940) * Skip LocalDevice identity signers not on current device (#942) * Skip LocalDevice identity signers not on current device * Update log * 3.0.0-beta.5 * Update config.yml (#102) * Update config.yml Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> * Update .circleci/config.yml Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com> Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> --------- Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com> * Update config.yml (#103) * Update config.yml Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> * Update .circleci/config.yml Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com> Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> --------- Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com> * fix: extras/web/package.json to reduce vulnerabilities (#101) The following vulnerabilities are fixed with an upgrade: - https://snyk.io/vuln/SNYK-JS-NEXT-14173355 Co-authored-by: snyk-io[bot] <141718529+snyk-io[bot]@users.noreply.github.com> * fix: extras/docs/package.json to reduce vulnerabilities (#100) The following vulnerabilities are fixed with an upgrade: - https://snyk.io/vuln/SNYK-JS-NEXT-14173355 Co-authored-by: snyk-io[bot] <141718529+snyk-io[bot]@users.noreply.github.com> * fix: package.json to reduce vulnerabilities (#104) The following vulnerabilities are fixed with an upgrade: - https://snyk.io/vuln/SNYK-JS-BABELHELPERS-9397697 - https://snyk.io/vuln/SNYK-JS-BABELRUNTIME-10044504 - https://snyk.io/vuln/SNYK-JS-BRACEEXPANSION-9789073 - https://snyk.io/vuln/SNYK-JS-CROSSSPAWN-8303230 - https://snyk.io/vuln/SNYK-JS-ELLIPTIC-7577916 - https://snyk.io/vuln/SNYK-JS-ELLIPTIC-7577917 - https://snyk.io/vuln/SNYK-JS-ELLIPTIC-7577918 - https://snyk.io/vuln/SNYK-JS-ELLIPTIC-8187303 - https://snyk.io/vuln/SNYK-JS-ELLIPTIC-8720086 - https://snyk.io/vuln/SNYK-JS-IMAGESIZE-9634164 - https://snyk.io/vuln/SNYK-JS-INFLIGHT-6095116 - https://snyk.io/vuln/SNYK-JS-JSYAML-13961110 - https://snyk.io/vuln/SNYK-JS-MICROMATCH-6838728 - https://snyk.io/vuln/SNYK-JS-NODEFORGE-14114940 - https://snyk.io/vuln/SNYK-JS-NODEFORGE-14125097 - https://snyk.io/vuln/SNYK-JS-NODEFORGE-14125745 - https://snyk.io/vuln/SNYK-JS-ONHEADERS-10773729 - https://snyk.io/vuln/SNYK-JS-ROLLUP-8073097 - https://snyk.io/vuln/SNYK-JS-SECP256K1-8237220 - https://snyk.io/vuln/SNYK-JS-SEND-7926862 - https://snyk.io/vuln/SNYK-JS-SERVESTATIC-7926865 - https://snyk.io/vuln/SNYK-JS-SHAJS-12089400 Co-authored-by: snyk-io[bot] <141718529+snyk-io[bot]@users.noreply.github.com> * Revert "Merge remote-tracking branch 'origin/dependabot/npm_and_yarn/npm_and_yarn-318c02e2da'" This reverts commit fd0fdf9ecc6ad9056447e381de7fc5bb19f78e47, reversing changes made to cba78943db9942a4635bb530b7a43fc5d18b0ab4. * fix: extras/web/package.json to reduce vulnerabilities (#109) The following vulnerabilities are fixed with an upgrade: - https://snyk.io/vuln/SNYK-JS-NEXT-14173355 Co-authored-by: snyk-bot * fix: extras/docs/package.json to reduce vulnerabilities (#106) The following vulnerabilities are fixed with an upgrade: - https://snyk.io/vuln/SNYK-JS-NEXT-14400636 - https://snyk.io/vuln/SNYK-JS-NEXT-14400644 Co-authored-by: snyk-bot * Bump next in the npm_and_yarn group across 1 directory (#110) Bumps the npm_and_yarn group with 1 update in the / directory: [next](https://github.com/vercel/next.js). Updates `next` from 15.5.7 to 15.5.9 - [Release notes](https://github.com/vercel/next.js/releases) - [Changelog](https://github.com/vercel/next.js/blob/canary/release.js) - [Commits](https://github.com/vercel/next.js/compare/v15.5.7...v15.5.9) --- updated-dependencies: - dependency-name: next dependency-version: 15.5.9 dependency-type: direct:production dependency-group: npm_and_yarn ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Delete .github/workflows/fortify.yml (#111) Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> * fix: extras/web/package.json to reduce vulnerabilities (#107) The following vulnerabilities are fixed with an upgrade: - https://snyk.io/vuln/SNYK-JS-NEXT-14400636 - https://snyk.io/vuln/SNYK-JS-NEXT-14400644 Co-authored-by: snyk-bot * Bump the npm_and_yarn group across 1 directory with 3 updates (#115) Bumps the npm_and_yarn group with 1 update in the / directory: [next](https://github.com/vercel/next.js). Updates `next` from 15.5.5 to 15.5.9 - [Release notes](https://github.com/vercel/next.js/releases) - [Changelog](https://github.com/vercel/next.js/blob/canary/release.js) - [Commits](https://github.com/vercel/next.js/compare/v15.5.5...v15.5.9) Updates `happy-dom` from 17.6.3 to 20.0.11 - [Release notes](https://github.com/capricorn86/happy-dom/releases) - [Commits](https://github.com/capricorn86/happy-dom/compare/v17.6.3...v20.0.11) Updates `vite` from 7.1.10 to 7.2.7 - [Release notes](https://github.com/vitejs/vite/releases) - [Changelog](https://github.com/vitejs/vite/blob/v7.2.7/packages/vite/CHANGELOG.md) - [Commits](https://github.com/vitejs/vite/commits/v7.2.7/packages/vite) --- updated-dependencies: - dependency-name: next dependency-version: 15.5.9 dependency-type: direct:production dependency-group: npm_and_yarn - dependency-name: happy-dom dependency-version: 20.0.11 dependency-type: direct:development dependency-group: npm_and_yarn - dependency-name: vite dependency-version: 7.2.7 dependency-type: indirect dependency-group: npm_and_yarn ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump next from 15.5.7 to 15.5.9 (#944) Bumps [next](https://github.com/vercel/next.js) from 15.5.7 to 15.5.9. - [Release notes](https://github.com/vercel/next.js/releases) - [Changelog](https://github.com/vercel/next.js/blob/canary/release.js) - [Commits](https://github.com/vercel/next.js/compare/v15.5.7...v15.5.9) --- updated-dependencies: - dependency-name: next dependency-version: 15.5.9 dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Pin foundry to v1.5.0 instead of nightly (#947) * Include repo and extras in syncpack config to ensure deps are synced (#945) * Include repo and extras in syncpack config to ensure deps are synced across all * Updating support deps * Updating deps * Updating pnpm lock * Fixing type errors within wdk tests * Short circuit 404s (#949) * skip witness on signers that don't support it * add passkey to test * 3.0.0-beta.6 * Update tests.yml (#119) Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> * Update config.yml (#120) Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> * Update packages/services/identity-instrument/src/index.ts Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> --------- Signed-off-by: dependabot[bot] Signed-off-by: AU_gdev_19 <64915515+Dargon789@users.noreply.github.com> Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: snyk-bot Co-authored-by: Michael Standen Co-authored-by: Gabi <56271768+VGabriel45@users.noreply.github.com> Co-authored-by: Tolgahan Arikan Co-authored-by: Taylan Pince Co-authored-by: Corban Brook Co-authored-by: Patryk Kalinowski Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Co-authored-by: Agusx1211 Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com> Co-authored-by: snyk-io[bot] <141718529+snyk-io[bot]@users.noreply.github.com> * Update wagmi-project/src/main.tsx Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com> Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> * Update wagmi-project/package.json Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> * Update wagmi-project/package.json Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> * fix: extras/docs/package.json to reduce vulnerabilities (#116) The following vulnerabilities are fixed with an upgrade: - https://snyk.io/vuln/SNYK-JS-NEXT-14400636 - https://snyk.io/vuln/SNYK-JS-NEXT-14400644 Co-authored-by: snyk-io[bot] <141718529+snyk-io[bot]@users.noreply.github.com> Co-authored-by: dargon789 <64915515+Dargon789@users.noreply.github.com> --------- Signed-off-by: dependabot[bot] Signed-off-by: AU_gdev_19 <64915515+Dargon789@users.noreply.github.com> Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: snyk-bot Co-authored-by: Michael Standen Co-authored-by: Gabi <56271768+VGabriel45@users.noreply.github.com> Co-authored-by: Tolgahan Arikan Co-authored-by: Taylan Pince Co-authored-by: Corban Brook Co-authored-by: Patryk Kalinowski Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Co-authored-by: Agusx1211 Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com> Co-authored-by: snyk-io[bot] <141718529+snyk-io[bot]@users.noreply.github.com> From 28a268eef9f36a4bcf257d175c49c31f55f8008b Mon Sep 17 00:00:00 2001 From: Dargon789 <64915515+Dargon789@users.noreply.github.com> Date: Tue, 23 Dec 2025 18:14:59 +0700 Subject: [PATCH 22/39] Update wagmi-project/src/App.tsx Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> --- wagmi-project/src/App.tsx | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/wagmi-project/src/App.tsx b/wagmi-project/src/App.tsx index 05da5e5b3..236da5167 100644 --- a/wagmi-project/src/App.tsx +++ b/wagmi-project/src/App.tsx @@ -109,11 +109,15 @@ const App = () => { const [isOpen, toggleModal] = useState(false) const [warning, setWarning] = useState(false) - useMemo(() => { - wallet.on('chainChanged', (chainId: string) => { + useEffect(() => { + const handleChainChanged = (chainId: string) => { setShowChainId(Number(BigInt(chainId))) - }) - }, []) + } + wallet.on('chainChanged', handleChainChanged) + return () => { + wallet.off('chainChanged', handleChainChanged) + } + }, [wallet]) useEffect(() => { setIsWalletConnected(wallet.isConnected()) From 51a64321d3c0b91c9bd43c1e7e693f974c045dbb Mon Sep 17 00:00:00 2001 From: Dargon789 <64915515+Dargon789@users.noreply.github.com> Date: Tue, 23 Dec 2025 18:15:24 +0700 Subject: [PATCH 23/39] Update wagmi-project/src/App.tsx Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> --- wagmi-project/src/App.tsx | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/wagmi-project/src/App.tsx b/wagmi-project/src/App.tsx index 236da5167..526262876 100644 --- a/wagmi-project/src/App.tsx +++ b/wagmi-project/src/App.tsx @@ -130,13 +130,20 @@ const App = () => { useEffect(() => { // Wallet events - wallet.client.onOpen(() => { + const onOpen = () => { console.log('wallet window opened') - }) + } + wallet.client.on('open', onOpen) - wallet.client.onClose(() => { + const onClose = () => { console.log('wallet window closed') - }) + } + wallet.client.on('close', onClose) + + return () => { + wallet.client.off('open', onOpen) + wallet.client.off('close', onClose) + } }, [wallet]) const defaultConnectOptions: ConnectOptions = { From 640be8ffe175c762828aded47cc76e8d2c404b56 Mon Sep 17 00:00:00 2001 From: Dargon789 <64915515+Dargon789@users.noreply.github.com> Date: Tue, 23 Dec 2025 18:15:48 +0700 Subject: [PATCH 24/39] Update wagmi-project/src/App.tsx Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> --- wagmi-project/src/App.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/wagmi-project/src/App.tsx b/wagmi-project/src/App.tsx index 526262876..2b4431b5e 100644 --- a/wagmi-project/src/App.tsx +++ b/wagmi-project/src/App.tsx @@ -79,7 +79,10 @@ const defaultChainId = getDefaultChainId() || ChainId.MAINNET const urlParams = new URLSearchParams(window.location.search) const env = urlParams.get('env') ?? 'production' -const envConfig = environments.find(x => x.name === env) +const envConfig = environments.find(x => x.name === env) ?? environments.find(x => x.name === 'production') +if (!envConfig) { + throw new Error('Invalid environment configuration.') +} const walletAppURL = urlParams.get('walletAppURL') ?? envConfig.walletUrl const projectAccessKey = urlParams.get('projectAccessKey') ?? envConfig.projectAccessKey const showProhibitedActions = urlParams.has('showProhibitedActions') From 7fe4a922dfbd817fa76b8e30e9be184e6f38ddb1 Mon Sep 17 00:00:00 2001 From: Dargon789 <64915515+Dargon789@users.noreply.github.com> Date: Tue, 23 Dec 2025 18:16:10 +0700 Subject: [PATCH 25/39] Update wagmi-project/src/App.tsx Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> --- wagmi-project/src/App.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wagmi-project/src/App.tsx b/wagmi-project/src/App.tsx index 2b4431b5e..9f245fc45 100644 --- a/wagmi-project/src/App.tsx +++ b/wagmi-project/src/App.tsx @@ -181,7 +181,7 @@ const App = () => { const connectDetails = await wallet.connect(connectOptions) // Example of how to verify using ETHAuth via Sequence API - if (connectOptions.authorize && connectDetails.connected) { + if (connectOptions.authorize && connectDetails.connected && connectDetails.proof) { let apiUrl = urlParams.get('apiUrl') if (!apiUrl || apiUrl.length === 0) { @@ -195,7 +195,7 @@ const App = () => { const { isValid } = await api.isValidETHAuthProof({ chainId: connectDetails.chainId, walletAddress: connectDetails.session.accountAddress, - ethAuthProofString: connectDetails.proof!.proofString + ethAuthProofString: connectDetails.proof.proofString }) appendConsoleLine(`isValid (API)?: ${isValid}`) From 802829cc116d9656dfb166beba03a1e77c8d556b Mon Sep 17 00:00:00 2001 From: Dargon789 <64915515+Dargon789@users.noreply.github.com> Date: Tue, 23 Dec 2025 21:15:56 +0700 Subject: [PATCH 26/39] 2.3.7 (#131) (#132) * 2.3.7 (#131) * fix broken guard private key * Expose access to passkey credential list * Dapp client direct txn request (#856) * Signature request refactor * WIP * Refactor * Update dapp-client exports (#858) * Add hasPermission method to DappClient (#859) * Save discovered passkey credentials upon login * Expose name property in PasskeySignupArgs * Fix blacklist sort * Add multi server script * relayer: /SimulateV3 (#857) * Add await for handleOpenDB scheduleExpiration * Update increment to always include native once used * Fix session tests * Adding lastLoginAt to PasskeyCredential * LoginToPasskeyArgs now accept a credentialId which is used to specify which credential to use * Adding onSignatureRequestStatus function to register single use callbacks for when a request reaches a terminal state of completed or cancelled * When a login is cancelled we can remove the wallet which is logging-in * Add RC3 contracts * Sessions space restriction * Dedupe signers for encoding * Support RC3 sessions * Tightly increment call validation * CLI defaults to RC3 wallet code * Rc3 address test * Fix hashing tests * Add deprecated encoding test * wdk: throw errors from otp respond callback (#864) * wdk: throw errors from otp respond callback * wdk: otp auth error and handler refactor * Handle guard 2FA (#861) * guard: return a specific error when auth required * core: pass guard token to the service * wdk: handle prompting for guard 2FA code * dapp-client: handle prompting for guard 2FA code * guard 2fa tests * wdk: separate wallet and sessions guards * dapp-client: remove guard 2fa * dapp-client: fix imports * fix guard tests * wdk: remove unneeded promise resolve * Update relayer and api gen.ts, force public packages * Add standalone fetch queued payloads * Replacing GuardRole enum with string union type, as well as replacing guardAddresses Map with Record * Fallback to chain for non-logged in recovery * Add Katana, Sandbox Tesnet, Incentiv Testnet v2 (#873) * Update a few remaining dev1 contract addresses to rc3 (#874) * Remove unnecessary console.error where we already throw error * Improve DappClient hasPermission method * Wallet db try checksum and lowercase * Update dapp client json utils to include Map reviver and replacer * Bump next in the npm_and_yarn group across 1 directory Bumps the npm_and_yarn group with 1 update in the / directory: [next](https://github.com/vercel/next.js). Updates `next` from 15.4.2 to 15.4.7 - [Release notes](https://github.com/vercel/next.js/releases) - [Changelog](https://github.com/vercel/next.js/blob/canary/release.js) - [Commits](https://github.com/vercel/next.js/compare/v15.4.2...v15.4.7) --- updated-dependencies: - dependency-name: next dependency-version: 15.4.7 dependency-type: direct:production dependency-group: npm_and_yarn ... Signed-off-by: dependabot[bot] * Update type name, update exports for dapp client * Expired explicit sessions can't sign * Improve session validity test * session isValid returns invalid reason * InvalidReason is typed * Support multiple identity signers in sessions configuration * Device signers can approve implicit sessions * Remove invalid test * Fix recursion * Fix comment * Improve test stability by reducing race conditions * Do not set passkey signer as identity signer * Use length checks * Throw on missing identity signer * Encoding requires identity signer to encode * Fix test * Refactor/types namings tsdoc redundant code (#880) * refactor types, namings, ts doc * fix session response payload * change parameter name * change parameter name * change type in tests * improve types and dapp client methods * fix session test to use new types * refactor * refactor implicit sessions array in chain session manager * remove unused types * remove unused types and add ConnectionError * update pnpm lock * move reusable session types to wallet-core * Update some imports and update some response type names --------- Co-authored-by: Tolgahan Arikan * Fix check for explicit session for the updated type in dapp-client * Update api.gen.ts and relayer.gen.ts * Add missing chainId for dapp client event * Fix initializing new chain session manager on redirect * Add support for non-viem, custom Sequence chains (#882) * Update issue templates * Provider sent to prepareBlankEnvelope * Add session signature decoding * Add feeTokens endpoint to relayer (#885) * const for node length * Clearer blacklist size encoding * identity signer node length * Potential fix for code scanning alert no. 84: Insecure randomness Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> Signed-off-by: AU_gdev_19 <64915515+Dargon789@users.noreply.github.com> * add getFeeTokens to dapp client (#889) * add getFeeTokens to dapp client * fix typo * make getFeeTokens independent of chain session manager and initialize state (#890) * make getFeeTokens independent of chain session manager and initialized state * remove getFeeTokens from chain session manager * Throw specific error when trying to sign with an expired session (#887) * Throw when supported session signer is expired * Fix tests * Make dapp-client implicit sessions chain agnostic (#893) * Add Monad, remove LAOS and Root Network * Bump the npm_and_yarn group across 3 directories with 1 update Bumps the npm_and_yarn group with 1 update in the / directory: [happy-dom](https://github.com/capricorn86/happy-dom). Bumps the npm_and_yarn group with 1 update in the /packages/wallet/dapp-client directory: [happy-dom](https://github.com/capricorn86/happy-dom). Bumps the npm_and_yarn group with 1 update in the /packages/wallet/wdk directory: [happy-dom](https://github.com/capricorn86/happy-dom). Updates `happy-dom` from 17.6.3 to 20.0.0 - [Release notes](https://github.com/capricorn86/happy-dom/releases) - [Commits](https://github.com/capricorn86/happy-dom/compare/v17.6.3...v20.0.0) Updates `happy-dom` from 17.6.3 to 20.0.0 - [Release notes](https://github.com/capricorn86/happy-dom/releases) - [Commits](https://github.com/capricorn86/happy-dom/compare/v17.6.3...v20.0.0) Updates `happy-dom` from 17.6.3 to 20.0.0 - [Release notes](https://github.com/capricorn86/happy-dom/releases) - [Commits](https://github.com/capricorn86/happy-dom/compare/v17.6.3...v20.0.0) --- updated-dependencies: - dependency-name: happy-dom dependency-version: 20.0.0 dependency-type: direct:development dependency-group: npm_and_yarn - dependency-name: happy-dom dependency-version: 20.0.0 dependency-type: direct:development dependency-group: npm_and_yarn - dependency-name: happy-dom dependency-version: 20.0.0 dependency-type: direct:development dependency-group: npm_and_yarn ... Signed-off-by: dependabot[bot] * Bump happy-dom in the npm_and_yarn group across 1 directory (#69) Bumps the npm_and_yarn group with 1 update in the / directory: [happy-dom](https://github.com/capricorn86/happy-dom). Updates `happy-dom` from 20.0.0 to 20.0.2 - [Release notes](https://github.com/capricorn86/happy-dom/releases) - [Commits](https://github.com/capricorn86/happy-dom/compare/v20.0.0...v20.0.2) --- updated-dependencies: - dependency-name: happy-dom dependency-version: 20.0.2 dependency-type: direct:development dependency-group: npm_and_yarn ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Create SECURITY.md for security policy (#70) * Create SECURITY.md for security policy Add a security policy document outlining supported versions and vulnerability reporting. Signed-off-by: AU_gdev_19 <64915515+Dargon789@users.noreply.github.com> * Update SECURITY.md Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Signed-off-by: AU_gdev_19 <64915515+Dargon789@users.noreply.github.com> * Update SECURITY.md Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Signed-off-by: AU_gdev_19 <64915515+Dargon789@users.noreply.github.com> --------- Signed-off-by: AU_gdev_19 <64915515+Dargon789@users.noreply.github.com> Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> * Update SECURITY.md Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Signed-off-by: AU_gdev_19 <64915515+Dargon789@users.noreply.github.com> * Add support for sessionless dapp connection (#896) * Refactor relayer package & update dependant packages (#891) * refactor exports for relayer (#900) * Add Arc Testnet * Fix changelog config * Sessionless connection upgrade and error handling in DappClient (#902) * dapp-client: add sessionless snapshot restore flow * Bump the npm_and_yarn group across 3 directories with 1 update Bumps the npm_and_yarn group with 1 update in the / directory: [happy-dom](https://github.com/capricorn86/happy-dom). Bumps the npm_and_yarn group with 1 update in the /packages/wallet/dapp-client directory: [happy-dom](https://github.com/capricorn86/happy-dom). Bumps the npm_and_yarn group with 1 update in the /packages/wallet/wdk directory: [happy-dom](https://github.com/capricorn86/happy-dom). Updates `happy-dom` from 17.6.3 to 20.0.2 - [Release notes](https://github.com/capricorn86/happy-dom/releases) - [Commits](https://github.com/capricorn86/happy-dom/compare/v17.6.3...v20.0.2) Updates `happy-dom` from 17.6.3 to 20.0.2 - [Release notes](https://github.com/capricorn86/happy-dom/releases) - [Commits](https://github.com/capricorn86/happy-dom/compare/v17.6.3...v20.0.2) Updates `happy-dom` from 17.6.3 to 20.0.2 - [Release notes](https://github.com/capricorn86/happy-dom/releases) - [Commits](https://github.com/capricorn86/happy-dom/compare/v17.6.3...v20.0.2) --- updated-dependencies: - dependency-name: happy-dom dependency-version: 20.0.2 dependency-type: direct:development dependency-group: npm_and_yarn - dependency-name: happy-dom dependency-version: 20.0.2 dependency-type: direct:development dependency-group: npm_and_yarn - dependency-name: happy-dom dependency-version: 20.0.2 dependency-type: direct:development dependency-group: npm_and_yarn ... Signed-off-by: dependabot[bot] * Allow to logout a wallet with skipRemoveDevice even if the wallet is not in a ready state to allow force removing of wallets (#906) * Pass request to PromptCodeHandler in guard registerUI (#909) * Pass request to PromptCodeHandler in guard registerUI * Fixing guard registerUI test * guard: allow using recovery code as 2FA token (#910) * guard: allow using recovery code as 2FA token * Cleanup types of ResponseFn --------- Co-authored-by: Corban Riley * Add a way to reset 2fa when using a backup code (#911) * Add a way to reset 2fa when using a backup code * use the GuardToken type instead of breaking out the props * Update SECURITY.md Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com> Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> * Update packages/wallet/dapp-client/src/DappTransport.ts Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> * Update package.json Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> * Update SECURITY.md Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> * Update wagmi-project/package.json Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> * Update wagmi-project/package.json Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> * Update wagmi-project/src/App.tsx Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> * Create FUNDING.json (#90) Enhancements: Include FUNDING.json to display GitHub sponsorship options in the repository Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> * Create config.yml (#91) Add initial CircleCI configuration to enable automated builds using a custom Docker executor and a defined workflow. Build: Add .circleci/config.yml with version 2.1 specification and custom Docker executor. CI: Define web3-defi-game-project job with checkout step. Set up my-custom-workflow to run the job. Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> * Add rc4 contracts * Set rc4 as default and add it to lists * Session enhanced replay protection * New sessions replay protection hashes payload * Use the 4337 factory wrapper * Update keymachine url in dapp-client constants * Update keymachine url in Provider constructor * SSR safety (#915) * SSR safety test * Fix CI job * Guard dapp-client for SSR (lazy transport, browser checks, gated storage) * Fix guard topology (#918) * Use proper guard topology * Test and fixes * login and setup tests * Switch prod manager settings (#917) * Add prod guard and identity instrument info * Remove completed TODOs * Small JS tweaks (#919) * Fix type exports to built declarations * Update repository links to current package paths * Improve Next app tooling and React typings * Expose primitives CLI bin and use base lint config * Update relayer.gen.ts and TransactionPrecondition interface * Update api.gen.ts * Update metadata.gen.ts * Update marketplace.gen.ts * Update guard.gen.ts * Support multiple identity signers in sessions configuration * Device signers can approve implicit sessions * Remove invalid test * Fix recursion * Fix comment * Improve test stability by reducing race conditions * Do not set passkey signer as identity signer * Use length checks * Throw on missing identity signer * Encoding requires identity signer to encode * Fix test * Refactor/types namings tsdoc redundant code (#880) * refactor types, namings, ts doc * fix session response payload * change parameter name * change parameter name * change type in tests * improve types and dapp client methods * fix session test to use new types * refactor * refactor implicit sessions array in chain session manager * remove unused types * remove unused types and add ConnectionError * update pnpm lock * move reusable session types to wallet-core * Update some imports and update some response type names --------- Co-authored-by: Tolgahan Arikan * Fix check for explicit session for the updated type in dapp-client * Update api.gen.ts and relayer.gen.ts * Add missing chainId for dapp client event * Fix initializing new chain session manager on redirect * Add support for non-viem, custom Sequence chains (#882) * Provider sent to prepareBlankEnvelope * Add session signature decoding * const for node length * Clearer blacklist size encoding * identity signer node length * Add feeTokens endpoint to relayer (#885) * add getFeeTokens to dapp client (#889) * add getFeeTokens to dapp client * fix typo * make getFeeTokens independent of chain session manager and initialize state (#890) * make getFeeTokens independent of chain session manager and initialized state * remove getFeeTokens from chain session manager * Throw specific error when trying to sign with an expired session (#887) * Throw when supported session signer is expired * Fix tests * Make dapp-client implicit sessions chain agnostic (#893) * Add Monad, remove LAOS and Root Network * Add support for sessionless dapp connection (#896) * Refactor relayer package & update dependant packages (#891) * refactor exports for relayer (#900) * Add Arc Testnet * Fix changelog config * Sessionless connection upgrade and error handling in DappClient (#902) * dapp-client: add sessionless snapshot restore flow * Allow to logout a wallet with skipRemoveDevice even if the wallet is not in a ready state to allow force removing of wallets (#906) * Pass request to PromptCodeHandler in guard registerUI (#909) * Pass request to PromptCodeHandler in guard registerUI * Fixing guard registerUI test * guard: allow using recovery code as 2FA token (#910) * guard: allow using recovery code as 2FA token * Cleanup types of ResponseFn --------- Co-authored-by: Corban Riley * Add a way to reset 2fa when using a backup code (#911) * Add a way to reset 2fa when using a backup code * use the GuardToken type instead of breaking out the props * Add rc4 contracts * Set rc4 as default and add it to lists * Session enhanced replay protection * New sessions replay protection hashes payload * Use the 4337 factory wrapper * Update keymachine url in dapp-client constants * Update keymachine url in Provider constructor * SSR safety (#915) * Guard dapp-client for SSR (lazy transport, browser checks, gated storage) * Fix guard topology (#918) * Use proper guard topology * Test and fixes * login and setup tests * Switch prod manager settings (#917) * Add prod guard and identity instrument info * Remove completed TODOs * Small JS tweaks (#919) * Fix type exports to built declarations * Update repository links to current package paths * Improve Next app tooling and React typings * Expose primitives CLI bin and use base lint config * Update relayer.gen.ts and TransactionPrecondition interface * Update relayer.gen.ts and TransactionPrecondition interface (#920) * 3.0.0-beta.1 * identity-instrument: generate nonce from current time (#921) * Remove publish-dists.yml github action (#923) * 3.0.0-beta.2 * Clean up changeset config * Improve test stability by removing race conditions * Ensure build before test * Updating happy-dom to 20.0.10 (#926) * Add support for custom auth providers (authcode & authcode-pkce only) (#894) * Add support for custom auth providers (authcode & authcode-pkce only) * fix authcode tests * Updating Deps November 2025 (#927) * Updating deps for the workspace root * Updating deps for wallet/wdk * Fixing sessions test for latest vitest * Lets not upgrade to the latest typescript quite yet * Updating to latest vitest * Updating deps for wallet/core * Updating deps for wallet/primitives-cli * Updating deps for wallet/dapp-client * Adding syncpack to check for dep version inconsistencies * Setup syncpack versionGroups for pnpm workspace:^ * Fixing dep versions mismatches * Fixing @types/node mismatches * Adding syncpack to pre commit hook * Remove the syncpack format script. * Update ox to v9.17.0 (#928) * Upgrading ox to 9.17.0 * WrappedSignature renamed to SignatureErc6492 * Fixing PasskeySignatureValidator interface * Lock ox lib dep to use the same version with pnpm overrides and update viem to latest * Fix explicitSessionRequested check in dapp client * Typescript 5.9.3 (#930) * Upgrading to typescript v5.9.3 * Fix type errors that arose from typescript upgrade related to Bytes and Buffer source typings. * Don't catch errors thrown by Guard 2FA or reject early to allow multiple attempts on incorrect TOTP (#931) * Update pnpm * Mark @0xsequence/wallet-primitives-cli as private * 3.0.0-beta.3 * changeset cleanup * Fix rc4 4337 factory (#933) * Add rc5 and set it as default (#934) * 3.0.0-beta.4 * Update SECURITY.md Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> * Update wagmi-project/package.json Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> * Update wagmi-project/package.json Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> * Bump next from 15.5.5 to 15.5.7 (#936) Bumps [next](https://github.com/vercel/next.js) from 15.5.5 to 15.5.7. - [Release notes](https://github.com/vercel/next.js/releases) - [Changelog](https://github.com/vercel/next.js/blob/canary/release.js) - [Commits](https://github.com/vercel/next.js/compare/v15.5.5...v15.5.7) --- updated-dependencies: - dependency-name: next dependency-version: 15.5.7 dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * add userdata service client (#940) * Skip LocalDevice identity signers not on current device (#942) * Skip LocalDevice identity signers not on current device * Update log * 3.0.0-beta.5 * Update config.yml (#102) * Update config.yml Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> * Update .circleci/config.yml Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com> Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> --------- Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com> * Update config.yml (#103) * Update config.yml Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> * Update .circleci/config.yml Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com> Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> --------- Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com> * fix: extras/web/package.json to reduce vulnerabilities (#101) The following vulnerabilities are fixed with an upgrade: - https://snyk.io/vuln/SNYK-JS-NEXT-14173355 Co-authored-by: snyk-io[bot] <141718529+snyk-io[bot]@users.noreply.github.com> * fix: extras/docs/package.json to reduce vulnerabilities (#100) The following vulnerabilities are fixed with an upgrade: - https://snyk.io/vuln/SNYK-JS-NEXT-14173355 Co-authored-by: snyk-io[bot] <141718529+snyk-io[bot]@users.noreply.github.com> * fix: package.json to reduce vulnerabilities (#104) The following vulnerabilities are fixed with an upgrade: - https://snyk.io/vuln/SNYK-JS-BABELHELPERS-9397697 - https://snyk.io/vuln/SNYK-JS-BABELRUNTIME-10044504 - https://snyk.io/vuln/SNYK-JS-BRACEEXPANSION-9789073 - https://snyk.io/vuln/SNYK-JS-CROSSSPAWN-8303230 - https://snyk.io/vuln/SNYK-JS-ELLIPTIC-7577916 - https://snyk.io/vuln/SNYK-JS-ELLIPTIC-7577917 - https://snyk.io/vuln/SNYK-JS-ELLIPTIC-7577918 - https://snyk.io/vuln/SNYK-JS-ELLIPTIC-8187303 - https://snyk.io/vuln/SNYK-JS-ELLIPTIC-8720086 - https://snyk.io/vuln/SNYK-JS-IMAGESIZE-9634164 - https://snyk.io/vuln/SNYK-JS-INFLIGHT-6095116 - https://snyk.io/vuln/SNYK-JS-JSYAML-13961110 - https://snyk.io/vuln/SNYK-JS-MICROMATCH-6838728 - https://snyk.io/vuln/SNYK-JS-NODEFORGE-14114940 - https://snyk.io/vuln/SNYK-JS-NODEFORGE-14125097 - https://snyk.io/vuln/SNYK-JS-NODEFORGE-14125745 - https://snyk.io/vuln/SNYK-JS-ONHEADERS-10773729 - https://snyk.io/vuln/SNYK-JS-ROLLUP-8073097 - https://snyk.io/vuln/SNYK-JS-SECP256K1-8237220 - https://snyk.io/vuln/SNYK-JS-SEND-7926862 - https://snyk.io/vuln/SNYK-JS-SERVESTATIC-7926865 - https://snyk.io/vuln/SNYK-JS-SHAJS-12089400 Co-authored-by: snyk-io[bot] <141718529+snyk-io[bot]@users.noreply.github.com> * Revert "Merge remote-tracking branch 'origin/dependabot/npm_and_yarn/npm_and_yarn-318c02e2da'" This reverts commit fd0fdf9ecc6ad9056447e381de7fc5bb19f78e47, reversing changes made to cba78943db9942a4635bb530b7a43fc5d18b0ab4. * fix: extras/web/package.json to reduce vulnerabilities (#109) The following vulnerabilities are fixed with an upgrade: - https://snyk.io/vuln/SNYK-JS-NEXT-14173355 Co-authored-by: snyk-bot * fix: extras/docs/package.json to reduce vulnerabilities (#106) The following vulnerabilities are fixed with an upgrade: - https://snyk.io/vuln/SNYK-JS-NEXT-14400636 - https://snyk.io/vuln/SNYK-JS-NEXT-14400644 Co-authored-by: snyk-bot * Bump next in the npm_and_yarn group across 1 directory (#110) Bumps the npm_and_yarn group with 1 update in the / directory: [next](https://github.com/vercel/next.js). Updates `next` from 15.5.7 to 15.5.9 - [Release notes](https://github.com/vercel/next.js/releases) - [Changelog](https://github.com/vercel/next.js/blob/canary/release.js) - [Commits](https://github.com/vercel/next.js/compare/v15.5.7...v15.5.9) --- updated-dependencies: - dependency-name: next dependency-version: 15.5.9 dependency-type: direct:production dependency-group: npm_and_yarn ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Delete .github/workflows/fortify.yml (#111) Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> * fix: extras/web/package.json to reduce vulnerabilities (#107) The following vulnerabilities are fixed with an upgrade: - https://snyk.io/vuln/SNYK-JS-NEXT-14400636 - https://snyk.io/vuln/SNYK-JS-NEXT-14400644 Co-authored-by: snyk-bot * Bump the npm_and_yarn group across 1 directory with 3 updates (#115) Bumps the npm_and_yarn group with 1 update in the / directory: [next](https://github.com/vercel/next.js). Updates `next` from 15.5.5 to 15.5.9 - [Release notes](https://github.com/vercel/next.js/releases) - [Changelog](https://github.com/vercel/next.js/blob/canary/release.js) - [Commits](https://github.com/vercel/next.js/compare/v15.5.5...v15.5.9) Updates `happy-dom` from 17.6.3 to 20.0.11 - [Release notes](https://github.com/capricorn86/happy-dom/releases) - [Commits](https://github.com/capricorn86/happy-dom/compare/v17.6.3...v20.0.11) Updates `vite` from 7.1.10 to 7.2.7 - [Release notes](https://github.com/vitejs/vite/releases) - [Changelog](https://github.com/vitejs/vite/blob/v7.2.7/packages/vite/CHANGELOG.md) - [Commits](https://github.com/vitejs/vite/commits/v7.2.7/packages/vite) --- updated-dependencies: - dependency-name: next dependency-version: 15.5.9 dependency-type: direct:production dependency-group: npm_and_yarn - dependency-name: happy-dom dependency-version: 20.0.11 dependency-type: direct:development dependency-group: npm_and_yarn - dependency-name: vite dependency-version: 7.2.7 dependency-type: indirect dependency-group: npm_and_yarn ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump next from 15.5.7 to 15.5.9 (#944) Bumps [next](https://github.com/vercel/next.js) from 15.5.7 to 15.5.9. - [Release notes](https://github.com/vercel/next.js/releases) - [Changelog](https://github.com/vercel/next.js/blob/canary/release.js) - [Commits](https://github.com/vercel/next.js/compare/v15.5.7...v15.5.9) --- updated-dependencies: - dependency-name: next dependency-version: 15.5.9 dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Pin foundry to v1.5.0 instead of nightly (#947) * Include repo and extras in syncpack config to ensure deps are synced (#945) * Include repo and extras in syncpack config to ensure deps are synced across all * Updating support deps * Updating deps * Updating pnpm lock * Fixing type errors within wdk tests * Short circuit 404s (#949) * skip witness on signers that don't support it * add passkey to test * 3.0.0-beta.6 * Update tests.yml (#119) Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> * Update config.yml (#120) Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> * Update packages/services/identity-instrument/src/index.ts Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> * feat: upgrade @wagmi/cli from 0.1.15 to 2.8.0 (#126) Snyk has created this PR to upgrade @wagmi/cli from 0.1.15 to 2.8.0. See this package in npm: @wagmi/cli See this project in Snyk: https://app.snyk.io/org/dargon789/project/bb845543-cbee-4e11-8cf9-8bfdf9205bf1?utm_source=github&utm_medium=referral&page=upgrade-pr Co-authored-by: snyk-bot * Potential fix for code scanning alert no. 82: Workflow does not contain permissions Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> * Potential fix for code scanning alert no. 62: Information exposure through a stack trace Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> --------- Signed-off-by: dependabot[bot] Signed-off-by: AU_gdev_19 <64915515+Dargon789@users.noreply.github.com> Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> Co-authored-by: Patryk Kalinowski Co-authored-by: Corban Riley Co-authored-by: tolgahan-arikan Co-authored-by: Agusx1211 Co-authored-by: Michael Standen Co-authored-by: William Hua Co-authored-by: Michael Standen Co-authored-by: Patryk Kalinowski Co-authored-by: Taylan Pince Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Gabi <56271768+VGabriel45@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com> Co-authored-by: snyk-io[bot] <141718529+snyk-io[bot]@users.noreply.github.com> Co-authored-by: snyk-bot * Update extras/docs/package.json Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> * Update extras/web/package.json Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> --------- Signed-off-by: dependabot[bot] Signed-off-by: AU_gdev_19 <64915515+Dargon789@users.noreply.github.com> Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> Co-authored-by: Patryk Kalinowski Co-authored-by: Corban Riley Co-authored-by: tolgahan-arikan Co-authored-by: Agusx1211 Co-authored-by: Michael Standen Co-authored-by: William Hua Co-authored-by: Michael Standen Co-authored-by: Patryk Kalinowski Co-authored-by: Taylan Pince Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Gabi <56271768+VGabriel45@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com> Co-authored-by: snyk-io[bot] <141718529+snyk-io[bot]@users.noreply.github.com> Co-authored-by: snyk-bot --- .circleci/config.yml | 2 +- .github/workflows/fortify.yml | 85 ----------------------------------- wagmi-project/package.json | 6 +-- 3 files changed, 4 insertions(+), 89 deletions(-) delete mode 100644 .github/workflows/fortify.yml diff --git a/.circleci/config.yml b/.circleci/config.yml index 709c9a747..ad53a8e49 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -8,7 +8,7 @@ executors: - image: cimg/base:stable auth: # ensure you have first added these secrets - # visit app.circleci.com/settings/project/github/Dargon789/hardhat-project/environment-variables + # visit app.circleci.com/settings/project/github/Dargon789/foundry/environment-variables username: $DOCKER_HUB_USER password: $DOCKER_HUB_PASSWORD jobs: diff --git a/.github/workflows/fortify.yml b/.github/workflows/fortify.yml deleted file mode 100644 index ff1a25baf..000000000 --- a/.github/workflows/fortify.yml +++ /dev/null @@ -1,85 +0,0 @@ -# This workflow uses actions that are not certified by GitHub. -# They are provided by a third-party and are governed by -# separate terms of service, privacy policy, and support -# documentation. - -################################################################################################################################################ -# Fortify Application Security provides your team with solutions to empower DevSecOps practices, enable cloud transformation, and secure your # -# software supply chain. To learn more about Fortify, start a free trial or contact our sales team, visit fortify.com. # -# # -# Use this starter workflow as a basis for integrating Fortify Application Security Testing into your GitHub workflows. This template # -# demonstrates the steps to package the code+dependencies, initiate a scan, and optionally import SAST vulnerabilities into GitHub Security # -# Code Scanning Alerts. Additional information is available in the workflow comments and the Fortify AST Action / fcli / Fortify product # -# documentation. If you need additional assistance, please contact Fortify support. # -################################################################################################################################################ - -name: Fortify AST Scan - -# Customize trigger events based on your DevSecOps process and/or policy -on: - push: - branches: [ "master" ] - pull_request: - # The branches below must be a subset of the branches above - branches: [ "master" ] - schedule: - - cron: '31 12 * * 4' - workflow_dispatch: - -jobs: - Fortify-AST-Scan: - # Use the appropriate runner for building your source code. Ensure dev tools required to build your code are present and configured appropriately (MSBuild, Python, etc). - runs-on: ubuntu-latest - permissions: - actions: read - contents: read - security-events: write - - steps: - # Check out source code - - name: Check Out Source Code - uses: actions/checkout@v4 - - # Java is required to run the various Fortify utilities. Ensuring proper version is installed on the runner. - - name: Setup Java - uses: actions/setup-java@v4 - with: - java-version: 17 - distribution: 'temurin' - - # Perform SAST and optionally SCA scan via Fortify on Demand/Fortify Hosted/Software Security Center, then - # optionally export SAST results to the GitHub code scanning dashboard. In case further customization is - # required, you can use sub-actions like fortify/github-action/setup@v1 to set up the various Fortify tools - # and run them directly from within your pipeline; see https://github.com/fortify/github-action#readme for - # details. - - - name: Run FoD SAST Scan - uses: fortify/github-action@a92347297e02391b857e7015792cd1926a4cd418 - with: - sast-scan: true - env: - ### Required configuration when integrating with Fortify on Demand - FOD_URL: https://ams.fortify.com - FOD_TENANT: ${{secrets.FOD_TENANT}} - FOD_USER: ${{secrets.FOD_USER}} - FOD_PASSWORD: ${{secrets.FOD_PAT}} - ### Optional configuration when integrating with Fortify on Demand - # EXTRA_PACKAGE_OPTS: -oss # Extra 'scancentral package' options, like '-oss'' if - # Debricked SCA scan is enabled on Fortify on Demand - # EXTRA_FOD_LOGIN_OPTS: --socket-timeout=60s # Extra 'fcli fod session login' options - # FOD_RELEASE: MyApp:MyRelease # FoD release name, default: /:; may - # replace app+release name with numeric release ID - # DO_WAIT: true # Wait for scan completion, implied if 'DO_EXPORT: true' - # DO_EXPORT: true # Export SAST results to GitHub code scanning dashboard - ### Required configuration when integrating with Fortify Hosted / Software Security Center & ScanCentral - # SSC_URL: ${{secrets.SSC_URL}} # SSC URL - # SSC_TOKEN: ${{secrets.SSC_TOKEN}} # SSC CIToken or AutomationToken - # SC_SAST_TOKEN: ${{secrets.SC_SAST_TOKEN}} # ScanCentral SAST client auth token - # SC_SAST_SENSOR_VERSION: ${{vars.SC_SAST_SENSOR_VERSION}} # Sensor version on which to run the scan; - # usually defined as organization or repo variable - ### Optional configuration when integrating with Fortify Hosted / Software Security Center & ScanCentral - # EXTRA_SC_SAST_LOGIN_OPTS: --socket-timeout=60s # Extra 'fcli sc-sast session login' options - # SSC_APPVERSION: MyApp:MyVersion # SSC application version, default: /: - # EXTRA_PACKAGE_OPTS: -bv myCustomPom.xml # Extra 'scancentral package' options - # DO_WAIT: true # Wait for scan completion, implied if 'DO_EXPORT: true' - # DO_EXPORT: true # Export SAST results to GitHub code scanning dashboard diff --git a/wagmi-project/package.json b/wagmi-project/package.json index 206445bb3..b3a2bc03e 100644 --- a/wagmi-project/package.json +++ b/wagmi-project/package.json @@ -13,15 +13,15 @@ "@tanstack/react-query": "5.64.2", "react": "^18.3.1", "react-dom": "^18.3.1", - "viem": "latest", - "wagmi": "latest" + "viem": "^2.x", + "wagmi": "~0.x.x" }, "devDependencies": { "@biomejs/biome": "^1.8.0", "@types/react": "^18.3.1", "@types/react-dom": "^18.3.0", "@vitejs/plugin-react": "^4.2.1", - "@wagmi/cli": "latest", + "@wagmi/cli": "~2.8.0", "buffer": "^6.0.3", "typescript": "^5.4.5", "vite": "^5.2.11" From 5e6dca3ce44d2e8d5b00b1182ba9d6eae7855b23 Mon Sep 17 00:00:00 2001 From: Dargon789 <64915515+Dargon789@users.noreply.github.com> Date: Tue, 23 Dec 2025 21:23:47 +0700 Subject: [PATCH 27/39] Pin foundry to v1.5.0 instead of nightly (0xsequence#947) (#134) (#135) * Pin foundry to v1.5.0 instead of nightly (0xsequence#947) (#134) * Bump next from 15.5.7 to 15.5.9 (#944) Bumps [next](https://github.com/vercel/next.js) from 15.5.7 to 15.5.9. - [Release notes](https://github.com/vercel/next.js/releases) - [Changelog](https://github.com/vercel/next.js/blob/canary/release.js) - [Commits](https://github.com/vercel/next.js/compare/v15.5.7...v15.5.9) --- updated-dependencies: - dependency-name: next dependency-version: 15.5.9 dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Pin foundry to v1.5.0 instead of nightly (#947) * Include repo and extras in syncpack config to ensure deps are synced (#945) * Include repo and extras in syncpack config to ensure deps are synced across all * Updating support deps * Updating deps * Updating pnpm lock * Fixing type errors within wdk tests * Short circuit 404s (#949) * skip witness on signers that don't support it * add passkey to test * 3.0.0-beta.6 --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Taylan Pince Co-authored-by: Corban Riley Co-authored-by: Agusx1211 * Update packages/wallet/wdk/test/wallets.test.ts Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> * Update packages/wallet/wdk/test/wallets.test.ts Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> --------- Signed-off-by: dependabot[bot] Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Taylan Pince Co-authored-by: Corban Riley Co-authored-by: Agusx1211 Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> From 8bad845d94b7ca97a1d01a255eb8b41357eaf38d Mon Sep 17 00:00:00 2001 From: Dargon789 <64915515+Dargon789@users.noreply.github.com> Date: Wed, 24 Dec 2025 19:35:49 +0700 Subject: [PATCH 28/39] feat: upgrade react from 18.3.1 to 19.2.0 (#121) Snyk has created this PR to upgrade react from 18.3.1 to 19.2.0. See this package in npm: react See this project in Snyk: https://app.snyk.io/org/dargon789/project/bb845543-cbee-4e11-8cf9-8bfdf9205bf1?utm_source=github&utm_medium=referral&page=upgrade-pr Co-authored-by: snyk-bot --- wagmi-project/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wagmi-project/package.json b/wagmi-project/package.json index b3a2bc03e..d2a252d67 100644 --- a/wagmi-project/package.json +++ b/wagmi-project/package.json @@ -11,7 +11,7 @@ }, "dependencies": { "@tanstack/react-query": "5.64.2", - "react": "^18.3.1", + "react": "^19.2.0", "react-dom": "^18.3.1", "viem": "^2.x", "wagmi": "~0.x.x" From 1f452493d6ac5f23e20def94b7edf207bc2ce40a Mon Sep 17 00:00:00 2001 From: "snyk-io[bot]" <141718529+snyk-io[bot]@users.noreply.github.com> Date: Wed, 24 Dec 2025 21:11:40 +0700 Subject: [PATCH 29/39] fix: extras/web/package.json to reduce vulnerabilities (#117) The following vulnerabilities are fixed with an upgrade: - https://snyk.io/vuln/SNYK-JS-NEXT-14400636 - https://snyk.io/vuln/SNYK-JS-NEXT-14400644 Co-authored-by: snyk-io[bot] <141718529+snyk-io[bot]@users.noreply.github.com> Co-authored-by: dargon789 <64915515+Dargon789@users.noreply.github.com> From e90b2e6395fb14c6463a02e88f65dc23ce455d6d Mon Sep 17 00:00:00 2001 From: dargon789 <64915515+Dargon789@users.noreply.github.com> Date: Thu, 25 Dec 2025 14:15:53 +0700 Subject: [PATCH 30/39] Initial project structure and core packages Add initial monorepo structure for wagmi-project, including CLI, connectors, and core packages with source code, tests, configuration, and CI/CD workflows. This sets up the foundation for further development and collaboration. --- wagmi-project/.changeset/README.md | 8 + wagmi-project/.changeset/config.json | 19 + .../.changeset/new-elephants-travel.md | 5 + wagmi-project/.changeset/nice-pandas-clap.md | 5 + .../.changeset/quick-hairs-scream.md | 6 + wagmi-project/.changeset/spicy-bats-juggle.md | 6 + wagmi-project/.changeset/tall-fans-mate.md | 6 + wagmi-project/.changeset/tiny-laws-dream.md | 5 + wagmi-project/.changeset/young-guests-care.md | 5 + wagmi-project/.circleci/config.yml | 26 + wagmi-project/.github/CODEOWNERS | 5 + wagmi-project/.github/CONTRIBUTING.md | 1 + .../DISCUSSION_TEMPLATE/connector-request.yml | 51 + .../.github/ISSUE_TEMPLATE/bug_report.yml | 88 + .../.github/ISSUE_TEMPLATE/config.yml | 14 + .../.github/ISSUE_TEMPLATE/docs_issue.yml | 34 + wagmi-project/.github/README.md | 256 + wagmi-project/.github/SECURITY.md | 6 + wagmi-project/.github/dependabot.yml | 6 + wagmi-project/.github/logo-dark.svg | 27 + wagmi-project/.github/logo-light.svg | 27 + .../.github/pull_request_template.md | 12 + .../workflows/Vercel Preview Deployment.yml | 22 + .../.github/workflows/changesets.yml | 60 + .../.github/workflows/dependency-review.yml | 39 + .../.github/workflows/issue-labeled.yml | 19 + .../.github/workflows/jekyll-docker.yml | 23 + .../.github/workflows/lock-issue.yml | 16 + .../.github/workflows/octopusdeploy.yml | 112 + .../.github/workflows/pull-request.yml | 32 + wagmi-project/.github/workflows/release.yml | 44 + wagmi-project/.github/workflows/snapshot.yml | 32 + wagmi-project/.github/workflows/verify.yml | 127 + wagmi-project/.gitignore | 60 +- wagmi-project/.npmrc | 6 +- wagmi-project/.vscode/extensions.json | 7 + wagmi-project/.vscode/settings.json | 17 + .../.vscode/workspace.code-workspace | 16 + wagmi-project/FUNDING.json | 10 + wagmi-project/LICENSE | 21 + wagmi-project/biome.json | 80 +- wagmi-project/package.json | 149 +- wagmi-project/packages/cli/CHANGELOG.md | 449 + wagmi-project/packages/cli/README.md | 13 + wagmi-project/packages/cli/package.json | 94 + wagmi-project/packages/cli/src/cli.ts | 53 + .../cli/src/commands/generate.test.ts | 409 + .../packages/cli/src/commands/generate.ts | 409 + .../packages/cli/src/commands/init.test.ts | 189 + .../packages/cli/src/commands/init.ts | 95 + wagmi-project/packages/cli/src/config.test.ts | 39 + wagmi-project/packages/cli/src/config.ts | 121 + wagmi-project/packages/cli/src/errors.ts | 57 + .../packages/cli/src/exports/config.test.ts | 12 + .../packages/cli/src/exports/config.ts | 10 + .../packages/cli/src/exports/index.test-d.ts | 4 + .../packages/cli/src/exports/index.test.ts | 14 + .../packages/cli/src/exports/index.ts | 14 + .../packages/cli/src/exports/plugins.test.ts | 20 + .../packages/cli/src/exports/plugins.ts | 27 + wagmi-project/packages/cli/src/logger.test.ts | 32 + wagmi-project/packages/cli/src/logger.ts | 37 + .../plugins/__fixtures__/foundry/.gitignore | 11 + .../plugins/__fixtures__/foundry/foundry.toml | 7 + .../__fixtures__/foundry/src/Counter.sol | 14 + .../plugins/__fixtures__/foundry/src/Foo.sol | 11 + .../plugins/__fixtures__/hardhat/.gitignore | 10 + .../hardhat/contracts/Counter.sol | 14 + .../__fixtures__/hardhat/contracts/Foo.sol | 10 + .../__fixtures__/hardhat/hardhat.config.js | 3 + .../plugins/__fixtures__/hardhat/package.json | 7 + .../__snapshots__/blockExplorer.test.ts.snap | 736 + .../__snapshots__/etherscan.test.ts.snap | 1238 + .../plugins/__snapshots__/fetch.test.ts.snap | 367 + .../__snapshots__/sourcify.test.ts.snap | 214 + .../packages/cli/src/plugins/actions.test.ts | 359 + .../packages/cli/src/plugins/actions.ts | 321 + .../cli/src/plugins/blockExplorer.test.ts | 53 + .../packages/cli/src/plugins/blockExplorer.ts | 107 + .../cli/src/plugins/etherscan.test.ts | 112 + .../packages/cli/src/plugins/etherscan.ts | 268 + .../packages/cli/src/plugins/fetch.test.ts | 186 + .../packages/cli/src/plugins/fetch.ts | 127 + .../packages/cli/src/plugins/foundry.test.ts | 153 + .../packages/cli/src/plugins/foundry.ts | 263 + .../packages/cli/src/plugins/hardhat.test.ts | 85 + .../packages/cli/src/plugins/hardhat.ts | 235 + .../packages/cli/src/plugins/react.test.ts | 337 + .../packages/cli/src/plugins/react.ts | 312 + .../packages/cli/src/plugins/sourcify.test.ts | 83 + .../packages/cli/src/plugins/sourcify.ts | 312 + wagmi-project/packages/cli/src/types.ts | 10 + .../packages/cli/src/utils/findConfig.test.ts | 42 + .../packages/cli/src/utils/findConfig.ts | 39 + .../packages/cli/src/utils/format.test.ts | 12 + .../packages/cli/src/utils/format.ts | 17 + .../cli/src/utils/getAddressDocString.test.ts | 40 + .../cli/src/utils/getAddressDocString.ts | 53 + .../src/utils/getIsUsingTypeScript.test.ts | 43 + .../cli/src/utils/getIsUsingTypeScript.ts | 33 + .../packages/cli/src/utils/loadEnv.test.ts | 77 + .../packages/cli/src/utils/loadEnv.ts | 90 + .../packages/cli/src/utils/packages.test.ts | 19 + .../packages/cli/src/utils/packages.ts | 124 + .../cli/src/utils/resolveConfig.test.ts | 83 + .../packages/cli/src/utils/resolveConfig.ts | 21 + wagmi-project/packages/cli/src/version.ts | 1 + wagmi-project/packages/cli/test/constants.ts | 32 + wagmi-project/packages/cli/test/setup.ts | 57 + wagmi-project/packages/cli/test/utils.ts | 292 + .../packages/cli/tsconfig.build.json | 9 + wagmi-project/packages/cli/tsconfig.json | 5 + .../packages/cli/types/fixturez.d.ts | 18 + .../packages/connectors/CHANGELOG.md | 1640 ++ wagmi-project/packages/connectors/README.md | 13 + .../packages/connectors/package.json | 71 + .../connectors/src/coinbaseWallet.test.ts | 17 + .../packages/connectors/src/coinbaseWallet.ts | 546 + .../connectors/src/exports/index.test.ts | 17 + .../packages/connectors/src/exports/index.ts | 23 + .../packages/connectors/src/metaMask.test.ts | 10 + .../packages/connectors/src/metaMask.ts | 505 + .../packages/connectors/src/safe.test.ts | 23 + wagmi-project/packages/connectors/src/safe.ts | 145 + .../packages/connectors/src/version.ts | 1 + .../connectors/src/walletConnect.test.ts | 67 + .../packages/connectors/src/walletConnect.ts | 468 + .../packages/connectors/tsconfig.build.json | 8 + .../packages/connectors/tsconfig.json | 5 + wagmi-project/packages/core/CHANGELOG.md | 3365 +++ wagmi-project/packages/core/README.md | 13 + wagmi-project/packages/core/package.json | 100 + .../packages/core/src/actions/call.test.ts | 149 + .../packages/core/src/actions/call.ts | 27 + .../codegen/createReadContract.test-d.ts | 130 + .../codegen/createReadContract.test.ts | 50 + .../src/actions/codegen/createReadContract.ts | 100 + .../codegen/createSimulateContract.test-d.ts | 211 + .../codegen/createSimulateContract.test.ts | 137 + .../actions/codegen/createSimulateContract.ts | 122 + .../createWatchContractEvent.test-d.ts | 123 + .../codegen/createWatchContractEvent.test.ts | 41 + .../codegen/createWatchContractEvent.ts | 88 + .../codegen/createWriteContract.test-d.ts | 129 + .../codegen/createWriteContract.test.ts | 11 + .../actions/codegen/createWriteContract.ts | 145 + .../core/src/actions/connect.test-d.ts | 48 + .../packages/core/src/actions/connect.test.ts | 71 + .../packages/core/src/actions/connect.ts | 110 + .../core/src/actions/deployContract.test-d.ts | 71 + .../core/src/actions/deployContract.test.ts | 67 + .../core/src/actions/deployContract.ts | 87 + .../core/src/actions/disconnect.test.ts | 33 + .../packages/core/src/actions/disconnect.ts | 71 + .../src/actions/estimateFeesPerGas.test-d.ts | 41 + .../src/actions/estimateFeesPerGas.test.ts | 16 + .../core/src/actions/estimateFeesPerGas.ts | 87 + .../core/src/actions/estimateGas.test-d.ts | 47 + .../core/src/actions/estimateGas.test.ts | 47 + .../packages/core/src/actions/estimateGas.ts | 73 + .../estimateMaxPriorityFeePerGas.test.ts | 16 + .../actions/estimateMaxPriorityFeePerGas.ts | 49 + .../core/src/actions/getAccount.test-d.ts | 69 + .../core/src/actions/getAccount.test.ts | 37 + .../packages/core/src/actions/getAccount.ts | 126 + .../core/src/actions/getBalance.test.ts | 102 + .../packages/core/src/actions/getBalance.ts | 149 + .../core/src/actions/getBlock.test-d.ts | 35 + .../core/src/actions/getBlock.test.ts | 153 + .../packages/core/src/actions/getBlock.ts | 74 + .../core/src/actions/getBlockNumber.test.ts | 8 + .../core/src/actions/getBlockNumber.ts | 36 + .../actions/getBlockTransactionCount.test.ts | 61 + .../src/actions/getBlockTransactionCount.ts | 44 + .../core/src/actions/getBytecode.test.ts | 45 + .../packages/core/src/actions/getBytecode.ts | 30 + .../core/src/actions/getCallsStatus.test.ts | 70 + .../core/src/actions/getCallsStatus.ts | 27 + .../core/src/actions/getCapabilities.test.ts | 64 + .../core/src/actions/getCapabilities.ts | 39 + .../core/src/actions/getChainId.test.ts | 10 + .../packages/core/src/actions/getChainId.ts | 11 + .../core/src/actions/getChains.test-d.ts | 12 + .../core/src/actions/getChains.test.ts | 14 + .../packages/core/src/actions/getChains.ts | 21 + .../core/src/actions/getClient.test-d.ts | 27 + .../core/src/actions/getClient.test.ts | 17 + .../packages/core/src/actions/getClient.ts | 52 + .../core/src/actions/getConnections.test.ts | 15 + .../core/src/actions/getConnections.ts | 16 + .../src/actions/getConnectorClient.test-d.ts | 19 + .../src/actions/getConnectorClient.test.ts | 106 + .../core/src/actions/getConnectorClient.ts | 147 + .../core/src/actions/getConnectors.test.ts | 8 + .../core/src/actions/getConnectors.ts | 17 + .../core/src/actions/getEnsAddress.test.ts | 12 + .../core/src/actions/getEnsAddress.ts | 30 + .../core/src/actions/getEnsAvatar.test.ts | 12 + .../packages/core/src/actions/getEnsAvatar.ts | 30 + .../core/src/actions/getEnsName.test.ts | 12 + .../packages/core/src/actions/getEnsName.ts | 30 + .../core/src/actions/getEnsResolver.test.ts | 14 + .../core/src/actions/getEnsResolver.ts | 30 + .../core/src/actions/getEnsText.test.ts | 13 + .../packages/core/src/actions/getEnsText.ts | 30 + .../core/src/actions/getFeeHistory.test.ts | 63 + .../core/src/actions/getFeeHistory.ts | 36 + .../core/src/actions/getGasPrice.test.ts | 21 + .../packages/core/src/actions/getGasPrice.ts | 35 + .../core/src/actions/getProof.test.ts | 16 + .../packages/core/src/actions/getProof.ts | 30 + .../src/actions/getPublicClient.test-d.ts | 27 + .../core/src/actions/getPublicClient.test.ts | 17 + .../core/src/actions/getPublicClient.ts | 52 + .../core/src/actions/getStorageAt.test.ts | 59 + .../packages/core/src/actions/getStorageAt.ts | 30 + .../core/src/actions/getToken.test.ts | 84 + .../packages/core/src/actions/getToken.ts | 141 + .../core/src/actions/getTransaction.test-d.ts | 29 + .../core/src/actions/getTransaction.test.ts | 36 + .../core/src/actions/getTransaction.ts | 51 + .../getTransactionConfirmations.test-d.ts | 85 + .../getTransactionConfirmations.test.ts | 25 + .../actions/getTransactionConfirmations.ts | 52 + .../src/actions/getTransactionCount.test.ts | 50 + .../core/src/actions/getTransactionCount.ts | 34 + .../actions/getTransactionReceipt.test-d.ts | 36 + .../src/actions/getTransactionReceipt.test.ts | 35 + .../core/src/actions/getTransactionReceipt.ts | 57 + .../src/actions/getWalletClient.test-d.ts | 22 + .../core/src/actions/getWalletClient.test.ts | 24 + .../core/src/actions/getWalletClient.ts | 50 + .../core/src/actions/multicall.test-d.ts | 106 + .../core/src/actions/multicall.test.ts | 46 + .../packages/core/src/actions/multicall.ts | 42 + .../prepareTransactionRequest.test-d.ts | 80 + .../actions/prepareTransactionRequest.test.ts | 108 + .../src/actions/prepareTransactionRequest.ts | 125 + .../core/src/actions/readContract.test-d.ts | 74 + .../core/src/actions/readContract.test.ts | 37 + .../packages/core/src/actions/readContract.ts | 58 + .../core/src/actions/readContracts.test-d.ts | 118 + .../core/src/actions/readContracts.test.ts | 678 + .../core/src/actions/readContracts.ts | 96 + .../core/src/actions/reconnect.test.ts | 119 + .../packages/core/src/actions/reconnect.ts | 127 + .../core/src/actions/sendCalls.test.ts | 121 + .../packages/core/src/actions/sendCalls.ts | 74 + .../src/actions/sendTransaction.test-d.ts | 50 + .../core/src/actions/sendTransaction.test.ts | 105 + .../core/src/actions/sendTransaction.ts | 86 + .../core/src/actions/showCallsStatus.test.ts | 36 + .../core/src/actions/showCallsStatus.ts | 27 + .../core/src/actions/signMessage.test.ts | 67 + .../packages/core/src/actions/signMessage.ts | 51 + .../core/src/actions/signTypedData.test-d.ts | 31 + .../core/src/actions/signTypedData.test.ts | 85 + .../core/src/actions/signTypedData.ts | 60 + .../src/actions/simulateContract.test-d.ts | 160 + .../core/src/actions/simulateContract.test.ts | 84 + .../core/src/actions/simulateContract.ts | 166 + .../core/src/actions/switchAccount.test.ts | 32 + .../core/src/actions/switchAccount.ts | 45 + .../core/src/actions/switchChain.test.ts | 73 + .../packages/core/src/actions/switchChain.ts | 83 + .../core/src/actions/verifyMessage.test.ts | 72 + .../core/src/actions/verifyMessage.ts | 30 + .../core/src/actions/verifyTypedData.test.ts | 42 + .../core/src/actions/verifyTypedData.ts | 40 + .../src/actions/waitForCallsStatus.test.ts | 77 + .../core/src/actions/waitForCallsStatus.ts | 27 + .../waitForTransactionReceipt.test-d.ts | 36 + .../actions/waitForTransactionReceipt.test.ts | 58 + .../src/actions/waitForTransactionReceipt.ts | 86 + .../core/src/actions/watchAccount.test.ts | 38 + .../packages/core/src/actions/watchAccount.ts | 33 + .../core/src/actions/watchAsset.test.ts | 23 + .../packages/core/src/actions/watchAsset.ts | 44 + .../src/actions/watchBlockNumber.test-d.ts | 56 + .../core/src/actions/watchBlockNumber.test.ts | 27 + .../core/src/actions/watchBlockNumber.ts | 78 + .../core/src/actions/watchBlocks.test-d.ts | 59 + .../core/src/actions/watchBlocks.test.ts | 30 + .../packages/core/src/actions/watchBlocks.ts | 90 + .../core/src/actions/watchChainId.test.ts | 26 + .../packages/core/src/actions/watchChainId.ts | 20 + .../core/src/actions/watchChains.test.ts | 37 + .../packages/core/src/actions/watchChains.ts | 29 + .../core/src/actions/watchClient.test-d.ts | 15 + .../core/src/actions/watchClient.test.ts | 23 + .../packages/core/src/actions/watchClient.ts | 35 + .../core/src/actions/watchConnections.test.ts | 25 + .../core/src/actions/watchConnections.ts | 26 + .../core/src/actions/watchConnectors.test.ts | 27 + .../core/src/actions/watchConnectors.ts | 22 + .../src/actions/watchContractEvent.test-d.ts | 142 + .../src/actions/watchContractEvent.test.ts | 96 + .../core/src/actions/watchContractEvent.ts | 102 + .../watchPendingTransactions.test-d.ts | 56 + .../actions/watchPendingTransactions.test.ts | 49 + .../src/actions/watchPendingTransactions.ts | 82 + .../src/actions/watchPublicClient.test-d.ts | 15 + .../src/actions/watchPublicClient.test.ts | 23 + .../core/src/actions/watchPublicClient.ts | 38 + .../core/src/actions/writeContract.test-d.ts | 152 + .../core/src/actions/writeContract.ts | 114 + .../src/connectors/createConnector.test.ts | 31 + .../core/src/connectors/createConnector.ts | 93 + .../core/src/connectors/injected.test.ts | 25 + .../packages/core/src/connectors/injected.ts | 697 + .../packages/core/src/connectors/mock.test.ts | 112 + .../packages/core/src/connectors/mock.ts | 315 + .../packages/core/src/createConfig.test-d.ts | 110 + .../packages/core/src/createConfig.test.ts | 440 + .../packages/core/src/createConfig.ts | 653 + .../packages/core/src/createEmitter.test.ts | 19 + .../packages/core/src/createEmitter.ts | 68 + .../packages/core/src/createStorage.test-d.ts | 74 + .../packages/core/src/createStorage.test.ts | 45 + .../packages/core/src/createStorage.ts | 112 + .../packages/core/src/errors/base.test.ts | 155 + .../packages/core/src/errors/base.ts | 74 + .../packages/core/src/errors/config.test.ts | 68 + .../packages/core/src/errors/config.ts | 103 + .../core/src/errors/connector.test.ts | 24 + .../packages/core/src/errors/connector.ts | 23 + .../actions/writeContracts.test.ts | 99 + .../experimental/actions/writeContracts.ts | 78 + .../experimental/query/writeContracts.test.ts | 15 + .../src/experimental/query/writeContracts.ts | 70 + .../packages/core/src/exports/actions.test.ts | 86 + .../packages/core/src/exports/actions.ts | 460 + .../packages/core/src/exports/chains.ts | 7 + .../packages/core/src/exports/codegen.test.ts | 14 + .../packages/core/src/exports/codegen.ts | 24 + .../packages/core/src/exports/experimental.ts | 158 + .../packages/core/src/exports/index.test.ts | 117 + .../packages/core/src/exports/index.ts | 594 + .../core/src/exports/internal.test.ts | 15 + .../packages/core/src/exports/internal.ts | 52 + .../packages/core/src/exports/query.test.ts | 97 + .../packages/core/src/exports/query.ts | 434 + .../packages/core/src/hydrate.test.ts | 114 + wagmi-project/packages/core/src/hydrate.ts | 62 + .../packages/core/src/query/call.test.ts | 306 + wagmi-project/packages/core/src/query/call.ts | 51 + .../packages/core/src/query/connect.test.ts | 15 + .../packages/core/src/query/connect.ts | 70 + .../core/src/query/deployContract.test.ts | 15 + .../packages/core/src/query/deployContract.ts | 73 + .../core/src/query/disconnect.test.ts | 15 + .../packages/core/src/query/disconnect.ts | 43 + .../core/src/query/estimateFeesPerGas.test.ts | 32 + .../core/src/query/estimateFeesPerGas.ts | 56 + .../core/src/query/estimateGas.test-d.ts | 55 + .../core/src/query/estimateGas.test.ts | 25 + .../packages/core/src/query/estimateGas.ts | 56 + .../estimateMaxPriorityFeePerGas.test.ts | 36 + .../src/query/estimateMaxPriorityFeePerGas.ts | 51 + .../core/src/query/getBalance.test.ts | 63 + .../packages/core/src/query/getBalance.ts | 53 + .../packages/core/src/query/getBlock.test.ts | 32 + .../packages/core/src/query/getBlock.ts | 84 + .../core/src/query/getBlockNumber.test.ts | 34 + .../packages/core/src/query/getBlockNumber.ts | 55 + .../query/getBlockTransactionCount.test.ts | 50 + .../src/query/getBlockTransactionCount.ts | 62 + .../core/src/query/getBytecode.test.ts | 82 + .../packages/core/src/query/getBytecode.ts | 49 + .../core/src/query/getCallsStatus.test.ts | 23 + .../packages/core/src/query/getCallsStatus.ts | 50 + .../core/src/query/getCapabilities.test.ts | 36 + .../core/src/query/getCapabilities.ts | 65 + .../core/src/query/getConnectorClient.test.ts | 37 + .../core/src/query/getConnectorClient.ts | 69 + .../core/src/query/getEnsAddress.test.ts | 32 + .../packages/core/src/query/getEnsAddress.ts | 49 + .../core/src/query/getEnsAvatar.test.ts | 32 + .../packages/core/src/query/getEnsAvatar.ts | 49 + .../core/src/query/getEnsName.test.ts | 32 + .../packages/core/src/query/getEnsName.ts | 49 + .../core/src/query/getEnsResolver.test.ts | 32 + .../packages/core/src/query/getEnsResolver.ts | 49 + .../core/src/query/getEnsText.test.ts | 46 + .../packages/core/src/query/getEnsText.ts | 49 + .../core/src/query/getFeeHistory.test.ts | 128 + .../packages/core/src/query/getFeeHistory.ts | 69 + .../core/src/query/getGasPrice.test.ts | 32 + .../packages/core/src/query/getGasPrice.ts | 54 + .../packages/core/src/query/getProof.test.ts | 106 + .../packages/core/src/query/getProof.ts | 50 + .../core/src/query/getStorageAt.test.ts | 90 + .../packages/core/src/query/getStorageAt.ts | 49 + .../packages/core/src/query/getToken.test.ts | 32 + .../packages/core/src/query/getToken.ts | 49 + .../core/src/query/getTransaction.test.ts | 32 + .../packages/core/src/query/getTransaction.ts | 69 + .../query/getTransactionConfirmations.test.ts | 42 + .../src/query/getTransactionConfirmations.ts | 78 + .../src/query/getTransactionCount.test.ts | 82 + .../core/src/query/getTransactionCount.ts | 55 + .../src/query/getTransactionReceipt.test.ts | 42 + .../core/src/query/getTransactionReceipt.ts | 60 + .../core/src/query/getWalletClient.test.ts | 37 + .../core/src/query/getWalletClient.ts | 65 + .../src/query/infiniteReadContracts.test-d.ts | 201 + .../src/query/infiniteReadContracts.test.ts | 60 + .../core/src/query/infiniteReadContracts.ts | 127 + .../query/prepareTransactionRequest.test.ts | 241 + .../src/query/prepareTransactionRequest.ts | 101 + .../core/src/query/readContract.test-d.ts | 15 + .../core/src/query/readContract.test.ts | 29 + .../packages/core/src/query/readContract.ts | 93 + .../core/src/query/readContracts.test-d.ts | 58 + .../core/src/query/readContracts.test.ts | 38 + .../packages/core/src/query/readContracts.ts | 98 + .../packages/core/src/query/reconnect.test.ts | 15 + .../packages/core/src/query/reconnect.ts | 42 + .../packages/core/src/query/sendCalls.test.ts | 15 + .../packages/core/src/query/sendCalls.ts | 67 + .../core/src/query/sendTransaction.test.ts | 15 + .../core/src/query/sendTransaction.ts | 65 + .../core/src/query/showCallsStatus.test.ts | 15 + .../core/src/query/showCallsStatus.ts | 57 + .../core/src/query/signMessage.test.ts | 15 + .../packages/core/src/query/signMessage.ts | 42 + .../core/src/query/signTypedData.test.ts | 15 + .../packages/core/src/query/signTypedData.ts | 75 + .../core/src/query/simulateContract.test-d.ts | 81 + .../core/src/query/simulateContract.test.ts | 31 + .../core/src/query/simulateContract.ts | 132 + .../core/src/query/switchAccount.test.ts | 15 + .../packages/core/src/query/switchAccount.ts | 52 + .../core/src/query/switchChain.test.ts | 15 + .../packages/core/src/query/switchChain.ts | 67 + .../packages/core/src/query/types.ts | 84 + .../packages/core/src/query/utils.test.ts | 20 + .../packages/core/src/query/utils.ts | 73 + .../core/src/query/verifyMessage.test.ts | 104 + .../packages/core/src/query/verifyMessage.ts | 56 + .../core/src/query/verifyTypedData.test.ts | 284 + .../core/src/query/verifyTypedData.ts | 82 + .../core/src/query/waitForCallsStatus.test.ts | 23 + .../core/src/query/waitForCallsStatus.ts | 53 + .../query/waitForTransactionReceipt.test.ts | 18 + .../src/query/waitForTransactionReceipt.ts | 71 + .../core/src/query/watchAsset.test.ts | 15 + .../packages/core/src/query/watchAsset.ts | 42 + .../core/src/query/writeContract.test-d.ts | 145 + .../core/src/query/writeContract.test.ts | 15 + .../packages/core/src/query/writeContract.ts | 116 + .../core/src/transports/connector.test.ts | 97 + .../packages/core/src/transports/connector.ts | 87 + .../core/src/transports/fallback.test.ts | 63 + .../packages/core/src/transports/fallback.ts | 10 + .../packages/core/src/types/chain.test-d.ts | 33 + .../packages/core/src/types/chain.ts | 26 + .../packages/core/src/types/properties.ts | 23 + .../packages/core/src/types/register.ts | 9 + wagmi-project/packages/core/src/types/unit.ts | 1 + .../packages/core/src/types/utils.test-d.ts | 40 + .../packages/core/src/types/utils.ts | 101 + .../packages/core/src/utils/cookie.test.ts | 69 + .../packages/core/src/utils/cookie.ts | 33 + .../packages/core/src/utils/deepEqual.test.ts | 40 + .../packages/core/src/utils/deepEqual.ts | 43 + .../core/src/utils/deserialize.test.ts | 114 + .../packages/core/src/utils/deserialize.ts | 10 + .../core/src/utils/extractRpcUrls.test.ts | 92 + .../packages/core/src/utils/extractRpcUrls.ts | 19 + .../packages/core/src/utils/getAction.test.ts | 49 + .../packages/core/src/utils/getAction.ts | 44 + .../packages/core/src/utils/getUnit.test.ts | 9 + .../packages/core/src/utils/getUnit.ts | 9 + .../core/src/utils/getVersion.test.ts | 7 + .../packages/core/src/utils/getVersion.ts | 3 + .../core/src/utils/normalizeChainId.test.ts | 24 + .../core/src/utils/normalizeChainId.ts | 13 + .../packages/core/src/utils/serialize.test.ts | 241 + .../packages/core/src/utils/serialize.ts | 116 + wagmi-project/packages/core/src/utils/uid.ts | 14 + wagmi-project/packages/core/src/version.ts | 1 + wagmi-project/packages/core/test/setup.ts | 5 + .../packages/core/tsconfig.build.json | 8 + wagmi-project/packages/core/tsconfig.json | 5 + .../packages/create-wagmi/CHANGELOG.md | 278 + wagmi-project/packages/create-wagmi/README.md | 17 + .../packages/create-wagmi/package.json | 49 + .../packages/create-wagmi/src/cli.test.ts | 151 + .../packages/create-wagmi/src/cli.ts | 284 + .../packages/create-wagmi/src/frameworks.ts | 66 + .../packages/create-wagmi/src/index.test-d.ts | 4 + .../packages/create-wagmi/src/utils.ts | 79 + .../packages/create-wagmi/src/version.ts | 1 + .../create-wagmi/templates/next/README.md | 1 + .../create-wagmi/templates/next/_env.local | 2 + .../create-wagmi/templates/next/_gitignore | 35 + .../create-wagmi/templates/next/_npmrc | 1 + .../create-wagmi/templates/next/next-env.d.ts | 5 + .../templates/next/next.config.js | 4 + .../create-wagmi/templates/next/package.json | 32 + .../templates/next/src/app/globals.css | 21 + .../templates/next/src/app/layout.tsx | 30 + .../templates/next/src/app/page.tsx | 48 + .../templates/next/src/app/providers.tsx | 23 + .../create-wagmi/templates/next/src/wagmi.ts | 28 + .../create-wagmi/templates/next/tsconfig.json | 27 + .../create-wagmi/templates/nuxt/_env.local | 3 + .../create-wagmi/templates/nuxt/_gitignore | 24 + .../create-wagmi/templates/nuxt/_npmrc | 2 + .../create-wagmi/templates/nuxt/app.vue | 28 + .../templates/nuxt/components/Account.vue | 22 + .../templates/nuxt/components/Connect.vue | 19 + .../templates/nuxt/nuxt.config.ts | 7 + .../create-wagmi/templates/nuxt/package.json | 21 + .../templates/nuxt/plugins/wagmi.ts | 10 + .../templates/nuxt/server/tsconfig.json | 3 + .../create-wagmi/templates/nuxt/tsconfig.json | 4 + .../create-wagmi/templates/nuxt/wagmi.ts | 29 + .../templates/vite-react/README.md | 1 + .../templates/vite-react/_env.local | 1 + .../templates/vite-react/_gitignore | 24 + .../create-wagmi/templates/vite-react/_npmrc | 1 + .../templates/vite-react/biome.json | 13 + .../templates/vite-react/index.html | 12 + .../templates/vite-react/package.json | 29 + .../templates/vite-react/src/App.tsx | 46 + .../templates/vite-react/src/index.css | 21 + .../templates/vite-react/src/main.tsx | 24 + .../templates/vite-react/src/vite-env.d.ts | 1 + .../templates/vite-react/src/wagmi.ts | 22 + .../templates/vite-react/tsconfig.json | 25 + .../templates/vite-react/tsconfig.node.json | 10 + .../templates/vite-react/vite.config.ts | 7 + .../templates/vite-vanilla/_env.local | 1 + .../templates/vite-vanilla/_gitignore | 24 + .../templates/vite-vanilla/_npmrc | 1 + .../templates/vite-vanilla/index.html | 12 + .../templates/vite-vanilla/package.json | 24 + .../templates/vite-vanilla/src/main.ts | 89 + .../templates/vite-vanilla/src/style.css | 21 + .../templates/vite-vanilla/src/vite-env.d.ts | 1 + .../templates/vite-vanilla/src/wagmi.ts | 16 + .../templates/vite-vanilla/tsconfig.json | 23 + .../create-wagmi/templates/vite-vue/README.md | 1 + .../templates/vite-vue/_env.local | 1 + .../templates/vite-vue/_gitignore | 24 + .../create-wagmi/templates/vite-vue/_npmrc | 1 + .../templates/vite-vue/biome.json | 13 + .../templates/vite-vue/index.html | 12 + .../templates/vite-vue/package.json | 24 + .../templates/vite-vue/src/App.vue | 19 + .../vite-vue/src/components/Account.vue | 22 + .../vite-vue/src/components/Connect.vue | 19 + .../templates/vite-vue/src/main.ts | 17 + .../templates/vite-vue/src/style.css | 21 + .../templates/vite-vue/src/vite-env.d.ts | 1 + .../templates/vite-vue/src/wagmi.ts | 25 + .../templates/vite-vue/tsconfig.json | 25 + .../templates/vite-vue/tsconfig.node.json | 11 + .../templates/vite-vue/vite.config.ts | 7 + .../packages/create-wagmi/tsconfig.build.json | 8 + .../packages/create-wagmi/tsconfig.json | 5 + wagmi-project/packages/react/CHANGELOG.md | 5037 ++++ wagmi-project/packages/react/README.md | 13 + wagmi-project/packages/react/package.json | 119 + .../packages/react/src/context.test.tsx | 101 + wagmi-project/packages/react/src/context.ts | 28 + .../packages/react/src/errors/base.test.ts | 155 + .../packages/react/src/errors/base.ts | 14 + .../packages/react/src/errors/context.test.ts | 12 + .../packages/react/src/errors/context.ts | 13 + .../hooks/useWriteContracts.test.ts | 45 + .../experimental/hooks/useWriteContracts.ts | 85 + .../react/src/exports/actions.test.ts | 86 + .../packages/react/src/exports/actions.ts | 7 + .../src/exports/actions/experimental.test.ts | 25 + .../react/src/exports/actions/experimental.ts | 7 + .../packages/react/src/exports/chains.ts | 7 + .../react/src/exports/codegen.test.ts | 18 + .../packages/react/src/exports/codegen.ts | 35 + .../react/src/exports/connectors.test.ts | 17 + .../packages/react/src/exports/connectors.ts | 7 + .../react/src/exports/experimental.ts | 58 + .../packages/react/src/exports/index.test.ts | 111 + .../packages/react/src/exports/index.ts | 487 + .../packages/react/src/exports/query.test.ts | 100 + .../packages/react/src/exports/query.ts | 19 + .../codegen/createUseReadContract.test-d.ts | 152 + .../codegen/createUseReadContract.test.ts | 177 + .../hooks/codegen/createUseReadContract.ts | 127 + .../createUseSimulateContract.test-d.ts | 199 + .../codegen/createUseSimulateContract.test.ts | 258 + .../codegen/createUseSimulateContract.ts | 120 + .../createUseWatchContractEvent.test-d.ts | 123 + .../createUseWatchContractEvent.test.ts | 44 + .../codegen/createUseWatchContractEvent.ts | 101 + .../codegen/createUseWriteContract.test-d.ts | 153 + .../codegen/createUseWriteContract.test.ts | 13 + .../hooks/codegen/createUseWriteContract.ts | 297 + .../react/src/hooks/useAccount.test-d.ts | 68 + .../react/src/hooks/useAccount.test.ts | 29 + .../packages/react/src/hooks/useAccount.ts | 31 + .../react/src/hooks/useAccountEffect.test.ts | 77 + .../react/src/hooks/useAccountEffect.ts | 62 + .../react/src/hooks/useBalance.test-d.ts | 14 + .../react/src/hooks/useBalance.test.ts | 312 + .../packages/react/src/hooks/useBalance.ts | 54 + .../react/src/hooks/useBlock.test-d.ts | 64 + .../packages/react/src/hooks/useBlock.test.ts | 67 + .../packages/react/src/hooks/useBlock.ts | 131 + .../react/src/hooks/useBlockNumber.test-d.ts | 65 + .../react/src/hooks/useBlockNumber.test.ts | 68 + .../react/src/hooks/useBlockNumber.ts | 97 + .../hooks/useBlockTransactionCount.test-d.ts | 14 + .../hooks/useBlockTransactionCount.test.ts | 231 + .../src/hooks/useBlockTransactionCount.ts | 67 + .../react/src/hooks/useBytecode.test-d.ts | 15 + .../react/src/hooks/useBytecode.test.ts | 291 + .../packages/react/src/hooks/useBytecode.ts | 57 + .../react/src/hooks/useCall.test-d.ts | 14 + .../packages/react/src/hooks/useCall.test.ts | 224 + .../packages/react/src/hooks/useCall.ts | 55 + .../react/src/hooks/useCallsStatus.test.ts | 101 + .../react/src/hooks/useCallsStatus.ts | 52 + .../react/src/hooks/useCapabilities.test.ts | 167 + .../react/src/hooks/useCapabilities.ts | 62 + .../react/src/hooks/useChainId.test-d.ts | 14 + .../react/src/hooks/useChainId.test.ts | 24 + .../packages/react/src/hooks/useChainId.ts | 32 + .../react/src/hooks/useChains.test.ts | 31 + .../packages/react/src/hooks/useChains.ts | 32 + .../react/src/hooks/useClient.test-d.ts | 40 + .../react/src/hooks/useClient.test.ts | 30 + .../packages/react/src/hooks/useClient.ts | 49 + .../react/src/hooks/useConfig.test-d.ts | 16 + .../react/src/hooks/useConfig.test.ts | 23 + .../packages/react/src/hooks/useConfig.ts | 22 + .../react/src/hooks/useConnect.test-d.ts | 124 + .../react/src/hooks/useConnect.test.ts | 35 + .../packages/react/src/hooks/useConnect.ts | 90 + .../react/src/hooks/useConnections.test.ts | 25 + .../react/src/hooks/useConnections.ts | 28 + .../src/hooks/useConnectorClient.test-d.ts | 12 + .../src/hooks/useConnectorClient.test.tsx | 239 + .../react/src/hooks/useConnectorClient.ts | 113 + .../react/src/hooks/useConnectors.test.ts | 30 + .../packages/react/src/hooks/useConnectors.ts | 34 + .../src/hooks/useDeployContract.test-d.ts | 105 + .../react/src/hooks/useDeployContract.test.ts | 24 + .../react/src/hooks/useDeployContract.ts | 78 + .../react/src/hooks/useDisconnect.test-d.ts | 87 + .../react/src/hooks/useDisconnect.test.ts | 32 + .../packages/react/src/hooks/useDisconnect.ts | 70 + .../react/src/hooks/useEnsAddress.test.ts | 50 + .../packages/react/src/hooks/useEnsAddress.ts | 58 + .../react/src/hooks/useEnsAvatar.test.ts | 50 + .../packages/react/src/hooks/useEnsAvatar.ts | 58 + .../react/src/hooks/useEnsName.test.ts | 50 + .../packages/react/src/hooks/useEnsName.ts | 54 + .../react/src/hooks/useEnsResolver.test.ts | 50 + .../react/src/hooks/useEnsResolver.ts | 58 + .../react/src/hooks/useEnsText.test.ts | 150 + .../packages/react/src/hooks/useEnsText.ts | 54 + .../src/hooks/useEstimateFeesPerGas.test-d.ts | 49 + .../src/hooks/useEstimateFeesPerGas.test.ts | 19 + .../react/src/hooks/useEstimateFeesPerGas.ts | 62 + .../react/src/hooks/useEstimateGas.test-d.ts | 14 + .../react/src/hooks/useEstimateGas.test.ts | 139 + .../react/src/hooks/useEstimateGas.ts | 70 + .../useEstimateMaxPriorityFeePerGas.test-d.ts | 13 + .../useEstimateMaxPriorityFeePerGas.test.ts | 96 + .../hooks/useEstimateMaxPriorityFeePerGas.ts | 61 + .../react/src/hooks/useFeeHistory.test-d.ts | 14 + .../react/src/hooks/useFeeHistory.test.ts | 452 + .../packages/react/src/hooks/useFeeHistory.ts | 64 + .../react/src/hooks/useGasPrice.test-d.ts | 14 + .../react/src/hooks/useGasPrice.test.ts | 103 + .../packages/react/src/hooks/useGasPrice.ts | 62 + .../hooks/useInfiniteReadContracts.test-d.ts | 44 + .../hooks/useInfiniteReadContracts.test.ts | 91 + .../src/hooks/useInfiniteReadContracts.ts | 89 + .../usePrepareTransactionRequest.test-d.ts | 27 + .../usePrepareTransactionRequest.test.ts | 81 + .../src/hooks/usePrepareTransactionRequest.ts | 102 + .../react/src/hooks/useProof.test-d.ts | 14 + .../packages/react/src/hooks/useProof.test.ts | 163 + .../packages/react/src/hooks/useProof.ts | 56 + .../react/src/hooks/usePublicClient.test-d.ts | 40 + .../react/src/hooks/usePublicClient.test.ts | 30 + .../react/src/hooks/usePublicClient.ts | 51 + .../react/src/hooks/useReadContract.test-d.ts | 96 + .../react/src/hooks/useReadContract.test.ts | 194 + .../react/src/hooks/useReadContract.ts | 99 + .../src/hooks/useReadContracts.test-d.ts | 93 + .../react/src/hooks/useReadContracts.test.ts | 262 + .../react/src/hooks/useReadContracts.ts | 91 + .../react/src/hooks/useReconnect.test-d.ts | 154 + .../react/src/hooks/useReconnect.test.ts | 83 + .../packages/react/src/hooks/useReconnect.ts | 67 + .../react/src/hooks/useSendCalls.test.ts | 44 + .../packages/react/src/hooks/useSendCalls.ts | 75 + .../src/hooks/useSendTransaction.test-d.ts | 78 + .../src/hooks/useSendTransaction.test.ts | 25 + .../react/src/hooks/useSendTransaction.ts | 79 + .../react/src/hooks/useShowCallsStatus.ts | 76 + .../react/src/hooks/useSignMessage.test-d.ts | 62 + .../react/src/hooks/useSignMessage.test.ts | 43 + .../react/src/hooks/useSignMessage.ts | 65 + .../src/hooks/useSignTypedData.test-d.ts | 93 + .../react/src/hooks/useSignTypedData.test.ts | 56 + .../react/src/hooks/useSignTypedData.ts | 66 + .../src/hooks/useSimulateContract.test-d.ts | 104 + .../src/hooks/useSimulateContract.test.ts | 95 + .../react/src/hooks/useSimulateContract.ts | 117 + .../react/src/hooks/useStorageAt.test-d.ts | 15 + .../react/src/hooks/useStorageAt.test.ts | 299 + .../packages/react/src/hooks/useStorageAt.ts | 57 + .../src/hooks/useSwitchAccount.test-d.ts | 87 + .../react/src/hooks/useSwitchAccount.test.ts | 44 + .../react/src/hooks/useSwitchAccount.ts | 84 + .../react/src/hooks/useSwitchChain.test-d.ts | 118 + .../react/src/hooks/useSwitchChain.test.ts | 114 + .../react/src/hooks/useSwitchChain.ts | 82 + .../useSyncExternalStoreWithTracked.test.tsx | 275 + .../hooks/useSyncExternalStoreWithTracked.ts | 67 + .../react/src/hooks/useToken.test-d.ts | 14 + .../packages/react/src/hooks/useToken.test.ts | 59 + .../packages/react/src/hooks/useToken.ts | 60 + .../react/src/hooks/useTransaction.test-d.ts | 14 + .../react/src/hooks/useTransaction.test.ts | 72 + .../react/src/hooks/useTransaction.ts | 72 + .../useTransactionConfirmations.test-d.ts | 14 + .../hooks/useTransactionConfirmations.test.ts | 215 + .../src/hooks/useTransactionConfirmations.ts | 66 + .../src/hooks/useTransactionCount.test-d.ts | 14 + .../src/hooks/useTransactionCount.test.ts | 238 + .../react/src/hooks/useTransactionCount.ts | 59 + .../src/hooks/useTransactionReceipt.test-d.ts | 14 + .../src/hooks/useTransactionReceipt.test.ts | 237 + .../react/src/hooks/useTransactionReceipt.ts | 69 + .../src/hooks/useVerifyMessage.test-d.ts | 14 + .../react/src/hooks/useVerifyMessage.test.ts | 318 + .../react/src/hooks/useVerifyMessage.ts | 59 + .../src/hooks/useVerifyTypedData.test-d.ts | 40 + .../src/hooks/useVerifyTypedData.test.ts | 481 + .../react/src/hooks/useVerifyTypedData.ts | 81 + .../src/hooks/useWaitForCallsStatus.test.ts | 101 + .../react/src/hooks/useWaitForCallsStatus.ts | 54 + .../useWaitForTransactionReceipt.test-d.ts | 14 + .../useWaitForTransactionReceipt.test.ts | 77 + .../src/hooks/useWaitForTransactionReceipt.ts | 74 + .../react/src/hooks/useWalletClient.test-d.ts | 12 + .../react/src/hooks/useWalletClient.test.tsx | 222 + .../react/src/hooks/useWalletClient.ts | 116 + .../react/src/hooks/useWatchAsset.test-d.ts | 66 + .../react/src/hooks/useWatchAsset.test.ts | 27 + .../packages/react/src/hooks/useWatchAsset.ts | 65 + .../src/hooks/useWatchBlockNumber.test-d.ts | 71 + .../src/hooks/useWatchBlockNumber.test.ts | 28 + .../react/src/hooks/useWatchBlockNumber.ts | 65 + .../react/src/hooks/useWatchBlocks.test-d.ts | 73 + .../react/src/hooks/useWatchBlocks.test.ts | 31 + .../react/src/hooks/useWatchBlocks.ts | 79 + .../src/hooks/useWatchContractEvent.test-d.ts | 128 + .../src/hooks/useWatchContractEvent.test.ts | 86 + .../react/src/hooks/useWatchContractEvent.ts | 85 + .../useWatchPendingTransactions.test-d.ts | 67 + .../hooks/useWatchPendingTransactions.test.ts | 49 + .../src/hooks/useWatchPendingTransactions.ts | 67 + .../src/hooks/useWriteContract.test-d.ts | 185 + .../react/src/hooks/useWriteContract.test.ts | 25 + .../react/src/hooks/useWriteContract.ts | 87 + wagmi-project/packages/react/src/hydrate.ts | 36 + .../packages/react/src/types/properties.ts | 51 + .../react/src/utils/getVersion.test.ts | 7 + .../packages/react/src/utils/getVersion.ts | 3 + .../packages/react/src/utils/query.ts | 145 + wagmi-project/packages/react/src/version.ts | 1 + wagmi-project/packages/react/test/setup.ts | 8 + .../packages/react/tsconfig.build.json | 8 + wagmi-project/packages/react/tsconfig.json | 8 + .../register-tests/react/package.json | 16 + .../register-tests/react/src/config.ts | 26 + .../src/createUseSimulateContract.test-d.ts | 39 + .../src/createUseWriteContract.test-d.ts | 66 + .../react/src/useAccount.test-d.ts | 15 + .../react/src/useBlock.test-d.ts | 27 + .../react/src/useChainId.test-d.ts | 15 + .../react/src/useChains.test-d.ts | 11 + .../react/src/useClient.test-d.ts | 38 + .../react/src/useConfig.test-d.ts | 17 + .../react/src/useConnect.test-d.ts | 13 + .../usePrepareTransactionRequest.test-d.ts | 42 + .../react/src/usePublicClient.ts | 38 + .../react/src/useReadContract.test-d.ts | 24 + .../react/src/useReadContracts.test-d.ts | 45 + .../react/src/useSendTransaction.test-d.ts | 55 + .../react/src/useSimulateContract.test-d.ts | 94 + .../react/src/useSwitchChain.test-d.ts | 25 + .../react/src/useTransaction.test-d.ts | 23 + .../src/useTransactionConfirmations.test-d.ts | 66 + .../react/src/useTransactionReceipt.test-d.ts | 31 + .../react/src/useWaitForTransactionReceipt.ts | 31 + .../react/src/useWriteContract.test-d.ts | 65 + .../register-tests/react/tsconfig.json | 5 + .../packages/register-tests/vue/package.json | 13 + .../packages/register-tests/vue/src/config.ts | 26 + .../vue/src/useAccount.test-d.ts | 17 + .../vue/src/useChainId.test-d.ts | 15 + .../vue/src/useChains.test-d.ts | 11 + .../vue/src/useClient.test-d.ts | 38 + .../vue/src/useConfig.test-d.ts | 17 + .../vue/src/useConnect.test-d.ts | 13 + .../vue/src/useReadContract.test-d.ts | 30 + .../vue/src/useSendTransaction.test-d.ts | 55 + .../vue/src/useSimulateContract.test-d.ts | 86 + .../vue/src/useSwitchChain.test-d.ts | 27 + .../vue/src/useTransaction.test-d.ts | 25 + .../vue/src/useTransactionReceipt.test-d.ts | 41 + .../vue/src/useWaitForTransaction.test-d.ts | 41 + .../vue/src/useWriteContract.test-d.ts | 65 + .../packages/register-tests/vue/tsconfig.json | 5 + wagmi-project/packages/test/package.json | 118 + wagmi-project/packages/test/src/chains.ts | 51 + wagmi-project/packages/test/src/clients.ts | 62 + wagmi-project/packages/test/src/config.ts | 29 + wagmi-project/packages/test/src/constants.ts | 318 + .../packages/test/src/exports/index.test-d.ts | 4 + .../packages/test/src/exports/index.test.ts | 29 + .../packages/test/src/exports/index.ts | 25 + .../packages/test/src/exports/react.ts | 63 + .../packages/test/src/exports/vue.ts | 66 + .../packages/test/src/globalSetup.ts | 26 + wagmi-project/packages/test/src/regex.ts | 3 + wagmi-project/packages/test/src/setup.ts | 8 + wagmi-project/packages/test/src/utils.ts | 25 + .../packages/test/tsconfig.build.json | 8 + wagmi-project/packages/test/tsconfig.json | 5 + wagmi-project/packages/vue/CHANGELOG.md | 706 + wagmi-project/packages/vue/README.md | 14 + wagmi-project/packages/vue/package.json | 113 + .../vue/src/composables/useAccount.test-d.ts | 69 + .../vue/src/composables/useAccount.test.ts | 20 + .../vue/src/composables/useAccount.ts | 37 + .../src/composables/useAccountEffect.test.ts | 75 + .../vue/src/composables/useAccountEffect.ts | 66 + .../vue/src/composables/useBalance.test-d.ts | 15 + .../vue/src/composables/useBalance.test.ts | 119 + .../vue/src/composables/useBalance.ts | 65 + .../src/composables/useBlockNumber.test-d.ts | 65 + .../src/composables/useBlockNumber.test.ts | 65 + .../vue/src/composables/useBlockNumber.ts | 120 + .../vue/src/composables/useBytecode.test-d.ts | 16 + .../vue/src/composables/useBytecode.test.ts | 296 + .../vue/src/composables/useBytecode.ts | 72 + .../vue/src/composables/useChainId.test-d.ts | 14 + .../vue/src/composables/useChainId.test.ts | 22 + .../vue/src/composables/useChainId.ts | 35 + .../vue/src/composables/useChains.test.ts | 16 + .../packages/vue/src/composables/useChains.ts | 35 + .../vue/src/composables/useClient.test-d.ts | 42 + .../vue/src/composables/useClient.test.ts | 41 + .../packages/vue/src/composables/useClient.ts | 66 + .../vue/src/composables/useConfig.test-d.ts | 16 + .../vue/src/composables/useConfig.test.ts | 24 + .../packages/vue/src/composables/useConfig.ts | 34 + .../vue/src/composables/useConnect.test-d.ts | 121 + .../vue/src/composables/useConnect.test.ts | 31 + .../vue/src/composables/useConnect.ts | 92 + .../src/composables/useConnections.test.ts | 16 + .../vue/src/composables/useConnections.ts | 30 + .../composables/useConnectorClient.test-d.ts | 12 + .../composables/useConnectorClient.test.ts | 156 + .../vue/src/composables/useConnectorClient.ts | 132 + .../vue/src/composables/useConnectors.test.ts | 21 + .../vue/src/composables/useConnectors.ts | 37 + .../src/composables/useDisconnect.test-d.ts | 87 + .../vue/src/composables/useDisconnect.test.ts | 30 + .../vue/src/composables/useDisconnect.ts | 70 + .../vue/src/composables/useEnsAddress.test.ts | 52 + .../vue/src/composables/useEnsAddress.ts | 65 + .../vue/src/composables/useEnsAvatar.test.ts | 52 + .../vue/src/composables/useEnsAvatar.ts | 65 + .../vue/src/composables/useEnsName.test.ts | 52 + .../vue/src/composables/useEnsName.ts | 65 + .../src/composables/useEstimateGas.test-d.ts | 14 + .../src/composables/useEstimateGas.test.ts | 117 + .../vue/src/composables/useEstimateGas.ts | 83 + .../src/composables/useReadContract.test-d.ts | 99 + .../src/composables/useReadContract.test.ts | 105 + .../vue/src/composables/useReadContract.ts | 116 + .../src/composables/useReconnect.test-d.ts | 154 + .../vue/src/composables/useReconnect.test.ts | 81 + .../vue/src/composables/useReconnect.ts | 65 + .../composables/useSendTransaction.test-d.ts | 78 + .../composables/useSendTransaction.test.ts | 25 + .../vue/src/composables/useSendTransaction.ts | 76 + .../src/composables/useSignMessage.test-d.ts | 64 + .../src/composables/useSignMessage.test.ts | 43 + .../vue/src/composables/useSignMessage.ts | 63 + .../composables/useSignTypedData.test-d.ts | 95 + .../src/composables/useSignTypedData.test.ts | 56 + .../vue/src/composables/useSignTypedData.ts | 64 + .../composables/useSimulateContract.test-d.ts | 96 + .../composables/useSimulateContract.test.ts | 59 + .../src/composables/useSimulateContract.ts | 145 + .../composables/useSwitchAccount.test-d.ts | 89 + .../src/composables/useSwitchAccount.test.ts | 42 + .../vue/src/composables/useSwitchAccount.ts | 84 + .../src/composables/useSwitchChain.test-d.ts | 118 + .../src/composables/useSwitchChain.test.ts | 35 + .../vue/src/composables/useSwitchChain.ts | 81 + .../src/composables/useTransaction.test-d.ts | 14 + .../src/composables/useTransaction.test.ts | 74 + .../vue/src/composables/useTransaction.ts | 91 + .../useTransactionReceipt.test-d.ts | 14 + .../composables/useTransactionReceipt.test.ts | 208 + .../src/composables/useTransactionReceipt.ts | 85 + .../useWaitForTransactionReceipt.test-d.ts | 14 + .../useWaitForTransactionReceipt.test.ts | 46 + .../useWaitForTransactionReceipt.ts | 84 + .../composables/useWatchBlockNumber.test-d.ts | 75 + .../composables/useWatchBlockNumber.test.ts | 67 + .../src/composables/useWatchBlockNumber.ts | 63 + .../useWatchContractEvent.test-d.ts | 126 + .../composables/useWatchContractEvent.test.ts | 106 + .../src/composables/useWatchContractEvent.ts | 77 + .../composables/useWriteContract.test-d.ts | 136 + .../src/composables/useWriteContract.test.ts | 25 + .../vue/src/composables/useWriteContract.ts | 85 + .../packages/vue/src/errors/base.test.ts | 155 + wagmi-project/packages/vue/src/errors/base.ts | 14 + .../packages/vue/src/errors/plugin.test.ts | 24 + .../packages/vue/src/errors/plugin.ts | 31 + .../packages/vue/src/exports/actions.test.ts | 86 + .../packages/vue/src/exports/actions.ts | 7 + .../src/exports/actions/experimental.test.ts | 25 + .../vue/src/exports/actions/experimental.ts | 7 + .../packages/vue/src/exports/chains.ts | 7 + .../vue/src/exports/connectors.test.ts | 17 + .../packages/vue/src/exports/connectors.ts | 7 + .../packages/vue/src/exports/index.test.ts | 74 + .../packages/vue/src/exports/index.ts | 280 + .../packages/vue/src/exports/nuxt.test.ts | 11 + .../packages/vue/src/exports/nuxt.ts | 4 + .../packages/vue/src/exports/query.test.ts | 99 + .../packages/vue/src/exports/query.ts | 19 + wagmi-project/packages/vue/src/nuxt/module.ts | 60 + .../vue/src/nuxt/runtime/composables.ts | 3 + wagmi-project/packages/vue/src/plugin.ts | 22 + .../packages/vue/src/types/properties.ts | 27 + wagmi-project/packages/vue/src/types/ref.ts | 39 + .../packages/vue/src/utils/cloneDeep.ts | 44 + .../packages/vue/src/utils/getVersion.test.ts | 7 + .../packages/vue/src/utils/getVersion.ts | 3 + wagmi-project/packages/vue/src/utils/query.ts | 161 + .../packages/vue/src/utils/updateState.ts | 10 + wagmi-project/packages/vue/src/version.ts | 1 + wagmi-project/packages/vue/test/setup.ts | 8 + .../packages/vue/tsconfig.build.json | 8 + wagmi-project/packages/vue/tsconfig.json | 5 + wagmi-project/playgrounds/next/.gitignore | 35 + .../playgrounds/next/next.config.mjs | 20 + wagmi-project/playgrounds/next/package.json | 31 + .../playgrounds/next/src/app/contracts.ts | 202 + .../playgrounds/next/src/app/globals.css | 21 + .../playgrounds/next/src/app/layout.tsx | 30 + .../playgrounds/next/src/app/page.tsx | 412 + .../playgrounds/next/src/app/providers.tsx | 23 + wagmi-project/playgrounds/next/src/wagmi.ts | 31 + wagmi-project/playgrounds/next/tsconfig.json | 24 + wagmi-project/playgrounds/nuxt/.gitignore | 24 + wagmi-project/playgrounds/nuxt/app.vue | 28 + .../playgrounds/nuxt/components/Account.vue | 22 + .../playgrounds/nuxt/components/Connect.vue | 19 + wagmi-project/playgrounds/nuxt/nuxt.config.ts | 7 + wagmi-project/playgrounds/nuxt/package.json | 20 + .../playgrounds/nuxt/plugins/wagmi.ts | 10 + .../playgrounds/nuxt/public/favicon.ico | Bin 0 -> 4286 bytes .../playgrounds/nuxt/server/tsconfig.json | 3 + wagmi-project/playgrounds/nuxt/tsconfig.json | 3 + wagmi-project/playgrounds/nuxt/wagmi.ts | 29 + .../playgrounds/vite-core/.gitignore | 24 + .../playgrounds/vite-core/index.html | 12 + .../playgrounds/vite-core/package.json | 24 + .../playgrounds/vite-core/src/App.tsx | 186 + .../playgrounds/vite-core/src/index.css | 21 + .../playgrounds/vite-core/src/main.tsx | 16 + .../playgrounds/vite-core/src/vite-env.d.ts | 1 + .../playgrounds/vite-core/src/wagmi.ts | 22 + .../playgrounds/vite-core/tsconfig.json | 28 + .../playgrounds/vite-core/tsconfig.node.json | 10 + .../playgrounds/vite-core/vite.config.ts | 7 + .../playgrounds/vite-react/.gitignore | 26 + .../playgrounds/vite-react/index.html | 12 + .../playgrounds/vite-react/package.json | 29 + .../vite-react/public/manifest.json | 5 + .../playgrounds/vite-react/src/App.tsx | 389 + .../playgrounds/vite-react/src/contracts.ts | 202 + .../playgrounds/vite-react/src/index.css | 21 + .../playgrounds/vite-react/src/main.tsx | 49 + .../playgrounds/vite-react/src/vite-env.d.ts | 1 + .../playgrounds/vite-react/src/wagmi.ts | 40 + .../playgrounds/vite-react/tsconfig.json | 30 + .../playgrounds/vite-react/tsconfig.node.json | 10 + .../playgrounds/vite-react/vite.config.ts | 7 + .../playgrounds/vite-react/wagmi.config.ts | 17 + wagmi-project/playgrounds/vite-vue/.gitignore | 24 + wagmi-project/playgrounds/vite-vue/index.html | 13 + .../playgrounds/vite-vue/package.json | 22 + .../playgrounds/vite-vue/public/vite.svg | 1 + .../playgrounds/vite-vue/src/App.vue | 29 + .../vite-vue/src/components/Account.vue | 22 + .../vite-vue/src/components/Balance.vue | 12 + .../vite-vue/src/components/BlockNumber.vue | 17 + .../vite-vue/src/components/Client.vue | 14 + .../vite-vue/src/components/Connect.vue | 19 + .../vite-vue/src/components/Connections.vue | 15 + .../src/components/ConnectorClient.vue | 14 + .../vite-vue/src/components/ReadContract.vue | 16 + .../src/components/SendTransaction.vue | 35 + .../vite-vue/src/components/SwitchAccount.vue | 20 + .../vite-vue/src/components/SwitchChain.vue | 22 + .../vite-vue/src/components/WriteContract.vue | 28 + .../playgrounds/vite-vue/src/contracts.ts | 202 + .../playgrounds/vite-vue/src/main.ts | 17 + .../playgrounds/vite-vue/src/style.css | 21 + .../playgrounds/vite-vue/src/vite-env.d.ts | 1 + .../playgrounds/vite-vue/src/wagmi.ts | 26 + .../playgrounds/vite-vue/tsconfig.json | 23 + .../playgrounds/vite-vue/tsconfig.node.json | 11 + .../playgrounds/vite-vue/vite.config.ts | 7 + wagmi-project/pnpm-lock.yaml | 19645 ++++++++++++++++ wagmi-project/pnpm-workspace.yaml | 19 + wagmi-project/scripts/formatPackageJson.ts | 36 + .../scripts/generateProxyPackages.ts | 57 + wagmi-project/scripts/preconstruct.ts | 87 + wagmi-project/scripts/restorePackageJson.ts | 29 + .../updateBlockExplorerPluginChains.ts | 53 + wagmi-project/scripts/updateVersion.ts | 43 + wagmi-project/scripts/updateViemVersion.ts | 44 + wagmi-project/site/.vitepress/config.ts | 151 + wagmi-project/site/.vitepress/constants.ts | 2 + wagmi-project/site/.vitepress/sidebar.ts | 1085 + .../theme/components/AsideSponsors.vue | 27 + .../.vitepress/theme/components/Banner.vue | 16 + .../theme/components/HomeBanner.vue | 13 + .../.vitepress/theme/components/HomePage.vue | 118 + .../theme/composables/useSponsors.ts | 212 + wagmi-project/site/.vitepress/theme/index.ts | 30 + wagmi-project/site/.vitepress/theme/style.css | 148 + wagmi-project/site/cli/api/commands.md | 53 + .../site/cli/api/commands/generate.md | 49 + wagmi-project/site/cli/api/commands/init.md | 40 + wagmi-project/site/cli/api/plugins.md | 42 + wagmi-project/site/cli/api/plugins/actions.md | 72 + .../site/cli/api/plugins/blockExplorer.md | 223 + .../site/cli/api/plugins/etherscan.md | 182 + wagmi-project/site/cli/api/plugins/fetch.md | 269 + wagmi-project/site/cli/api/plugins/foundry.md | 217 + wagmi-project/site/cli/api/plugins/hardhat.md | 199 + wagmi-project/site/cli/api/plugins/react.md | 52 + .../site/cli/api/plugins/sourcify.md | 115 + .../site/cli/config/configuring-cli.md | 124 + wagmi-project/site/cli/config/options.md | 132 + wagmi-project/site/cli/create-wagmi.md | 75 + wagmi-project/site/cli/getting-started.md | 167 + .../site/cli/guides/migrate-from-v1-to-v2.md | 51 + wagmi-project/site/cli/installation.md | 60 + wagmi-project/site/cli/why.md | 92 + wagmi-project/site/components/Browsers.vue | 9 + .../site/components/SearchChains.vue | 82 + wagmi-project/site/core/api/actions.md | 25 + wagmi-project/site/core/api/actions/call.md | 340 + .../site/core/api/actions/connect.md | 102 + .../site/core/api/actions/deployContract.md | 264 + .../site/core/api/actions/disconnect.md | 60 + .../core/api/actions/estimateFeesPerGas.md | 139 + .../site/core/api/actions/estimateGas.md | 340 + .../actions/estimateMaxPriorityFeePerGas.md | 74 + .../site/core/api/actions/getAccount.md | 29 + .../site/core/api/actions/getBalance.md | 197 + .../site/core/api/actions/getBlock.md | 146 + .../site/core/api/actions/getBlockNumber.md | 93 + .../api/actions/getBlockTransactionCount.md | 92 + .../site/core/api/actions/getBytecode.md | 133 + .../site/core/api/actions/getCallsStatus.md | 97 + .../site/core/api/actions/getCapabilities.md | 96 + .../site/core/api/actions/getChainId.md | 38 + .../site/core/api/actions/getChains.md | 31 + .../site/core/api/actions/getClient.md | 56 + .../site/core/api/actions/getConnections.md | 31 + .../core/api/actions/getConnectorClient.md | 108 + .../site/core/api/actions/getConnectors.md | 31 + .../site/core/api/actions/getEnsAddress.md | 187 + .../site/core/api/actions/getEnsAvatar.md | 210 + .../site/core/api/actions/getEnsName.md | 157 + .../site/core/api/actions/getEnsResolver.md | 167 + .../site/core/api/actions/getEnsText.md | 195 + .../site/core/api/actions/getFeeHistory.md | 157 + .../site/core/api/actions/getGasPrice.md | 74 + .../site/core/api/actions/getProof.md | 169 + .../site/core/api/actions/getPublicClient.md | 60 + .../site/core/api/actions/getStorageAt.md | 157 + .../site/core/api/actions/getToken.md | 141 + .../site/core/api/actions/getTransaction.md | 173 + .../actions/getTransactionConfirmations.md | 117 + .../core/api/actions/getTransactionCount.md | 139 + .../core/api/actions/getTransactionReceipt.md | 95 + .../site/core/api/actions/getWalletClient.md | 112 + .../site/core/api/actions/multicall.md | 355 + .../api/actions/prepareTransactionRequest.md | 307 + .../site/core/api/actions/readContract.md | 258 + .../site/core/api/actions/readContracts.md | 363 + .../site/core/api/actions/reconnect.md | 72 + .../site/core/api/actions/sendCalls.md | 223 + .../site/core/api/actions/sendTransaction.md | 341 + .../site/core/api/actions/showCallsStatus.md | 99 + .../site/core/api/actions/signMessage.md | 125 + .../site/core/api/actions/signTypedData.md | 409 + .../site/core/api/actions/simulateContract.md | 598 + .../site/core/api/actions/switchAccount.md | 81 + .../site/core/api/actions/switchChain.md | 122 + .../site/core/api/actions/verifyMessage.md | 200 + .../site/core/api/actions/verifyTypedData.md | 595 + .../core/api/actions/waitForCallsStatus.md | 143 + .../api/actions/waitForTransactionReceipt.md | 155 + .../site/core/api/actions/watchAccount.md | 61 + .../site/core/api/actions/watchAsset.md | 134 + .../site/core/api/actions/watchBlockNumber.md | 226 + .../site/core/api/actions/watchBlocks.md | 249 + .../site/core/api/actions/watchChainId.md | 61 + .../site/core/api/actions/watchClient.md | 61 + .../site/core/api/actions/watchConnections.md | 61 + .../site/core/api/actions/watchConnectors.md | 61 + .../core/api/actions/watchContractEvent.md | 376 + .../api/actions/watchPendingTransactions.md | 207 + .../core/api/actions/watchPublicClient.md | 61 + .../site/core/api/actions/writeContract.md | 560 + .../site/core/api/actions/writeContracts.md | 317 + wagmi-project/site/core/api/chains.md | 24 + wagmi-project/site/core/api/connectors.md | 28 + .../core/api/connectors/coinbaseWallet.md | 6 + .../site/core/api/connectors/injected.md | 7 + .../site/core/api/connectors/metaMask.md | 7 + .../site/core/api/connectors/mock.md | 6 + .../site/core/api/connectors/safe.md | 6 + .../site/core/api/connectors/walletConnect.md | 6 + wagmi-project/site/core/api/createConfig.md | 7 + .../site/core/api/createConnector.md | 31 + wagmi-project/site/core/api/createStorage.md | 6 + wagmi-project/site/core/api/errors.md | 11 + wagmi-project/site/core/api/transports.md | 28 + .../site/core/api/transports/custom.md | 5 + .../site/core/api/transports/fallback.md | 5 + .../site/core/api/transports/http.md | 5 + .../core/api/transports/unstable_connector.md | 6 + .../site/core/api/transports/webSocket.md | 5 + .../api/utilities/cookieToInitialState.md | 5 + .../site/core/api/utilities/deserialize.md | 5 + .../core/api/utilities/normalizeChainId.md | 5 + .../site/core/api/utilities/serialize.md | 5 + wagmi-project/site/core/getting-started.md | 71 + .../site/core/guides/chain-properties.md | 91 + .../site/core/guides/error-handling.md | 37 + wagmi-project/site/core/guides/ethers.md | 306 + wagmi-project/site/core/guides/faq.md | 9 + .../site/core/guides/framework-adapters.md | 35 + .../site/core/guides/migrate-from-v1-to-v2.md | 585 + wagmi-project/site/core/guides/testing.md | 3 + wagmi-project/site/core/guides/viem.md | 197 + wagmi-project/site/core/installation.md | 52 + wagmi-project/site/core/typescript.md | 241 + wagmi-project/site/core/why.md | 46 + wagmi-project/site/dev/contributing.md | 171 + wagmi-project/site/dev/creating-connectors.md | 155 + wagmi-project/site/index.md | 58 + wagmi-project/site/package.json | 28 + wagmi-project/site/public/browsers/chrome.png | Bin 0 -> 12226 bytes wagmi-project/site/public/browsers/edge.png | Bin 0 -> 11311 bytes .../site/public/browsers/firefox.png | Bin 0 -> 15035 bytes wagmi-project/site/public/browsers/opera.png | Bin 0 -> 5749 bytes wagmi-project/site/public/browsers/safari.png | Bin 0 -> 24056 bytes wagmi-project/site/public/favicon.svg | 10 + wagmi-project/site/public/logo-dark.svg | 6 + wagmi-project/site/public/logo-light.svg | 6 + wagmi-project/site/public/og.png | Bin 0 -> 12491 bytes wagmi-project/site/react/api/WagmiProvider.md | 112 + wagmi-project/site/react/api/actions.md | 28 + wagmi-project/site/react/api/chains.md | 26 + wagmi-project/site/react/api/connectors.md | 28 + .../react/api/connectors/coinbaseWallet.md | 6 + .../site/react/api/connectors/injected.md | 7 + .../site/react/api/connectors/metaMask.md | 7 + .../site/react/api/connectors/mock.md | 6 + .../site/react/api/connectors/safe.md | 6 + .../react/api/connectors/walletConnect.md | 6 + wagmi-project/site/react/api/createConfig.md | 7 + wagmi-project/site/react/api/createStorage.md | 6 + wagmi-project/site/react/api/errors.md | 20 + wagmi-project/site/react/api/hooks.md | 25 + .../site/react/api/hooks/useAccount.md | 65 + .../site/react/api/hooks/useAccountEffect.md | 113 + .../site/react/api/hooks/useBalance.md | 226 + .../site/react/api/hooks/useBlock.md | 227 + .../site/react/api/hooks/useBlockNumber.md | 169 + .../api/hooks/useBlockTransactionCount.md | 175 + .../site/react/api/hooks/useBytecode.md | 181 + wagmi-project/site/react/api/hooks/useCall.md | 397 + .../site/react/api/hooks/useCallsStatus.md | 143 + .../site/react/api/hooks/useCapabilities.md | 138 + .../site/react/api/hooks/useChainId.md | 74 + .../site/react/api/hooks/useChains.md | 67 + .../site/react/api/hooks/useClient.md | 89 + .../site/react/api/hooks/useConfig.md | 75 + .../site/react/api/hooks/useConnect.md | 117 + .../site/react/api/hooks/useConnections.md | 64 + .../react/api/hooks/useConnectorClient.md | 128 + .../site/react/api/hooks/useConnectors.md | 41 + .../site/react/api/hooks/useDeployContract.md | 145 + .../site/react/api/hooks/useDisconnect.md | 113 + .../site/react/api/hooks/useEnsAddress.md | 238 + .../site/react/api/hooks/useEnsAvatar.md | 262 + .../site/react/api/hooks/useEnsName.md | 206 + .../site/react/api/hooks/useEnsResolver.md | 217 + .../site/react/api/hooks/useEnsText.md | 247 + .../react/api/hooks/useEstimateFeesPerGas.md | 155 + .../site/react/api/hooks/useEstimateGas.md | 387 + .../hooks/useEstimateMaxPriorityFeePerGas.md | 116 + .../site/react/api/hooks/useFeeHistory.md | 210 + .../site/react/api/hooks/useGasPrice.md | 117 + .../api/hooks/useInfiniteReadContracts.md | 358 + .../api/hooks/usePrepareTransactionRequest.md | 368 + .../site/react/api/hooks/useProof.md | 224 + .../site/react/api/hooks/usePublicClient.md | 93 + .../site/react/api/hooks/useReadContract.md | 406 + .../site/react/api/hooks/useReadContracts.md | 394 + .../site/react/api/hooks/useReconnect.md | 111 + .../site/react/api/hooks/useSendCalls.md | 103 + .../react/api/hooks/useSendTransaction.md | 93 + .../react/api/hooks/useShowCallsStatus.md | 96 + .../site/react/api/hooks/useSignMessage.md | 85 + .../site/react/api/hooks/useSignTypedData.md | 217 + .../react/api/hooks/useSimulateContract.md | 686 + .../site/react/api/hooks/useStorageAt.md | 208 + .../site/react/api/hooks/useSwitchAccount.md | 116 + .../site/react/api/hooks/useSwitchChain.md | 120 + .../site/react/api/hooks/useToken.md | 162 + .../site/react/api/hooks/useTransaction.md | 184 + .../api/hooks/useTransactionConfirmations.md | 153 + .../react/api/hooks/useTransactionCount.md | 185 + .../react/api/hooks/useTransactionReceipt.md | 142 + .../site/react/api/hooks/useVerifyMessage.md | 257 + .../react/api/hooks/useVerifyTypedData.md | 724 + .../react/api/hooks/useWaitForCallsStatus.md | 181 + .../api/hooks/useWaitForTransactionReceipt.md | 168 + .../site/react/api/hooks/useWalletClient.md | 132 + .../site/react/api/hooks/useWatchAsset.md | 94 + .../react/api/hooks/useWatchBlockNumber.md | 276 + .../site/react/api/hooks/useWatchBlocks.md | 318 + .../react/api/hooks/useWatchContractEvent.md | 413 + .../api/hooks/useWatchPendingTransactions.md | 229 + .../site/react/api/hooks/useWriteContract.md | 116 + .../site/react/api/hooks/useWriteContracts.md | 119 + wagmi-project/site/react/api/transports.md | 28 + .../site/react/api/transports/custom.md | 5 + .../site/react/api/transports/fallback.md | 5 + .../site/react/api/transports/http.md | 5 + .../api/transports/unstable_connector.md | 6 + .../site/react/api/transports/webSocket.md | 5 + .../api/utilities/cookieToInitialState.md | 5 + .../site/react/api/utilities/deserialize.md | 5 + .../react/api/utilities/normalizeChainId.md | 5 + .../site/react/api/utilities/serialize.md | 5 + wagmi-project/site/react/comparisons.md | 90 + wagmi-project/site/react/getting-started.md | 214 + .../site/react/guides/chain-properties.md | 97 + .../site/react/guides/connect-wallet.md | 421 + .../site/react/guides/error-handling.md | 42 + wagmi-project/site/react/guides/ethers.md | 285 + wagmi-project/site/react/guides/faq.md | 24 + .../react/guides/migrate-from-v1-to-v2.md | 658 + .../site/react/guides/read-from-contract.md | 202 + .../site/react/guides/send-transaction.md | 362 + wagmi-project/site/react/guides/ssr.md | 168 + .../site/react/guides/tanstack-query.md | 403 + wagmi-project/site/react/guides/testing.md | 2 + wagmi-project/site/react/guides/viem.md | 150 + .../site/react/guides/write-to-contract.md | 438 + wagmi-project/site/react/installation.md | 56 + wagmi-project/site/react/typescript.md | 302 + wagmi-project/site/react/why.md | 46 + .../site/shared/connectors/coinbaseWallet.md | 160 + .../site/shared/connectors/injected.md | 89 + .../site/shared/connectors/metaMask.md | 124 + wagmi-project/site/shared/connectors/mock.md | 128 + wagmi-project/site/shared/connectors/safe.md | 77 + .../site/shared/connectors/walletConnect.md | 215 + wagmi-project/site/shared/create-chain.md | 93 + wagmi-project/site/shared/createConfig.md | 485 + wagmi-project/site/shared/createStorage.md | 161 + wagmi-project/site/shared/errors.md | 90 + wagmi-project/site/shared/faq.md | 81 + .../site/shared/getAccount-return-type.md | 107 + wagmi-project/site/shared/installation.md | 62 + wagmi-project/site/shared/mutation-imports.md | 19 + wagmi-project/site/shared/mutation-options.md | 89 + wagmi-project/site/shared/mutation-result.md | 122 + wagmi-project/site/shared/query-imports.md | 20 + wagmi-project/site/shared/query-options.md | 208 + wagmi-project/site/shared/query-result.md | 193 + .../site/shared/transports/custom.md | 110 + .../site/shared/transports/fallback.md | 36 + wagmi-project/site/shared/transports/http.md | 178 + .../shared/transports/unstable_connector.md | 123 + .../site/shared/transports/webSocket.md | 108 + .../shared/utilities/cookieToInitialState.md | 74 + .../site/shared/utilities/deserialize.md | 44 + .../site/shared/utilities/normalizeChainId.md | 56 + .../site/shared/utilities/serialize.md | 53 + wagmi-project/site/snippets/abi-event.ts | 20 + .../site/snippets/abi-infinite-read.ts | 23 + wagmi-project/site/snippets/abi-read.ts | 16 + wagmi-project/site/snippets/abi-write.ts | 23 + .../snippets/core/config-chain-properties.ts | 11 + wagmi-project/site/snippets/core/config.ts | 10 + wagmi-project/site/snippets/react/app.tsx | 16 + .../snippets/react/config-chain-properties.ts | 17 + wagmi-project/site/snippets/react/config.ts | 10 + wagmi-project/site/snippets/typedData.ts | 13 + wagmi-project/site/snippets/vue/App.vue | 5 + .../snippets/vue/config-chain-properties.ts | 17 + wagmi-project/site/snippets/vue/config.ts | 10 + wagmi-project/site/snippets/vue/main.ts | 13 + wagmi-project/site/tsconfig.json | 23 + wagmi-project/site/vercel.json | 148 + wagmi-project/site/vue/api/Nuxt.md | 27 + wagmi-project/site/vue/api/WagmiPlugin.md | 113 + wagmi-project/site/vue/api/actions.md | 30 + wagmi-project/site/vue/api/chains.md | 26 + wagmi-project/site/vue/api/composables.md | 25 + .../site/vue/api/composables/useAccount.md | 80 + .../vue/api/composables/useAccountEffect.md | 113 + .../site/vue/api/composables/useBalance.md | 226 + .../vue/api/composables/useBlockNumber.md | 172 + .../site/vue/api/composables/useBytecode.md | 209 + .../site/vue/api/composables/useChainId.md | 74 + .../site/vue/api/composables/useChains.md | 67 + .../site/vue/api/composables/useClient.md | 89 + .../site/vue/api/composables/useConfig.md | 33 + .../site/vue/api/composables/useConnect.md | 115 + .../vue/api/composables/useConnections.md | 64 + .../vue/api/composables/useConnectorClient.md | 128 + .../site/vue/api/composables/useConnectors.md | 41 + .../site/vue/api/composables/useDisconnect.md | 111 + .../site/vue/api/composables/useEnsAddress.md | 238 + .../site/vue/api/composables/useEnsAvatar.md | 262 + .../site/vue/api/composables/useEnsName.md | 206 + .../vue/api/composables/useEstimateGas.md | 387 + .../vue/api/composables/useReadContract.md | 410 + .../site/vue/api/composables/useReconnect.md | 106 + .../vue/api/composables/useSendTransaction.md | 91 + .../vue/api/composables/useSignMessage.md | 85 + .../vue/api/composables/useSignTypedData.md | 214 + .../api/composables/useSimulateContract.md | 686 + .../vue/api/composables/useSwitchAccount.md | 120 + .../vue/api/composables/useSwitchChain.md | 124 + .../vue/api/composables/useTransaction.md | 184 + .../api/composables/useTransactionReceipt.md | 141 + .../useWaitForTransactionReceipt.md | 168 + .../api/composables/useWatchBlockNumber.md | 109 + .../api/composables/useWatchContractEvent.md | 134 + .../vue/api/composables/useWriteContract.md | 112 + wagmi-project/site/vue/api/connectors.md | 28 + .../site/vue/api/connectors/coinbaseWallet.md | 6 + .../site/vue/api/connectors/injected.md | 7 + .../site/vue/api/connectors/metaMask.md | 7 + wagmi-project/site/vue/api/connectors/mock.md | 6 + wagmi-project/site/vue/api/connectors/safe.md | 6 + .../site/vue/api/connectors/walletConnect.md | 6 + wagmi-project/site/vue/api/createConfig.md | 7 + wagmi-project/site/vue/api/createStorage.md | 6 + wagmi-project/site/vue/api/errors.md | 10 + wagmi-project/site/vue/api/transports.md | 28 + .../site/vue/api/transports/custom.md | 5 + .../site/vue/api/transports/fallback.md | 5 + wagmi-project/site/vue/api/transports/http.md | 5 + .../vue/api/transports/unstable_connector.md | 6 + .../site/vue/api/transports/webSocket.md | 5 + .../site/vue/api/utilities/deserialize.md | 5 + .../site/vue/api/utilities/serialize.md | 5 + wagmi-project/site/vue/getting-started.md | 217 + .../site/vue/guides/chain-properties.md | 97 + .../site/vue/guides/connect-wallet.md | 387 + .../site/vue/guides/error-handling.md | 39 + wagmi-project/site/vue/guides/faq.md | 9 + .../site/vue/guides/read-from-contract.md | 206 + .../site/vue/guides/send-transaction.md | 311 + wagmi-project/site/vue/guides/ssr.md | 77 + .../site/vue/guides/tanstack-query.md | 287 + wagmi-project/site/vue/guides/viem.md | 94 + .../site/vue/guides/write-to-contract.md | 387 + wagmi-project/site/vue/installation.md | 41 + wagmi-project/site/vue/typescript.md | 302 + wagmi-project/site/vue/why.md | 46 + wagmi-project/tsconfig.base.json | 42 + wagmi-project/tsconfig.json | 27 +- wagmi-project/vitest.config.ts | 27 + wagmi-project/vitest.workspace.ts | 85 + 1410 files changed, 147262 insertions(+), 69 deletions(-) create mode 100644 wagmi-project/.changeset/README.md create mode 100644 wagmi-project/.changeset/config.json create mode 100644 wagmi-project/.changeset/new-elephants-travel.md create mode 100644 wagmi-project/.changeset/nice-pandas-clap.md create mode 100644 wagmi-project/.changeset/quick-hairs-scream.md create mode 100644 wagmi-project/.changeset/spicy-bats-juggle.md create mode 100644 wagmi-project/.changeset/tall-fans-mate.md create mode 100644 wagmi-project/.changeset/tiny-laws-dream.md create mode 100644 wagmi-project/.changeset/young-guests-care.md create mode 100644 wagmi-project/.circleci/config.yml create mode 100644 wagmi-project/.github/CODEOWNERS create mode 100644 wagmi-project/.github/CONTRIBUTING.md create mode 100644 wagmi-project/.github/DISCUSSION_TEMPLATE/connector-request.yml create mode 100644 wagmi-project/.github/ISSUE_TEMPLATE/bug_report.yml create mode 100644 wagmi-project/.github/ISSUE_TEMPLATE/config.yml create mode 100644 wagmi-project/.github/ISSUE_TEMPLATE/docs_issue.yml create mode 100644 wagmi-project/.github/README.md create mode 100644 wagmi-project/.github/SECURITY.md create mode 100644 wagmi-project/.github/dependabot.yml create mode 100644 wagmi-project/.github/logo-dark.svg create mode 100644 wagmi-project/.github/logo-light.svg create mode 100644 wagmi-project/.github/pull_request_template.md create mode 100644 wagmi-project/.github/workflows/Vercel Preview Deployment.yml create mode 100644 wagmi-project/.github/workflows/changesets.yml create mode 100644 wagmi-project/.github/workflows/dependency-review.yml create mode 100644 wagmi-project/.github/workflows/issue-labeled.yml create mode 100644 wagmi-project/.github/workflows/jekyll-docker.yml create mode 100644 wagmi-project/.github/workflows/lock-issue.yml create mode 100644 wagmi-project/.github/workflows/octopusdeploy.yml create mode 100644 wagmi-project/.github/workflows/pull-request.yml create mode 100644 wagmi-project/.github/workflows/release.yml create mode 100644 wagmi-project/.github/workflows/snapshot.yml create mode 100644 wagmi-project/.github/workflows/verify.yml create mode 100644 wagmi-project/.vscode/extensions.json create mode 100644 wagmi-project/.vscode/settings.json create mode 100644 wagmi-project/.vscode/workspace.code-workspace create mode 100644 wagmi-project/FUNDING.json create mode 100644 wagmi-project/LICENSE create mode 100644 wagmi-project/packages/cli/CHANGELOG.md create mode 100644 wagmi-project/packages/cli/README.md create mode 100644 wagmi-project/packages/cli/package.json create mode 100644 wagmi-project/packages/cli/src/cli.ts create mode 100644 wagmi-project/packages/cli/src/commands/generate.test.ts create mode 100644 wagmi-project/packages/cli/src/commands/generate.ts create mode 100644 wagmi-project/packages/cli/src/commands/init.test.ts create mode 100644 wagmi-project/packages/cli/src/commands/init.ts create mode 100644 wagmi-project/packages/cli/src/config.test.ts create mode 100644 wagmi-project/packages/cli/src/config.ts create mode 100644 wagmi-project/packages/cli/src/errors.ts create mode 100644 wagmi-project/packages/cli/src/exports/config.test.ts create mode 100644 wagmi-project/packages/cli/src/exports/config.ts create mode 100644 wagmi-project/packages/cli/src/exports/index.test-d.ts create mode 100644 wagmi-project/packages/cli/src/exports/index.test.ts create mode 100644 wagmi-project/packages/cli/src/exports/index.ts create mode 100644 wagmi-project/packages/cli/src/exports/plugins.test.ts create mode 100644 wagmi-project/packages/cli/src/exports/plugins.ts create mode 100644 wagmi-project/packages/cli/src/logger.test.ts create mode 100644 wagmi-project/packages/cli/src/logger.ts create mode 100644 wagmi-project/packages/cli/src/plugins/__fixtures__/foundry/.gitignore create mode 100644 wagmi-project/packages/cli/src/plugins/__fixtures__/foundry/foundry.toml create mode 100644 wagmi-project/packages/cli/src/plugins/__fixtures__/foundry/src/Counter.sol create mode 100644 wagmi-project/packages/cli/src/plugins/__fixtures__/foundry/src/Foo.sol create mode 100644 wagmi-project/packages/cli/src/plugins/__fixtures__/hardhat/.gitignore create mode 100644 wagmi-project/packages/cli/src/plugins/__fixtures__/hardhat/contracts/Counter.sol create mode 100644 wagmi-project/packages/cli/src/plugins/__fixtures__/hardhat/contracts/Foo.sol create mode 100644 wagmi-project/packages/cli/src/plugins/__fixtures__/hardhat/hardhat.config.js create mode 100644 wagmi-project/packages/cli/src/plugins/__fixtures__/hardhat/package.json create mode 100644 wagmi-project/packages/cli/src/plugins/__snapshots__/blockExplorer.test.ts.snap create mode 100644 wagmi-project/packages/cli/src/plugins/__snapshots__/etherscan.test.ts.snap create mode 100644 wagmi-project/packages/cli/src/plugins/__snapshots__/fetch.test.ts.snap create mode 100644 wagmi-project/packages/cli/src/plugins/__snapshots__/sourcify.test.ts.snap create mode 100644 wagmi-project/packages/cli/src/plugins/actions.test.ts create mode 100644 wagmi-project/packages/cli/src/plugins/actions.ts create mode 100644 wagmi-project/packages/cli/src/plugins/blockExplorer.test.ts create mode 100644 wagmi-project/packages/cli/src/plugins/blockExplorer.ts create mode 100644 wagmi-project/packages/cli/src/plugins/etherscan.test.ts create mode 100644 wagmi-project/packages/cli/src/plugins/etherscan.ts create mode 100644 wagmi-project/packages/cli/src/plugins/fetch.test.ts create mode 100644 wagmi-project/packages/cli/src/plugins/fetch.ts create mode 100644 wagmi-project/packages/cli/src/plugins/foundry.test.ts create mode 100644 wagmi-project/packages/cli/src/plugins/foundry.ts create mode 100644 wagmi-project/packages/cli/src/plugins/hardhat.test.ts create mode 100644 wagmi-project/packages/cli/src/plugins/hardhat.ts create mode 100644 wagmi-project/packages/cli/src/plugins/react.test.ts create mode 100644 wagmi-project/packages/cli/src/plugins/react.ts create mode 100644 wagmi-project/packages/cli/src/plugins/sourcify.test.ts create mode 100644 wagmi-project/packages/cli/src/plugins/sourcify.ts create mode 100644 wagmi-project/packages/cli/src/types.ts create mode 100644 wagmi-project/packages/cli/src/utils/findConfig.test.ts create mode 100644 wagmi-project/packages/cli/src/utils/findConfig.ts create mode 100644 wagmi-project/packages/cli/src/utils/format.test.ts create mode 100644 wagmi-project/packages/cli/src/utils/format.ts create mode 100644 wagmi-project/packages/cli/src/utils/getAddressDocString.test.ts create mode 100644 wagmi-project/packages/cli/src/utils/getAddressDocString.ts create mode 100644 wagmi-project/packages/cli/src/utils/getIsUsingTypeScript.test.ts create mode 100644 wagmi-project/packages/cli/src/utils/getIsUsingTypeScript.ts create mode 100644 wagmi-project/packages/cli/src/utils/loadEnv.test.ts create mode 100644 wagmi-project/packages/cli/src/utils/loadEnv.ts create mode 100644 wagmi-project/packages/cli/src/utils/packages.test.ts create mode 100644 wagmi-project/packages/cli/src/utils/packages.ts create mode 100644 wagmi-project/packages/cli/src/utils/resolveConfig.test.ts create mode 100644 wagmi-project/packages/cli/src/utils/resolveConfig.ts create mode 100644 wagmi-project/packages/cli/src/version.ts create mode 100644 wagmi-project/packages/cli/test/constants.ts create mode 100644 wagmi-project/packages/cli/test/setup.ts create mode 100644 wagmi-project/packages/cli/test/utils.ts create mode 100644 wagmi-project/packages/cli/tsconfig.build.json create mode 100644 wagmi-project/packages/cli/tsconfig.json create mode 100644 wagmi-project/packages/cli/types/fixturez.d.ts create mode 100644 wagmi-project/packages/connectors/CHANGELOG.md create mode 100644 wagmi-project/packages/connectors/README.md create mode 100644 wagmi-project/packages/connectors/package.json create mode 100644 wagmi-project/packages/connectors/src/coinbaseWallet.test.ts create mode 100644 wagmi-project/packages/connectors/src/coinbaseWallet.ts create mode 100644 wagmi-project/packages/connectors/src/exports/index.test.ts create mode 100644 wagmi-project/packages/connectors/src/exports/index.ts create mode 100644 wagmi-project/packages/connectors/src/metaMask.test.ts create mode 100644 wagmi-project/packages/connectors/src/metaMask.ts create mode 100644 wagmi-project/packages/connectors/src/safe.test.ts create mode 100644 wagmi-project/packages/connectors/src/safe.ts create mode 100644 wagmi-project/packages/connectors/src/version.ts create mode 100644 wagmi-project/packages/connectors/src/walletConnect.test.ts create mode 100644 wagmi-project/packages/connectors/src/walletConnect.ts create mode 100644 wagmi-project/packages/connectors/tsconfig.build.json create mode 100644 wagmi-project/packages/connectors/tsconfig.json create mode 100644 wagmi-project/packages/core/CHANGELOG.md create mode 100644 wagmi-project/packages/core/README.md create mode 100644 wagmi-project/packages/core/package.json create mode 100644 wagmi-project/packages/core/src/actions/call.test.ts create mode 100644 wagmi-project/packages/core/src/actions/call.ts create mode 100644 wagmi-project/packages/core/src/actions/codegen/createReadContract.test-d.ts create mode 100644 wagmi-project/packages/core/src/actions/codegen/createReadContract.test.ts create mode 100644 wagmi-project/packages/core/src/actions/codegen/createReadContract.ts create mode 100644 wagmi-project/packages/core/src/actions/codegen/createSimulateContract.test-d.ts create mode 100644 wagmi-project/packages/core/src/actions/codegen/createSimulateContract.test.ts create mode 100644 wagmi-project/packages/core/src/actions/codegen/createSimulateContract.ts create mode 100644 wagmi-project/packages/core/src/actions/codegen/createWatchContractEvent.test-d.ts create mode 100644 wagmi-project/packages/core/src/actions/codegen/createWatchContractEvent.test.ts create mode 100644 wagmi-project/packages/core/src/actions/codegen/createWatchContractEvent.ts create mode 100644 wagmi-project/packages/core/src/actions/codegen/createWriteContract.test-d.ts create mode 100644 wagmi-project/packages/core/src/actions/codegen/createWriteContract.test.ts create mode 100644 wagmi-project/packages/core/src/actions/codegen/createWriteContract.ts create mode 100644 wagmi-project/packages/core/src/actions/connect.test-d.ts create mode 100644 wagmi-project/packages/core/src/actions/connect.test.ts create mode 100644 wagmi-project/packages/core/src/actions/connect.ts create mode 100644 wagmi-project/packages/core/src/actions/deployContract.test-d.ts create mode 100644 wagmi-project/packages/core/src/actions/deployContract.test.ts create mode 100644 wagmi-project/packages/core/src/actions/deployContract.ts create mode 100644 wagmi-project/packages/core/src/actions/disconnect.test.ts create mode 100644 wagmi-project/packages/core/src/actions/disconnect.ts create mode 100644 wagmi-project/packages/core/src/actions/estimateFeesPerGas.test-d.ts create mode 100644 wagmi-project/packages/core/src/actions/estimateFeesPerGas.test.ts create mode 100644 wagmi-project/packages/core/src/actions/estimateFeesPerGas.ts create mode 100644 wagmi-project/packages/core/src/actions/estimateGas.test-d.ts create mode 100644 wagmi-project/packages/core/src/actions/estimateGas.test.ts create mode 100644 wagmi-project/packages/core/src/actions/estimateGas.ts create mode 100644 wagmi-project/packages/core/src/actions/estimateMaxPriorityFeePerGas.test.ts create mode 100644 wagmi-project/packages/core/src/actions/estimateMaxPriorityFeePerGas.ts create mode 100644 wagmi-project/packages/core/src/actions/getAccount.test-d.ts create mode 100644 wagmi-project/packages/core/src/actions/getAccount.test.ts create mode 100644 wagmi-project/packages/core/src/actions/getAccount.ts create mode 100644 wagmi-project/packages/core/src/actions/getBalance.test.ts create mode 100644 wagmi-project/packages/core/src/actions/getBalance.ts create mode 100644 wagmi-project/packages/core/src/actions/getBlock.test-d.ts create mode 100644 wagmi-project/packages/core/src/actions/getBlock.test.ts create mode 100644 wagmi-project/packages/core/src/actions/getBlock.ts create mode 100644 wagmi-project/packages/core/src/actions/getBlockNumber.test.ts create mode 100644 wagmi-project/packages/core/src/actions/getBlockNumber.ts create mode 100644 wagmi-project/packages/core/src/actions/getBlockTransactionCount.test.ts create mode 100644 wagmi-project/packages/core/src/actions/getBlockTransactionCount.ts create mode 100644 wagmi-project/packages/core/src/actions/getBytecode.test.ts create mode 100644 wagmi-project/packages/core/src/actions/getBytecode.ts create mode 100644 wagmi-project/packages/core/src/actions/getCallsStatus.test.ts create mode 100644 wagmi-project/packages/core/src/actions/getCallsStatus.ts create mode 100644 wagmi-project/packages/core/src/actions/getCapabilities.test.ts create mode 100644 wagmi-project/packages/core/src/actions/getCapabilities.ts create mode 100644 wagmi-project/packages/core/src/actions/getChainId.test.ts create mode 100644 wagmi-project/packages/core/src/actions/getChainId.ts create mode 100644 wagmi-project/packages/core/src/actions/getChains.test-d.ts create mode 100644 wagmi-project/packages/core/src/actions/getChains.test.ts create mode 100644 wagmi-project/packages/core/src/actions/getChains.ts create mode 100644 wagmi-project/packages/core/src/actions/getClient.test-d.ts create mode 100644 wagmi-project/packages/core/src/actions/getClient.test.ts create mode 100644 wagmi-project/packages/core/src/actions/getClient.ts create mode 100644 wagmi-project/packages/core/src/actions/getConnections.test.ts create mode 100644 wagmi-project/packages/core/src/actions/getConnections.ts create mode 100644 wagmi-project/packages/core/src/actions/getConnectorClient.test-d.ts create mode 100644 wagmi-project/packages/core/src/actions/getConnectorClient.test.ts create mode 100644 wagmi-project/packages/core/src/actions/getConnectorClient.ts create mode 100644 wagmi-project/packages/core/src/actions/getConnectors.test.ts create mode 100644 wagmi-project/packages/core/src/actions/getConnectors.ts create mode 100644 wagmi-project/packages/core/src/actions/getEnsAddress.test.ts create mode 100644 wagmi-project/packages/core/src/actions/getEnsAddress.ts create mode 100644 wagmi-project/packages/core/src/actions/getEnsAvatar.test.ts create mode 100644 wagmi-project/packages/core/src/actions/getEnsAvatar.ts create mode 100644 wagmi-project/packages/core/src/actions/getEnsName.test.ts create mode 100644 wagmi-project/packages/core/src/actions/getEnsName.ts create mode 100644 wagmi-project/packages/core/src/actions/getEnsResolver.test.ts create mode 100644 wagmi-project/packages/core/src/actions/getEnsResolver.ts create mode 100644 wagmi-project/packages/core/src/actions/getEnsText.test.ts create mode 100644 wagmi-project/packages/core/src/actions/getEnsText.ts create mode 100644 wagmi-project/packages/core/src/actions/getFeeHistory.test.ts create mode 100644 wagmi-project/packages/core/src/actions/getFeeHistory.ts create mode 100644 wagmi-project/packages/core/src/actions/getGasPrice.test.ts create mode 100644 wagmi-project/packages/core/src/actions/getGasPrice.ts create mode 100644 wagmi-project/packages/core/src/actions/getProof.test.ts create mode 100644 wagmi-project/packages/core/src/actions/getProof.ts create mode 100644 wagmi-project/packages/core/src/actions/getPublicClient.test-d.ts create mode 100644 wagmi-project/packages/core/src/actions/getPublicClient.test.ts create mode 100644 wagmi-project/packages/core/src/actions/getPublicClient.ts create mode 100644 wagmi-project/packages/core/src/actions/getStorageAt.test.ts create mode 100644 wagmi-project/packages/core/src/actions/getStorageAt.ts create mode 100644 wagmi-project/packages/core/src/actions/getToken.test.ts create mode 100644 wagmi-project/packages/core/src/actions/getToken.ts create mode 100644 wagmi-project/packages/core/src/actions/getTransaction.test-d.ts create mode 100644 wagmi-project/packages/core/src/actions/getTransaction.test.ts create mode 100644 wagmi-project/packages/core/src/actions/getTransaction.ts create mode 100644 wagmi-project/packages/core/src/actions/getTransactionConfirmations.test-d.ts create mode 100644 wagmi-project/packages/core/src/actions/getTransactionConfirmations.test.ts create mode 100644 wagmi-project/packages/core/src/actions/getTransactionConfirmations.ts create mode 100644 wagmi-project/packages/core/src/actions/getTransactionCount.test.ts create mode 100644 wagmi-project/packages/core/src/actions/getTransactionCount.ts create mode 100644 wagmi-project/packages/core/src/actions/getTransactionReceipt.test-d.ts create mode 100644 wagmi-project/packages/core/src/actions/getTransactionReceipt.test.ts create mode 100644 wagmi-project/packages/core/src/actions/getTransactionReceipt.ts create mode 100644 wagmi-project/packages/core/src/actions/getWalletClient.test-d.ts create mode 100644 wagmi-project/packages/core/src/actions/getWalletClient.test.ts create mode 100644 wagmi-project/packages/core/src/actions/getWalletClient.ts create mode 100644 wagmi-project/packages/core/src/actions/multicall.test-d.ts create mode 100644 wagmi-project/packages/core/src/actions/multicall.test.ts create mode 100644 wagmi-project/packages/core/src/actions/multicall.ts create mode 100644 wagmi-project/packages/core/src/actions/prepareTransactionRequest.test-d.ts create mode 100644 wagmi-project/packages/core/src/actions/prepareTransactionRequest.test.ts create mode 100644 wagmi-project/packages/core/src/actions/prepareTransactionRequest.ts create mode 100644 wagmi-project/packages/core/src/actions/readContract.test-d.ts create mode 100644 wagmi-project/packages/core/src/actions/readContract.test.ts create mode 100644 wagmi-project/packages/core/src/actions/readContract.ts create mode 100644 wagmi-project/packages/core/src/actions/readContracts.test-d.ts create mode 100644 wagmi-project/packages/core/src/actions/readContracts.test.ts create mode 100644 wagmi-project/packages/core/src/actions/readContracts.ts create mode 100644 wagmi-project/packages/core/src/actions/reconnect.test.ts create mode 100644 wagmi-project/packages/core/src/actions/reconnect.ts create mode 100644 wagmi-project/packages/core/src/actions/sendCalls.test.ts create mode 100644 wagmi-project/packages/core/src/actions/sendCalls.ts create mode 100644 wagmi-project/packages/core/src/actions/sendTransaction.test-d.ts create mode 100644 wagmi-project/packages/core/src/actions/sendTransaction.test.ts create mode 100644 wagmi-project/packages/core/src/actions/sendTransaction.ts create mode 100644 wagmi-project/packages/core/src/actions/showCallsStatus.test.ts create mode 100644 wagmi-project/packages/core/src/actions/showCallsStatus.ts create mode 100644 wagmi-project/packages/core/src/actions/signMessage.test.ts create mode 100644 wagmi-project/packages/core/src/actions/signMessage.ts create mode 100644 wagmi-project/packages/core/src/actions/signTypedData.test-d.ts create mode 100644 wagmi-project/packages/core/src/actions/signTypedData.test.ts create mode 100644 wagmi-project/packages/core/src/actions/signTypedData.ts create mode 100644 wagmi-project/packages/core/src/actions/simulateContract.test-d.ts create mode 100644 wagmi-project/packages/core/src/actions/simulateContract.test.ts create mode 100644 wagmi-project/packages/core/src/actions/simulateContract.ts create mode 100644 wagmi-project/packages/core/src/actions/switchAccount.test.ts create mode 100644 wagmi-project/packages/core/src/actions/switchAccount.ts create mode 100644 wagmi-project/packages/core/src/actions/switchChain.test.ts create mode 100644 wagmi-project/packages/core/src/actions/switchChain.ts create mode 100644 wagmi-project/packages/core/src/actions/verifyMessage.test.ts create mode 100644 wagmi-project/packages/core/src/actions/verifyMessage.ts create mode 100644 wagmi-project/packages/core/src/actions/verifyTypedData.test.ts create mode 100644 wagmi-project/packages/core/src/actions/verifyTypedData.ts create mode 100644 wagmi-project/packages/core/src/actions/waitForCallsStatus.test.ts create mode 100644 wagmi-project/packages/core/src/actions/waitForCallsStatus.ts create mode 100644 wagmi-project/packages/core/src/actions/waitForTransactionReceipt.test-d.ts create mode 100644 wagmi-project/packages/core/src/actions/waitForTransactionReceipt.test.ts create mode 100644 wagmi-project/packages/core/src/actions/waitForTransactionReceipt.ts create mode 100644 wagmi-project/packages/core/src/actions/watchAccount.test.ts create mode 100644 wagmi-project/packages/core/src/actions/watchAccount.ts create mode 100644 wagmi-project/packages/core/src/actions/watchAsset.test.ts create mode 100644 wagmi-project/packages/core/src/actions/watchAsset.ts create mode 100644 wagmi-project/packages/core/src/actions/watchBlockNumber.test-d.ts create mode 100644 wagmi-project/packages/core/src/actions/watchBlockNumber.test.ts create mode 100644 wagmi-project/packages/core/src/actions/watchBlockNumber.ts create mode 100644 wagmi-project/packages/core/src/actions/watchBlocks.test-d.ts create mode 100644 wagmi-project/packages/core/src/actions/watchBlocks.test.ts create mode 100644 wagmi-project/packages/core/src/actions/watchBlocks.ts create mode 100644 wagmi-project/packages/core/src/actions/watchChainId.test.ts create mode 100644 wagmi-project/packages/core/src/actions/watchChainId.ts create mode 100644 wagmi-project/packages/core/src/actions/watchChains.test.ts create mode 100644 wagmi-project/packages/core/src/actions/watchChains.ts create mode 100644 wagmi-project/packages/core/src/actions/watchClient.test-d.ts create mode 100644 wagmi-project/packages/core/src/actions/watchClient.test.ts create mode 100644 wagmi-project/packages/core/src/actions/watchClient.ts create mode 100644 wagmi-project/packages/core/src/actions/watchConnections.test.ts create mode 100644 wagmi-project/packages/core/src/actions/watchConnections.ts create mode 100644 wagmi-project/packages/core/src/actions/watchConnectors.test.ts create mode 100644 wagmi-project/packages/core/src/actions/watchConnectors.ts create mode 100644 wagmi-project/packages/core/src/actions/watchContractEvent.test-d.ts create mode 100644 wagmi-project/packages/core/src/actions/watchContractEvent.test.ts create mode 100644 wagmi-project/packages/core/src/actions/watchContractEvent.ts create mode 100644 wagmi-project/packages/core/src/actions/watchPendingTransactions.test-d.ts create mode 100644 wagmi-project/packages/core/src/actions/watchPendingTransactions.test.ts create mode 100644 wagmi-project/packages/core/src/actions/watchPendingTransactions.ts create mode 100644 wagmi-project/packages/core/src/actions/watchPublicClient.test-d.ts create mode 100644 wagmi-project/packages/core/src/actions/watchPublicClient.test.ts create mode 100644 wagmi-project/packages/core/src/actions/watchPublicClient.ts create mode 100644 wagmi-project/packages/core/src/actions/writeContract.test-d.ts create mode 100644 wagmi-project/packages/core/src/actions/writeContract.ts create mode 100644 wagmi-project/packages/core/src/connectors/createConnector.test.ts create mode 100644 wagmi-project/packages/core/src/connectors/createConnector.ts create mode 100644 wagmi-project/packages/core/src/connectors/injected.test.ts create mode 100644 wagmi-project/packages/core/src/connectors/injected.ts create mode 100644 wagmi-project/packages/core/src/connectors/mock.test.ts create mode 100644 wagmi-project/packages/core/src/connectors/mock.ts create mode 100644 wagmi-project/packages/core/src/createConfig.test-d.ts create mode 100644 wagmi-project/packages/core/src/createConfig.test.ts create mode 100644 wagmi-project/packages/core/src/createConfig.ts create mode 100644 wagmi-project/packages/core/src/createEmitter.test.ts create mode 100644 wagmi-project/packages/core/src/createEmitter.ts create mode 100644 wagmi-project/packages/core/src/createStorage.test-d.ts create mode 100644 wagmi-project/packages/core/src/createStorage.test.ts create mode 100644 wagmi-project/packages/core/src/createStorage.ts create mode 100644 wagmi-project/packages/core/src/errors/base.test.ts create mode 100644 wagmi-project/packages/core/src/errors/base.ts create mode 100644 wagmi-project/packages/core/src/errors/config.test.ts create mode 100644 wagmi-project/packages/core/src/errors/config.ts create mode 100644 wagmi-project/packages/core/src/errors/connector.test.ts create mode 100644 wagmi-project/packages/core/src/errors/connector.ts create mode 100644 wagmi-project/packages/core/src/experimental/actions/writeContracts.test.ts create mode 100644 wagmi-project/packages/core/src/experimental/actions/writeContracts.ts create mode 100644 wagmi-project/packages/core/src/experimental/query/writeContracts.test.ts create mode 100644 wagmi-project/packages/core/src/experimental/query/writeContracts.ts create mode 100644 wagmi-project/packages/core/src/exports/actions.test.ts create mode 100644 wagmi-project/packages/core/src/exports/actions.ts create mode 100644 wagmi-project/packages/core/src/exports/chains.ts create mode 100644 wagmi-project/packages/core/src/exports/codegen.test.ts create mode 100644 wagmi-project/packages/core/src/exports/codegen.ts create mode 100644 wagmi-project/packages/core/src/exports/experimental.ts create mode 100644 wagmi-project/packages/core/src/exports/index.test.ts create mode 100644 wagmi-project/packages/core/src/exports/index.ts create mode 100644 wagmi-project/packages/core/src/exports/internal.test.ts create mode 100644 wagmi-project/packages/core/src/exports/internal.ts create mode 100644 wagmi-project/packages/core/src/exports/query.test.ts create mode 100644 wagmi-project/packages/core/src/exports/query.ts create mode 100644 wagmi-project/packages/core/src/hydrate.test.ts create mode 100644 wagmi-project/packages/core/src/hydrate.ts create mode 100644 wagmi-project/packages/core/src/query/call.test.ts create mode 100644 wagmi-project/packages/core/src/query/call.ts create mode 100644 wagmi-project/packages/core/src/query/connect.test.ts create mode 100644 wagmi-project/packages/core/src/query/connect.ts create mode 100644 wagmi-project/packages/core/src/query/deployContract.test.ts create mode 100644 wagmi-project/packages/core/src/query/deployContract.ts create mode 100644 wagmi-project/packages/core/src/query/disconnect.test.ts create mode 100644 wagmi-project/packages/core/src/query/disconnect.ts create mode 100644 wagmi-project/packages/core/src/query/estimateFeesPerGas.test.ts create mode 100644 wagmi-project/packages/core/src/query/estimateFeesPerGas.ts create mode 100644 wagmi-project/packages/core/src/query/estimateGas.test-d.ts create mode 100644 wagmi-project/packages/core/src/query/estimateGas.test.ts create mode 100644 wagmi-project/packages/core/src/query/estimateGas.ts create mode 100644 wagmi-project/packages/core/src/query/estimateMaxPriorityFeePerGas.test.ts create mode 100644 wagmi-project/packages/core/src/query/estimateMaxPriorityFeePerGas.ts create mode 100644 wagmi-project/packages/core/src/query/getBalance.test.ts create mode 100644 wagmi-project/packages/core/src/query/getBalance.ts create mode 100644 wagmi-project/packages/core/src/query/getBlock.test.ts create mode 100644 wagmi-project/packages/core/src/query/getBlock.ts create mode 100644 wagmi-project/packages/core/src/query/getBlockNumber.test.ts create mode 100644 wagmi-project/packages/core/src/query/getBlockNumber.ts create mode 100644 wagmi-project/packages/core/src/query/getBlockTransactionCount.test.ts create mode 100644 wagmi-project/packages/core/src/query/getBlockTransactionCount.ts create mode 100644 wagmi-project/packages/core/src/query/getBytecode.test.ts create mode 100644 wagmi-project/packages/core/src/query/getBytecode.ts create mode 100644 wagmi-project/packages/core/src/query/getCallsStatus.test.ts create mode 100644 wagmi-project/packages/core/src/query/getCallsStatus.ts create mode 100644 wagmi-project/packages/core/src/query/getCapabilities.test.ts create mode 100644 wagmi-project/packages/core/src/query/getCapabilities.ts create mode 100644 wagmi-project/packages/core/src/query/getConnectorClient.test.ts create mode 100644 wagmi-project/packages/core/src/query/getConnectorClient.ts create mode 100644 wagmi-project/packages/core/src/query/getEnsAddress.test.ts create mode 100644 wagmi-project/packages/core/src/query/getEnsAddress.ts create mode 100644 wagmi-project/packages/core/src/query/getEnsAvatar.test.ts create mode 100644 wagmi-project/packages/core/src/query/getEnsAvatar.ts create mode 100644 wagmi-project/packages/core/src/query/getEnsName.test.ts create mode 100644 wagmi-project/packages/core/src/query/getEnsName.ts create mode 100644 wagmi-project/packages/core/src/query/getEnsResolver.test.ts create mode 100644 wagmi-project/packages/core/src/query/getEnsResolver.ts create mode 100644 wagmi-project/packages/core/src/query/getEnsText.test.ts create mode 100644 wagmi-project/packages/core/src/query/getEnsText.ts create mode 100644 wagmi-project/packages/core/src/query/getFeeHistory.test.ts create mode 100644 wagmi-project/packages/core/src/query/getFeeHistory.ts create mode 100644 wagmi-project/packages/core/src/query/getGasPrice.test.ts create mode 100644 wagmi-project/packages/core/src/query/getGasPrice.ts create mode 100644 wagmi-project/packages/core/src/query/getProof.test.ts create mode 100644 wagmi-project/packages/core/src/query/getProof.ts create mode 100644 wagmi-project/packages/core/src/query/getStorageAt.test.ts create mode 100644 wagmi-project/packages/core/src/query/getStorageAt.ts create mode 100644 wagmi-project/packages/core/src/query/getToken.test.ts create mode 100644 wagmi-project/packages/core/src/query/getToken.ts create mode 100644 wagmi-project/packages/core/src/query/getTransaction.test.ts create mode 100644 wagmi-project/packages/core/src/query/getTransaction.ts create mode 100644 wagmi-project/packages/core/src/query/getTransactionConfirmations.test.ts create mode 100644 wagmi-project/packages/core/src/query/getTransactionConfirmations.ts create mode 100644 wagmi-project/packages/core/src/query/getTransactionCount.test.ts create mode 100644 wagmi-project/packages/core/src/query/getTransactionCount.ts create mode 100644 wagmi-project/packages/core/src/query/getTransactionReceipt.test.ts create mode 100644 wagmi-project/packages/core/src/query/getTransactionReceipt.ts create mode 100644 wagmi-project/packages/core/src/query/getWalletClient.test.ts create mode 100644 wagmi-project/packages/core/src/query/getWalletClient.ts create mode 100644 wagmi-project/packages/core/src/query/infiniteReadContracts.test-d.ts create mode 100644 wagmi-project/packages/core/src/query/infiniteReadContracts.test.ts create mode 100644 wagmi-project/packages/core/src/query/infiniteReadContracts.ts create mode 100644 wagmi-project/packages/core/src/query/prepareTransactionRequest.test.ts create mode 100644 wagmi-project/packages/core/src/query/prepareTransactionRequest.ts create mode 100644 wagmi-project/packages/core/src/query/readContract.test-d.ts create mode 100644 wagmi-project/packages/core/src/query/readContract.test.ts create mode 100644 wagmi-project/packages/core/src/query/readContract.ts create mode 100644 wagmi-project/packages/core/src/query/readContracts.test-d.ts create mode 100644 wagmi-project/packages/core/src/query/readContracts.test.ts create mode 100644 wagmi-project/packages/core/src/query/readContracts.ts create mode 100644 wagmi-project/packages/core/src/query/reconnect.test.ts create mode 100644 wagmi-project/packages/core/src/query/reconnect.ts create mode 100644 wagmi-project/packages/core/src/query/sendCalls.test.ts create mode 100644 wagmi-project/packages/core/src/query/sendCalls.ts create mode 100644 wagmi-project/packages/core/src/query/sendTransaction.test.ts create mode 100644 wagmi-project/packages/core/src/query/sendTransaction.ts create mode 100644 wagmi-project/packages/core/src/query/showCallsStatus.test.ts create mode 100644 wagmi-project/packages/core/src/query/showCallsStatus.ts create mode 100644 wagmi-project/packages/core/src/query/signMessage.test.ts create mode 100644 wagmi-project/packages/core/src/query/signMessage.ts create mode 100644 wagmi-project/packages/core/src/query/signTypedData.test.ts create mode 100644 wagmi-project/packages/core/src/query/signTypedData.ts create mode 100644 wagmi-project/packages/core/src/query/simulateContract.test-d.ts create mode 100644 wagmi-project/packages/core/src/query/simulateContract.test.ts create mode 100644 wagmi-project/packages/core/src/query/simulateContract.ts create mode 100644 wagmi-project/packages/core/src/query/switchAccount.test.ts create mode 100644 wagmi-project/packages/core/src/query/switchAccount.ts create mode 100644 wagmi-project/packages/core/src/query/switchChain.test.ts create mode 100644 wagmi-project/packages/core/src/query/switchChain.ts create mode 100644 wagmi-project/packages/core/src/query/types.ts create mode 100644 wagmi-project/packages/core/src/query/utils.test.ts create mode 100644 wagmi-project/packages/core/src/query/utils.ts create mode 100644 wagmi-project/packages/core/src/query/verifyMessage.test.ts create mode 100644 wagmi-project/packages/core/src/query/verifyMessage.ts create mode 100644 wagmi-project/packages/core/src/query/verifyTypedData.test.ts create mode 100644 wagmi-project/packages/core/src/query/verifyTypedData.ts create mode 100644 wagmi-project/packages/core/src/query/waitForCallsStatus.test.ts create mode 100644 wagmi-project/packages/core/src/query/waitForCallsStatus.ts create mode 100644 wagmi-project/packages/core/src/query/waitForTransactionReceipt.test.ts create mode 100644 wagmi-project/packages/core/src/query/waitForTransactionReceipt.ts create mode 100644 wagmi-project/packages/core/src/query/watchAsset.test.ts create mode 100644 wagmi-project/packages/core/src/query/watchAsset.ts create mode 100644 wagmi-project/packages/core/src/query/writeContract.test-d.ts create mode 100644 wagmi-project/packages/core/src/query/writeContract.test.ts create mode 100644 wagmi-project/packages/core/src/query/writeContract.ts create mode 100644 wagmi-project/packages/core/src/transports/connector.test.ts create mode 100644 wagmi-project/packages/core/src/transports/connector.ts create mode 100644 wagmi-project/packages/core/src/transports/fallback.test.ts create mode 100644 wagmi-project/packages/core/src/transports/fallback.ts create mode 100644 wagmi-project/packages/core/src/types/chain.test-d.ts create mode 100644 wagmi-project/packages/core/src/types/chain.ts create mode 100644 wagmi-project/packages/core/src/types/properties.ts create mode 100644 wagmi-project/packages/core/src/types/register.ts create mode 100644 wagmi-project/packages/core/src/types/unit.ts create mode 100644 wagmi-project/packages/core/src/types/utils.test-d.ts create mode 100644 wagmi-project/packages/core/src/types/utils.ts create mode 100644 wagmi-project/packages/core/src/utils/cookie.test.ts create mode 100644 wagmi-project/packages/core/src/utils/cookie.ts create mode 100644 wagmi-project/packages/core/src/utils/deepEqual.test.ts create mode 100644 wagmi-project/packages/core/src/utils/deepEqual.ts create mode 100644 wagmi-project/packages/core/src/utils/deserialize.test.ts create mode 100644 wagmi-project/packages/core/src/utils/deserialize.ts create mode 100644 wagmi-project/packages/core/src/utils/extractRpcUrls.test.ts create mode 100644 wagmi-project/packages/core/src/utils/extractRpcUrls.ts create mode 100644 wagmi-project/packages/core/src/utils/getAction.test.ts create mode 100644 wagmi-project/packages/core/src/utils/getAction.ts create mode 100644 wagmi-project/packages/core/src/utils/getUnit.test.ts create mode 100644 wagmi-project/packages/core/src/utils/getUnit.ts create mode 100644 wagmi-project/packages/core/src/utils/getVersion.test.ts create mode 100644 wagmi-project/packages/core/src/utils/getVersion.ts create mode 100644 wagmi-project/packages/core/src/utils/normalizeChainId.test.ts create mode 100644 wagmi-project/packages/core/src/utils/normalizeChainId.ts create mode 100644 wagmi-project/packages/core/src/utils/serialize.test.ts create mode 100644 wagmi-project/packages/core/src/utils/serialize.ts create mode 100644 wagmi-project/packages/core/src/utils/uid.ts create mode 100644 wagmi-project/packages/core/src/version.ts create mode 100644 wagmi-project/packages/core/test/setup.ts create mode 100644 wagmi-project/packages/core/tsconfig.build.json create mode 100644 wagmi-project/packages/core/tsconfig.json create mode 100644 wagmi-project/packages/create-wagmi/CHANGELOG.md create mode 100644 wagmi-project/packages/create-wagmi/README.md create mode 100644 wagmi-project/packages/create-wagmi/package.json create mode 100644 wagmi-project/packages/create-wagmi/src/cli.test.ts create mode 100644 wagmi-project/packages/create-wagmi/src/cli.ts create mode 100644 wagmi-project/packages/create-wagmi/src/frameworks.ts create mode 100644 wagmi-project/packages/create-wagmi/src/index.test-d.ts create mode 100644 wagmi-project/packages/create-wagmi/src/utils.ts create mode 100644 wagmi-project/packages/create-wagmi/src/version.ts create mode 100644 wagmi-project/packages/create-wagmi/templates/next/README.md create mode 100644 wagmi-project/packages/create-wagmi/templates/next/_env.local create mode 100644 wagmi-project/packages/create-wagmi/templates/next/_gitignore create mode 100644 wagmi-project/packages/create-wagmi/templates/next/_npmrc create mode 100644 wagmi-project/packages/create-wagmi/templates/next/next-env.d.ts create mode 100644 wagmi-project/packages/create-wagmi/templates/next/next.config.js create mode 100644 wagmi-project/packages/create-wagmi/templates/next/package.json create mode 100644 wagmi-project/packages/create-wagmi/templates/next/src/app/globals.css create mode 100644 wagmi-project/packages/create-wagmi/templates/next/src/app/layout.tsx create mode 100644 wagmi-project/packages/create-wagmi/templates/next/src/app/page.tsx create mode 100644 wagmi-project/packages/create-wagmi/templates/next/src/app/providers.tsx create mode 100644 wagmi-project/packages/create-wagmi/templates/next/src/wagmi.ts create mode 100644 wagmi-project/packages/create-wagmi/templates/next/tsconfig.json create mode 100644 wagmi-project/packages/create-wagmi/templates/nuxt/_env.local create mode 100644 wagmi-project/packages/create-wagmi/templates/nuxt/_gitignore create mode 100644 wagmi-project/packages/create-wagmi/templates/nuxt/_npmrc create mode 100644 wagmi-project/packages/create-wagmi/templates/nuxt/app.vue create mode 100644 wagmi-project/packages/create-wagmi/templates/nuxt/components/Account.vue create mode 100644 wagmi-project/packages/create-wagmi/templates/nuxt/components/Connect.vue create mode 100644 wagmi-project/packages/create-wagmi/templates/nuxt/nuxt.config.ts create mode 100644 wagmi-project/packages/create-wagmi/templates/nuxt/package.json create mode 100644 wagmi-project/packages/create-wagmi/templates/nuxt/plugins/wagmi.ts create mode 100644 wagmi-project/packages/create-wagmi/templates/nuxt/server/tsconfig.json create mode 100644 wagmi-project/packages/create-wagmi/templates/nuxt/tsconfig.json create mode 100644 wagmi-project/packages/create-wagmi/templates/nuxt/wagmi.ts create mode 100644 wagmi-project/packages/create-wagmi/templates/vite-react/README.md create mode 100644 wagmi-project/packages/create-wagmi/templates/vite-react/_env.local create mode 100644 wagmi-project/packages/create-wagmi/templates/vite-react/_gitignore create mode 100644 wagmi-project/packages/create-wagmi/templates/vite-react/_npmrc create mode 100644 wagmi-project/packages/create-wagmi/templates/vite-react/biome.json create mode 100644 wagmi-project/packages/create-wagmi/templates/vite-react/index.html create mode 100644 wagmi-project/packages/create-wagmi/templates/vite-react/package.json create mode 100644 wagmi-project/packages/create-wagmi/templates/vite-react/src/App.tsx create mode 100644 wagmi-project/packages/create-wagmi/templates/vite-react/src/index.css create mode 100644 wagmi-project/packages/create-wagmi/templates/vite-react/src/main.tsx create mode 100644 wagmi-project/packages/create-wagmi/templates/vite-react/src/vite-env.d.ts create mode 100644 wagmi-project/packages/create-wagmi/templates/vite-react/src/wagmi.ts create mode 100644 wagmi-project/packages/create-wagmi/templates/vite-react/tsconfig.json create mode 100644 wagmi-project/packages/create-wagmi/templates/vite-react/tsconfig.node.json create mode 100644 wagmi-project/packages/create-wagmi/templates/vite-react/vite.config.ts create mode 100644 wagmi-project/packages/create-wagmi/templates/vite-vanilla/_env.local create mode 100644 wagmi-project/packages/create-wagmi/templates/vite-vanilla/_gitignore create mode 100644 wagmi-project/packages/create-wagmi/templates/vite-vanilla/_npmrc create mode 100644 wagmi-project/packages/create-wagmi/templates/vite-vanilla/index.html create mode 100644 wagmi-project/packages/create-wagmi/templates/vite-vanilla/package.json create mode 100644 wagmi-project/packages/create-wagmi/templates/vite-vanilla/src/main.ts create mode 100644 wagmi-project/packages/create-wagmi/templates/vite-vanilla/src/style.css create mode 100644 wagmi-project/packages/create-wagmi/templates/vite-vanilla/src/vite-env.d.ts create mode 100644 wagmi-project/packages/create-wagmi/templates/vite-vanilla/src/wagmi.ts create mode 100644 wagmi-project/packages/create-wagmi/templates/vite-vanilla/tsconfig.json create mode 100644 wagmi-project/packages/create-wagmi/templates/vite-vue/README.md create mode 100644 wagmi-project/packages/create-wagmi/templates/vite-vue/_env.local create mode 100644 wagmi-project/packages/create-wagmi/templates/vite-vue/_gitignore create mode 100644 wagmi-project/packages/create-wagmi/templates/vite-vue/_npmrc create mode 100644 wagmi-project/packages/create-wagmi/templates/vite-vue/biome.json create mode 100644 wagmi-project/packages/create-wagmi/templates/vite-vue/index.html create mode 100644 wagmi-project/packages/create-wagmi/templates/vite-vue/package.json create mode 100644 wagmi-project/packages/create-wagmi/templates/vite-vue/src/App.vue create mode 100644 wagmi-project/packages/create-wagmi/templates/vite-vue/src/components/Account.vue create mode 100644 wagmi-project/packages/create-wagmi/templates/vite-vue/src/components/Connect.vue create mode 100644 wagmi-project/packages/create-wagmi/templates/vite-vue/src/main.ts create mode 100644 wagmi-project/packages/create-wagmi/templates/vite-vue/src/style.css create mode 100644 wagmi-project/packages/create-wagmi/templates/vite-vue/src/vite-env.d.ts create mode 100644 wagmi-project/packages/create-wagmi/templates/vite-vue/src/wagmi.ts create mode 100644 wagmi-project/packages/create-wagmi/templates/vite-vue/tsconfig.json create mode 100644 wagmi-project/packages/create-wagmi/templates/vite-vue/tsconfig.node.json create mode 100644 wagmi-project/packages/create-wagmi/templates/vite-vue/vite.config.ts create mode 100644 wagmi-project/packages/create-wagmi/tsconfig.build.json create mode 100644 wagmi-project/packages/create-wagmi/tsconfig.json create mode 100644 wagmi-project/packages/react/CHANGELOG.md create mode 100644 wagmi-project/packages/react/README.md create mode 100644 wagmi-project/packages/react/package.json create mode 100644 wagmi-project/packages/react/src/context.test.tsx create mode 100644 wagmi-project/packages/react/src/context.ts create mode 100644 wagmi-project/packages/react/src/errors/base.test.ts create mode 100644 wagmi-project/packages/react/src/errors/base.ts create mode 100644 wagmi-project/packages/react/src/errors/context.test.ts create mode 100644 wagmi-project/packages/react/src/errors/context.ts create mode 100644 wagmi-project/packages/react/src/experimental/hooks/useWriteContracts.test.ts create mode 100644 wagmi-project/packages/react/src/experimental/hooks/useWriteContracts.ts create mode 100644 wagmi-project/packages/react/src/exports/actions.test.ts create mode 100644 wagmi-project/packages/react/src/exports/actions.ts create mode 100644 wagmi-project/packages/react/src/exports/actions/experimental.test.ts create mode 100644 wagmi-project/packages/react/src/exports/actions/experimental.ts create mode 100644 wagmi-project/packages/react/src/exports/chains.ts create mode 100644 wagmi-project/packages/react/src/exports/codegen.test.ts create mode 100644 wagmi-project/packages/react/src/exports/codegen.ts create mode 100644 wagmi-project/packages/react/src/exports/connectors.test.ts create mode 100644 wagmi-project/packages/react/src/exports/connectors.ts create mode 100644 wagmi-project/packages/react/src/exports/experimental.ts create mode 100644 wagmi-project/packages/react/src/exports/index.test.ts create mode 100644 wagmi-project/packages/react/src/exports/index.ts create mode 100644 wagmi-project/packages/react/src/exports/query.test.ts create mode 100644 wagmi-project/packages/react/src/exports/query.ts create mode 100644 wagmi-project/packages/react/src/hooks/codegen/createUseReadContract.test-d.ts create mode 100644 wagmi-project/packages/react/src/hooks/codegen/createUseReadContract.test.ts create mode 100644 wagmi-project/packages/react/src/hooks/codegen/createUseReadContract.ts create mode 100644 wagmi-project/packages/react/src/hooks/codegen/createUseSimulateContract.test-d.ts create mode 100644 wagmi-project/packages/react/src/hooks/codegen/createUseSimulateContract.test.ts create mode 100644 wagmi-project/packages/react/src/hooks/codegen/createUseSimulateContract.ts create mode 100644 wagmi-project/packages/react/src/hooks/codegen/createUseWatchContractEvent.test-d.ts create mode 100644 wagmi-project/packages/react/src/hooks/codegen/createUseWatchContractEvent.test.ts create mode 100644 wagmi-project/packages/react/src/hooks/codegen/createUseWatchContractEvent.ts create mode 100644 wagmi-project/packages/react/src/hooks/codegen/createUseWriteContract.test-d.ts create mode 100644 wagmi-project/packages/react/src/hooks/codegen/createUseWriteContract.test.ts create mode 100644 wagmi-project/packages/react/src/hooks/codegen/createUseWriteContract.ts create mode 100644 wagmi-project/packages/react/src/hooks/useAccount.test-d.ts create mode 100644 wagmi-project/packages/react/src/hooks/useAccount.test.ts create mode 100644 wagmi-project/packages/react/src/hooks/useAccount.ts create mode 100644 wagmi-project/packages/react/src/hooks/useAccountEffect.test.ts create mode 100644 wagmi-project/packages/react/src/hooks/useAccountEffect.ts create mode 100644 wagmi-project/packages/react/src/hooks/useBalance.test-d.ts create mode 100644 wagmi-project/packages/react/src/hooks/useBalance.test.ts create mode 100644 wagmi-project/packages/react/src/hooks/useBalance.ts create mode 100644 wagmi-project/packages/react/src/hooks/useBlock.test-d.ts create mode 100644 wagmi-project/packages/react/src/hooks/useBlock.test.ts create mode 100644 wagmi-project/packages/react/src/hooks/useBlock.ts create mode 100644 wagmi-project/packages/react/src/hooks/useBlockNumber.test-d.ts create mode 100644 wagmi-project/packages/react/src/hooks/useBlockNumber.test.ts create mode 100644 wagmi-project/packages/react/src/hooks/useBlockNumber.ts create mode 100644 wagmi-project/packages/react/src/hooks/useBlockTransactionCount.test-d.ts create mode 100644 wagmi-project/packages/react/src/hooks/useBlockTransactionCount.test.ts create mode 100644 wagmi-project/packages/react/src/hooks/useBlockTransactionCount.ts create mode 100644 wagmi-project/packages/react/src/hooks/useBytecode.test-d.ts create mode 100644 wagmi-project/packages/react/src/hooks/useBytecode.test.ts create mode 100644 wagmi-project/packages/react/src/hooks/useBytecode.ts create mode 100644 wagmi-project/packages/react/src/hooks/useCall.test-d.ts create mode 100644 wagmi-project/packages/react/src/hooks/useCall.test.ts create mode 100644 wagmi-project/packages/react/src/hooks/useCall.ts create mode 100644 wagmi-project/packages/react/src/hooks/useCallsStatus.test.ts create mode 100644 wagmi-project/packages/react/src/hooks/useCallsStatus.ts create mode 100644 wagmi-project/packages/react/src/hooks/useCapabilities.test.ts create mode 100644 wagmi-project/packages/react/src/hooks/useCapabilities.ts create mode 100644 wagmi-project/packages/react/src/hooks/useChainId.test-d.ts create mode 100644 wagmi-project/packages/react/src/hooks/useChainId.test.ts create mode 100644 wagmi-project/packages/react/src/hooks/useChainId.ts create mode 100644 wagmi-project/packages/react/src/hooks/useChains.test.ts create mode 100644 wagmi-project/packages/react/src/hooks/useChains.ts create mode 100644 wagmi-project/packages/react/src/hooks/useClient.test-d.ts create mode 100644 wagmi-project/packages/react/src/hooks/useClient.test.ts create mode 100644 wagmi-project/packages/react/src/hooks/useClient.ts create mode 100644 wagmi-project/packages/react/src/hooks/useConfig.test-d.ts create mode 100644 wagmi-project/packages/react/src/hooks/useConfig.test.ts create mode 100644 wagmi-project/packages/react/src/hooks/useConfig.ts create mode 100644 wagmi-project/packages/react/src/hooks/useConnect.test-d.ts create mode 100644 wagmi-project/packages/react/src/hooks/useConnect.test.ts create mode 100644 wagmi-project/packages/react/src/hooks/useConnect.ts create mode 100644 wagmi-project/packages/react/src/hooks/useConnections.test.ts create mode 100644 wagmi-project/packages/react/src/hooks/useConnections.ts create mode 100644 wagmi-project/packages/react/src/hooks/useConnectorClient.test-d.ts create mode 100644 wagmi-project/packages/react/src/hooks/useConnectorClient.test.tsx create mode 100644 wagmi-project/packages/react/src/hooks/useConnectorClient.ts create mode 100644 wagmi-project/packages/react/src/hooks/useConnectors.test.ts create mode 100644 wagmi-project/packages/react/src/hooks/useConnectors.ts create mode 100644 wagmi-project/packages/react/src/hooks/useDeployContract.test-d.ts create mode 100644 wagmi-project/packages/react/src/hooks/useDeployContract.test.ts create mode 100644 wagmi-project/packages/react/src/hooks/useDeployContract.ts create mode 100644 wagmi-project/packages/react/src/hooks/useDisconnect.test-d.ts create mode 100644 wagmi-project/packages/react/src/hooks/useDisconnect.test.ts create mode 100644 wagmi-project/packages/react/src/hooks/useDisconnect.ts create mode 100644 wagmi-project/packages/react/src/hooks/useEnsAddress.test.ts create mode 100644 wagmi-project/packages/react/src/hooks/useEnsAddress.ts create mode 100644 wagmi-project/packages/react/src/hooks/useEnsAvatar.test.ts create mode 100644 wagmi-project/packages/react/src/hooks/useEnsAvatar.ts create mode 100644 wagmi-project/packages/react/src/hooks/useEnsName.test.ts create mode 100644 wagmi-project/packages/react/src/hooks/useEnsName.ts create mode 100644 wagmi-project/packages/react/src/hooks/useEnsResolver.test.ts create mode 100644 wagmi-project/packages/react/src/hooks/useEnsResolver.ts create mode 100644 wagmi-project/packages/react/src/hooks/useEnsText.test.ts create mode 100644 wagmi-project/packages/react/src/hooks/useEnsText.ts create mode 100644 wagmi-project/packages/react/src/hooks/useEstimateFeesPerGas.test-d.ts create mode 100644 wagmi-project/packages/react/src/hooks/useEstimateFeesPerGas.test.ts create mode 100644 wagmi-project/packages/react/src/hooks/useEstimateFeesPerGas.ts create mode 100644 wagmi-project/packages/react/src/hooks/useEstimateGas.test-d.ts create mode 100644 wagmi-project/packages/react/src/hooks/useEstimateGas.test.ts create mode 100644 wagmi-project/packages/react/src/hooks/useEstimateGas.ts create mode 100644 wagmi-project/packages/react/src/hooks/useEstimateMaxPriorityFeePerGas.test-d.ts create mode 100644 wagmi-project/packages/react/src/hooks/useEstimateMaxPriorityFeePerGas.test.ts create mode 100644 wagmi-project/packages/react/src/hooks/useEstimateMaxPriorityFeePerGas.ts create mode 100644 wagmi-project/packages/react/src/hooks/useFeeHistory.test-d.ts create mode 100644 wagmi-project/packages/react/src/hooks/useFeeHistory.test.ts create mode 100644 wagmi-project/packages/react/src/hooks/useFeeHistory.ts create mode 100644 wagmi-project/packages/react/src/hooks/useGasPrice.test-d.ts create mode 100644 wagmi-project/packages/react/src/hooks/useGasPrice.test.ts create mode 100644 wagmi-project/packages/react/src/hooks/useGasPrice.ts create mode 100644 wagmi-project/packages/react/src/hooks/useInfiniteReadContracts.test-d.ts create mode 100644 wagmi-project/packages/react/src/hooks/useInfiniteReadContracts.test.ts create mode 100644 wagmi-project/packages/react/src/hooks/useInfiniteReadContracts.ts create mode 100644 wagmi-project/packages/react/src/hooks/usePrepareTransactionRequest.test-d.ts create mode 100644 wagmi-project/packages/react/src/hooks/usePrepareTransactionRequest.test.ts create mode 100644 wagmi-project/packages/react/src/hooks/usePrepareTransactionRequest.ts create mode 100644 wagmi-project/packages/react/src/hooks/useProof.test-d.ts create mode 100644 wagmi-project/packages/react/src/hooks/useProof.test.ts create mode 100644 wagmi-project/packages/react/src/hooks/useProof.ts create mode 100644 wagmi-project/packages/react/src/hooks/usePublicClient.test-d.ts create mode 100644 wagmi-project/packages/react/src/hooks/usePublicClient.test.ts create mode 100644 wagmi-project/packages/react/src/hooks/usePublicClient.ts create mode 100644 wagmi-project/packages/react/src/hooks/useReadContract.test-d.ts create mode 100644 wagmi-project/packages/react/src/hooks/useReadContract.test.ts create mode 100644 wagmi-project/packages/react/src/hooks/useReadContract.ts create mode 100644 wagmi-project/packages/react/src/hooks/useReadContracts.test-d.ts create mode 100644 wagmi-project/packages/react/src/hooks/useReadContracts.test.ts create mode 100644 wagmi-project/packages/react/src/hooks/useReadContracts.ts create mode 100644 wagmi-project/packages/react/src/hooks/useReconnect.test-d.ts create mode 100644 wagmi-project/packages/react/src/hooks/useReconnect.test.ts create mode 100644 wagmi-project/packages/react/src/hooks/useReconnect.ts create mode 100644 wagmi-project/packages/react/src/hooks/useSendCalls.test.ts create mode 100644 wagmi-project/packages/react/src/hooks/useSendCalls.ts create mode 100644 wagmi-project/packages/react/src/hooks/useSendTransaction.test-d.ts create mode 100644 wagmi-project/packages/react/src/hooks/useSendTransaction.test.ts create mode 100644 wagmi-project/packages/react/src/hooks/useSendTransaction.ts create mode 100644 wagmi-project/packages/react/src/hooks/useShowCallsStatus.ts create mode 100644 wagmi-project/packages/react/src/hooks/useSignMessage.test-d.ts create mode 100644 wagmi-project/packages/react/src/hooks/useSignMessage.test.ts create mode 100644 wagmi-project/packages/react/src/hooks/useSignMessage.ts create mode 100644 wagmi-project/packages/react/src/hooks/useSignTypedData.test-d.ts create mode 100644 wagmi-project/packages/react/src/hooks/useSignTypedData.test.ts create mode 100644 wagmi-project/packages/react/src/hooks/useSignTypedData.ts create mode 100644 wagmi-project/packages/react/src/hooks/useSimulateContract.test-d.ts create mode 100644 wagmi-project/packages/react/src/hooks/useSimulateContract.test.ts create mode 100644 wagmi-project/packages/react/src/hooks/useSimulateContract.ts create mode 100644 wagmi-project/packages/react/src/hooks/useStorageAt.test-d.ts create mode 100644 wagmi-project/packages/react/src/hooks/useStorageAt.test.ts create mode 100644 wagmi-project/packages/react/src/hooks/useStorageAt.ts create mode 100644 wagmi-project/packages/react/src/hooks/useSwitchAccount.test-d.ts create mode 100644 wagmi-project/packages/react/src/hooks/useSwitchAccount.test.ts create mode 100644 wagmi-project/packages/react/src/hooks/useSwitchAccount.ts create mode 100644 wagmi-project/packages/react/src/hooks/useSwitchChain.test-d.ts create mode 100644 wagmi-project/packages/react/src/hooks/useSwitchChain.test.ts create mode 100644 wagmi-project/packages/react/src/hooks/useSwitchChain.ts create mode 100644 wagmi-project/packages/react/src/hooks/useSyncExternalStoreWithTracked.test.tsx create mode 100644 wagmi-project/packages/react/src/hooks/useSyncExternalStoreWithTracked.ts create mode 100644 wagmi-project/packages/react/src/hooks/useToken.test-d.ts create mode 100644 wagmi-project/packages/react/src/hooks/useToken.test.ts create mode 100644 wagmi-project/packages/react/src/hooks/useToken.ts create mode 100644 wagmi-project/packages/react/src/hooks/useTransaction.test-d.ts create mode 100644 wagmi-project/packages/react/src/hooks/useTransaction.test.ts create mode 100644 wagmi-project/packages/react/src/hooks/useTransaction.ts create mode 100644 wagmi-project/packages/react/src/hooks/useTransactionConfirmations.test-d.ts create mode 100644 wagmi-project/packages/react/src/hooks/useTransactionConfirmations.test.ts create mode 100644 wagmi-project/packages/react/src/hooks/useTransactionConfirmations.ts create mode 100644 wagmi-project/packages/react/src/hooks/useTransactionCount.test-d.ts create mode 100644 wagmi-project/packages/react/src/hooks/useTransactionCount.test.ts create mode 100644 wagmi-project/packages/react/src/hooks/useTransactionCount.ts create mode 100644 wagmi-project/packages/react/src/hooks/useTransactionReceipt.test-d.ts create mode 100644 wagmi-project/packages/react/src/hooks/useTransactionReceipt.test.ts create mode 100644 wagmi-project/packages/react/src/hooks/useTransactionReceipt.ts create mode 100644 wagmi-project/packages/react/src/hooks/useVerifyMessage.test-d.ts create mode 100644 wagmi-project/packages/react/src/hooks/useVerifyMessage.test.ts create mode 100644 wagmi-project/packages/react/src/hooks/useVerifyMessage.ts create mode 100644 wagmi-project/packages/react/src/hooks/useVerifyTypedData.test-d.ts create mode 100644 wagmi-project/packages/react/src/hooks/useVerifyTypedData.test.ts create mode 100644 wagmi-project/packages/react/src/hooks/useVerifyTypedData.ts create mode 100644 wagmi-project/packages/react/src/hooks/useWaitForCallsStatus.test.ts create mode 100644 wagmi-project/packages/react/src/hooks/useWaitForCallsStatus.ts create mode 100644 wagmi-project/packages/react/src/hooks/useWaitForTransactionReceipt.test-d.ts create mode 100644 wagmi-project/packages/react/src/hooks/useWaitForTransactionReceipt.test.ts create mode 100644 wagmi-project/packages/react/src/hooks/useWaitForTransactionReceipt.ts create mode 100644 wagmi-project/packages/react/src/hooks/useWalletClient.test-d.ts create mode 100644 wagmi-project/packages/react/src/hooks/useWalletClient.test.tsx create mode 100644 wagmi-project/packages/react/src/hooks/useWalletClient.ts create mode 100644 wagmi-project/packages/react/src/hooks/useWatchAsset.test-d.ts create mode 100644 wagmi-project/packages/react/src/hooks/useWatchAsset.test.ts create mode 100644 wagmi-project/packages/react/src/hooks/useWatchAsset.ts create mode 100644 wagmi-project/packages/react/src/hooks/useWatchBlockNumber.test-d.ts create mode 100644 wagmi-project/packages/react/src/hooks/useWatchBlockNumber.test.ts create mode 100644 wagmi-project/packages/react/src/hooks/useWatchBlockNumber.ts create mode 100644 wagmi-project/packages/react/src/hooks/useWatchBlocks.test-d.ts create mode 100644 wagmi-project/packages/react/src/hooks/useWatchBlocks.test.ts create mode 100644 wagmi-project/packages/react/src/hooks/useWatchBlocks.ts create mode 100644 wagmi-project/packages/react/src/hooks/useWatchContractEvent.test-d.ts create mode 100644 wagmi-project/packages/react/src/hooks/useWatchContractEvent.test.ts create mode 100644 wagmi-project/packages/react/src/hooks/useWatchContractEvent.ts create mode 100644 wagmi-project/packages/react/src/hooks/useWatchPendingTransactions.test-d.ts create mode 100644 wagmi-project/packages/react/src/hooks/useWatchPendingTransactions.test.ts create mode 100644 wagmi-project/packages/react/src/hooks/useWatchPendingTransactions.ts create mode 100644 wagmi-project/packages/react/src/hooks/useWriteContract.test-d.ts create mode 100644 wagmi-project/packages/react/src/hooks/useWriteContract.test.ts create mode 100644 wagmi-project/packages/react/src/hooks/useWriteContract.ts create mode 100644 wagmi-project/packages/react/src/hydrate.ts create mode 100644 wagmi-project/packages/react/src/types/properties.ts create mode 100644 wagmi-project/packages/react/src/utils/getVersion.test.ts create mode 100644 wagmi-project/packages/react/src/utils/getVersion.ts create mode 100644 wagmi-project/packages/react/src/utils/query.ts create mode 100644 wagmi-project/packages/react/src/version.ts create mode 100644 wagmi-project/packages/react/test/setup.ts create mode 100644 wagmi-project/packages/react/tsconfig.build.json create mode 100644 wagmi-project/packages/react/tsconfig.json create mode 100644 wagmi-project/packages/register-tests/react/package.json create mode 100644 wagmi-project/packages/register-tests/react/src/config.ts create mode 100644 wagmi-project/packages/register-tests/react/src/createUseSimulateContract.test-d.ts create mode 100644 wagmi-project/packages/register-tests/react/src/createUseWriteContract.test-d.ts create mode 100644 wagmi-project/packages/register-tests/react/src/useAccount.test-d.ts create mode 100644 wagmi-project/packages/register-tests/react/src/useBlock.test-d.ts create mode 100644 wagmi-project/packages/register-tests/react/src/useChainId.test-d.ts create mode 100644 wagmi-project/packages/register-tests/react/src/useChains.test-d.ts create mode 100644 wagmi-project/packages/register-tests/react/src/useClient.test-d.ts create mode 100644 wagmi-project/packages/register-tests/react/src/useConfig.test-d.ts create mode 100644 wagmi-project/packages/register-tests/react/src/useConnect.test-d.ts create mode 100644 wagmi-project/packages/register-tests/react/src/usePrepareTransactionRequest.test-d.ts create mode 100644 wagmi-project/packages/register-tests/react/src/usePublicClient.ts create mode 100644 wagmi-project/packages/register-tests/react/src/useReadContract.test-d.ts create mode 100644 wagmi-project/packages/register-tests/react/src/useReadContracts.test-d.ts create mode 100644 wagmi-project/packages/register-tests/react/src/useSendTransaction.test-d.ts create mode 100644 wagmi-project/packages/register-tests/react/src/useSimulateContract.test-d.ts create mode 100644 wagmi-project/packages/register-tests/react/src/useSwitchChain.test-d.ts create mode 100644 wagmi-project/packages/register-tests/react/src/useTransaction.test-d.ts create mode 100644 wagmi-project/packages/register-tests/react/src/useTransactionConfirmations.test-d.ts create mode 100644 wagmi-project/packages/register-tests/react/src/useTransactionReceipt.test-d.ts create mode 100644 wagmi-project/packages/register-tests/react/src/useWaitForTransactionReceipt.ts create mode 100644 wagmi-project/packages/register-tests/react/src/useWriteContract.test-d.ts create mode 100644 wagmi-project/packages/register-tests/react/tsconfig.json create mode 100644 wagmi-project/packages/register-tests/vue/package.json create mode 100644 wagmi-project/packages/register-tests/vue/src/config.ts create mode 100644 wagmi-project/packages/register-tests/vue/src/useAccount.test-d.ts create mode 100644 wagmi-project/packages/register-tests/vue/src/useChainId.test-d.ts create mode 100644 wagmi-project/packages/register-tests/vue/src/useChains.test-d.ts create mode 100644 wagmi-project/packages/register-tests/vue/src/useClient.test-d.ts create mode 100644 wagmi-project/packages/register-tests/vue/src/useConfig.test-d.ts create mode 100644 wagmi-project/packages/register-tests/vue/src/useConnect.test-d.ts create mode 100644 wagmi-project/packages/register-tests/vue/src/useReadContract.test-d.ts create mode 100644 wagmi-project/packages/register-tests/vue/src/useSendTransaction.test-d.ts create mode 100644 wagmi-project/packages/register-tests/vue/src/useSimulateContract.test-d.ts create mode 100644 wagmi-project/packages/register-tests/vue/src/useSwitchChain.test-d.ts create mode 100644 wagmi-project/packages/register-tests/vue/src/useTransaction.test-d.ts create mode 100644 wagmi-project/packages/register-tests/vue/src/useTransactionReceipt.test-d.ts create mode 100644 wagmi-project/packages/register-tests/vue/src/useWaitForTransaction.test-d.ts create mode 100644 wagmi-project/packages/register-tests/vue/src/useWriteContract.test-d.ts create mode 100644 wagmi-project/packages/register-tests/vue/tsconfig.json create mode 100644 wagmi-project/packages/test/package.json create mode 100644 wagmi-project/packages/test/src/chains.ts create mode 100644 wagmi-project/packages/test/src/clients.ts create mode 100644 wagmi-project/packages/test/src/config.ts create mode 100644 wagmi-project/packages/test/src/constants.ts create mode 100644 wagmi-project/packages/test/src/exports/index.test-d.ts create mode 100644 wagmi-project/packages/test/src/exports/index.test.ts create mode 100644 wagmi-project/packages/test/src/exports/index.ts create mode 100644 wagmi-project/packages/test/src/exports/react.ts create mode 100644 wagmi-project/packages/test/src/exports/vue.ts create mode 100644 wagmi-project/packages/test/src/globalSetup.ts create mode 100644 wagmi-project/packages/test/src/regex.ts create mode 100644 wagmi-project/packages/test/src/setup.ts create mode 100644 wagmi-project/packages/test/src/utils.ts create mode 100644 wagmi-project/packages/test/tsconfig.build.json create mode 100644 wagmi-project/packages/test/tsconfig.json create mode 100644 wagmi-project/packages/vue/CHANGELOG.md create mode 100644 wagmi-project/packages/vue/README.md create mode 100644 wagmi-project/packages/vue/package.json create mode 100644 wagmi-project/packages/vue/src/composables/useAccount.test-d.ts create mode 100644 wagmi-project/packages/vue/src/composables/useAccount.test.ts create mode 100644 wagmi-project/packages/vue/src/composables/useAccount.ts create mode 100644 wagmi-project/packages/vue/src/composables/useAccountEffect.test.ts create mode 100644 wagmi-project/packages/vue/src/composables/useAccountEffect.ts create mode 100644 wagmi-project/packages/vue/src/composables/useBalance.test-d.ts create mode 100644 wagmi-project/packages/vue/src/composables/useBalance.test.ts create mode 100644 wagmi-project/packages/vue/src/composables/useBalance.ts create mode 100644 wagmi-project/packages/vue/src/composables/useBlockNumber.test-d.ts create mode 100644 wagmi-project/packages/vue/src/composables/useBlockNumber.test.ts create mode 100644 wagmi-project/packages/vue/src/composables/useBlockNumber.ts create mode 100644 wagmi-project/packages/vue/src/composables/useBytecode.test-d.ts create mode 100644 wagmi-project/packages/vue/src/composables/useBytecode.test.ts create mode 100644 wagmi-project/packages/vue/src/composables/useBytecode.ts create mode 100644 wagmi-project/packages/vue/src/composables/useChainId.test-d.ts create mode 100644 wagmi-project/packages/vue/src/composables/useChainId.test.ts create mode 100644 wagmi-project/packages/vue/src/composables/useChainId.ts create mode 100644 wagmi-project/packages/vue/src/composables/useChains.test.ts create mode 100644 wagmi-project/packages/vue/src/composables/useChains.ts create mode 100644 wagmi-project/packages/vue/src/composables/useClient.test-d.ts create mode 100644 wagmi-project/packages/vue/src/composables/useClient.test.ts create mode 100644 wagmi-project/packages/vue/src/composables/useClient.ts create mode 100644 wagmi-project/packages/vue/src/composables/useConfig.test-d.ts create mode 100644 wagmi-project/packages/vue/src/composables/useConfig.test.ts create mode 100644 wagmi-project/packages/vue/src/composables/useConfig.ts create mode 100644 wagmi-project/packages/vue/src/composables/useConnect.test-d.ts create mode 100644 wagmi-project/packages/vue/src/composables/useConnect.test.ts create mode 100644 wagmi-project/packages/vue/src/composables/useConnect.ts create mode 100644 wagmi-project/packages/vue/src/composables/useConnections.test.ts create mode 100644 wagmi-project/packages/vue/src/composables/useConnections.ts create mode 100644 wagmi-project/packages/vue/src/composables/useConnectorClient.test-d.ts create mode 100644 wagmi-project/packages/vue/src/composables/useConnectorClient.test.ts create mode 100644 wagmi-project/packages/vue/src/composables/useConnectorClient.ts create mode 100644 wagmi-project/packages/vue/src/composables/useConnectors.test.ts create mode 100644 wagmi-project/packages/vue/src/composables/useConnectors.ts create mode 100644 wagmi-project/packages/vue/src/composables/useDisconnect.test-d.ts create mode 100644 wagmi-project/packages/vue/src/composables/useDisconnect.test.ts create mode 100644 wagmi-project/packages/vue/src/composables/useDisconnect.ts create mode 100644 wagmi-project/packages/vue/src/composables/useEnsAddress.test.ts create mode 100644 wagmi-project/packages/vue/src/composables/useEnsAddress.ts create mode 100644 wagmi-project/packages/vue/src/composables/useEnsAvatar.test.ts create mode 100644 wagmi-project/packages/vue/src/composables/useEnsAvatar.ts create mode 100644 wagmi-project/packages/vue/src/composables/useEnsName.test.ts create mode 100644 wagmi-project/packages/vue/src/composables/useEnsName.ts create mode 100644 wagmi-project/packages/vue/src/composables/useEstimateGas.test-d.ts create mode 100644 wagmi-project/packages/vue/src/composables/useEstimateGas.test.ts create mode 100644 wagmi-project/packages/vue/src/composables/useEstimateGas.ts create mode 100644 wagmi-project/packages/vue/src/composables/useReadContract.test-d.ts create mode 100644 wagmi-project/packages/vue/src/composables/useReadContract.test.ts create mode 100644 wagmi-project/packages/vue/src/composables/useReadContract.ts create mode 100644 wagmi-project/packages/vue/src/composables/useReconnect.test-d.ts create mode 100644 wagmi-project/packages/vue/src/composables/useReconnect.test.ts create mode 100644 wagmi-project/packages/vue/src/composables/useReconnect.ts create mode 100644 wagmi-project/packages/vue/src/composables/useSendTransaction.test-d.ts create mode 100644 wagmi-project/packages/vue/src/composables/useSendTransaction.test.ts create mode 100644 wagmi-project/packages/vue/src/composables/useSendTransaction.ts create mode 100644 wagmi-project/packages/vue/src/composables/useSignMessage.test-d.ts create mode 100644 wagmi-project/packages/vue/src/composables/useSignMessage.test.ts create mode 100644 wagmi-project/packages/vue/src/composables/useSignMessage.ts create mode 100644 wagmi-project/packages/vue/src/composables/useSignTypedData.test-d.ts create mode 100644 wagmi-project/packages/vue/src/composables/useSignTypedData.test.ts create mode 100644 wagmi-project/packages/vue/src/composables/useSignTypedData.ts create mode 100644 wagmi-project/packages/vue/src/composables/useSimulateContract.test-d.ts create mode 100644 wagmi-project/packages/vue/src/composables/useSimulateContract.test.ts create mode 100644 wagmi-project/packages/vue/src/composables/useSimulateContract.ts create mode 100644 wagmi-project/packages/vue/src/composables/useSwitchAccount.test-d.ts create mode 100644 wagmi-project/packages/vue/src/composables/useSwitchAccount.test.ts create mode 100644 wagmi-project/packages/vue/src/composables/useSwitchAccount.ts create mode 100644 wagmi-project/packages/vue/src/composables/useSwitchChain.test-d.ts create mode 100644 wagmi-project/packages/vue/src/composables/useSwitchChain.test.ts create mode 100644 wagmi-project/packages/vue/src/composables/useSwitchChain.ts create mode 100644 wagmi-project/packages/vue/src/composables/useTransaction.test-d.ts create mode 100644 wagmi-project/packages/vue/src/composables/useTransaction.test.ts create mode 100644 wagmi-project/packages/vue/src/composables/useTransaction.ts create mode 100644 wagmi-project/packages/vue/src/composables/useTransactionReceipt.test-d.ts create mode 100644 wagmi-project/packages/vue/src/composables/useTransactionReceipt.test.ts create mode 100644 wagmi-project/packages/vue/src/composables/useTransactionReceipt.ts create mode 100644 wagmi-project/packages/vue/src/composables/useWaitForTransactionReceipt.test-d.ts create mode 100644 wagmi-project/packages/vue/src/composables/useWaitForTransactionReceipt.test.ts create mode 100644 wagmi-project/packages/vue/src/composables/useWaitForTransactionReceipt.ts create mode 100644 wagmi-project/packages/vue/src/composables/useWatchBlockNumber.test-d.ts create mode 100644 wagmi-project/packages/vue/src/composables/useWatchBlockNumber.test.ts create mode 100644 wagmi-project/packages/vue/src/composables/useWatchBlockNumber.ts create mode 100644 wagmi-project/packages/vue/src/composables/useWatchContractEvent.test-d.ts create mode 100644 wagmi-project/packages/vue/src/composables/useWatchContractEvent.test.ts create mode 100644 wagmi-project/packages/vue/src/composables/useWatchContractEvent.ts create mode 100644 wagmi-project/packages/vue/src/composables/useWriteContract.test-d.ts create mode 100644 wagmi-project/packages/vue/src/composables/useWriteContract.test.ts create mode 100644 wagmi-project/packages/vue/src/composables/useWriteContract.ts create mode 100644 wagmi-project/packages/vue/src/errors/base.test.ts create mode 100644 wagmi-project/packages/vue/src/errors/base.ts create mode 100644 wagmi-project/packages/vue/src/errors/plugin.test.ts create mode 100644 wagmi-project/packages/vue/src/errors/plugin.ts create mode 100644 wagmi-project/packages/vue/src/exports/actions.test.ts create mode 100644 wagmi-project/packages/vue/src/exports/actions.ts create mode 100644 wagmi-project/packages/vue/src/exports/actions/experimental.test.ts create mode 100644 wagmi-project/packages/vue/src/exports/actions/experimental.ts create mode 100644 wagmi-project/packages/vue/src/exports/chains.ts create mode 100644 wagmi-project/packages/vue/src/exports/connectors.test.ts create mode 100644 wagmi-project/packages/vue/src/exports/connectors.ts create mode 100644 wagmi-project/packages/vue/src/exports/index.test.ts create mode 100644 wagmi-project/packages/vue/src/exports/index.ts create mode 100644 wagmi-project/packages/vue/src/exports/nuxt.test.ts create mode 100644 wagmi-project/packages/vue/src/exports/nuxt.ts create mode 100644 wagmi-project/packages/vue/src/exports/query.test.ts create mode 100644 wagmi-project/packages/vue/src/exports/query.ts create mode 100644 wagmi-project/packages/vue/src/nuxt/module.ts create mode 100644 wagmi-project/packages/vue/src/nuxt/runtime/composables.ts create mode 100644 wagmi-project/packages/vue/src/plugin.ts create mode 100644 wagmi-project/packages/vue/src/types/properties.ts create mode 100644 wagmi-project/packages/vue/src/types/ref.ts create mode 100644 wagmi-project/packages/vue/src/utils/cloneDeep.ts create mode 100644 wagmi-project/packages/vue/src/utils/getVersion.test.ts create mode 100644 wagmi-project/packages/vue/src/utils/getVersion.ts create mode 100644 wagmi-project/packages/vue/src/utils/query.ts create mode 100644 wagmi-project/packages/vue/src/utils/updateState.ts create mode 100644 wagmi-project/packages/vue/src/version.ts create mode 100644 wagmi-project/packages/vue/test/setup.ts create mode 100644 wagmi-project/packages/vue/tsconfig.build.json create mode 100644 wagmi-project/packages/vue/tsconfig.json create mode 100644 wagmi-project/playgrounds/next/.gitignore create mode 100644 wagmi-project/playgrounds/next/next.config.mjs create mode 100644 wagmi-project/playgrounds/next/package.json create mode 100644 wagmi-project/playgrounds/next/src/app/contracts.ts create mode 100644 wagmi-project/playgrounds/next/src/app/globals.css create mode 100644 wagmi-project/playgrounds/next/src/app/layout.tsx create mode 100644 wagmi-project/playgrounds/next/src/app/page.tsx create mode 100644 wagmi-project/playgrounds/next/src/app/providers.tsx create mode 100644 wagmi-project/playgrounds/next/src/wagmi.ts create mode 100644 wagmi-project/playgrounds/next/tsconfig.json create mode 100644 wagmi-project/playgrounds/nuxt/.gitignore create mode 100644 wagmi-project/playgrounds/nuxt/app.vue create mode 100644 wagmi-project/playgrounds/nuxt/components/Account.vue create mode 100644 wagmi-project/playgrounds/nuxt/components/Connect.vue create mode 100644 wagmi-project/playgrounds/nuxt/nuxt.config.ts create mode 100644 wagmi-project/playgrounds/nuxt/package.json create mode 100644 wagmi-project/playgrounds/nuxt/plugins/wagmi.ts create mode 100644 wagmi-project/playgrounds/nuxt/public/favicon.ico create mode 100644 wagmi-project/playgrounds/nuxt/server/tsconfig.json create mode 100644 wagmi-project/playgrounds/nuxt/tsconfig.json create mode 100644 wagmi-project/playgrounds/nuxt/wagmi.ts create mode 100644 wagmi-project/playgrounds/vite-core/.gitignore create mode 100644 wagmi-project/playgrounds/vite-core/index.html create mode 100644 wagmi-project/playgrounds/vite-core/package.json create mode 100644 wagmi-project/playgrounds/vite-core/src/App.tsx create mode 100644 wagmi-project/playgrounds/vite-core/src/index.css create mode 100644 wagmi-project/playgrounds/vite-core/src/main.tsx create mode 100644 wagmi-project/playgrounds/vite-core/src/vite-env.d.ts create mode 100644 wagmi-project/playgrounds/vite-core/src/wagmi.ts create mode 100644 wagmi-project/playgrounds/vite-core/tsconfig.json create mode 100644 wagmi-project/playgrounds/vite-core/tsconfig.node.json create mode 100644 wagmi-project/playgrounds/vite-core/vite.config.ts create mode 100644 wagmi-project/playgrounds/vite-react/.gitignore create mode 100644 wagmi-project/playgrounds/vite-react/index.html create mode 100644 wagmi-project/playgrounds/vite-react/package.json create mode 100644 wagmi-project/playgrounds/vite-react/public/manifest.json create mode 100644 wagmi-project/playgrounds/vite-react/src/App.tsx create mode 100644 wagmi-project/playgrounds/vite-react/src/contracts.ts create mode 100644 wagmi-project/playgrounds/vite-react/src/index.css create mode 100644 wagmi-project/playgrounds/vite-react/src/main.tsx create mode 100644 wagmi-project/playgrounds/vite-react/src/vite-env.d.ts create mode 100644 wagmi-project/playgrounds/vite-react/src/wagmi.ts create mode 100644 wagmi-project/playgrounds/vite-react/tsconfig.json create mode 100644 wagmi-project/playgrounds/vite-react/tsconfig.node.json create mode 100644 wagmi-project/playgrounds/vite-react/vite.config.ts create mode 100644 wagmi-project/playgrounds/vite-react/wagmi.config.ts create mode 100644 wagmi-project/playgrounds/vite-vue/.gitignore create mode 100644 wagmi-project/playgrounds/vite-vue/index.html create mode 100644 wagmi-project/playgrounds/vite-vue/package.json create mode 100644 wagmi-project/playgrounds/vite-vue/public/vite.svg create mode 100644 wagmi-project/playgrounds/vite-vue/src/App.vue create mode 100644 wagmi-project/playgrounds/vite-vue/src/components/Account.vue create mode 100644 wagmi-project/playgrounds/vite-vue/src/components/Balance.vue create mode 100644 wagmi-project/playgrounds/vite-vue/src/components/BlockNumber.vue create mode 100644 wagmi-project/playgrounds/vite-vue/src/components/Client.vue create mode 100644 wagmi-project/playgrounds/vite-vue/src/components/Connect.vue create mode 100644 wagmi-project/playgrounds/vite-vue/src/components/Connections.vue create mode 100644 wagmi-project/playgrounds/vite-vue/src/components/ConnectorClient.vue create mode 100644 wagmi-project/playgrounds/vite-vue/src/components/ReadContract.vue create mode 100644 wagmi-project/playgrounds/vite-vue/src/components/SendTransaction.vue create mode 100644 wagmi-project/playgrounds/vite-vue/src/components/SwitchAccount.vue create mode 100644 wagmi-project/playgrounds/vite-vue/src/components/SwitchChain.vue create mode 100644 wagmi-project/playgrounds/vite-vue/src/components/WriteContract.vue create mode 100644 wagmi-project/playgrounds/vite-vue/src/contracts.ts create mode 100644 wagmi-project/playgrounds/vite-vue/src/main.ts create mode 100644 wagmi-project/playgrounds/vite-vue/src/style.css create mode 100644 wagmi-project/playgrounds/vite-vue/src/vite-env.d.ts create mode 100644 wagmi-project/playgrounds/vite-vue/src/wagmi.ts create mode 100644 wagmi-project/playgrounds/vite-vue/tsconfig.json create mode 100644 wagmi-project/playgrounds/vite-vue/tsconfig.node.json create mode 100644 wagmi-project/playgrounds/vite-vue/vite.config.ts create mode 100644 wagmi-project/pnpm-lock.yaml create mode 100644 wagmi-project/pnpm-workspace.yaml create mode 100644 wagmi-project/scripts/formatPackageJson.ts create mode 100644 wagmi-project/scripts/generateProxyPackages.ts create mode 100644 wagmi-project/scripts/preconstruct.ts create mode 100644 wagmi-project/scripts/restorePackageJson.ts create mode 100644 wagmi-project/scripts/updateBlockExplorerPluginChains.ts create mode 100644 wagmi-project/scripts/updateVersion.ts create mode 100644 wagmi-project/scripts/updateViemVersion.ts create mode 100644 wagmi-project/site/.vitepress/config.ts create mode 100644 wagmi-project/site/.vitepress/constants.ts create mode 100644 wagmi-project/site/.vitepress/sidebar.ts create mode 100644 wagmi-project/site/.vitepress/theme/components/AsideSponsors.vue create mode 100644 wagmi-project/site/.vitepress/theme/components/Banner.vue create mode 100644 wagmi-project/site/.vitepress/theme/components/HomeBanner.vue create mode 100644 wagmi-project/site/.vitepress/theme/components/HomePage.vue create mode 100644 wagmi-project/site/.vitepress/theme/composables/useSponsors.ts create mode 100644 wagmi-project/site/.vitepress/theme/index.ts create mode 100644 wagmi-project/site/.vitepress/theme/style.css create mode 100644 wagmi-project/site/cli/api/commands.md create mode 100644 wagmi-project/site/cli/api/commands/generate.md create mode 100644 wagmi-project/site/cli/api/commands/init.md create mode 100644 wagmi-project/site/cli/api/plugins.md create mode 100644 wagmi-project/site/cli/api/plugins/actions.md create mode 100644 wagmi-project/site/cli/api/plugins/blockExplorer.md create mode 100644 wagmi-project/site/cli/api/plugins/etherscan.md create mode 100644 wagmi-project/site/cli/api/plugins/fetch.md create mode 100644 wagmi-project/site/cli/api/plugins/foundry.md create mode 100644 wagmi-project/site/cli/api/plugins/hardhat.md create mode 100644 wagmi-project/site/cli/api/plugins/react.md create mode 100644 wagmi-project/site/cli/api/plugins/sourcify.md create mode 100644 wagmi-project/site/cli/config/configuring-cli.md create mode 100644 wagmi-project/site/cli/config/options.md create mode 100644 wagmi-project/site/cli/create-wagmi.md create mode 100644 wagmi-project/site/cli/getting-started.md create mode 100644 wagmi-project/site/cli/guides/migrate-from-v1-to-v2.md create mode 100644 wagmi-project/site/cli/installation.md create mode 100644 wagmi-project/site/cli/why.md create mode 100644 wagmi-project/site/components/Browsers.vue create mode 100644 wagmi-project/site/components/SearchChains.vue create mode 100644 wagmi-project/site/core/api/actions.md create mode 100644 wagmi-project/site/core/api/actions/call.md create mode 100644 wagmi-project/site/core/api/actions/connect.md create mode 100644 wagmi-project/site/core/api/actions/deployContract.md create mode 100644 wagmi-project/site/core/api/actions/disconnect.md create mode 100644 wagmi-project/site/core/api/actions/estimateFeesPerGas.md create mode 100644 wagmi-project/site/core/api/actions/estimateGas.md create mode 100644 wagmi-project/site/core/api/actions/estimateMaxPriorityFeePerGas.md create mode 100644 wagmi-project/site/core/api/actions/getAccount.md create mode 100644 wagmi-project/site/core/api/actions/getBalance.md create mode 100644 wagmi-project/site/core/api/actions/getBlock.md create mode 100644 wagmi-project/site/core/api/actions/getBlockNumber.md create mode 100644 wagmi-project/site/core/api/actions/getBlockTransactionCount.md create mode 100644 wagmi-project/site/core/api/actions/getBytecode.md create mode 100644 wagmi-project/site/core/api/actions/getCallsStatus.md create mode 100644 wagmi-project/site/core/api/actions/getCapabilities.md create mode 100644 wagmi-project/site/core/api/actions/getChainId.md create mode 100644 wagmi-project/site/core/api/actions/getChains.md create mode 100644 wagmi-project/site/core/api/actions/getClient.md create mode 100644 wagmi-project/site/core/api/actions/getConnections.md create mode 100644 wagmi-project/site/core/api/actions/getConnectorClient.md create mode 100644 wagmi-project/site/core/api/actions/getConnectors.md create mode 100644 wagmi-project/site/core/api/actions/getEnsAddress.md create mode 100644 wagmi-project/site/core/api/actions/getEnsAvatar.md create mode 100644 wagmi-project/site/core/api/actions/getEnsName.md create mode 100644 wagmi-project/site/core/api/actions/getEnsResolver.md create mode 100644 wagmi-project/site/core/api/actions/getEnsText.md create mode 100644 wagmi-project/site/core/api/actions/getFeeHistory.md create mode 100644 wagmi-project/site/core/api/actions/getGasPrice.md create mode 100644 wagmi-project/site/core/api/actions/getProof.md create mode 100644 wagmi-project/site/core/api/actions/getPublicClient.md create mode 100644 wagmi-project/site/core/api/actions/getStorageAt.md create mode 100644 wagmi-project/site/core/api/actions/getToken.md create mode 100644 wagmi-project/site/core/api/actions/getTransaction.md create mode 100644 wagmi-project/site/core/api/actions/getTransactionConfirmations.md create mode 100644 wagmi-project/site/core/api/actions/getTransactionCount.md create mode 100644 wagmi-project/site/core/api/actions/getTransactionReceipt.md create mode 100644 wagmi-project/site/core/api/actions/getWalletClient.md create mode 100644 wagmi-project/site/core/api/actions/multicall.md create mode 100644 wagmi-project/site/core/api/actions/prepareTransactionRequest.md create mode 100644 wagmi-project/site/core/api/actions/readContract.md create mode 100644 wagmi-project/site/core/api/actions/readContracts.md create mode 100644 wagmi-project/site/core/api/actions/reconnect.md create mode 100644 wagmi-project/site/core/api/actions/sendCalls.md create mode 100644 wagmi-project/site/core/api/actions/sendTransaction.md create mode 100644 wagmi-project/site/core/api/actions/showCallsStatus.md create mode 100644 wagmi-project/site/core/api/actions/signMessage.md create mode 100644 wagmi-project/site/core/api/actions/signTypedData.md create mode 100644 wagmi-project/site/core/api/actions/simulateContract.md create mode 100644 wagmi-project/site/core/api/actions/switchAccount.md create mode 100644 wagmi-project/site/core/api/actions/switchChain.md create mode 100644 wagmi-project/site/core/api/actions/verifyMessage.md create mode 100644 wagmi-project/site/core/api/actions/verifyTypedData.md create mode 100644 wagmi-project/site/core/api/actions/waitForCallsStatus.md create mode 100644 wagmi-project/site/core/api/actions/waitForTransactionReceipt.md create mode 100644 wagmi-project/site/core/api/actions/watchAccount.md create mode 100644 wagmi-project/site/core/api/actions/watchAsset.md create mode 100644 wagmi-project/site/core/api/actions/watchBlockNumber.md create mode 100644 wagmi-project/site/core/api/actions/watchBlocks.md create mode 100644 wagmi-project/site/core/api/actions/watchChainId.md create mode 100644 wagmi-project/site/core/api/actions/watchClient.md create mode 100644 wagmi-project/site/core/api/actions/watchConnections.md create mode 100644 wagmi-project/site/core/api/actions/watchConnectors.md create mode 100644 wagmi-project/site/core/api/actions/watchContractEvent.md create mode 100644 wagmi-project/site/core/api/actions/watchPendingTransactions.md create mode 100644 wagmi-project/site/core/api/actions/watchPublicClient.md create mode 100644 wagmi-project/site/core/api/actions/writeContract.md create mode 100644 wagmi-project/site/core/api/actions/writeContracts.md create mode 100644 wagmi-project/site/core/api/chains.md create mode 100644 wagmi-project/site/core/api/connectors.md create mode 100644 wagmi-project/site/core/api/connectors/coinbaseWallet.md create mode 100644 wagmi-project/site/core/api/connectors/injected.md create mode 100644 wagmi-project/site/core/api/connectors/metaMask.md create mode 100644 wagmi-project/site/core/api/connectors/mock.md create mode 100644 wagmi-project/site/core/api/connectors/safe.md create mode 100644 wagmi-project/site/core/api/connectors/walletConnect.md create mode 100644 wagmi-project/site/core/api/createConfig.md create mode 100644 wagmi-project/site/core/api/createConnector.md create mode 100644 wagmi-project/site/core/api/createStorage.md create mode 100644 wagmi-project/site/core/api/errors.md create mode 100644 wagmi-project/site/core/api/transports.md create mode 100644 wagmi-project/site/core/api/transports/custom.md create mode 100644 wagmi-project/site/core/api/transports/fallback.md create mode 100644 wagmi-project/site/core/api/transports/http.md create mode 100644 wagmi-project/site/core/api/transports/unstable_connector.md create mode 100644 wagmi-project/site/core/api/transports/webSocket.md create mode 100644 wagmi-project/site/core/api/utilities/cookieToInitialState.md create mode 100644 wagmi-project/site/core/api/utilities/deserialize.md create mode 100644 wagmi-project/site/core/api/utilities/normalizeChainId.md create mode 100644 wagmi-project/site/core/api/utilities/serialize.md create mode 100644 wagmi-project/site/core/getting-started.md create mode 100644 wagmi-project/site/core/guides/chain-properties.md create mode 100644 wagmi-project/site/core/guides/error-handling.md create mode 100644 wagmi-project/site/core/guides/ethers.md create mode 100644 wagmi-project/site/core/guides/faq.md create mode 100644 wagmi-project/site/core/guides/framework-adapters.md create mode 100644 wagmi-project/site/core/guides/migrate-from-v1-to-v2.md create mode 100644 wagmi-project/site/core/guides/testing.md create mode 100644 wagmi-project/site/core/guides/viem.md create mode 100644 wagmi-project/site/core/installation.md create mode 100644 wagmi-project/site/core/typescript.md create mode 100644 wagmi-project/site/core/why.md create mode 100644 wagmi-project/site/dev/contributing.md create mode 100644 wagmi-project/site/dev/creating-connectors.md create mode 100644 wagmi-project/site/index.md create mode 100644 wagmi-project/site/package.json create mode 100644 wagmi-project/site/public/browsers/chrome.png create mode 100644 wagmi-project/site/public/browsers/edge.png create mode 100644 wagmi-project/site/public/browsers/firefox.png create mode 100644 wagmi-project/site/public/browsers/opera.png create mode 100644 wagmi-project/site/public/browsers/safari.png create mode 100644 wagmi-project/site/public/favicon.svg create mode 100644 wagmi-project/site/public/logo-dark.svg create mode 100644 wagmi-project/site/public/logo-light.svg create mode 100644 wagmi-project/site/public/og.png create mode 100644 wagmi-project/site/react/api/WagmiProvider.md create mode 100644 wagmi-project/site/react/api/actions.md create mode 100644 wagmi-project/site/react/api/chains.md create mode 100644 wagmi-project/site/react/api/connectors.md create mode 100644 wagmi-project/site/react/api/connectors/coinbaseWallet.md create mode 100644 wagmi-project/site/react/api/connectors/injected.md create mode 100644 wagmi-project/site/react/api/connectors/metaMask.md create mode 100644 wagmi-project/site/react/api/connectors/mock.md create mode 100644 wagmi-project/site/react/api/connectors/safe.md create mode 100644 wagmi-project/site/react/api/connectors/walletConnect.md create mode 100644 wagmi-project/site/react/api/createConfig.md create mode 100644 wagmi-project/site/react/api/createStorage.md create mode 100644 wagmi-project/site/react/api/errors.md create mode 100644 wagmi-project/site/react/api/hooks.md create mode 100644 wagmi-project/site/react/api/hooks/useAccount.md create mode 100644 wagmi-project/site/react/api/hooks/useAccountEffect.md create mode 100644 wagmi-project/site/react/api/hooks/useBalance.md create mode 100644 wagmi-project/site/react/api/hooks/useBlock.md create mode 100644 wagmi-project/site/react/api/hooks/useBlockNumber.md create mode 100644 wagmi-project/site/react/api/hooks/useBlockTransactionCount.md create mode 100644 wagmi-project/site/react/api/hooks/useBytecode.md create mode 100644 wagmi-project/site/react/api/hooks/useCall.md create mode 100644 wagmi-project/site/react/api/hooks/useCallsStatus.md create mode 100644 wagmi-project/site/react/api/hooks/useCapabilities.md create mode 100644 wagmi-project/site/react/api/hooks/useChainId.md create mode 100644 wagmi-project/site/react/api/hooks/useChains.md create mode 100644 wagmi-project/site/react/api/hooks/useClient.md create mode 100644 wagmi-project/site/react/api/hooks/useConfig.md create mode 100644 wagmi-project/site/react/api/hooks/useConnect.md create mode 100644 wagmi-project/site/react/api/hooks/useConnections.md create mode 100644 wagmi-project/site/react/api/hooks/useConnectorClient.md create mode 100644 wagmi-project/site/react/api/hooks/useConnectors.md create mode 100644 wagmi-project/site/react/api/hooks/useDeployContract.md create mode 100644 wagmi-project/site/react/api/hooks/useDisconnect.md create mode 100644 wagmi-project/site/react/api/hooks/useEnsAddress.md create mode 100644 wagmi-project/site/react/api/hooks/useEnsAvatar.md create mode 100644 wagmi-project/site/react/api/hooks/useEnsName.md create mode 100644 wagmi-project/site/react/api/hooks/useEnsResolver.md create mode 100644 wagmi-project/site/react/api/hooks/useEnsText.md create mode 100644 wagmi-project/site/react/api/hooks/useEstimateFeesPerGas.md create mode 100644 wagmi-project/site/react/api/hooks/useEstimateGas.md create mode 100644 wagmi-project/site/react/api/hooks/useEstimateMaxPriorityFeePerGas.md create mode 100644 wagmi-project/site/react/api/hooks/useFeeHistory.md create mode 100644 wagmi-project/site/react/api/hooks/useGasPrice.md create mode 100644 wagmi-project/site/react/api/hooks/useInfiniteReadContracts.md create mode 100644 wagmi-project/site/react/api/hooks/usePrepareTransactionRequest.md create mode 100644 wagmi-project/site/react/api/hooks/useProof.md create mode 100644 wagmi-project/site/react/api/hooks/usePublicClient.md create mode 100644 wagmi-project/site/react/api/hooks/useReadContract.md create mode 100644 wagmi-project/site/react/api/hooks/useReadContracts.md create mode 100644 wagmi-project/site/react/api/hooks/useReconnect.md create mode 100644 wagmi-project/site/react/api/hooks/useSendCalls.md create mode 100644 wagmi-project/site/react/api/hooks/useSendTransaction.md create mode 100644 wagmi-project/site/react/api/hooks/useShowCallsStatus.md create mode 100644 wagmi-project/site/react/api/hooks/useSignMessage.md create mode 100644 wagmi-project/site/react/api/hooks/useSignTypedData.md create mode 100644 wagmi-project/site/react/api/hooks/useSimulateContract.md create mode 100644 wagmi-project/site/react/api/hooks/useStorageAt.md create mode 100644 wagmi-project/site/react/api/hooks/useSwitchAccount.md create mode 100644 wagmi-project/site/react/api/hooks/useSwitchChain.md create mode 100644 wagmi-project/site/react/api/hooks/useToken.md create mode 100644 wagmi-project/site/react/api/hooks/useTransaction.md create mode 100644 wagmi-project/site/react/api/hooks/useTransactionConfirmations.md create mode 100644 wagmi-project/site/react/api/hooks/useTransactionCount.md create mode 100644 wagmi-project/site/react/api/hooks/useTransactionReceipt.md create mode 100644 wagmi-project/site/react/api/hooks/useVerifyMessage.md create mode 100644 wagmi-project/site/react/api/hooks/useVerifyTypedData.md create mode 100644 wagmi-project/site/react/api/hooks/useWaitForCallsStatus.md create mode 100644 wagmi-project/site/react/api/hooks/useWaitForTransactionReceipt.md create mode 100644 wagmi-project/site/react/api/hooks/useWalletClient.md create mode 100644 wagmi-project/site/react/api/hooks/useWatchAsset.md create mode 100644 wagmi-project/site/react/api/hooks/useWatchBlockNumber.md create mode 100644 wagmi-project/site/react/api/hooks/useWatchBlocks.md create mode 100644 wagmi-project/site/react/api/hooks/useWatchContractEvent.md create mode 100644 wagmi-project/site/react/api/hooks/useWatchPendingTransactions.md create mode 100644 wagmi-project/site/react/api/hooks/useWriteContract.md create mode 100644 wagmi-project/site/react/api/hooks/useWriteContracts.md create mode 100644 wagmi-project/site/react/api/transports.md create mode 100644 wagmi-project/site/react/api/transports/custom.md create mode 100644 wagmi-project/site/react/api/transports/fallback.md create mode 100644 wagmi-project/site/react/api/transports/http.md create mode 100644 wagmi-project/site/react/api/transports/unstable_connector.md create mode 100644 wagmi-project/site/react/api/transports/webSocket.md create mode 100644 wagmi-project/site/react/api/utilities/cookieToInitialState.md create mode 100644 wagmi-project/site/react/api/utilities/deserialize.md create mode 100644 wagmi-project/site/react/api/utilities/normalizeChainId.md create mode 100644 wagmi-project/site/react/api/utilities/serialize.md create mode 100644 wagmi-project/site/react/comparisons.md create mode 100644 wagmi-project/site/react/getting-started.md create mode 100644 wagmi-project/site/react/guides/chain-properties.md create mode 100644 wagmi-project/site/react/guides/connect-wallet.md create mode 100644 wagmi-project/site/react/guides/error-handling.md create mode 100644 wagmi-project/site/react/guides/ethers.md create mode 100644 wagmi-project/site/react/guides/faq.md create mode 100644 wagmi-project/site/react/guides/migrate-from-v1-to-v2.md create mode 100644 wagmi-project/site/react/guides/read-from-contract.md create mode 100644 wagmi-project/site/react/guides/send-transaction.md create mode 100644 wagmi-project/site/react/guides/ssr.md create mode 100644 wagmi-project/site/react/guides/tanstack-query.md create mode 100644 wagmi-project/site/react/guides/testing.md create mode 100644 wagmi-project/site/react/guides/viem.md create mode 100644 wagmi-project/site/react/guides/write-to-contract.md create mode 100644 wagmi-project/site/react/installation.md create mode 100644 wagmi-project/site/react/typescript.md create mode 100644 wagmi-project/site/react/why.md create mode 100644 wagmi-project/site/shared/connectors/coinbaseWallet.md create mode 100644 wagmi-project/site/shared/connectors/injected.md create mode 100644 wagmi-project/site/shared/connectors/metaMask.md create mode 100644 wagmi-project/site/shared/connectors/mock.md create mode 100644 wagmi-project/site/shared/connectors/safe.md create mode 100644 wagmi-project/site/shared/connectors/walletConnect.md create mode 100644 wagmi-project/site/shared/create-chain.md create mode 100644 wagmi-project/site/shared/createConfig.md create mode 100644 wagmi-project/site/shared/createStorage.md create mode 100644 wagmi-project/site/shared/errors.md create mode 100644 wagmi-project/site/shared/faq.md create mode 100644 wagmi-project/site/shared/getAccount-return-type.md create mode 100644 wagmi-project/site/shared/installation.md create mode 100644 wagmi-project/site/shared/mutation-imports.md create mode 100644 wagmi-project/site/shared/mutation-options.md create mode 100644 wagmi-project/site/shared/mutation-result.md create mode 100644 wagmi-project/site/shared/query-imports.md create mode 100644 wagmi-project/site/shared/query-options.md create mode 100644 wagmi-project/site/shared/query-result.md create mode 100644 wagmi-project/site/shared/transports/custom.md create mode 100644 wagmi-project/site/shared/transports/fallback.md create mode 100644 wagmi-project/site/shared/transports/http.md create mode 100644 wagmi-project/site/shared/transports/unstable_connector.md create mode 100644 wagmi-project/site/shared/transports/webSocket.md create mode 100644 wagmi-project/site/shared/utilities/cookieToInitialState.md create mode 100644 wagmi-project/site/shared/utilities/deserialize.md create mode 100644 wagmi-project/site/shared/utilities/normalizeChainId.md create mode 100644 wagmi-project/site/shared/utilities/serialize.md create mode 100644 wagmi-project/site/snippets/abi-event.ts create mode 100644 wagmi-project/site/snippets/abi-infinite-read.ts create mode 100644 wagmi-project/site/snippets/abi-read.ts create mode 100644 wagmi-project/site/snippets/abi-write.ts create mode 100644 wagmi-project/site/snippets/core/config-chain-properties.ts create mode 100644 wagmi-project/site/snippets/core/config.ts create mode 100644 wagmi-project/site/snippets/react/app.tsx create mode 100644 wagmi-project/site/snippets/react/config-chain-properties.ts create mode 100644 wagmi-project/site/snippets/react/config.ts create mode 100644 wagmi-project/site/snippets/typedData.ts create mode 100644 wagmi-project/site/snippets/vue/App.vue create mode 100644 wagmi-project/site/snippets/vue/config-chain-properties.ts create mode 100644 wagmi-project/site/snippets/vue/config.ts create mode 100644 wagmi-project/site/snippets/vue/main.ts create mode 100644 wagmi-project/site/tsconfig.json create mode 100644 wagmi-project/site/vercel.json create mode 100644 wagmi-project/site/vue/api/Nuxt.md create mode 100644 wagmi-project/site/vue/api/WagmiPlugin.md create mode 100644 wagmi-project/site/vue/api/actions.md create mode 100644 wagmi-project/site/vue/api/chains.md create mode 100644 wagmi-project/site/vue/api/composables.md create mode 100644 wagmi-project/site/vue/api/composables/useAccount.md create mode 100644 wagmi-project/site/vue/api/composables/useAccountEffect.md create mode 100644 wagmi-project/site/vue/api/composables/useBalance.md create mode 100644 wagmi-project/site/vue/api/composables/useBlockNumber.md create mode 100644 wagmi-project/site/vue/api/composables/useBytecode.md create mode 100644 wagmi-project/site/vue/api/composables/useChainId.md create mode 100644 wagmi-project/site/vue/api/composables/useChains.md create mode 100644 wagmi-project/site/vue/api/composables/useClient.md create mode 100644 wagmi-project/site/vue/api/composables/useConfig.md create mode 100644 wagmi-project/site/vue/api/composables/useConnect.md create mode 100644 wagmi-project/site/vue/api/composables/useConnections.md create mode 100644 wagmi-project/site/vue/api/composables/useConnectorClient.md create mode 100644 wagmi-project/site/vue/api/composables/useConnectors.md create mode 100644 wagmi-project/site/vue/api/composables/useDisconnect.md create mode 100644 wagmi-project/site/vue/api/composables/useEnsAddress.md create mode 100644 wagmi-project/site/vue/api/composables/useEnsAvatar.md create mode 100644 wagmi-project/site/vue/api/composables/useEnsName.md create mode 100644 wagmi-project/site/vue/api/composables/useEstimateGas.md create mode 100644 wagmi-project/site/vue/api/composables/useReadContract.md create mode 100644 wagmi-project/site/vue/api/composables/useReconnect.md create mode 100644 wagmi-project/site/vue/api/composables/useSendTransaction.md create mode 100644 wagmi-project/site/vue/api/composables/useSignMessage.md create mode 100644 wagmi-project/site/vue/api/composables/useSignTypedData.md create mode 100644 wagmi-project/site/vue/api/composables/useSimulateContract.md create mode 100644 wagmi-project/site/vue/api/composables/useSwitchAccount.md create mode 100644 wagmi-project/site/vue/api/composables/useSwitchChain.md create mode 100644 wagmi-project/site/vue/api/composables/useTransaction.md create mode 100644 wagmi-project/site/vue/api/composables/useTransactionReceipt.md create mode 100644 wagmi-project/site/vue/api/composables/useWaitForTransactionReceipt.md create mode 100644 wagmi-project/site/vue/api/composables/useWatchBlockNumber.md create mode 100644 wagmi-project/site/vue/api/composables/useWatchContractEvent.md create mode 100644 wagmi-project/site/vue/api/composables/useWriteContract.md create mode 100644 wagmi-project/site/vue/api/connectors.md create mode 100644 wagmi-project/site/vue/api/connectors/coinbaseWallet.md create mode 100644 wagmi-project/site/vue/api/connectors/injected.md create mode 100644 wagmi-project/site/vue/api/connectors/metaMask.md create mode 100644 wagmi-project/site/vue/api/connectors/mock.md create mode 100644 wagmi-project/site/vue/api/connectors/safe.md create mode 100644 wagmi-project/site/vue/api/connectors/walletConnect.md create mode 100644 wagmi-project/site/vue/api/createConfig.md create mode 100644 wagmi-project/site/vue/api/createStorage.md create mode 100644 wagmi-project/site/vue/api/errors.md create mode 100644 wagmi-project/site/vue/api/transports.md create mode 100644 wagmi-project/site/vue/api/transports/custom.md create mode 100644 wagmi-project/site/vue/api/transports/fallback.md create mode 100644 wagmi-project/site/vue/api/transports/http.md create mode 100644 wagmi-project/site/vue/api/transports/unstable_connector.md create mode 100644 wagmi-project/site/vue/api/transports/webSocket.md create mode 100644 wagmi-project/site/vue/api/utilities/deserialize.md create mode 100644 wagmi-project/site/vue/api/utilities/serialize.md create mode 100644 wagmi-project/site/vue/getting-started.md create mode 100644 wagmi-project/site/vue/guides/chain-properties.md create mode 100644 wagmi-project/site/vue/guides/connect-wallet.md create mode 100644 wagmi-project/site/vue/guides/error-handling.md create mode 100644 wagmi-project/site/vue/guides/faq.md create mode 100644 wagmi-project/site/vue/guides/read-from-contract.md create mode 100644 wagmi-project/site/vue/guides/send-transaction.md create mode 100644 wagmi-project/site/vue/guides/ssr.md create mode 100644 wagmi-project/site/vue/guides/tanstack-query.md create mode 100644 wagmi-project/site/vue/guides/viem.md create mode 100644 wagmi-project/site/vue/guides/write-to-contract.md create mode 100644 wagmi-project/site/vue/installation.md create mode 100644 wagmi-project/site/vue/typescript.md create mode 100644 wagmi-project/site/vue/why.md create mode 100644 wagmi-project/tsconfig.base.json create mode 100644 wagmi-project/vitest.config.ts create mode 100644 wagmi-project/vitest.workspace.ts diff --git a/wagmi-project/.changeset/README.md b/wagmi-project/.changeset/README.md new file mode 100644 index 000000000..e5b6d8d6a --- /dev/null +++ b/wagmi-project/.changeset/README.md @@ -0,0 +1,8 @@ +# Changesets + +Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works +with multi-package repos, or single-package repos to help you version and publish your code. You can +find the full documentation for it [in our repository](https://github.com/changesets/changesets) + +We have a quick list of common questions to get you started engaging with this project in +[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md) diff --git a/wagmi-project/.changeset/config.json b/wagmi-project/.changeset/config.json new file mode 100644 index 000000000..c47279e4c --- /dev/null +++ b/wagmi-project/.changeset/config.json @@ -0,0 +1,19 @@ +{ + "$schema": "https://unpkg.com/@changesets/config@2.3.1/schema.json", + "access": "public", + "baseBranch": "main", + "changelog": ["@changesets/changelog-github", { "repo": "wevm/wagmi" }], + "commit": false, + "ignore": [ + "*-register", + "@wagmi/test", + "site", + "next-app", + "nuxt-app", + "vite-*" + ], + "updateInternalDependencies": "patch", + "___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH": { + "onlyUpdatePeerDependentsWhenOutOfRange": true + } +} diff --git a/wagmi-project/.changeset/new-elephants-travel.md b/wagmi-project/.changeset/new-elephants-travel.md new file mode 100644 index 000000000..ddfb37374 --- /dev/null +++ b/wagmi-project/.changeset/new-elephants-travel.md @@ -0,0 +1,5 @@ +--- +"@wagmi/cli": patch +--- + +Updated block explorer chains. diff --git a/wagmi-project/.changeset/nice-pandas-clap.md b/wagmi-project/.changeset/nice-pandas-clap.md new file mode 100644 index 000000000..7f4af5301 --- /dev/null +++ b/wagmi-project/.changeset/nice-pandas-clap.md @@ -0,0 +1,5 @@ +--- + +--- + +Circleci project setup diff --git a/wagmi-project/.changeset/quick-hairs-scream.md b/wagmi-project/.changeset/quick-hairs-scream.md new file mode 100644 index 000000000..206e94e24 --- /dev/null +++ b/wagmi-project/.changeset/quick-hairs-scream.md @@ -0,0 +1,6 @@ +--- +"wagmi": patch +"@wagmi/core": patch +--- + +Added `chainId` parameter to `getCapabilities`/`useCapabilities`. diff --git a/wagmi-project/.changeset/spicy-bats-juggle.md b/wagmi-project/.changeset/spicy-bats-juggle.md new file mode 100644 index 000000000..cf7a15422 --- /dev/null +++ b/wagmi-project/.changeset/spicy-bats-juggle.md @@ -0,0 +1,6 @@ +--- +"@wagmi/cli": patch +"site": patch +--- + +Circleci project setup diff --git a/wagmi-project/.changeset/tall-fans-mate.md b/wagmi-project/.changeset/tall-fans-mate.md new file mode 100644 index 000000000..cf7a15422 --- /dev/null +++ b/wagmi-project/.changeset/tall-fans-mate.md @@ -0,0 +1,6 @@ +--- +"@wagmi/cli": patch +"site": patch +--- + +Circleci project setup diff --git a/wagmi-project/.changeset/tiny-laws-dream.md b/wagmi-project/.changeset/tiny-laws-dream.md new file mode 100644 index 000000000..c39a3d68b --- /dev/null +++ b/wagmi-project/.changeset/tiny-laws-dream.md @@ -0,0 +1,5 @@ +--- +"@fake-scope/fake-pkg": patch +--- + +Circleci project setup diff --git a/wagmi-project/.changeset/young-guests-care.md b/wagmi-project/.changeset/young-guests-care.md new file mode 100644 index 000000000..8de2292dd --- /dev/null +++ b/wagmi-project/.changeset/young-guests-care.md @@ -0,0 +1,5 @@ +--- +"site": patch +--- + +docs(readme): fix typo diff --git a/wagmi-project/.circleci/config.yml b/wagmi-project/.circleci/config.yml new file mode 100644 index 000000000..709c9a747 --- /dev/null +++ b/wagmi-project/.circleci/config.yml @@ -0,0 +1,26 @@ +# Use the latest 2.1 version of CircleCI pipeline process engine. +# See: https://circleci.com/docs/configuration-reference + +version: 2.1 +executors: + my-custom-executor: + docker: + - image: cimg/base:stable + auth: + # ensure you have first added these secrets + # visit app.circleci.com/settings/project/github/Dargon789/hardhat-project/environment-variables + username: $DOCKER_HUB_USER + password: $DOCKER_HUB_PASSWORD +jobs: + web3-defi-game-project-: + + executor: my-custom-executor + steps: + - checkout + - run: | + # echo Hello, World! + +workflows: + my-custom-workflow: + jobs: + - web3-defi-game-project- diff --git a/wagmi-project/.github/CODEOWNERS b/wagmi-project/.github/CODEOWNERS new file mode 100644 index 000000000..12451d4bc --- /dev/null +++ b/wagmi-project/.github/CODEOWNERS @@ -0,0 +1,5 @@ +@tmm @jxom + +/packages/connectors/src/metaMask @ecp4224 @omridan159 @abretonc7s @elefantel @BjornGunnarsson @EdouardBougon +/packages/connectors/src/safe @DaniSomoza @dasanra @mikhailxyz @yagopv +/packages/connectors/src/walletConnect @ganchoradkov @glitch-txs @ignaciosantise @tomiir diff --git a/wagmi-project/.github/CONTRIBUTING.md b/wagmi-project/.github/CONTRIBUTING.md new file mode 100644 index 000000000..d3ab387e1 --- /dev/null +++ b/wagmi-project/.github/CONTRIBUTING.md @@ -0,0 +1 @@ +[View Contributing Guide on wagmi.sh](https://wagmi.sh/dev/contributing) \ No newline at end of file diff --git a/wagmi-project/.github/DISCUSSION_TEMPLATE/connector-request.yml b/wagmi-project/.github/DISCUSSION_TEMPLATE/connector-request.yml new file mode 100644 index 000000000..c1e31b1b6 --- /dev/null +++ b/wagmi-project/.github/DISCUSSION_TEMPLATE/connector-request.yml @@ -0,0 +1,51 @@ +title: '[Connector Request] ' +body: + - type: markdown + attributes: + value: | + Thanks for your interest in contributing a new Connector to the Wagmi! If you haven't already, please read the [Contributing Guidelines](https://wagmi.sh/dev/contributing). Once you submit the form, the Wagmi team will follow up in the discussion thread to discuss next steps. + + Please note that in order for connector requests to be accepted, the team creating the Connector must [sponsor Wagmi](https://github.com/sponsors/wevm). It takes time and effort to maintain third-party connectors. Wagmi is an OSS project that depends on sponsors and grants to continue our work. Please get in touch via [dev@wevm.dev](mailto:dev@wevm.dev) if you have questions about sponsoring. + + - type: textarea + attributes: + label: What **novel use-case** does the Connector provide? + description: | + A novel use-case is likely one that is not already covered by or not easily extended from another Connector (such as the `injected` or `walletConnect`). + + Examples of **novel** use-cases could be a connector that integrates with: + + - the injected `window.ethereum` provider (a la `injected`) + - a series of wallets via QR Codes or Mobile Deep Links (a la `walletConnect`) + - a wallet with it's own SDK (a la `coinbaseWallet`) + - hardware wallet(s) via Web USB/Bluetooth + - an Externally Owned Account via a private key or some other method + + Examples of **nonnovel** use-cases would be a connector that: + + - extends another connector (e.g. `walletConnect`) with no significant differences in functionality other than branding, etc. + placeholder: Info on what makes this connector different. + validations: + required: true + + - type: textarea + attributes: + label: Are the Connector's integrations production-ready and generally available? + description: Connectors are intended to be used by consumers in production as part of Wagmi. As such, the Connector and all dependencies must be production-ready and generally available. This means your connector should not rely on non-production software or be restricted to a limited group of users. For example, if your connector requires a wallet that has a closed beta, it is not ready for inclusion in Wagmi. + placeholder: Info about the Connector and any dependencies (e.g. browser extension, wallet app, npm package). + validations: + required: true + + - type: checkboxes + attributes: + label: Are you committed to actively maintaining the Connector? + description: It is critical connectors are updated in a timely manner and actively maintained so that users of Wagmi can rely on them in production settings. The Wagmi core team will provide as much assistance as possible to keep connectors up-to-date with breaking changes from Wagmi, but it is your responsibility to ensure that any dependencies and issues/discussions related to the Connector are handled in a timely manner. If this is not done, the Connector could be removed from the future versions. + options: + - label: Yes, my team is or I am committed to actively maintaining the Connector. + required: true + + - type: textarea + attributes: + label: Additional comments + description: Feel free to jot down any additional info you think might be helpful. + placeholder: Additional comments, questions, feedback. diff --git a/wagmi-project/.github/ISSUE_TEMPLATE/bug_report.yml b/wagmi-project/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 000000000..8a561abba --- /dev/null +++ b/wagmi-project/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,88 @@ +name: Bug Report +description: Report bugs or issues. +body: + - type: markdown + attributes: + value: | + Thanks for taking the time to fill out this bug report! The more info you provide, the more we can help you. + + If you are a [Wagmi Sponsor](https://github.com/sponsors/wevm?metadata_campaign=gh_issue), your issues are prioritized. + + - type: checkboxes + attributes: + label: Check existing issues + description: By submitting this issue, you checked there isn't [already an issue](https://github.com/wevm/wagmi/issues) for this bug. + options: + - label: I checked there isn't [already an issue](https://github.com/wevm/wagmi/issues) for the bug I encountered. + required: true + + - type: textarea + attributes: + label: Describe the bug + description: Clear and concise description of the bug. If you intend to submit a PR for this issue, tell us in the description. Thanks! + placeholder: I am doing… What I expect is… What is actually happening… + validations: + required: true + + - type: input + id: reproduction + attributes: + label: Link to Minimal Reproducible Example + description: "Please provide a link that can reproduce the problem: [new.wagmi.sh](https://new.wagmi.sh) for runtime issues or [TypeScript Playground](https://www.typescriptlang.org/play) for type issues. For most issues, you will likely get asked to provide a minimal reproducible example so why not add one now :) If a report is vague (e.g. just snippets, generic error message, screenshot, etc.) and has no reproduction, it will receive a \"Needs Reproduction\" label and be auto-closed." + placeholder: https://new.wagmi.sh + validations: + required: false + + - type: textarea + attributes: + label: Steps To Reproduce + description: Steps or code snippets to reproduce the behavior. + validations: + required: false + + - type: dropdown + attributes: + label: What Wagmi package(s) are you using? + multiple: true + options: + - 'wagmi' + - '@wagmi/cli' + - '@wagmi/connectors' + - '@wagmi/core' + - '@wagmi/vue' + - 'create-wagmi' + validations: + required: true + + - type: input + attributes: + label: Wagmi Package(s) Version(s) + description: What version of the Wagmi packages you selected above are you using? If using multiple, separate with comma (e.g. `wagmi@x.y.z, @wagmi/cli@x.y.z`). + placeholder: x.y.z (do not write `latest`) + validations: + required: true + + - type: input + attributes: + label: Viem Version + description: What version of [Viem](https://viem.sh) are you using? + placeholder: x.y.z (do not write `latest`) + validations: + required: true + + - type: input + attributes: + label: TypeScript Version + description: What version of TypeScript are you using? Wagmi requires `typescript@>=5`. + placeholder: x.y.z (do not write `latest`) + validations: + required: false + + - type: textarea + attributes: + label: Anything else? + description: Anything that will give us more context about the issue you are encountering. Framework version (e.g. React, Vue), app framework (e.g. Next.js, Nuxt), bundler, etc. + validations: + required: false + + diff --git a/wagmi-project/.github/ISSUE_TEMPLATE/config.yml b/wagmi-project/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 000000000..fc8027c87 --- /dev/null +++ b/wagmi-project/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,14 @@ +blank_issues_enabled: false +contact_links: + - name: Get Help + url: https://github.com/wevm/wagmi/discussions/new?category=q-a + about: Ask a question and discuss with other community members. + + - name: Feature Request + url: https://github.com/wevm/wagmi/discussions/new?category=ideas + about: Request features or brainstorm ideas for new functionality. + + - name: Connector Request + url: https://github.com/wevm/wagmi/discussions/new?category=connector-request + about: Kick off a request for a new connector + diff --git a/wagmi-project/.github/ISSUE_TEMPLATE/docs_issue.yml b/wagmi-project/.github/ISSUE_TEMPLATE/docs_issue.yml new file mode 100644 index 000000000..f2d53b8a9 --- /dev/null +++ b/wagmi-project/.github/ISSUE_TEMPLATE/docs_issue.yml @@ -0,0 +1,34 @@ +name: Documentation Issue +description: Tell us about missing or incorrect documentation. +labels: ['Area: Docs'] +body: + - type: markdown + attributes: + value: | + Thank you for submitting a documentation request. It helps make Wagmi better. + + If it's a small change, like misspelling or example that needs updating, feel free to submit a PR instead of creating this issue. + + - type: dropdown + attributes: + label: What is the type of issue? + multiple: true + options: + - Documentation is missing + - Documentation is incorrect + - Documentation is confusing + - Example code is not working + - Something else + + - type: textarea + attributes: + label: What is the issue? + validations: + required: true + + - type: textarea + attributes: + label: Where did you find it? + description: Please provide the URL(s) where you found this issue. + validations: + required: true diff --git a/wagmi-project/.github/README.md b/wagmi-project/.github/README.md new file mode 100644 index 000000000..6b5f33641 --- /dev/null +++ b/wagmi-project/.github/README.md @@ -0,0 +1,256 @@ + + + +
+ +

+ + + + wagmi logo + + +

+ +

+ Reactive primitives for Ethereum apps +

+ +

+ + + + Version + + + + + + MIT License + + + + + + Downloads per month + + + + + + Best of JS + + + + + + Code coverage + + +

+ +--- + +## Documentation + +For documentation and guides, visit [wagmi.sh](https://wagmi.sh). + +## Community + +For help, discussion about best practices, or any other conversation that would benefit from being searchable: + +[Discuss Wagmi on GitHub](https://github.com/wevm/wagmi/discussions) + +For casual chit-chat with others using the framework: + +[Join the Wagmi Discord](https://discord.gg/SghfWBKexF) + +## Contributing + +Contributions to Wagmi are greatly appreciated! If you're interested in contributing to Wagmi, please read the [Contributing Guide](https://wagmi.sh/dev/contributing) **before submitting a pull request**. + +## Sponsors + +If you find Wagmi useful or use it for work, please consider [sponsoring Wagmi](https://github.com/sponsors/wevm?metadata_campaign=gh_readme_support). Thank you 🙏 + +

+ + + + paradigm logo + + + + + + ithaca logo + + +

+ +

+ + + + family logo + + + + + + context logo + + + + + + WalletConnect logo + + + + + + PartyDAO logo + + + + + + Dynamic logo + + + + + + Sushi logo + + + + + + Stripe logo + + + + + + Privy logo + + + + + + pancake logo + + + + + + celo logo + + + + + + rainbow logo + + + + + + pimlico logo + + + + + + zora logo + + + + + + lattice logo + + + + + + supa logo + + + + + + zksync logo + + + + + + syndicate logo + + + + + + reservoir logo + + + + + + linea logo + + + + + + uniswap logo + + + + + + biconomy logo + + + + + + thirdweb logo + + + + + + polymarket logo + + + + + + routescan logo + + + + + + sequence logo + + +

+ +[Sponsor Wagmi](https://github.com/sponsors/wevm?metadata_campaign=gh_readme_support_bottom) + +
+
+ + + Powered by Vercel + +
+ + Powered by QuickNode + + diff --git a/wagmi-project/.github/SECURITY.md b/wagmi-project/.github/SECURITY.md new file mode 100644 index 000000000..54f40f38d --- /dev/null +++ b/wagmi-project/.github/SECURITY.md @@ -0,0 +1,6 @@ +# Security Policy + +## Reporting a Vulnerability + +Contact [dev@wevm.dev](mailto:dev@wevm.dev). + diff --git a/wagmi-project/.github/dependabot.yml b/wagmi-project/.github/dependabot.yml new file mode 100644 index 000000000..bc63aca35 --- /dev/null +++ b/wagmi-project/.github/dependabot.yml @@ -0,0 +1,6 @@ +version: 2 +updates: + - package-ecosystem: 'github-actions' + directory: '/' + schedule: + interval: 'monthly' diff --git a/wagmi-project/.github/logo-dark.svg b/wagmi-project/.github/logo-dark.svg new file mode 100644 index 000000000..5d47cce33 --- /dev/null +++ b/wagmi-project/.github/logo-dark.svg @@ -0,0 +1,27 @@ + + + + + + + diff --git a/wagmi-project/.github/logo-light.svg b/wagmi-project/.github/logo-light.svg new file mode 100644 index 000000000..4e28590c3 --- /dev/null +++ b/wagmi-project/.github/logo-light.svg @@ -0,0 +1,27 @@ + + + + + + + diff --git a/wagmi-project/.github/pull_request_template.md b/wagmi-project/.github/pull_request_template.md new file mode 100644 index 000000000..602a32d0a --- /dev/null +++ b/wagmi-project/.github/pull_request_template.md @@ -0,0 +1,12 @@ + + + diff --git a/wagmi-project/.github/workflows/Vercel Preview Deployment.yml b/wagmi-project/.github/workflows/Vercel Preview Deployment.yml new file mode 100644 index 000000000..ca7ca9700 --- /dev/null +++ b/wagmi-project/.github/workflows/Vercel Preview Deployment.yml @@ -0,0 +1,22 @@ +name: Playwright Tests + +on: + repository_dispatch: + types: + - 'vercel.deployment.success' +permissions: + contents: read +jobs: + run-e2es: + if: github.event_name == 'repository_dispatch' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ github.event.client_payload.git.sha }} + - name: Install dependencies + run: npm ci && npx playwright install --with-deps + - name: Run tests + run: npx playwright test + env: + BASE_URL: ${{ github.event.client_payload.url }} diff --git a/wagmi-project/.github/workflows/changesets.yml b/wagmi-project/.github/workflows/changesets.yml new file mode 100644 index 000000000..745341ed9 --- /dev/null +++ b/wagmi-project/.github/workflows/changesets.yml @@ -0,0 +1,60 @@ +name: Changesets +on: + push: + branches: [main] + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + verify: + name: Verify + uses: ./.github/workflows/verify.yml + secrets: inherit + + changesets: + name: Publish + needs: verify + permissions: + contents: write + id-token: write + pull-requests: write + runs-on: ubuntu-latest + timeout-minutes: 5 + + steps: + - name: Clone repository + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + with: + # This makes Actions fetch all Git history so that Changesets can generate changelogs with the correct commits + fetch-depth: 0 + + - name: Install dependencies + uses: wevm/actions/.github/actions/pnpm@main + + - name: PR or publish + uses: changesets/action@e0145edc7d9d8679003495b11f87bd8ef63c0cba + with: + title: 'chore: version packages' + commit: 'chore: version packages' + createGithubReleases: ${{ github.ref == 'refs/heads/main' }} + publish: pnpm changeset:publish + version: pnpm changeset:version + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + + - name: Publish prerelease + if: steps.changesets.outputs.published != 'true' + continue-on-error: true + env: + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + npm config set "//registry.npmjs.org/:_authToken" "$NPM_TOKEN" + git reset --hard origin/main + pnpm clean + pnpm changeset version --no-git-tag --snapshot canary + pnpm changeset:prepublish + pnpm changeset publish --no-git-tag --snapshot canary --tag canary diff --git a/wagmi-project/.github/workflows/dependency-review.yml b/wagmi-project/.github/workflows/dependency-review.yml new file mode 100644 index 000000000..d19e21b79 --- /dev/null +++ b/wagmi-project/.github/workflows/dependency-review.yml @@ -0,0 +1,39 @@ +# Dependency Review Action +# +# This Action will scan dependency manifest files that change as part of a Pull Request, +# surfacing known-vulnerable versions of the packages declared or updated in the PR. +# Once installed, if the workflow run is marked as required, PRs introducing known-vulnerable +# packages will be blocked from merging. +# +# Source repository: https://github.com/actions/dependency-review-action +# Public documentation: https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/about-dependency-review#dependency-review-enforcement +name: 'Dependency review' +on: + pull_request: + branches: [ "main" ] + +# If using a dependency submission action in this workflow this permission will need to be set to: +# +# permissions: +# contents: write +# +# https://docs.github.com/en/enterprise-cloud@latest/code-security/supply-chain-security/understanding-your-software-supply-chain/using-the-dependency-submission-api +permissions: + contents: read + # Write permissions for pull-requests are required for using the `comment-summary-in-pr` option, comment out if you aren't using this option + pull-requests: write + +jobs: + dependency-review: + runs-on: ubuntu-latest + steps: + - name: 'Checkout repository' + uses: actions/checkout@v4 + - name: 'Dependency Review' + uses: actions/dependency-review-action@v4 + # Commonly enabled options, see https://github.com/actions/dependency-review-action#configuration-options for all available options. + with: + comment-summary-in-pr: always + # fail-on-severity: moderate + # deny-licenses: GPL-1.0-or-later, LGPL-2.0-or-later + # retry-on-snapshot-warnings: true diff --git a/wagmi-project/.github/workflows/issue-labeled.yml b/wagmi-project/.github/workflows/issue-labeled.yml new file mode 100644 index 000000000..39b98291d --- /dev/null +++ b/wagmi-project/.github/workflows/issue-labeled.yml @@ -0,0 +1,19 @@ +name: Issue Labeled + +on: + issues: + types: [labeled] + +jobs: + issue-labeled: + if: ${{ github.repository_owner == 'wevm' }} + uses: wevm/actions/.github/workflows/issue-labeled.yml@main + with: + needs-reproduction-body: | + Hello @${{ github.event.issue.user.login }}. + + Please provide a [minimal reproduction](https://stackoverflow.com/help/minimal-reproducible-example) using [StackBlitz](https://new.wagmi.sh), [TypeScript Playground](https://www.typescriptlang.org/play) (for type issues), or a separate minimal GitHub repository. + + [Minimal reproductions are required](https://antfu.me/posts/why-reproductions-are-required) as they save us a lot of time reproducing your config/environment and issue, and allow us to help you faster. + + Once a minimal reproduction is added, a team member will confirm it works, then re-open the issue. diff --git a/wagmi-project/.github/workflows/jekyll-docker.yml b/wagmi-project/.github/workflows/jekyll-docker.yml new file mode 100644 index 000000000..c88a4430c --- /dev/null +++ b/wagmi-project/.github/workflows/jekyll-docker.yml @@ -0,0 +1,23 @@ +name: Jekyll site CI + +permissions: + contents: read + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + - name: Build the site in the jekyll/builder container + run: | + docker run \ + -v ${{ github.workspace }}:/srv/jekyll -v ${{ github.workspace }}/_site:/srv/jekyll/_site \ + jekyll/builder:latest /bin/bash -c "chmod -R 777 /srv/jekyll && jekyll build --future" diff --git a/wagmi-project/.github/workflows/lock-issue.yml b/wagmi-project/.github/workflows/lock-issue.yml new file mode 100644 index 000000000..279452d22 --- /dev/null +++ b/wagmi-project/.github/workflows/lock-issue.yml @@ -0,0 +1,16 @@ +name: Lock Issue + +on: + schedule: + - cron: '0 0 * * *' + +jobs: + lock-issue: + if: ${{ github.repository_owner == 'wevm' }} + uses: wevm/actions/.github/workflows/lock-issue.yml@main + with: + issue-comment: | + This issue has been locked since it has been closed for more than 14 days. + + If you found a concrete bug or regression related to it, please open a new [bug report](https://github.com/wevm/wagmi/issues/new?template=bug_report.yml) with a reproduction against the latest Wagmi version. If you have any questions or comments you can create a new [discussion thread](https://github.com/wevm/wagmi/discussions). + diff --git a/wagmi-project/.github/workflows/octopusdeploy.yml b/wagmi-project/.github/workflows/octopusdeploy.yml new file mode 100644 index 000000000..9c4403d55 --- /dev/null +++ b/wagmi-project/.github/workflows/octopusdeploy.yml @@ -0,0 +1,112 @@ +# This workflow uses actions that are not certified by GitHub. +# They are provided by a third-party and are governed by separate terms of service, +# privacy policy, and support documentation. +# +# This workflow will build and publish a Docker container which is then deployed through Octopus Deploy. +# +# The build job in this workflow currently assumes that there is a Dockerfile that generates the relevant application image. +# If required, this job can be modified to generate whatever alternative build artifact is required for your deployment. +# +# This workflow assumes you have already created a Project in Octopus Deploy. +# For instructions see https://octopus.com/docs/projects/setting-up-projects +# +# To configure this workflow: +# +# 1. Decide where you are going to host your image. +# This template uses the GitHub Registry for simplicity but if required you can update the relevant DOCKER_REGISTRY variables below. +# +# 2. Create and configure an OIDC credential for a service account in Octopus. +# This allows for passwordless authentication to your Octopus instance through a trust relationship configured between Octopus, GitHub and your GitHub Repository. +# https://octopus.com/docs/octopus-rest-api/openid-connect/github-actions +# +# 3. Configure your Octopus project details below: +# OCTOPUS_URL: update to your Octopus Instance Url +# OCTOPUS_SERVICE_ACCOUNT: update to your service account Id +# OCTOPUS_SPACE: update to the name of the space your project is configured in +# OCTOPUS_PROJECT: update to the name of your Octopus project +# OCTOPUS_ENVIRONMENT: update to the name of the environment to recieve the first deployment + + +name: 'Build and Deploy to Octopus Deploy' + +on: + push: + branches: + - '"main"' + +jobs: + build: + name: Build + runs-on: ubuntu-latest + permissions: + packages: write + contents: read + env: + DOCKER_REGISTRY: ghcr.io # TODO: Update to your docker registry uri + DOCKER_REGISTRY_USERNAME: ${{ github.actor }} # TODO: Update to your docker registry username + DOCKER_REGISTRY_PASSWORD: ${{ secrets.GITHUB_TOKEN }} # TODO: Update to your docker registry password + outputs: + image_tag: ${{ steps.meta.outputs.version }} + steps: + - uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0 + + - name: Log in to the Container registry + uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1 + with: + registry: ${{ env.DOCKER_REGISTRY }} + username: ${{ env.DOCKER_REGISTRY_USERNAME }} + password: ${{ env.DOCKER_REGISTRY_PASSWORD }} + + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7 + with: + images: ${{ env.DOCKER_REGISTRY }}/${{ github.repository }} + tags: type=semver,pattern={{version}},value=v1.0.0-{{sha}} + + - name: Build and push Docker image + id: push + uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4 + with: + context: . + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + deploy: + name: Deploy + permissions: + id-token: write + runs-on: ubuntu-latest + needs: [ build ] + env: + OCTOPUS_URL: 'https://your-octopus-url' # TODO: update to your Octopus Instance url + OCTOPUS_SERVICE_ACCOUNT: 'your-service-account-id' # TODO: update to your service account Id + OCTOPUS_SPACE: 'your-space' # TODO: update to the name of the space your project is configured in + OCTOPUS_PROJECT: 'your-project' # TODO: update to the name of your Octopus project + OCTOPUS_ENVIRONMENT: 'your-environment' # TODO: update to the name of the environment to recieve the first deployment + + steps: + - name: Log in to Octopus Deploy + uses: OctopusDeploy/login@e485a40e4b47a154bdf59cc79e57894b0769a760 #v1.0.3 + with: + server: '${{ env.OCTOPUS_URL }}' + service_account_id: '${{ env.OCTOPUS_SERVICE_ACCOUNT }}' + + - name: Create Release + id: create_release + uses: OctopusDeploy/create-release-action@fea7e7b45c38c021b6bc5a14bd7eaa2ed5269214 #v3.2.2 + with: + project: '${{ env.OCTOPUS_PROJECT }}' + space: '${{ env.OCTOPUS_SPACE }}' + packages: '*:${{ needs.build.outputs.image_tag }}' + + - name: Deploy Release + uses: OctopusDeploy/deploy-release-action@b10a606c903b0a5bce24102af9d066638ab429ac #v3.2.1 + with: + project: '${{ env.OCTOPUS_PROJECT }}' + space: '${{ env.OCTOPUS_SPACE }}' + release_number: '${{ steps.create_release.outputs.release_number }}' + environments: ${{ env.OCTOPUS_ENVIRONMENT }} diff --git a/wagmi-project/.github/workflows/pull-request.yml b/wagmi-project/.github/workflows/pull-request.yml new file mode 100644 index 000000000..9ff4c5bb7 --- /dev/null +++ b/wagmi-project/.github/workflows/pull-request.yml @@ -0,0 +1,32 @@ +name: Pull Request +on: + pull_request: + types: [opened, reopened, synchronize, ready_for_review] + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +jobs: + verify: + name: Verify + uses: ./.github/workflows/verify.yml + secrets: inherit + + size: + name: Size + runs-on: ubuntu-latest + timeout-minutes: 5 + + steps: + - name: Clone repository + uses: actions/checkout@v4 + + - name: Install dependencies + uses: wevm/actions/.github/actions/pnpm@main + + - name: Report build size + uses: preactjs/compressed-size-action@v2 + with: + pattern: 'packages/**/dist/**' + repo-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/wagmi-project/.github/workflows/release.yml b/wagmi-project/.github/workflows/release.yml new file mode 100644 index 000000000..297c74f63 --- /dev/null +++ b/wagmi-project/.github/workflows/release.yml @@ -0,0 +1,44 @@ +name: Release + +on: + push: + branches: + - main + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: + contents: write + +jobs: + release: + name: Release + runs-on: ubuntu-latest + steps: + - name: Checkout Repo + uses: actions/checkout@v3 + + - name: Setup Node.js 20.x + uses: actions/setup-node@v3 + with: + node-version: 20.x + + - name: Install Dependencies + run: pnpm install + + - name: Create Release Pull Request or Publish to npm + id: changesets + uses: changesets/action@v1 + with: + # This expects you to have a script called release which does a build for your packages and calls changeset publish + publish: pnpm release + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + + - name: Send a Slack notification if a publish happens + if: steps.changesets.outputs.published == 'true' + # You can do something when a publish happens. + run: my-slack-bot send-notification --message "A new version of ${GITHUB_REPOSITORY} was published!" diff --git a/wagmi-project/.github/workflows/snapshot.yml b/wagmi-project/.github/workflows/snapshot.yml new file mode 100644 index 000000000..39683bb68 --- /dev/null +++ b/wagmi-project/.github/workflows/snapshot.yml @@ -0,0 +1,32 @@ +name: Snapshot +on: + workflow_dispatch: + +jobs: + snapshot: + name: Release snapshot version + permissions: + contents: write + id-token: write + runs-on: ubuntu-latest + timeout-minutes: 5 + + steps: + - name: Clone repository + uses: actions/checkout@v4 + + - name: Install dependencies + uses: wevm/actions/.github/actions/pnpm@main + + - name: Publish Snapshots + continue-on-error: true + env: + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + snapshot=$(git branch --show-current | tr -cs '[:alnum:]-' '-' | tr '[:upper:]' '[:lower:]' | sed 's/-$//') + npm config set "//registry.npmjs.org/:_authToken" "$NPM_TOKEN" + pnpm clean + pnpm changeset version --no-git-tag --snapshot $snapshot + pnpm changeset:prepublish + pnpm changeset publish --no-git-tag --snapshot $snapshot --tag $snapshot diff --git a/wagmi-project/.github/workflows/verify.yml b/wagmi-project/.github/workflows/verify.yml new file mode 100644 index 000000000..582eef2d5 --- /dev/null +++ b/wagmi-project/.github/workflows/verify.yml @@ -0,0 +1,127 @@ +name: Verify +on: + workflow_call: + workflow_dispatch: + +jobs: + check: + name: Check + permissions: + contents: write + runs-on: ubuntu-latest + timeout-minutes: 5 + + steps: + - name: Clone repository + uses: actions/checkout@v4 + with: + token: ${{ secrets.GH_PTOKEN }} + + - name: Install dependencies + uses: wevm/actions/.github/actions/pnpm@main + + - name: Check repo + run: pnpm check:repo + + - name: Check code + run: pnpm check + + - name: Update package versions + run: pnpm version:update + + - uses: stefanzweifel/git-auto-commit-action@v5 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + commit_message: 'chore: format' + commit_user_name: 'github-actions[bot]' + commit_user_email: 'github-actions[bot]@users.noreply.github.com' + + build: + name: Build + needs: check + runs-on: ubuntu-latest + timeout-minutes: 5 + + steps: + - name: Clone repository + uses: actions/checkout@v4 + + - name: Install dependencies + uses: wevm/actions/.github/actions/pnpm@main + + - name: Build + run: pnpm build + + - name: Publint + run: pnpm test:build + + - name: Check for unused files, dependencies, and exports + run: pnpm knip --production + + types: + name: Types + needs: check + runs-on: ubuntu-latest + timeout-minutes: 5 + strategy: + matrix: + typescript-version: ['5.7.3', '5.8.3', 'latest'] + viem-version: ['2.29.2', 'latest'] + + steps: + - name: Clone repository + uses: actions/checkout@v4 + + - name: Install dependencies + uses: wevm/actions/.github/actions/pnpm@main + + - run: pnpm add -D -w typescript@${{ matrix.typescript-version }} viem@${{ matrix.viem-version }} + + - name: Link packages + run: pnpm preconstruct + + - name: Check types + run: pnpm check:types + + # Redundant with `pnpm check:types` + # If Vitest adds special features in the future, e.g. type coverage, can add this back! + # - name: Test types + # run: pnpm test:typecheck + + test: + name: Test + runs-on: ubuntu-latest + timeout-minutes: 10 + strategy: + max-parallel: 3 + matrix: + shard: [1, 2, 3] + total-shards: [3] + + steps: + - name: Clone repository + uses: actions/checkout@v4 + + - name: Install dependencies + uses: wevm/actions/.github/actions/pnpm@main + + - name: Set up foundry + uses: foundry-rs/foundry-toolchain@v1 + with: + version: nightly + + - name: Run tests + uses: nick-fields/retry@v3 + with: + command: CI=true pnpm test:cov --shard=${{ matrix.shard }}/${{ matrix.total-shards }} --retry=3 --bail=1 + max_attempts: 3 + timeout_minutes: 5 + env: + VITE_MAINNET_FORK_URL: ${{ secrets.VITE_MAINNET_FORK_URL }} + VITE_OPTIMISM_FORK_URL: ${{ secrets.VITE_OPTIMISM_FORK_URL }} + + - name: Upload coverage reports to Codecov + uses: codecov/codecov-action@v5 + with: + token: ${{ secrets.CODECOV_TOKEN }} diff --git a/wagmi-project/.gitignore b/wagmi-project/.gitignore index fc5ae9f0c..1834fe72a 100644 --- a/wagmi-project/.gitignore +++ b/wagmi-project/.gitignore @@ -1,25 +1,39 @@ -# Logs -logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -pnpm-debug.log* -lerna-debug.log* - -node_modules +.DS_Store +.next +.nuxt +.pnpm-debug.log* +cache +coverage dist -dist-ssr -*.local +node_modules +tsconfig.tsbuildinfo +*.vitest-temp.json -# Editor directories and files -.vscode/* -!.vscode/extensions.json -.idea -.DS_Store -*.suo -*.ntvs* -*.njsproj -*.sln -*.sw? -.vercel +# local env files +.env +.env.local +.env.development.local +.env.test.local +.env.production.local +.envrc + +# proxy packages +packages/cli/config +packages/cli/plugins +packages/core/actions +packages/core/chains +packages/core/codegen +packages/core/experimental +packages/core/internal +packages/core/query +packages/react/actions +packages/react/chains +packages/react/codegen +packages/react/connectors +packages/react/experimental +packages/react/query +packages/vue/actions +packages/vue/chains +packages/vue/connectors +packages/vue/nuxt +packages/vue/query diff --git a/wagmi-project/.npmrc b/wagmi-project/.npmrc index ca1e9d98b..47687565b 100644 --- a/wagmi-project/.npmrc +++ b/wagmi-project/.npmrc @@ -1 +1,5 @@ -legacy-peer-deps = true \ No newline at end of file +auto-install-peers=false +enable-pre-post-scripts=true +link-workspace-packages=deep +provenance=true +strict-peer-dependencies=false diff --git a/wagmi-project/.vscode/extensions.json b/wagmi-project/.vscode/extensions.json new file mode 100644 index 000000000..9cb435094 --- /dev/null +++ b/wagmi-project/.vscode/extensions.json @@ -0,0 +1,7 @@ +{ + "recommendations": [ + "biomejs.biome", + "orta.vscode-twoslash-queries", + "Vue.volar" + ] +} diff --git a/wagmi-project/.vscode/settings.json b/wagmi-project/.vscode/settings.json new file mode 100644 index 000000000..c32e8fa4c --- /dev/null +++ b/wagmi-project/.vscode/settings.json @@ -0,0 +1,17 @@ +{ + "editor.defaultFormatter": "biomejs.biome", + "editor.formatOnSave": true, + "typescript.enablePromptUseWorkspaceTsdk": true, + "typescript.preferences.importModuleSpecifier": "shortest", + "typescript.tsdk": "node_modules/typescript/lib", + "editor.codeActionsOnSave": { + "quickfix.biome": "explicit", + "source.organizeImports.biome": "explicit" + }, + "[javascript][javascriptreact][json][typescript][typescriptreact]": { + "editor.defaultFormatter": "biomejs.biome" + }, + "[vue]": { + "editor.defaultFormatter": "Vue.volar" + } +} diff --git a/wagmi-project/.vscode/workspace.code-workspace b/wagmi-project/.vscode/workspace.code-workspace new file mode 100644 index 000000000..0d626129d --- /dev/null +++ b/wagmi-project/.vscode/workspace.code-workspace @@ -0,0 +1,16 @@ +{ + "folders": [ + { + "name": "docs", + "path": "../docs" + }, + { + "name": "packages", + "path": "../packages" + }, + { + "name": "playgrounds", + "path": "../playgrounds" + } + ] +} diff --git a/wagmi-project/FUNDING.json b/wagmi-project/FUNDING.json new file mode 100644 index 000000000..5e0125416 --- /dev/null +++ b/wagmi-project/FUNDING.json @@ -0,0 +1,10 @@ +{ + "drips": { + "ethereum": { + "ownedBy": "0xd2135CfB216b74109775236E36d4b433F1DF507B" + } + }, + "opRetro": { + "projectId": "0xc0615947773148cbc340b175fb9afc98dbb4e0acd31d018b1ee41a5538785abf" + } +} diff --git a/wagmi-project/LICENSE b/wagmi-project/LICENSE new file mode 100644 index 000000000..650c3c1c0 --- /dev/null +++ b/wagmi-project/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022-present weth, LLC + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/wagmi-project/biome.json b/wagmi-project/biome.json index 08eb8a26a..ce99662cb 100644 --- a/wagmi-project/biome.json +++ b/wagmi-project/biome.json @@ -1,13 +1,89 @@ { + "$schema": "./node_modules/@biomejs/biome/configuration_schema.json", + "files": { + "ignore": ["CHANGELOG.md", "pnpm-lock.yaml", "tsconfig.base.json"] + }, "formatter": { "enabled": true, + "formatWithErrors": false, "indentStyle": "space", - "lineWidth": 120 + "indentWidth": 2, + "lineWidth": 80 }, "linter": { - "enabled": true + "ignore": ["packages/create-wagmi/templates/*"], + "enabled": true, + "rules": { + "recommended": true, + "a11y": { + "useButtonType": "off" + }, + "correctness": { + "noUnusedVariables": "error", + "useExhaustiveDependencies": "error" + }, + "performance": { + "noBarrelFile": "error", + "noReExportAll": "error", + "noDelete": "off" + }, + "style": { + "noNonNullAssertion": "off", + "useShorthandArrayType": "error" + }, + "suspicious": { + "noArrayIndexKey": "off", + "noConfusingVoidType": "off", + "noConsoleLog": "error", + "noExplicitAny": "off" + } + } + }, + "javascript": { + "formatter": { + "quoteStyle": "single", + "trailingCommas": "all", + "semicolons": "asNeeded" + } }, "organizeImports": { "enabled": true + }, + "overrides": [ + { + "include": ["*.vue"], + "linter": { + "rules": { + "correctness": { + "noUnusedVariables": "off" + } + } + } + }, + { + "include": ["./scripts/**/*.ts"], + "linter": { + "rules": { + "suspicious": { + "noConsoleLog": "off" + } + } + } + }, + { + "include": ["./playgrounds/**"], + "linter": { + "rules": { + "style": { + "useNodejsImportProtocol": "off" + } + } + } + } + ], + "vcs": { + "enabled": true, + "clientKind": "git", + "useIgnoreFile": true } } diff --git a/wagmi-project/package.json b/wagmi-project/package.json index d2a252d67..5c456e7b3 100644 --- a/wagmi-project/package.json +++ b/wagmi-project/package.json @@ -1,29 +1,136 @@ { - "name": "wagmi-project", "private": true, - "version": "0.0.0", "type": "module", "scripts": { - "dev": "vite", - "build": "tsc && vite build", - "lint": "biome check .", - "preview": "vite preview" - }, - "dependencies": { - "@tanstack/react-query": "5.64.2", - "react": "^19.2.0", - "react-dom": "^18.3.1", - "viem": "^2.x", - "wagmi": "~0.x.x" + "build": "pnpm run --r --filter \"./packages/**\" build", + "changeset:prepublish": "pnpm version:update && pnpm build && bun scripts/formatPackageJson.ts && bun scripts/generateProxyPackages.ts", + "changeset:publish": "pnpm changeset:prepublish && changeset publish", + "changeset:version": "changeset version && pnpm version:update && pnpm format", + "check": "biome check --write", + "check:repo": "sherif -i viem", + "check:types": "pnpm run --r --parallel check:types && tsc --noEmit", + "check:unused": "pnpm clean && knip", + "clean": "pnpm run --r --parallel clean && rm -rf packages/**/*.json.tmp", + "deps": "pnpx taze -r", + "dev": "pnpm dev:react", + "dev:cli": "pnpm --filter cli dev", + "dev:core": "pnpm --filter vite-core dev", + "dev:create-wagmi": "pnpm --filter create-wagmi dev", + "dev:next": "pnpm --filter next-app dev", + "dev:nuxt": "pnpm --filter nuxt-app dev", + "dev:react": "pnpm --filter vite-react dev", + "dev:vue": "pnpm --filter vite-vue dev", + "docs:dev": "pnpm --filter site dev", + "format": "biome format --write", + "postinstall": "pnpm preconstruct", + "preconstruct": "bun scripts/preconstruct.ts", + "preinstall": "pnpx only-allow pnpm", + "prepare": "pnpm simple-git-hooks", + "test": "vitest", + "test:build": "bun scripts/generateProxyPackages.ts && pnpm run --r --parallel test:build", + "test:cli": "vitest --project @wagmi/cli", + "test:connectors": "vitest --project @wagmi/connectors", + "test:core": "vitest --project @wagmi/core", + "test:create-wagmi": "vitest --project create-wagmi", + "test:cov": "vitest run --coverage", + "test:react": "vitest --project wagmi", + "test:typecheck": "vitest typecheck", + "test:update": "vitest --update", + "test:vue": "vitest --project @wagmi/vue", + "version:update": "bun scripts/updateVersion.ts", + "version:update:viem": "bun scripts/updateViemVersion.ts" }, "devDependencies": { - "@biomejs/biome": "^1.8.0", - "@types/react": "^18.3.1", - "@types/react-dom": "^18.3.0", - "@vitejs/plugin-react": "^4.2.1", - "@wagmi/cli": "~2.8.0", - "buffer": "^6.0.3", - "typescript": "^5.4.5", - "vite": "^5.2.11" + "@arethetypeswrong/cli": "^0.16.4", + "@biomejs/biome": "^1.9.4", + "@changesets/changelog-github": "0.4.6", + "@changesets/cli": "^2.27.8", + "@types/bun": "^1.1.10", + "@vitest/coverage-v8": "^3.2.4", + "@wagmi/test": "workspace:*", + "bun": "^1.1.30", + "happy-dom": "^18.0.1", + "knip": "^5.30.6", + "prool": "^0.0.23", + "publint": "^0.3.0", + "sherif": "^1.0.0", + "simple-git-hooks": "^2.11.1", + "typescript": "5.8.3", + "viem": "2.31.4", + "vitest": "^2.1.9" + }, + "packageManager": "pnpm@9.11.0", + "pnpm": { + "peerDependencyRules": { + "ignoreMissing": [ + "@algolia/client-search", + "react", + "react-native", + "search-insights" + ] + } + }, + "engines": { + "node": "22.x" + }, + "simple-git-hooks": { + "pre-commit": "pnpm check" + }, + "knip": { + "ignore": ["**/templates/**", "**/hardhat.config.js"], + "ignoreBinaries": ["only-allow"], + "ignoreWorkspaces": [ + "packages/register-tests/**", + "packages/test", + "playgrounds/**" + ], + "workspaces": { + ".": { + "project": "scripts/*.ts" + }, + "packages/cli": { + "entry": [ + "src/cli.ts!", + "src/exports/{config,index,plugins}.ts!", + "types/*.d.ts!" + ], + "ignore": ["test/{constants,setup,utils}.ts"] + }, + "packages/connectors": { + "entry": "src/exports/index.ts!" + }, + "packages/core": { + "entry": "src/exports/{actions,chains,codegen,experimental,index,internal,query}.ts!", + "ignore": ["test/setup.ts"], + "ignoreDependencies": ["@tanstack/query-core"] + }, + "packages/create-wagmi": { + "entry": "src/cli.ts!" + }, + "packages/react": { + "entry": [ + "src/exports/{actions,chains,codegen,connectors,experimental,index,query}.ts!", + "src/exports/actions/experimental.ts!" + ], + "ignore": ["test/setup.ts"] + }, + "packages/test": { + "entry": [ + "src/{globalSetup,setup}.ts!", + "src/exports/{index,react}.ts!" + ] + }, + "packages/vue": { + "entry": [ + "src/exports/{actions,chains,connectors,index,nuxt,query}.ts!", + "src/exports/actions/experimental.ts!" + ], + "ignore": ["src/nuxt/runtime/*", "test/setup.ts"], + "ignoreDependencies": ["nuxt"] + }, + "site": { + "project": ["**/*.ts", "**/*.tsx"] + } + } } } diff --git a/wagmi-project/packages/cli/CHANGELOG.md b/wagmi-project/packages/cli/CHANGELOG.md new file mode 100644 index 000000000..a2911e230 --- /dev/null +++ b/wagmi-project/packages/cli/CHANGELOG.md @@ -0,0 +1,449 @@ +# @wagmi/cli + +## 2.3.1 + +### Patch Changes + +- [#4655](https://github.com/wevm/wagmi/pull/4655) [`43241c8417f3c342036bb46ec8e507d052ae2691`](https://github.com/wevm/wagmi/commit/43241c8417f3c342036bb46ec8e507d052ae2691) Thanks [@tmm](https://github.com/tmm)! - Bumped internal deps. + +## 2.3.0 + +### Minor Changes + +- [#4629](https://github.com/wevm/wagmi/pull/4629) [`66dec7d75d580b3121ebc7e8162c1f9ae37cfd41`](https://github.com/wevm/wagmi/commit/66dec7d75d580b3121ebc7e8162c1f9ae37cfd41) Thanks [@allezxandre](https://github.com/allezxandre)! - Upgraded to Sourcify v2 API in `sourcify` plugin + +## 2.2.1 + +### Patch Changes + +- [`7b0dbe3886c1a7c6dbbdab945d7436ec20ad8f93`](https://github.com/wevm/wagmi/commit/7b0dbe3886c1a7c6dbbdab945d7436ec20ad8f93) Thanks [@tmm](https://github.com/tmm)! - Updated block explorer chains. + +## 2.2.0 + +### Minor Changes + +- [#4503](https://github.com/wevm/wagmi/pull/4503) [`8fce8a6f97aa2ee5fd1bda6a3ece422b10324b5a`](https://github.com/wevm/wagmi/commit/8fce8a6f97aa2ee5fd1bda6a3ece422b10324b5a) Thanks [@tmm](https://github.com/tmm)! - Updated Etherscan Plugin to use Etherscan API v2. + +- [#4507](https://github.com/wevm/wagmi/pull/4507) [`6f09cc57935891e1c67d6df3459f6998985c69dc`](https://github.com/wevm/wagmi/commit/6f09cc57935891e1c67d6df3459f6998985c69dc) Thanks [@tmm](https://github.com/tmm)! - Added `tryFetchProxyImplementation` flag to Etherscan Plugin to enable fetching the implementation ABI instead of the proxy ABI. + +## 2.1.22 + +### Patch Changes + +- [#4462](https://github.com/wevm/wagmi/pull/4462) [`0b2238d27cecbcd33aee64fb0e30ddc18b6ddf74`](https://github.com/wevm/wagmi/commit/0b2238d27cecbcd33aee64fb0e30ddc18b6ddf74) Thanks [@groninge01](https://github.com/groninge01)! - Added Sonic to Etherscan plugin. + +## 2.1.21 + +### Patch Changes + +- [#4457](https://github.com/wevm/wagmi/pull/4457) [`21ec74da7f93fc13e253d7b35ddeddc23422a6c1`](https://github.com/wevm/wagmi/commit/21ec74da7f93fc13e253d7b35ddeddc23422a6c1) Thanks [@tmm](https://github.com/tmm)! - Removed internal dependency. + +## 2.1.20 + +### Patch Changes + +- [#4450](https://github.com/wevm/wagmi/pull/4450) [`7b9a6bb35881b657a00bdd7ccd7edea32660f5bf`](https://github.com/wevm/wagmi/commit/7b9a6bb35881b657a00bdd7ccd7edea32660f5bf) Thanks [@tmm](https://github.com/tmm)! - Removed internal usage of `fs-extra`. + +## 2.1.19 + +### Patch Changes + +- [#4449](https://github.com/wevm/wagmi/pull/4449) [`3fa5c238baa13d948e89974b0bb8530f8fa264fd`](https://github.com/wevm/wagmi/commit/3fa5c238baa13d948e89974b0bb8530f8fa264fd) Thanks [@tmm](https://github.com/tmm)! - Removed `ora` for `nanospinner`. + +## 2.1.18 + +### Patch Changes + +- [#4399](https://github.com/wevm/wagmi/pull/4399) [`bc18673e4c272e3b60a1b6016934fe3fbeb6d93a`](https://github.com/wevm/wagmi/commit/bc18673e4c272e3b60a1b6016934fe3fbeb6d93a) Thanks [@tmm](https://github.com/tmm)! - Added Polygon Amoy to Sourcify and Etherscan plugins. + +## 2.1.17 + +### Patch Changes + +- [#4370](https://github.com/wevm/wagmi/pull/4370) [`cb58b1ea3ad40e77210f24eb598f9d2306db998c`](https://github.com/wevm/wagmi/commit/cb58b1ea3ad40e77210f24eb598f9d2306db998c) Thanks [@talentlessguy](https://github.com/talentlessguy)! - Bumped internal dependencies. + +## 2.1.16 + +### Patch Changes + +- [#4224](https://github.com/wevm/wagmi/pull/4224) [`b0eb89c2a0781bb3434996fa53ee7ceb3bb44db9`](https://github.com/wevm/wagmi/commit/b0eb89c2a0781bb3434996fa53ee7ceb3bb44db9) Thanks [@roderik](https://github.com/roderik)! - Fixed package detection for Bun. + +## 2.1.15 + +### Patch Changes + +- [`0bb8b562ae04ecfeb2d6b2f1b980ebae31dc127e`](https://github.com/wevm/wagmi/commit/0bb8b562ae04ecfeb2d6b2f1b980ebae31dc127e) Thanks [@tmm](https://github.com/tmm)! - Improved TypeScript `'exactOptionalPropertyTypes'` support. + +## 2.1.14 + +### Patch Changes + +- [#4120](https://github.com/wevm/wagmi/pull/4120) [`59407bf1276a46e6f1f22a370dde71c92524cd0f`](https://github.com/wevm/wagmi/commit/59407bf1276a46e6f1f22a370dde71c92524cd0f) Thanks [@tmm](https://github.com/tmm)! - Fixed an issue where the Foundry and Hardhat plugins' `exclude` option was ignored. + +## 2.1.13 + +### Patch Changes + +- [`7264d1f450727f6ba0cbea8aa1c7a83e22a5bf20`](https://github.com/wevm/wagmi/commit/7264d1f450727f6ba0cbea8aa1c7a83e22a5bf20) Thanks [@tmm](https://github.com/tmm)! - Fixed generate not exiting for long-running processes. + +## 2.1.12 + +### Patch Changes + +- [`ac038b29623ccb0d2fee40d9f943c8df28138dac`](https://github.com/wevm/wagmi/commit/ac038b29623ccb0d2fee40d9f943c8df28138dac) Thanks [@tmm](https://github.com/tmm)! - Updated Foundry default excludes. + +## 2.1.11 + +### Patch Changes + +- [#4084](https://github.com/wevm/wagmi/pull/4084) [`b54203bf8fa911e6f14b9675980cf38fb95d7d3e`](https://github.com/wevm/wagmi/commit/b54203bf8fa911e6f14b9675980cf38fb95d7d3e) Thanks [@tmm](https://github.com/tmm)! - Reduced internal dependencies. + +## 2.1.10 + +### Patch Changes + +- [#4051](https://github.com/wevm/wagmi/pull/4051) [`275e78b0e585f0ec9da2f9661ce9990aed18e9f4`](https://github.com/wevm/wagmi/commit/275e78b0e585f0ec9da2f9661ce9990aed18e9f4) Thanks [@tmm](https://github.com/tmm)! - Updated Sourcify plugin internals. + +## 2.1.9 + +### Patch Changes + +- [`f9346dbcffaf57a8949cb96e43df111a89d733b1`](https://github.com/wevm/wagmi/commit/f9346dbcffaf57a8949cb96e43df111a89d733b1) Thanks [@tmm](https://github.com/tmm)! - Updated Foundry plugin default excludes. + +## 2.1.8 + +### Patch Changes + +- [#3957](https://github.com/wevm/wagmi/pull/3957) [`7d00680f73b090eb34af928ae74277bec1973953`](https://github.com/wevm/wagmi/commit/7d00680f73b090eb34af928ae74277bec1973953) Thanks [@cstoneham](https://github.com/cstoneham)! - Added Blast to Etherscan plugin + +## 2.1.7 + +### Patch Changes + +- [`1122678bbad0232590bd4060a73752de2c84982d`](https://github.com/wevm/wagmi/commit/1122678bbad0232590bd4060a73752de2c84982d) Thanks [@tmm](https://github.com/tmm)! - Published unpublished changes in [#3756](https://github.com/wevm/wagmi/pull/3756). + +## 2.1.6 + +### Patch Changes + +- [#3756](https://github.com/wevm/wagmi/pull/3756) [`c7d6f467`](https://github.com/wevm/wagmi/commit/c7d6f4679125fd2f6cca5b5ef362abf47e37f934) Thanks [@jrfrantz](https://github.com/jrfrantz)! - Added basescan to etherscan cli plugin + +## 2.1.5 + +### Patch Changes + +- [`e1ca4e63`](https://github.com/wevm/wagmi/commit/e1ca4e637ae6cec7f5902b0a2c0e0efc3b751a1d) Thanks [@tmm](https://github.com/tmm)! - Added title to CLI process. + +- [#3723](https://github.com/wevm/wagmi/pull/3723) [`d6bc98ca`](https://github.com/wevm/wagmi/commit/d6bc98ca0ce9081f192f62e0b0fcfea3cb07a2bb) Thanks [@leecobaby](https://github.com/leecobaby)! - Broadened TypeScript detection. + +## 2.1.4 + +### Patch Changes + +- [#3737](https://github.com/wevm/wagmi/pull/3737) [`11020fed`](https://github.com/wevm/wagmi/commit/11020fedfc68639eace241e328331cff43bf91af) Thanks [@oskarvu](https://github.com/oskarvu)! - Added Gnosis to Etherscan plugin. + +## 2.1.3 + +### Patch Changes + +- [#3660](https://github.com/wevm/wagmi/pull/3660) [`11a22a23`](https://github.com/wevm/wagmi/commit/11a22a23d88c025cde9c91610e9ddf62cd4fa650) Thanks [@JazzBashara](https://github.com/JazzBashara)! - Replaced SnowTrace with SnowScan for the Etherscan plugin + +## 2.1.2 + +### Patch Changes + +- [#3641](https://github.com/wevm/wagmi/pull/3641) [`0a866403`](https://github.com/wevm/wagmi/commit/0a866403182ea6b8ba7f976c45be294e48fb7de8) Thanks [@cmwhited](https://github.com/cmwhited)! - Added Arbitrum Sepolia testnet to Etherscan plugin + +- [#3633](https://github.com/wevm/wagmi/pull/3633) [`a1d3d1ab`](https://github.com/wevm/wagmi/commit/a1d3d1ab2b023c61c0dbb5d7bf867a9fca673630) Thanks [@pegahcarter](https://github.com/pegahcarter)! - Added Fraxtal to Etherscan plugin + +- [#3616](https://github.com/wevm/wagmi/pull/3616) [`2a9f4473`](https://github.com/wevm/wagmi/commit/2a9f4473adc5bcdddf388389387ed5459583769e) Thanks [@petermazzocco](https://github.com/petermazzocco)! - Added Holesky Testnet to Etherscan Plugin + +## 2.1.1 + +### Patch Changes + +- [#3579](https://github.com/wevm/wagmi/pull/3579) [`a057919c`](https://github.com/wevm/wagmi/commit/a057919ca3942adeed90af2e343403dc5274e84c) Thanks [@FaisalAli19](https://github.com/FaisalAli19)! - Added Optimism Sepolia Etherscan support + +## 2.1.0 + +### Minor Changes + +- [#3506](https://github.com/wevm/wagmi/pull/3506) [`134eb4a1`](https://github.com/wevm/wagmi/commit/134eb4a1e0e29aab87bd5c7cdf05b06dfd7c4fc4) Thanks [@vmaark](https://github.com/vmaark)! - Added resolution of TypeScript Wagmi CLI config to determine if TypeScript generated output is allowed. + +## 2.0.4 + +### Patch Changes + +- [#3462](https://github.com/wevm/wagmi/pull/3462) [`d25573ea`](https://github.com/wevm/wagmi/commit/d25573ea03358f967953e37c176b220a7b341769) Thanks [@cruzdanilo](https://github.com/cruzdanilo)! - Upgraded dependencies + +## 2.0.3 + +### Patch Changes + +- [#3410](https://github.com/wevm/wagmi/pull/3410) [`55e31c3e`](https://github.com/wevm/wagmi/commit/55e31c3e96c2cbd1d9eb44e5a89f4365489c8310) Thanks [@o-az](https://github.com/o-az)! - Fixed actions plugin issue where `functionName` was used instead of `eventName` for generated contract event actions. + +## 2.0.2 + +### Patch Changes + +- [#3371](https://github.com/wevm/wagmi/pull/3371) [`8294d9e5`](https://github.com/wevm/wagmi/commit/8294d9e5b358018ba869b2018cd7ed95462e021f) Thanks [@iceanddust](https://github.com/iceanddust)! - Fixed prop name when generating contract event watch hooks + +## 2.0.1 + +### Major Changes + +- [#3333](https://github.com/wevm/wagmi/pull/3333) [`b3a0baaa`](https://github.com/wevm/wagmi/commit/b3a0baaaee7decf750d376aab2502cd33ca4825a) Thanks [@tmm](https://github.com/tmm)! - Wagmi CLI 2.0. + + [Breaking Changes & Migration Guide](https://wagmi.sh/cli/guides/migrate-from-v1-to-v2) + +## 1.5.2 + +### Patch Changes + +- [#3051](https://github.com/wagmi-dev/wagmi/pull/3051) [`4704d351`](https://github.com/wagmi-dev/wagmi/commit/4704d351164d39704a4e375c06525554fcc8340e) Thanks [@oxSaturn](https://github.com/oxSaturn)! - Fixed ESM require issue for prettier + +## 1.5.1 + +### Patch Changes + +- [#3035](https://github.com/wagmi-dev/wagmi/pull/3035) [`187bf96c`](https://github.com/wagmi-dev/wagmi/commit/187bf96c9fd31675b9d17a7cb4d4e24eea3fa777) Thanks [@cruzdanilo](https://github.com/cruzdanilo)! - ignore foundry invariant lib + +## 1.5.0 + +### Minor Changes + +- [#2956](https://github.com/wevm/wagmi/pull/2956) [`2abeb285`](https://github.com/wevm/wagmi/commit/2abeb285674af3e539cc2550b1f5027b1eb0c895) Thanks [@tmm](https://github.com/tmm)! - Replaced `@wagmi/chains` with `viem/chains`. + +## 1.4.1 + +### Patch Changes + +- [#2962](https://github.com/wevm/wagmi/pull/2962) [`8ac5b572`](https://github.com/wevm/wagmi/commit/8ac5b57254f77eeb0e07dd83f7d49f396d4581d8) Thanks [@tmm](https://github.com/tmm)! - Fixed esbuild version + +## 1.4.0 + +### Minor Changes + +- [#2946](https://github.com/wevm/wagmi/pull/2946) [`1c3228bf`](https://github.com/wevm/wagmi/commit/1c3228bf3fe99b0900b2c9a223c9b81c70bdcd90) Thanks [@tomquirk](https://github.com/tomquirk)! - Added default chain ID to generated `useContractRead` hook. + +### Patch Changes + +- [#2547](https://github.com/wevm/wagmi/pull/2547) [`8c3889fe`](https://github.com/wevm/wagmi/commit/8c3889fe82c5a1ddb29e74e3863ea6f4917b777a) Thanks [@Iamshankhadeep](https://github.com/Iamshankhadeep)! - Deterministic CLI output + +- [#2958](https://github.com/wevm/wagmi/pull/2958) [`b31f36d5`](https://github.com/wevm/wagmi/commit/b31f36d522a634f53d44349d6a9ea47f59d84d7a) Thanks [@tmm](https://github.com/tmm)! - Removed generated file header + +- [#2960](https://github.com/wevm/wagmi/pull/2960) [`5d4c4592`](https://github.com/wevm/wagmi/commit/5d4c4592009568cd0b096906a424f27469721a42) Thanks [@tmm](https://github.com/tmm)! - Updated esbuild version + +## 1.3.0 + +### Minor Changes + +- [#2616](https://github.com/wevm/wagmi/pull/2616) [`c282a8f7`](https://github.com/wevm/wagmi/commit/c282a8f786d57fec77c931fe99dc20220e843bc8) Thanks [@portdeveloper](https://github.com/portdeveloper)! - Added sepolia chain id + +## 1.2.1 + +### Patch Changes + +- [#2607](https://github.com/wevm/wagmi/pull/2607) [`79335b4c`](https://github.com/wevm/wagmi/commit/79335b4c0fcd5e8152a2a1d28314c634db9d9cbf) Thanks [@roninjin10](https://github.com/roninjin10)! - Fixed opitmism goerli chain id + +## 1.2.0 + +### Minor Changes + +- [#2536](https://github.com/wevm/wagmi/pull/2536) [`85e9760a`](https://github.com/wevm/wagmi/commit/85e9760a140cb169ac6236d9466b96e2105dd193) Thanks [@tmm](https://github.com/tmm)! - Changed `Address` type import from ABIType to viem. + +## 1.1.0 + +### Minor Changes + +- [#2482](https://github.com/wevm/wagmi/pull/2482) [`8764b54a`](https://github.com/wevm/wagmi/commit/8764b54aab68020063946112e8fe52aff650c99c) Thanks [@tmm](https://github.com/tmm)! - Bumped minimum TypeScript version to v5.0.4. + +### Patch Changes + +- [#2484](https://github.com/wevm/wagmi/pull/2484) [`3adf1f4f`](https://github.com/wevm/wagmi/commit/3adf1f4feab863cb7b5d52c81ad46f7e4eb56f09) Thanks [@jxom](https://github.com/jxom)! - Updated `abitype` to 0.8.7 + +- [#2484](https://github.com/wevm/wagmi/pull/2484) [`3adf1f4f`](https://github.com/wevm/wagmi/commit/3adf1f4feab863cb7b5d52c81ad46f7e4eb56f09) Thanks [@jxom](https://github.com/jxom)! - Updated references. + +## 1.0.3 + +### Patch Changes + +- [#2441](https://github.com/wevm/wagmi/pull/2441) [`326edee4`](https://github.com/wevm/wagmi/commit/326edee4bc85db84a7a4e3768e33785849ab8d8e) Thanks [@tmm](https://github.com/tmm)! - Fixed internal type issue + +## 1.0.2 + +### Patch Changes + +- [#2430](https://github.com/wevm/wagmi/pull/2430) [`71d92029`](https://github.com/wevm/wagmi/commit/71d92029ee4344842cd41698858a330fee95b6e0) Thanks [@tmm](https://github.com/tmm)! - Added message when command is not found. + +## 1.0.1 + +### Patch Changes + +- [`ea651cd7`](https://github.com/wevm/wagmi/commit/ea651cd7fc75b7866272605467db11fd6e1d81af) Thanks [@jxom](https://github.com/jxom)! - Downgraded abitype. + +## 1.0.0 + +### Major Changes + +- [#2235](https://github.com/wevm/wagmi/pull/2235) [`5be0655c`](https://github.com/wevm/wagmi/commit/5be0655c8e48b25d38009022461fbf611af54349) Thanks [@jxom](https://github.com/jxom)! - Released v1. Read [Migration Guide](https://next.wagmi.sh/react/migration-guide#1xx-breaking-changes). + +## 1.0.0-next.7 + +### Patch Changes + +- Fixed react plugin generic. + +## 1.0.0-next.6 + +### Major Changes + +- Updated references. + +## 1.0.0-next.5 + +### Major Changes + +- Added `config.setConnectors` + +## 1.0.0-next.4 + +### Major Changes + +- Updated viem. + Removed `goerli` export from main entrypoint. + +## 1.0.0-next.3 + +### Major Changes + +- Updated references. + +## 1.0.0-next.2 + +### Major Changes + +- Updated dependencies + +### Patch Changes + +- Updated dependencies []: + - @wagmi/chains@1.0.0-next.0 + +## 1.0.0-next.1 + +### Major Changes + +- updated viem + +## 1.0.0-next.0 + +### Major Changes + +- [`a7dda00c`](https://github.com/wevm/wagmi/commit/a7dda00c5b546f8b2c42b527e4d9ac1b9e9ab1fb) Thanks [@jxom](https://github.com/jxom)! - Released v1. + +### Patch Changes + +- Updated dependencies [[`a7dda00c`](https://github.com/wevm/wagmi/commit/a7dda00c5b546f8b2c42b527e4d9ac1b9e9ab1fb)]: + - @wagmi/core@1.0.0-next.0 + - wagmi@1.0.0-next.0 + +## 0.1.15 + +### Patch Changes + +- [#2145](https://github.com/wevm/wagmi/pull/2145) [`2520743c`](https://github.com/wevm/wagmi/commit/2520743c417a158a00d5edca13a9aa92cefb0cfd) Thanks [@tmm](https://github.com/tmm)! - Fixed issue using Hardhat Plugin with npm. + +## 0.1.14 + +### Patch Changes + +- [#2039](https://github.com/wevm/wagmi/pull/2039) [`bac893ab`](https://github.com/wevm/wagmi/commit/bac893ab26012d4d8741c4f80e8b8813aee26f0c) Thanks [@tmm](https://github.com/tmm)! - Updated references. + +- [#2039](https://github.com/wevm/wagmi/pull/2039) [`bac893ab`](https://github.com/wevm/wagmi/commit/bac893ab26012d4d8741c4f80e8b8813aee26f0c) Thanks [@tmm](https://github.com/tmm)! - Fixed Actions plugin `overridePackageName` option. + +## 0.1.13 + +### Patch Changes + +- [#2000](https://github.com/wevm/wagmi/pull/2000) [`01254765`](https://github.com/wevm/wagmi/commit/01254765eb37b77aca26500c00c721f08a260912) Thanks [@tmm](https://github.com/tmm)! - Fixed React plugin name conflict. + +## 0.1.12 + +### Patch Changes + +- [#1992](https://github.com/wevm/wagmi/pull/1992) [`efc93cad`](https://github.com/wevm/wagmi/commit/efc93cadacdb9c9960644dabe4ae837d384df52b) Thanks [@tmm](https://github.com/tmm)! - Refactored internals from ethers to viem. + +## 0.1.11 + +### Patch Changes + +- [#1916](https://github.com/wevm/wagmi/pull/1916) [`950490fd`](https://github.com/wevm/wagmi/commit/950490fd132b3fb5b3455e77b58d70f134b8e5c9) Thanks [@technophile-04](https://github.com/technophile-04)! - Updated React plugin to use `Address` type instead of hardcoding `` `0x{string}` ``. + +## 0.1.10 + +### Patch Changes + +- [#1892](https://github.com/wevm/wagmi/pull/1892) [`d3d6973b`](https://github.com/wevm/wagmi/commit/d3d6973ba9407e490140d2434eb83aad88d6e10d) Thanks [@greg-schrammel](https://github.com/greg-schrammel)! - Fixed generated read hooks `select` type. + +## 0.1.9 + +### Patch Changes + +- [#1886](https://github.com/wevm/wagmi/pull/1886) [`36e119c6`](https://github.com/wevm/wagmi/commit/36e119c6d4bc28a7ae15c9602d0c613bc9681356) Thanks [@roninjin10](https://github.com/roninjin10)! - Fixed package detection for yarn^3 + +## 0.1.8 + +### Patch Changes + +- [#1884](https://github.com/wevm/wagmi/pull/1884) [`cc03bb44`](https://github.com/wevm/wagmi/commit/cc03bb44268874f95203de67f6d32586e34c0857) Thanks [@roninjin10](https://github.com/roninjin10)! - Added better compatibility for yarn@^3 in `@wagmi/cli`. + +## 0.1.7 + +### Patch Changes + +- [#1841](https://github.com/wevm/wagmi/pull/1841) [`cb707f01`](https://github.com/wevm/wagmi/commit/cb707f01cbdcc62a70cf5c8a162d77948d6b6a56) Thanks [@tmm](https://github.com/tmm)! - Added [Sourcify](https://sourcify.dev) CLI plugin. + +## 0.1.6 + +### Patch Changes + +- [#1803](https://github.com/wevm/wagmi/pull/1803) [`09b13538`](https://github.com/wevm/wagmi/commit/09b13538abcde879034293cae39551c30cc81445) Thanks [@shotaronowhere](https://github.com/shotaronowhere)! - Swapped deprecated Arbitrum Rinkeby for Arbitrum Goerli URL for Etherscan Plugin. + +## 0.1.5 + +### Patch Changes + +- [#1788](https://github.com/wevm/wagmi/pull/1788) [`c3e16d82`](https://github.com/wevm/wagmi/commit/c3e16d82c9c39b8b1c2f3c51037e11d642a20cd6) Thanks [@tmm](https://github.com/tmm)! - Fixed CLI import + +## 0.1.4 + +### Patch Changes + +- [#1779](https://github.com/wevm/wagmi/pull/1779) [`97346750`](https://github.com/wevm/wagmi/commit/973467505dc2bb46198a3e9fe6072306170d24c0) Thanks [@tmm](https://github.com/tmm)! - Made `project` optional for Foundry plugin + +## 0.1.3 + +### Patch Changes + +- [#1754](https://github.com/wevm/wagmi/pull/1754) [`298728b5`](https://github.com/wevm/wagmi/commit/298728b5918fa15b6b5b082597204a268d4b01f1) Thanks [@tmm](https://github.com/tmm)! - Updated project resolution for Foundry and Hardhat plugins. + +- [#1738](https://github.com/wevm/wagmi/pull/1738) [`37c221d0`](https://github.com/wevm/wagmi/commit/37c221d0f4d175084e23a6b172d72f177bfa0c81) Thanks [@roninjin10](https://github.com/roninjin10)! - Added automatic Foundry config detection for artifacts directory. + +## 0.1.2 + +### Patch Changes + +- [#1743](https://github.com/wevm/wagmi/pull/1743) [`379315fa`](https://github.com/wevm/wagmi/commit/379315fa359c3118b5d200ec50db3812b0cdd984) Thanks [@kyscott18](https://github.com/kyscott18)! - Add celoscan to `etherscan` plugin + +## 0.1.1 + +### Patch Changes + +- [#1736](https://github.com/wevm/wagmi/pull/1736) [`7c43e431`](https://github.com/wevm/wagmi/commit/7c43e431e2eb970610cc6490cee6a4093655a683) Thanks [@tmm](https://github.com/tmm)! - Fixed generated address object key type. + +## 0.1.0 + +### Minor Changes + +- [#1732](https://github.com/wevm/wagmi/pull/1732) [`01e21897`](https://github.com/wevm/wagmi/commit/01e2189747a5c22dc758c6d719b4145adc2a643c) Thanks [@tmm](https://github.com/tmm)! - Initial release diff --git a/wagmi-project/packages/cli/README.md b/wagmi-project/packages/cli/README.md new file mode 100644 index 000000000..640acb22d --- /dev/null +++ b/wagmi-project/packages/cli/README.md @@ -0,0 +1,13 @@ +# @wagmi/cli + +Manage and generate code from Ethereum ABIs + +## Installation + +```bash +pnpm add @wagmi/cli +``` + +## Documentation + +For documentation and guides, visit [wagmi.sh](https://wagmi.sh). diff --git a/wagmi-project/packages/cli/package.json b/wagmi-project/packages/cli/package.json new file mode 100644 index 000000000..1a00143c5 --- /dev/null +++ b/wagmi-project/packages/cli/package.json @@ -0,0 +1,94 @@ +{ + "name": "@wagmi/cli", + "description": "Manage and generate code from Ethereum ABIs", + "version": "2.3.1", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/wevm/wagmi.git", + "directory": "packages/cli" + }, + "scripts": { + "build": "pnpm run clean && pnpm run build:esm+types", + "build:esm+types": "tsc --project tsconfig.build.json --outDir ./dist/esm --declaration --declarationMap --declarationDir ./dist/types", + "check:types": "tsc --noEmit", + "clean": "rm -rf dist tsconfig.tsbuildinfo config plugins", + "dev": "bun src/cli.ts", + "test:build": "publint --strict && attw --pack --ignore-rules cjs-resolves-to-esm" + }, + "files": [ + "dist/**", + "!dist/**/*.tsbuildinfo", + "src/**/*.ts", + "!src/**/*.test.ts", + "!src/**/*.test-d.ts", + "/config", + "/plugins" + ], + "bin": { + "wagmi": "./dist/esm/cli.js" + }, + "sideEffects": false, + "type": "module", + "main": "./dist/esm/exports/index.js", + "types": "./dist/types/exports/index.d.ts", + "typings": "./dist/types/exports/index.d.ts", + "exports": { + ".": { + "types": "./dist/types/exports/index.d.ts", + "default": "./dist/esm/exports/index.js" + }, + "./config": { + "types": "./dist/types/exports/config.d.ts", + "default": "./dist/esm/exports/config.js" + }, + "./plugins": { + "types": "./dist/types/exports/plugins.d.ts", + "default": "./dist/esm/exports/plugins.js" + }, + "./package.json": "./package.json" + }, + "typesVersions": { + "*": { + "config": ["./dist/types/exports/config.d.ts"], + "plugins": ["./dist/types/exports/plugins.d.ts"] + } + }, + "peerDependencies": { + "typescript": ">=5.0.4" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + }, + "dependencies": { + "abitype": "^1.0.4", + "bundle-require": "^5.1.0", + "cac": "^6.7.14", + "change-case": "^5.4.4", + "chokidar": "4.0.3", + "dedent": "^1.5.3", + "dotenv": "^16.3.1", + "dotenv-expand": "^10.0.0", + "esbuild": "~0.25.5", + "escalade": "3.2.0", + "fdir": "^6.1.1", + "nanospinner": "1.2.2", + "pathe": "^2.0.3", + "picocolors": "^1.0.0", + "picomatch": "^4.0.2", + "prettier": "^3.0.3", + "viem": "2.x", + "zod": "^3.22.3" + }, + "devDependencies": { + "@types/dedent": "^0.7.2", + "@types/node": "^22.14.0", + "fixturez": "^1.1.0", + "msw": "^2.4.9" + }, + "contributors": ["awkweb.eth ", "jxom.eth "], + "funding": "https://github.com/sponsors/wevm", + "keywords": ["wagmi", "eth", "ethereum", "dapps", "wallet", "web3", "cli"] +} diff --git a/wagmi-project/packages/cli/src/cli.ts b/wagmi-project/packages/cli/src/cli.ts new file mode 100644 index 000000000..551543bb2 --- /dev/null +++ b/wagmi-project/packages/cli/src/cli.ts @@ -0,0 +1,53 @@ +#!/usr/bin/env node +import { cac } from 'cac' + +import { type Generate, generate } from './commands/generate.js' +import { type Init, init } from './commands/init.js' +import * as logger from './logger.js' +import { version } from './version.js' + +const cli = cac('wagmi') + +cli + .command('generate', 'generate code based on configuration') + .option('-c, --config ', '[string] path to config file') + .option('-r, --root ', '[string] root path to resolve config from') + .option('-w, --watch', '[boolean] watch for changes') + .example((name) => `${name} generate`) + .action(async (options: Generate) => { + await generate(options) + if (!options.watch) process.exit(0) + }) + +cli + .command('init', 'create configuration file') + .option('-c, --config ', '[string] path to config file') + .option('-r, --root ', '[string] root path to resolve config from') + .example((name) => `${name} init`) + .action(async (options: Init) => { + await init(options) + process.exit(0) + }) + +cli.help() +cli.version(version) + +void (async () => { + try { + process.title = 'node (wagmi)' + } catch {} + + try { + // Parse CLI args without running command + cli.parse(process.argv, { run: false }) + if (!cli.matchedCommand) { + if (cli.args.length === 0) { + if (!cli.options.help && !cli.options.version) cli.outputHelp() + } else throw new Error(`Unknown command: ${cli.args.join(' ')}`) + } + await cli.runMatchedCommand() + } catch (error) { + logger.error(`\n${(error as Error).message}`) + process.exit(1) + } +})() diff --git a/wagmi-project/packages/cli/src/commands/generate.test.ts b/wagmi-project/packages/cli/src/commands/generate.test.ts new file mode 100644 index 000000000..91e426521 --- /dev/null +++ b/wagmi-project/packages/cli/src/commands/generate.test.ts @@ -0,0 +1,409 @@ +import { readFile } from 'node:fs/promises' +import dedent from 'dedent' +import { resolve } from 'pathe' +import { afterEach, beforeEach, expect, test, vi } from 'vitest' + +import { createFixture, typecheck, watchConsole } from '../../test/utils.js' +import { generate } from './generate.js' + +let console: ReturnType +beforeEach(() => { + console = watchConsole() + vi.useFakeTimers() + + const date = new Date(2023, 0, 30, 12) + vi.setSystemTime(date) +}) + +afterEach(() => { + vi.restoreAllMocks() + vi.useRealTimers() +}) + +test('generates output', async () => { + const { dir } = await createFixture({ + files: { + tsconfig: true, + 'wagmi.config.js': dedent` + export default { + out: 'generated.js', + contracts: [ + { + abi: [], + name: 'Foo', + }, + ], + } + `, + }, + }) + const spy = vi.spyOn(process, 'cwd') + spy.mockImplementation(() => dir) + + await generate() + + expect(console.formatted).toMatchInlineSnapshot(` + "- Validating plugins + √ Validating plugins + - Resolving contracts + √ Resolving contracts + - Running plugins + √ Running plugins + - Writing to generated.js + √ Writing to generated.js" + `) +}) + +test('generates typescript output', async () => { + const { dir, paths } = await createFixture({ + files: { + tsconfig: true, + 'wagmi.config.ts': dedent` + export default { + out: 'generated.ts', + contracts: [ + { + abi: [], + name: 'Foo', + }, + ], + } + `, + }, + }) + const spy = vi.spyOn(process, 'cwd') + spy.mockImplementation(() => dir) + + await generate() + + expect(console.formatted).toMatchInlineSnapshot(` + "- Validating plugins + √ Validating plugins + - Resolving contracts + √ Resolving contracts + - Running plugins + √ Running plugins + - Writing to generated.ts + √ Writing to generated.ts" + `) + await expect(typecheck(paths.tsconfig)).resolves.toMatchInlineSnapshot('""') +}) + +test('generates output with plugin', async () => { + const { dir } = await createFixture({ + files: { + tsconfig: true, + 'wagmi.config.ts': dedent` + export default { + out: 'generated.ts', + contracts: [ + { + abi: [], + name: 'Foo', + }, + ], + plugins: [ + { + name: 'Test', + async run({ contracts, isTypeScript, outputs }) { + return { + imports: '/* imports test */', + prepend: '/* prepend test */', + content: '/* content test */', + } + }, + }, + ], + } + `, + }, + }) + const spy = vi.spyOn(process, 'cwd') + spy.mockImplementation(() => dir) + + await generate() + + expect(console.formatted).toMatchInlineSnapshot(` + "- Validating plugins + √ Validating plugins + - Resolving contracts + √ Resolving contracts + - Running plugins + √ Running plugins + - Writing to generated.ts + √ Writing to generated.ts" + `) + /* eslint-disable no-irregular-whitespace */ + await expect( + readFile(resolve(dir, 'generated.ts'), 'utf8'), + ).resolves.toMatchInlineSnapshot(` + "/* imports test */ + + /* prepend test */ + + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // Foo + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + export const fooAbi = [] as const + + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // Test + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + /* content test */ + " + `) + /* eslint-enable no-irregular-whitespace */ +}) + +test('behavior: invalid cli options', async () => { + const { dir } = await createFixture() + const spy = vi.spyOn(process, 'cwd') + spy.mockImplementation(() => dir) + + await expect( + generate({ + // @ts-expect-error possible to pass untyped options through from cli + config: 1, + }), + ).rejects.toThrowErrorMatchingInlineSnapshot(` + [Error: Invalid option + - Expected string, received number at \`config\`] + `) +}) + +test('behavior: config not found', async () => { + const { dir } = await createFixture() + const spy = vi.spyOn(process, 'cwd') + spy.mockImplementation(() => dir) + + await expect(generate()).rejects.toThrowErrorMatchingInlineSnapshot( + '[Error: Config not found]', + ) +}) + +test('behavior: config not found for path', async () => { + const { dir } = await createFixture() + const spy = vi.spyOn(process, 'cwd') + spy.mockImplementation(() => dir) + + try { + await generate({ config: 'wagmi.config.js' }) + } catch (error) { + expect( + (error as Error).message.replace(dir, 'path/to/project'), + ).toMatchInlineSnapshot('"Config not found at wagmi.config.js"') + } +}) + +test('behavior: config out not unique', async () => { + const { dir } = await createFixture({ + files: { + 'wagmi.config.js': dedent` + export default [ + { + out: 'generated.ts', + contracts: [ + { + abi: [], + name: 'Foo', + }, + ] + }, + { + out: 'generated.ts', + contracts: [ + { + abi: [], + name: 'Foo', + }, + ], + }, + ] + `, + }, + }) + const spy = vi.spyOn(process, 'cwd') + spy.mockImplementation(() => dir) + + await expect(generate()).rejects.toThrowErrorMatchingInlineSnapshot( + `[Error: out "generated.ts" must be unique.]`, + ) +}) + +test('behavior: config contract names not unique', async () => { + const { dir } = await createFixture({ + files: { + 'wagmi.config.js': dedent` + export default { + out: 'generated.ts', + contracts: [ + { + abi: [], + name: 'Foo', + }, + { + abi: [], + name: 'Foo', + }, + ], + } + `, + }, + }) + const spy = vi.spyOn(process, 'cwd') + spy.mockImplementation(() => dir) + + await expect(generate()).rejects.toThrowErrorMatchingInlineSnapshot( + `[Error: Contract name "Foo" must be unique.]`, + ) +}) + +test('behavior: displays message if no contracts found', async () => { + const { dir } = await createFixture({ + files: { + 'wagmi.config.js': "export default { out: 'generated.ts' }", + }, + }) + const spy = vi.spyOn(process, 'cwd') + spy.mockImplementation(() => dir) + + await generate() + + expect(console.formatted).toMatchInlineSnapshot( + ` + "- Validating plugins + √ Validating plugins + - Resolving contracts + × Resolving contracts + No contracts found." + `, + ) +}) + +test('behavior: throws when abi is invalid', async () => { + const { dir } = await createFixture({ + files: { + 'wagmi.config.js': dedent` + export default { + out: 'generated.ts', + contracts: [ + { + abi: [{ + type: 'function', + name: 'balanceOf', + stateMutability: 'view', + inputs: [{ type: 'address' }], + }], + name: 'Foo', + }, + ], + } + `, + }, + }) + const spy = vi.spyOn(process, 'cwd') + spy.mockImplementation(() => dir) + + await expect(generate()).rejects.toThrowErrorMatchingInlineSnapshot(` + [Error: Invalid ABI for contract "Foo" + - Invalid input at \`[0]\`] + `) +}) + +test('behavior: throws when address is invalid', async () => { + const { dir } = await createFixture({ + files: { + 'wagmi.config.js': dedent` + export default { + out: 'generated.ts', + contracts: [ + { + abi: [], + address: '0xfoo', + name: 'Foo', + }, + ], + } + `, + }, + }) + const spy = vi.spyOn(process, 'cwd') + spy.mockImplementation(() => dir) + + await expect(generate()).rejects.toThrowErrorMatchingInlineSnapshot(` + [Error: Invalid address for contract "Foo" + - Invalid address] + `) +}) + +test('behavior: throws when multichain address is invalid', async () => { + const { dir } = await createFixture({ + files: { + 'wagmi.config.js': dedent` + export default { + out: 'generated.ts', + contracts: [ + { + abi: [], + address: { + 1: '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 5: '0xfoo', + }, + name: 'Foo', + }, + ], + } + `, + }, + }) + const spy = vi.spyOn(process, 'cwd') + spy.mockImplementation(() => dir) + + await expect(generate()).rejects.toThrowErrorMatchingInlineSnapshot(` + [Error: Invalid address for contract "Foo" + - Invalid address at \`5\`] + `) +}) + +test('behavior: displays message if using --watch flag without watchers configured', async () => { + const { dir } = await createFixture({ + files: { + 'wagmi.config.js': dedent` + export default { + out: 'generated.ts', + contracts: [ + { + abi: [], + name: 'Foo', + }, + ], + } + `, + }, + }) + const spy = vi.spyOn(process, 'cwd') + spy.mockImplementation(() => dir) + + await generate({ watch: true }) + + expect(console.formatted).toMatchInlineSnapshot(` + "- Validating plugins + √ Validating plugins + - Resolving contracts + √ Resolving contracts + - Running plugins + √ Running plugins + - Writing to generated.ts + √ Writing to generated.ts + Used --watch flag, but no plugins are watching." + `) +}) + +test.todo('behavior: save config file logs change') +test.todo('behavior: updates on add file') +test.todo('behavior: updates on change file') +test.todo('behavior: updates on unlink file') +test.todo('behavior: runs watch command') +test.todo('behavior: shuts down watch on SIGINT/SIGTERM') diff --git a/wagmi-project/packages/cli/src/commands/generate.ts b/wagmi-project/packages/cli/src/commands/generate.ts new file mode 100644 index 000000000..992a2e292 --- /dev/null +++ b/wagmi-project/packages/cli/src/commands/generate.ts @@ -0,0 +1,409 @@ +import { mkdir, writeFile } from 'node:fs/promises' +import { Abi as AbiSchema } from 'abitype/zod' +import { camelCase } from 'change-case' +import type { ChokidarOptions, FSWatcher } from 'chokidar' +import { watch } from 'chokidar' +import { default as dedent } from 'dedent' +import { basename, dirname, resolve } from 'pathe' +import pc from 'picocolors' +import { type Abi, type Address, getAddress } from 'viem' +import { z } from 'zod' + +import type { Contract, ContractConfig, Plugin, Watch } from '../config.js' +import { fromZodError } from '../errors.js' +import * as logger from '../logger.js' +import { findConfig } from '../utils/findConfig.js' +import { format } from '../utils/format.js' +import { getAddressDocString } from '../utils/getAddressDocString.js' +import { getIsUsingTypeScript } from '../utils/getIsUsingTypeScript.js' +import { resolveConfig } from '../utils/resolveConfig.js' + +const Generate = z.object({ + /** Path to config file */ + config: z.string().optional(), + /** Directory to search for config file */ + root: z.string().optional(), + /** Watch for file system changes to config and plugins */ + watch: z.boolean().optional(), +}) +export type Generate = z.infer + +export async function generate(options: Generate = {}) { + // Validate command line options + try { + await Generate.parseAsync(options) + } catch (error) { + if (error instanceof z.ZodError) + throw fromZodError(error, { prefix: 'Invalid option' }) + throw error + } + + // Get cli config file + const configPath = await findConfig(options) + if (!configPath) { + if (options.config) + throw new Error(`Config not found at ${pc.gray(options.config)}`) + throw new Error('Config not found') + } + + const resolvedConfigs = await resolveConfig({ configPath }) + const isTypeScript = await getIsUsingTypeScript() + + type Watcher = FSWatcher & { config?: Watch } + const watchers: Watcher[] = [] + const watchWriteDelay = 100 + const watchOptions = { + atomic: true, + // awaitWriteFinish: true, + ignoreInitial: true, + persistent: true, + } satisfies ChokidarOptions + + const outNames = new Set() + const isArrayConfig = Array.isArray(resolvedConfigs) + const configs = isArrayConfig ? resolvedConfigs : [resolvedConfigs] + for (const config of configs) { + if (isArrayConfig) + logger.log(`Using config ${pc.gray(basename(configPath))}`) + if (!config.out) throw new Error('out is required.') + if (outNames.has(config.out)) + throw new Error(`out "${config.out}" must be unique.`) + outNames.add(config.out) + + // Collect contracts and watch configs from plugins + const plugins = (config.plugins ?? []).map((x, i) => ({ + ...x, + id: `${x.name}-${i}`, + })) + const spinner = logger.spinner('Validating plugins') + spinner.start() + for (const plugin of plugins) { + await plugin.validate?.() + } + spinner.success() + + // Add plugin contracts to config contracts + const contractConfigs = config.contracts ?? [] + const watchConfigs: Watch[] = [] + spinner.start('Resolving contracts') + for (const plugin of plugins) { + if (plugin.watch) watchConfigs.push(plugin.watch) + if (plugin.contracts) { + const contracts = await plugin.contracts() + contractConfigs.push(...contracts) + } + } + + // Get contracts from config + const contractNames = new Set() + const contractMap = new Map() + for (const contractConfig of contractConfigs) { + if (contractNames.has(contractConfig.name)) + throw new Error( + `Contract name "${contractConfig.name}" must be unique.`, + ) + const contract = await getContract({ ...contractConfig, isTypeScript }) + contractMap.set(contract.name, contract) + + contractNames.add(contractConfig.name) + } + + // Sort contracts by name Ascending (low to high) as the key is `String` + const sortedAscContractMap = new Map([...contractMap].sort()) + const contracts = [...sortedAscContractMap.values()] + if (!contracts.length && !options.watch) { + spinner.error() + logger.warn('No contracts found.') + return + } + spinner.success() + + // Run plugins + const imports = [] + const prepend = [] + const content = [] + type Output = { + plugin: Pick + } & Awaited>> + const outputs: Output[] = [] + spinner.start('Running plugins') + for (const plugin of plugins) { + if (!plugin.run) continue + const result = await plugin.run({ + contracts, + isTypeScript, + outputs, + }) + outputs.push({ + plugin: { name: plugin.name }, + ...result, + }) + if (!result.imports && !result.prepend && !result.content) continue + content.push(getBannerContent({ name: plugin.name }), result.content) + result.imports && imports.push(result.imports) + result.prepend && prepend.push(result.prepend) + } + spinner.success() + + // Write output to file + spinner.start(`Writing to ${pc.gray(config.out)}`) + await writeContracts({ + content, + contracts, + imports, + prepend, + filename: config.out, + }) + spinner.success() + + if (options.watch) { + if (!watchConfigs.length) { + logger.log(pc.gray('Used --watch flag, but no plugins are watching.')) + continue + } + logger.log() + logger.log('Setting up watch process') + + // Watch for changes + let timeout: NodeJS.Timeout | null + for (const watchConfig of watchConfigs) { + const paths = + typeof watchConfig.paths === 'function' + ? await watchConfig.paths() + : watchConfig.paths + const watcher = watch(paths, watchOptions) + // Watch for changes to files, new files, and deleted files + watcher.on('all', async (event, path) => { + if (event !== 'change' && event !== 'add' && event !== 'unlink') + return + + let needsWrite = false + if (event === 'change' || event === 'add') { + const eventFn = + event === 'change' ? watchConfig.onChange : watchConfig.onAdd + const config = await eventFn?.(path) + if (!config) return + const contract = await getContract({ ...config, isTypeScript }) + contractMap.set(contract.name, contract) + needsWrite = true + } else if (event === 'unlink') { + const name = await watchConfig.onRemove?.(path) + if (!name) return + contractMap.delete(name) + needsWrite = true + } + + // Debounce writes + if (needsWrite) { + if (timeout) clearTimeout(timeout) + timeout = setTimeout(async () => { + timeout = null + // Sort contracts by name Ascending (low to high) as the key is `String` + const sortedAscContractMap = new Map([...contractMap].sort()) + const contracts = [...sortedAscContractMap.values()] + const imports = [] + const prepend = [] + const content = [] + const outputs: Output[] = [] + for (const plugin of plugins) { + if (!plugin.run) continue + const result = await plugin.run({ + contracts, + isTypeScript, + outputs, + }) + outputs.push({ + plugin: { name: plugin.name }, + ...result, + }) + if (!result.imports && !result.prepend && !result.content) + continue + content.push( + getBannerContent({ name: plugin.name }), + result.content, + ) + result.imports && imports.push(result.imports) + result.prepend && prepend.push(result.prepend) + } + + const spinner = logger.spinner( + `Writing to ${pc.gray(config.out)}`, + ) + spinner.start() + await writeContracts({ + content, + contracts, + imports, + prepend, + filename: config.out, + }) + spinner.success() + }, watchWriteDelay) + needsWrite = false + } + }) + + // Run parallel command on ready + if (watchConfig.command) + watcher.on('ready', async () => { + await watchConfig.command?.() + }) + ;(watcher as Watcher).config = watchConfig + watchers.push(watcher) + } + } + } + + if (!watchers.length) return + + // Watch `@wagmi/cli` config file for changes + const watcher = watch(configPath).on('change', async (path) => { + logger.log( + `> Found a change to config ${pc.gray( + basename(path), + )}. Restart process for changes to take effect.`, + ) + }) + watchers.push(watcher) + + // Display message and close watchers on exit + process.once('SIGINT', shutdown) + process.once('SIGTERM', shutdown) + async function shutdown() { + logger.log() + logger.log('Shutting down watch process') + const promises = [] + for (const watcher of watchers) { + if (watcher.config?.onClose) promises.push(watcher.config?.onClose?.()) + promises.push(watcher.close()) + } + await Promise.allSettled(promises) + process.exit(0) + } +} + +async function getContract({ + abi, + address, + name, + isTypeScript, +}: ContractConfig & { isTypeScript: boolean }): Promise { + const constAssertion = isTypeScript ? ' as const' : '' + const abiName = `${camelCase(name)}Abi` + try { + abi = (await AbiSchema.parseAsync(abi)) as Abi + } catch (error) { + if (error instanceof z.ZodError) + throw fromZodError(error, { + prefix: `Invalid ABI for contract "${name}"`, + }) + throw error + } + const docString = + typeof address === 'object' + ? dedent`\n + /** + ${getAddressDocString({ address })} + */ + ` + : '' + let content = dedent` + ${getBannerContent({ name })} + + ${docString} + export const ${abiName} = ${JSON.stringify(abi)}${constAssertion} + ` + + let meta: Contract['meta'] = { abiName } + if (address) { + let resolvedAddress: Address | Record + try { + const Address = z + .string() + .regex(/^0x[a-fA-F0-9]{40}$/, { message: 'Invalid address' }) + .transform((val) => getAddress(val)) as z.ZodType
+ const MultiChainAddress = z.record(z.string(), Address) + const AddressSchema = z.union([Address, MultiChainAddress]) + resolvedAddress = await AddressSchema.parseAsync(address) + } catch (error) { + if (error instanceof z.ZodError) + throw fromZodError(error, { + prefix: `Invalid address for contract "${name}"`, + }) + throw error + } + + const addressName = `${camelCase(name)}Address` + const configName = `${camelCase(name)}Config` + meta = { + ...meta, + addressName, + configName, + } + + const addressContent = + typeof resolvedAddress === 'string' + ? JSON.stringify(resolvedAddress) + : // Remove quotes from chain id key + JSON.stringify(resolvedAddress, null, 2).replace(/"(\d*)":/gm, '$1:') + content = dedent` + ${content} + + ${docString} + export const ${addressName} = ${addressContent}${constAssertion} + + ${docString} + export const ${configName} = { address: ${addressName}, abi: ${abiName} }${constAssertion} + ` + } + + return { abi, address, content, meta, name } +} + +async function writeContracts({ + content, + contracts, + imports, + prepend, + filename, +}: { + content: string[] + contracts: Contract[] + imports: string[] + prepend: string[] + filename: string +}) { + // Assemble code + let code = dedent` + ${imports.join('\n\n') ?? ''} + + ${prepend.join('\n\n') ?? ''} + ` + for (const contract of contracts) { + code = dedent` + ${code} + + ${contract.content} + ` + } + code = dedent` + ${code} + + ${content.join('\n\n') ?? ''} + ` + + // Format and write output + const cwd = process.cwd() + const outPath = resolve(cwd, filename) + await mkdir(dirname(outPath), { recursive: true }) + const formatted = await format(code) + await writeFile(outPath, formatted) +} + +function getBannerContent({ name }: { name: string }) { + return dedent` + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // ${name} + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + ` +} diff --git a/wagmi-project/packages/cli/src/commands/init.test.ts b/wagmi-project/packages/cli/src/commands/init.test.ts new file mode 100644 index 000000000..ed4a1d164 --- /dev/null +++ b/wagmi-project/packages/cli/src/commands/init.test.ts @@ -0,0 +1,189 @@ +import { existsSync } from 'node:fs' +import { mkdir, readFile } from 'node:fs/promises' +import { resolve } from 'pathe' +import { afterEach, beforeEach, expect, test, vi } from 'vitest' + +import { createFixture, watchConsole } from '../../test/utils.js' +import { defaultConfig } from '../config.js' +import { init } from './init.js' + +let console: ReturnType +beforeEach(() => { + console = watchConsole() +}) + +afterEach(() => { + vi.restoreAllMocks() +}) + +test('creates config file', async () => { + const { dir } = await createFixture() + const spy = vi.spyOn(process, 'cwd') + spy.mockImplementation(() => dir) + + const configFile = await init() + + expect(existsSync(configFile)).toBeTruthy() + expect(await readFile(configFile, 'utf-8')).toMatchInlineSnapshot(` + "// @ts-check + + /** @type {import('@wagmi/cli').Config} */ + export default { + out: 'src/generated.js', + contracts: [], + plugins: [], + } + " + `) + expect( + console.formatted.replaceAll(dir, 'path/to/project'), + ).toMatchInlineSnapshot(` + "- Creating config + √ Creating config + Config created at wagmi.config.js" + `) +}) + +test('parameters: config', async () => { + const { dir } = await createFixture() + const spy = vi.spyOn(process, 'cwd') + spy.mockImplementation(() => dir) + + const configFile = await init({ + config: 'foo.config.ts', + }) + + expect(existsSync(configFile)).toBeTruthy() + expect(await readFile(configFile, 'utf-8')).toMatchInlineSnapshot(` + "// @ts-check + + /** @type {import('@wagmi/cli').Config} */ + export default { + out: 'src/generated.js', + contracts: [], + plugins: [], + } + " + `) + expect( + console.formatted.replaceAll(dir, 'path/to/project'), + ).toMatchInlineSnapshot(` + "- Creating config + √ Creating config + Config created at foo.config.ts" + `) +}) + +test('parameters: content', async () => { + const { dir } = await createFixture({ + files: { + 'tsconfig.json': '{}', + }, + }) + const spy = vi.spyOn(process, 'cwd') + spy.mockImplementation(() => dir) + + const configFile = await init({ + content: { + ...defaultConfig, + out: 'foo/bar/baz.ts', + }, + }) + + expect(existsSync(configFile)).toBeTruthy() + expect(await readFile(configFile, 'utf-8')).toMatchInlineSnapshot(` + "import { defineConfig } from '@wagmi/cli' + + export default defineConfig({ + out: 'foo/bar/baz.ts', + contracts: [], + plugins: [], + }) + " + `) + expect( + console.formatted.replaceAll(dir, 'path/to/project'), + ).toMatchInlineSnapshot(` + "- Creating config + √ Creating config + Config created at wagmi.config.ts" + `) +}) + +test('parameters: root', async () => { + const { dir } = await createFixture() + const spy = vi.spyOn(process, 'cwd') + spy.mockImplementation(() => dir) + mkdir(resolve(dir, 'foo')) + + const configFile = await init({ + root: 'foo/', + }) + + expect(existsSync(configFile)).toBeTruthy() + expect(await readFile(configFile, 'utf-8')).toMatchInlineSnapshot(` + "// @ts-check + + /** @type {import('@wagmi/cli').Config} */ + export default { + out: 'src/generated.js', + contracts: [], + plugins: [], + } + " + `) + expect( + console.formatted.replaceAll(dir, 'path/to/project'), + ).toMatchInlineSnapshot(` + "- Creating config + √ Creating config + Config created at foo/wagmi.config.js" + `) +}) + +test('behavior: creates config file in TypeScript format', async () => { + const { dir } = await createFixture({ + files: { + 'tsconfig.json': '{}', + }, + }) + const spy = vi.spyOn(process, 'cwd') + spy.mockImplementation(() => dir) + + const configFile = await init() + + expect(existsSync(configFile)).toBeTruthy() + expect(await readFile(configFile, 'utf-8')).toMatchInlineSnapshot(` + "import { defineConfig } from '@wagmi/cli' + + export default defineConfig({ + out: 'src/generated.ts', + contracts: [], + plugins: [], + }) + " + `) + expect( + console.formatted.replaceAll(dir, 'path/to/project'), + ).toMatchInlineSnapshot(` + "- Creating config + √ Creating config + Config created at wagmi.config.ts" + `) +}) + +test('behavior: displays config file location when config exists', async () => { + const { dir } = await createFixture({ + files: { + 'wagmi.config.ts': '', + }, + }) + const spy = vi.spyOn(process, 'cwd') + spy.mockImplementation(() => dir) + + const configFile = await init() + + expect( + console.formatted.replaceAll(configFile, 'path/to/project/wagmi.config.ts'), + ).toMatchInlineSnapshot('"Config already exists at wagmi.config.ts"') +}) diff --git a/wagmi-project/packages/cli/src/commands/init.ts b/wagmi-project/packages/cli/src/commands/init.ts new file mode 100644 index 000000000..ce4e5b32d --- /dev/null +++ b/wagmi-project/packages/cli/src/commands/init.ts @@ -0,0 +1,95 @@ +import { writeFile } from 'node:fs/promises' +import dedent from 'dedent' +import { relative, resolve } from 'pathe' +import pc from 'picocolors' +import { z } from 'zod' + +import { type Config, defaultConfig } from '../config.js' +import { fromZodError } from '../errors.js' +import * as logger from '../logger.js' +import { findConfig } from '../utils/findConfig.js' +import { format } from '../utils/format.js' +import { getIsUsingTypeScript } from '../utils/getIsUsingTypeScript.js' + +export type Init = { + /** Path to config file */ + config?: string + /** Watch for file system changes to config and plugins */ + content?: Config + /** Directory to init config file */ + root?: string +} + +const Init = z.object({ + config: z.string().optional(), + content: z.object({}).optional(), + root: z.string().optional(), +}) + +export async function init(options: Init = {}) { + // Validate command line options + try { + await Init.parseAsync(options) + } catch (error) { + if (error instanceof z.ZodError) + throw fromZodError(error, { prefix: 'Invalid option' }) + throw error + } + + // Check for existing config file + const configPath = await findConfig(options) + if (configPath) { + logger.info( + `Config already exists at ${pc.gray( + relative(process.cwd(), configPath), + )}`, + ) + return configPath + } + + const spinner = logger.spinner('Creating config') + spinner.start() + // Check if project is using TypeScript + const isUsingTypeScript = await getIsUsingTypeScript() + const rootDir = resolve(options.root || process.cwd()) + let outPath: string + if (options.config) { + outPath = resolve(rootDir, options.config) + } else { + const extension = isUsingTypeScript ? 'ts' : 'js' + outPath = resolve(rootDir, `wagmi.config.${extension}`) + } + + let content: string + if (isUsingTypeScript) { + const config = options.content ?? defaultConfig + content = dedent(` + import { defineConfig } from '@wagmi/cli' + + export default defineConfig(${JSON.stringify(config)}) + `) + } else { + const config = options.content ?? { + ...defaultConfig, + out: defaultConfig.out.replace('.ts', '.js'), + } + content = dedent(` + // @ts-check + + /** @type {import('@wagmi/cli').Config} */ + export default ${JSON.stringify(config, null, 2).replace( + /"(\d*)":/gm, + '$1:', + )} + `) + } + + const formatted = await format(content) + await writeFile(outPath, formatted) + spinner.success() + logger.success( + `Config created at ${pc.gray(relative(process.cwd(), outPath))}`, + ) + + return outPath +} diff --git a/wagmi-project/packages/cli/src/config.test.ts b/wagmi-project/packages/cli/src/config.test.ts new file mode 100644 index 000000000..f95d7cb6d --- /dev/null +++ b/wagmi-project/packages/cli/src/config.test.ts @@ -0,0 +1,39 @@ +import { expect, test, vi } from 'vitest' + +import { type Config, defineConfig } from './config.js' + +test('object', () => { + const config: Config = { + contracts: [], + out: 'wagmi.ts', + plugins: [], + } + expect(defineConfig(config)).toEqual(config) +}) + +test('array', () => { + const config: Config = { + contracts: [], + out: 'wagmi.ts', + plugins: [], + } + expect(defineConfig([config, config])).toEqual([config, config]) +}) + +test('function', () => { + const config = vi.fn().mockImplementation(() => ({ + contracts: [], + out: 'wagmi.ts', + plugins: [], + })) + expect(defineConfig(config)).toEqual(config) +}) + +test('async function', () => { + const config = vi.fn().mockImplementation(async () => ({ + contracts: [], + out: 'wagmi.ts', + plugins: [], + })) + expect(defineConfig(config)).toEqual(config) +}) diff --git a/wagmi-project/packages/cli/src/config.ts b/wagmi-project/packages/cli/src/config.ts new file mode 100644 index 000000000..146a1e342 --- /dev/null +++ b/wagmi-project/packages/cli/src/config.ts @@ -0,0 +1,121 @@ +import type { Abi, Address } from 'viem' + +import type { Compute, MaybeArray, MaybePromise } from './types.js' + +export type ContractConfig< + chainId extends number = number, + requiredChainId extends number | undefined = undefined, +> = { + /** + * Contract ABI + */ + abi: Abi + /** + * Contract address or addresses. + * + * Accepts an object `{ [chainId]: address }` to support multiple chains. + * + * @example + * '0x314159265dd8dbb310642f98f50c066173c1259b' + * + * @example + * { + * 1: '0x314159265dd8dbb310642f98f50c066173c1259b', + * 5: '0x112234455c3a32fd11230c42e7bccd4a84e02010', + * } + */ + address?: + | Address + | (requiredChainId extends number + ? Record & Partial> + : Record) + | undefined + /** + * Name of contract. + */ + name: string +} + +export type Contract = Compute< + ContractConfig & { + /** Generated string content */ + content: string + /** Meta info about contract */ + meta: { + abiName: string + addressName?: string | undefined + configName?: string | undefined + } + } +> + +export type Watch = { + /** Command to run along with watch process */ + command?: (() => MaybePromise) | undefined + /** Paths to watch for changes. */ + paths: string[] | (() => MaybePromise) + /** Callback that fires when file is added */ + onAdd?: + | ((path: string) => MaybePromise) + | undefined + /** Callback that fires when file changes */ + onChange: (path: string) => MaybePromise + /** Callback that fires when watcher is shutdown */ + onClose?: (() => MaybePromise) | undefined + /** Callback that fires when file is removed */ + onRemove?: ((path: string) => MaybePromise) | undefined +} + +export type Plugin = { + /** Contracts provided by plugin */ + contracts?: (() => MaybePromise) | undefined + /** Plugin name */ + name: string + /** Run plugin logic */ + run?: + | ((config: { + /** All resolved contracts from config and plugins */ + contracts: Contract[] + /** Whether TypeScript is detected in project */ + isTypeScript: boolean + /** Previous plugin outputs */ + outputs: readonly { + plugin: Pick + imports?: string + prepend?: string + content: string + }[] + }) => MaybePromise<{ + imports?: string + prepend?: string + content: string + }>) + | undefined + /** + * Validate plugin configuration or other @wagmi/cli settings require for plugin. + */ + validate?: (() => MaybePromise) | undefined + /** File system watch config */ + watch?: Watch | undefined +} + +export type Config = { + /** Contracts to use in commands */ + contracts?: ContractConfig[] | undefined + /** Output file path */ + out: string + /** Plugins to run */ + plugins?: Plugin[] | undefined +} + +export function defineConfig( + config: MaybeArray | (() => MaybePromise>), +) { + return config +} + +export const defaultConfig = { + out: 'src/generated.ts', + contracts: [], + plugins: [], +} satisfies Config diff --git a/wagmi-project/packages/cli/src/errors.ts b/wagmi-project/packages/cli/src/errors.ts new file mode 100644 index 000000000..6ef37093f --- /dev/null +++ b/wagmi-project/packages/cli/src/errors.ts @@ -0,0 +1,57 @@ +import type { z } from 'zod' + +class ValidationError extends Error { + details: Zod.ZodIssue[] + + constructor( + message: string, + options: { + details: Zod.ZodIssue[] + }, + ) { + super(message) + this.details = options.details + } +} + +// From https://github.com/causaly/zod-validation-error +export function fromZodError( + zError: z.ZodError, + { + maxIssuesInMessage = 99, + issueSeparator = '\n- ', + prefixSeparator = '\n- ', + prefix = 'Validation Error', + }: { + maxIssuesInMessage?: number + issueSeparator?: string + prefixSeparator?: string + prefix?: string + } = {}, +): ValidationError { + function joinPath(arr: Array): string { + return arr.reduce((acc, value) => { + if (typeof value === 'number') return `${acc}[${value}]` + const separator = acc === '' ? '' : '.' + return acc + separator + value + }, '') + } + + const reason = zError.errors + // limit max number of issues printed in the reason section + .slice(0, maxIssuesInMessage) + // format error message + .map((issue) => { + const { message, path } = issue + if (path.length > 0) return `${message} at \`${joinPath(path)}\`` + return message + }) + // concat as string + .join(issueSeparator) + + const message = reason ? [prefix, reason].join(prefixSeparator) : prefix + + return new ValidationError(message, { + details: zError.errors, + }) +} diff --git a/wagmi-project/packages/cli/src/exports/config.test.ts b/wagmi-project/packages/cli/src/exports/config.test.ts new file mode 100644 index 000000000..c833780ff --- /dev/null +++ b/wagmi-project/packages/cli/src/exports/config.test.ts @@ -0,0 +1,12 @@ +import { expect, test } from 'vitest' + +import * as Exports from './config.js' + +test('exports', () => { + expect(Object.keys(Exports)).toMatchInlineSnapshot(` + [ + "defineConfig", + "defaultConfig", + ] + `) +}) diff --git a/wagmi-project/packages/cli/src/exports/config.ts b/wagmi-project/packages/cli/src/exports/config.ts new file mode 100644 index 000000000..b3c4a83ba --- /dev/null +++ b/wagmi-project/packages/cli/src/exports/config.ts @@ -0,0 +1,10 @@ +// biome-ignore lint/performance/noBarrelFile: entrypoint module +export { + type ContractConfig, + type Contract, + type Watch, + type Plugin, + type Config, + defineConfig, + defaultConfig, +} from '../config.js' diff --git a/wagmi-project/packages/cli/src/exports/index.test-d.ts b/wagmi-project/packages/cli/src/exports/index.test-d.ts new file mode 100644 index 000000000..b056d5635 --- /dev/null +++ b/wagmi-project/packages/cli/src/exports/index.test-d.ts @@ -0,0 +1,4 @@ +import { expectTypeOf } from 'vitest' + +// noop test because vitest typecheck fails unless each workspace project has type test +expectTypeOf(1).toEqualTypeOf() diff --git a/wagmi-project/packages/cli/src/exports/index.test.ts b/wagmi-project/packages/cli/src/exports/index.test.ts new file mode 100644 index 000000000..2da78e8da --- /dev/null +++ b/wagmi-project/packages/cli/src/exports/index.test.ts @@ -0,0 +1,14 @@ +import { expect, test } from 'vitest' + +import * as Exports from './index.js' + +test('exports', () => { + expect(Object.keys(Exports)).toMatchInlineSnapshot(` + [ + "defineConfig", + "logger", + "loadEnv", + "version", + ] + `) +}) diff --git a/wagmi-project/packages/cli/src/exports/index.ts b/wagmi-project/packages/cli/src/exports/index.ts new file mode 100644 index 000000000..1c5e624df --- /dev/null +++ b/wagmi-project/packages/cli/src/exports/index.ts @@ -0,0 +1,14 @@ +// biome-ignore lint/performance/noBarrelFile: entrypoint module +export { + defineConfig, + type Config, + type ContractConfig, + type Plugin, +} from '../config.js' + +// biome-ignore lint/performance/noReExportAll: entrypoint module +export * as logger from '../logger.js' + +export { loadEnv } from '../utils/loadEnv.js' + +export { version } from '../version.js' diff --git a/wagmi-project/packages/cli/src/exports/plugins.test.ts b/wagmi-project/packages/cli/src/exports/plugins.test.ts new file mode 100644 index 000000000..4d7b5a97c --- /dev/null +++ b/wagmi-project/packages/cli/src/exports/plugins.test.ts @@ -0,0 +1,20 @@ +import { expect, test } from 'vitest' + +import * as Exports from './plugins.js' + +test('exports', () => { + expect(Object.keys(Exports)).toMatchInlineSnapshot(` + [ + "actions", + "blockExplorer", + "etherscan", + "fetch", + "foundry", + "foundryDefaultExcludes", + "hardhat", + "hardhatDefaultExcludes", + "react", + "sourcify", + ] + `) +}) diff --git a/wagmi-project/packages/cli/src/exports/plugins.ts b/wagmi-project/packages/cli/src/exports/plugins.ts new file mode 100644 index 000000000..a289b5c57 --- /dev/null +++ b/wagmi-project/packages/cli/src/exports/plugins.ts @@ -0,0 +1,27 @@ +// biome-ignore lint/performance/noBarrelFile: entrypoint module +export { actions, type ActionsConfig } from '../plugins/actions.js' + +export { + blockExplorer, + type BlockExplorerConfig, +} from '../plugins/blockExplorer.js' + +export { etherscan, type EtherscanConfig } from '../plugins/etherscan.js' + +export { fetch, type FetchConfig } from '../plugins/fetch.js' + +export { + foundry, + foundryDefaultExcludes, + type FoundryConfig, +} from '../plugins/foundry.js' + +export { + hardhat, + hardhatDefaultExcludes, + type HardhatConfig, +} from '../plugins/hardhat.js' + +export { react, type ReactConfig } from '../plugins/react.js' + +export { sourcify, type SourcifyConfig } from '../plugins/sourcify.js' diff --git a/wagmi-project/packages/cli/src/logger.test.ts b/wagmi-project/packages/cli/src/logger.test.ts new file mode 100644 index 000000000..7338c3bb1 --- /dev/null +++ b/wagmi-project/packages/cli/src/logger.test.ts @@ -0,0 +1,32 @@ +import { afterEach, expect, test, vi } from 'vitest' + +import { watchConsole } from '../test/utils.js' + +import * as logger from './logger.js' + +const mockLog = vi.fn() + +afterEach(() => { + vi.restoreAllMocks() +}) + +test.each(['success', 'info', 'log', 'warn', 'error'])('%s()', (level) => { + const spy = vi.spyOn(logger, level as any) + spy.mockImplementation(mockLog) + const loggerFn = (logger as any)[level] + loggerFn(level) + expect(spy).toHaveBeenCalledWith(level) +}) + +test('spinner', () => { + const console = watchConsole() + const spinner = logger.spinner('start') + spinner.start() + spinner.success('success') + spinner.error('error') + expect(console.formatted).toMatchInlineSnapshot(` + "- start + √ success + × error" + `) +}) diff --git a/wagmi-project/packages/cli/src/logger.ts b/wagmi-project/packages/cli/src/logger.ts new file mode 100644 index 000000000..b56fb9728 --- /dev/null +++ b/wagmi-project/packages/cli/src/logger.ts @@ -0,0 +1,37 @@ +import { format as utilFormat } from 'node:util' +import { createSpinner } from 'nanospinner' +import pc from 'picocolors' + +function format(args: any[]) { + return utilFormat(...args) + .split('\n') + .join('\n') +} + +export function success(...args: any[]) { + // biome-ignore lint/suspicious/noConsoleLog: console.log is used for logging + console.log(pc.green(format(args))) +} + +export function info(...args: any[]) { + console.info(pc.blue(format(args))) +} + +export function log(...args: any[]) { + // biome-ignore lint/suspicious/noConsoleLog: console.log is used for logging + console.log(pc.white(format(args))) +} + +export function warn(...args: any[]) { + console.warn(pc.yellow(format(args))) +} + +export function error(...args: any[]) { + console.error(pc.red(format(args))) +} + +export function spinner(text: string) { + return createSpinner(text, { + color: 'yellow', + }) +} diff --git a/wagmi-project/packages/cli/src/plugins/__fixtures__/foundry/.gitignore b/wagmi-project/packages/cli/src/plugins/__fixtures__/foundry/.gitignore new file mode 100644 index 000000000..3269660cc --- /dev/null +++ b/wagmi-project/packages/cli/src/plugins/__fixtures__/foundry/.gitignore @@ -0,0 +1,11 @@ +# Compiler files +cache/ +out/ + +# Ignores development broadcast logs +!/broadcast +/broadcast/*/31337/ +/broadcast/**/dry-run/ + +# Dotenv file +.env diff --git a/wagmi-project/packages/cli/src/plugins/__fixtures__/foundry/foundry.toml b/wagmi-project/packages/cli/src/plugins/__fixtures__/foundry/foundry.toml new file mode 100644 index 000000000..59374b16c --- /dev/null +++ b/wagmi-project/packages/cli/src/plugins/__fixtures__/foundry/foundry.toml @@ -0,0 +1,7 @@ +[profile.default] +libs = ['lib'] +out = 'out' +solc = '0.8.13' +src = 'src' + +# See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options diff --git a/wagmi-project/packages/cli/src/plugins/__fixtures__/foundry/src/Counter.sol b/wagmi-project/packages/cli/src/plugins/__fixtures__/foundry/src/Counter.sol new file mode 100644 index 000000000..5242caa43 --- /dev/null +++ b/wagmi-project/packages/cli/src/plugins/__fixtures__/foundry/src/Counter.sol @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; + +contract Counter { + uint256 public number; + + function setNumber(uint256 newNumber) public { + number = newNumber; + } + + function increment() public { + number++; + } +} diff --git a/wagmi-project/packages/cli/src/plugins/__fixtures__/foundry/src/Foo.sol b/wagmi-project/packages/cli/src/plugins/__fixtures__/foundry/src/Foo.sol new file mode 100644 index 000000000..f47873652 --- /dev/null +++ b/wagmi-project/packages/cli/src/plugins/__fixtures__/foundry/src/Foo.sol @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; + +contract Foo { + string public bar; + + function setFoo(string memory baz) public { + bar = baz; + } +} + diff --git a/wagmi-project/packages/cli/src/plugins/__fixtures__/hardhat/.gitignore b/wagmi-project/packages/cli/src/plugins/__fixtures__/hardhat/.gitignore new file mode 100644 index 000000000..85d361b91 --- /dev/null +++ b/wagmi-project/packages/cli/src/plugins/__fixtures__/hardhat/.gitignore @@ -0,0 +1,10 @@ +node_modules +.env +coverage +coverage.json +typechain +typechain-types + +# Hardhat files +cache +artifacts \ No newline at end of file diff --git a/wagmi-project/packages/cli/src/plugins/__fixtures__/hardhat/contracts/Counter.sol b/wagmi-project/packages/cli/src/plugins/__fixtures__/hardhat/contracts/Counter.sol new file mode 100644 index 000000000..5242caa43 --- /dev/null +++ b/wagmi-project/packages/cli/src/plugins/__fixtures__/hardhat/contracts/Counter.sol @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; + +contract Counter { + uint256 public number; + + function setNumber(uint256 newNumber) public { + number = newNumber; + } + + function increment() public { + number++; + } +} diff --git a/wagmi-project/packages/cli/src/plugins/__fixtures__/hardhat/contracts/Foo.sol b/wagmi-project/packages/cli/src/plugins/__fixtures__/hardhat/contracts/Foo.sol new file mode 100644 index 000000000..699a63ce0 --- /dev/null +++ b/wagmi-project/packages/cli/src/plugins/__fixtures__/hardhat/contracts/Foo.sol @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; + +contract Foo { + string public bar; + + function setFoo(string memory baz) public { + bar = baz; + } +} diff --git a/wagmi-project/packages/cli/src/plugins/__fixtures__/hardhat/hardhat.config.js b/wagmi-project/packages/cli/src/plugins/__fixtures__/hardhat/hardhat.config.js new file mode 100644 index 000000000..c8126eedf --- /dev/null +++ b/wagmi-project/packages/cli/src/plugins/__fixtures__/hardhat/hardhat.config.js @@ -0,0 +1,3 @@ +module.exports = { + solidity: '0.8.17', +} diff --git a/wagmi-project/packages/cli/src/plugins/__fixtures__/hardhat/package.json b/wagmi-project/packages/cli/src/plugins/__fixtures__/hardhat/package.json new file mode 100644 index 000000000..85c9ffb7b --- /dev/null +++ b/wagmi-project/packages/cli/src/plugins/__fixtures__/hardhat/package.json @@ -0,0 +1,7 @@ +{ + "name": "hardhat-fixture", + "private": true, + "devDependencies": { + "hardhat": "^2.22.3" + } +} diff --git a/wagmi-project/packages/cli/src/plugins/__snapshots__/blockExplorer.test.ts.snap b/wagmi-project/packages/cli/src/plugins/__snapshots__/blockExplorer.test.ts.snap new file mode 100644 index 000000000..2abd35174 --- /dev/null +++ b/wagmi-project/packages/cli/src/plugins/__snapshots__/blockExplorer.test.ts.snap @@ -0,0 +1,736 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`fetches ABI 1`] = ` +[ + { + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor", + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address", + }, + { + "indexed": true, + "internalType": "address", + "name": "approved", + "type": "address", + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "Approval", + "type": "event", + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address", + }, + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address", + }, + { + "indexed": false, + "internalType": "bool", + "name": "approved", + "type": "bool", + }, + ], + "name": "ApprovalForAll", + "type": "event", + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address", + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address", + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "Transfer", + "type": "event", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address", + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "approve", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address", + }, + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "getApproved", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address", + }, + { + "internalType": "address", + "name": "operator", + "type": "address", + }, + ], + "name": "isApprovedForAll", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "ownerOf", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address", + }, + { + "internalType": "address", + "name": "to", + "type": "address", + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address", + }, + { + "internalType": "address", + "name": "to", + "type": "address", + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes", + }, + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operator", + "type": "address", + }, + { + "internalType": "bool", + "name": "approved", + "type": "bool", + }, + ], + "name": "setApprovalForAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4", + }, + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "tokenURI", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string", + }, + ], + "stateMutability": "pure", + "type": "function", + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address", + }, + { + "internalType": "address", + "name": "to", + "type": "address", + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "transferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + ], + "address": "0xaf0326d92b97df1221759476b072abfd8084f9be", + "name": "WagmiMintExample", + }, +] +`; + +exports[`fetches ABI with multichain deployment 1`] = ` +[ + { + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor", + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address", + }, + { + "indexed": true, + "internalType": "address", + "name": "approved", + "type": "address", + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "Approval", + "type": "event", + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address", + }, + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address", + }, + { + "indexed": false, + "internalType": "bool", + "name": "approved", + "type": "bool", + }, + ], + "name": "ApprovalForAll", + "type": "event", + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address", + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address", + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "Transfer", + "type": "event", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address", + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "approve", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address", + }, + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "getApproved", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address", + }, + { + "internalType": "address", + "name": "operator", + "type": "address", + }, + ], + "name": "isApprovedForAll", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "ownerOf", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address", + }, + { + "internalType": "address", + "name": "to", + "type": "address", + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address", + }, + { + "internalType": "address", + "name": "to", + "type": "address", + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes", + }, + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operator", + "type": "address", + }, + { + "internalType": "bool", + "name": "approved", + "type": "bool", + }, + ], + "name": "setApprovalForAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4", + }, + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "tokenURI", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string", + }, + ], + "stateMutability": "pure", + "type": "function", + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address", + }, + { + "internalType": "address", + "name": "to", + "type": "address", + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "transferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + ], + "address": { + "1": "0xaf0326d92b97df1221759476b072abfd8084f9be", + "10": "0xaf0326d92b97df1221759476b072abfd8084f9be", + }, + "name": "WagmiMintExample", + }, +] +`; diff --git a/wagmi-project/packages/cli/src/plugins/__snapshots__/etherscan.test.ts.snap b/wagmi-project/packages/cli/src/plugins/__snapshots__/etherscan.test.ts.snap new file mode 100644 index 000000000..e03ee30f8 --- /dev/null +++ b/wagmi-project/packages/cli/src/plugins/__snapshots__/etherscan.test.ts.snap @@ -0,0 +1,1238 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`fetches ABI 1`] = ` +[ + { + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor", + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address", + }, + { + "indexed": true, + "internalType": "address", + "name": "approved", + "type": "address", + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "Approval", + "type": "event", + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address", + }, + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address", + }, + { + "indexed": false, + "internalType": "bool", + "name": "approved", + "type": "bool", + }, + ], + "name": "ApprovalForAll", + "type": "event", + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address", + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address", + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "Transfer", + "type": "event", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address", + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "approve", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address", + }, + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "getApproved", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address", + }, + { + "internalType": "address", + "name": "operator", + "type": "address", + }, + ], + "name": "isApprovedForAll", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "ownerOf", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address", + }, + { + "internalType": "address", + "name": "to", + "type": "address", + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address", + }, + { + "internalType": "address", + "name": "to", + "type": "address", + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes", + }, + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operator", + "type": "address", + }, + { + "internalType": "bool", + "name": "approved", + "type": "bool", + }, + ], + "name": "setApprovalForAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4", + }, + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "tokenURI", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string", + }, + ], + "stateMutability": "pure", + "type": "function", + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address", + }, + { + "internalType": "address", + "name": "to", + "type": "address", + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "transferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + ], + "address": { + "1": "0xaf0326d92b97df1221759476b072abfd8084f9be", + }, + "name": "WagmiMintExample", + }, +] +`; + +exports[`fetches ABI with multichain deployment 1`] = ` +[ + { + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor", + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address", + }, + { + "indexed": true, + "internalType": "address", + "name": "approved", + "type": "address", + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "Approval", + "type": "event", + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address", + }, + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address", + }, + { + "indexed": false, + "internalType": "bool", + "name": "approved", + "type": "bool", + }, + ], + "name": "ApprovalForAll", + "type": "event", + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address", + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address", + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "Transfer", + "type": "event", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address", + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "approve", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address", + }, + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "getApproved", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address", + }, + { + "internalType": "address", + "name": "operator", + "type": "address", + }, + ], + "name": "isApprovedForAll", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "ownerOf", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address", + }, + { + "internalType": "address", + "name": "to", + "type": "address", + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address", + }, + { + "internalType": "address", + "name": "to", + "type": "address", + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes", + }, + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operator", + "type": "address", + }, + { + "internalType": "bool", + "name": "approved", + "type": "bool", + }, + ], + "name": "setApprovalForAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4", + }, + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "tokenURI", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string", + }, + ], + "stateMutability": "pure", + "type": "function", + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address", + }, + { + "internalType": "address", + "name": "to", + "type": "address", + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "transferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + ], + "address": { + "1": "0xaf0326d92b97df1221759476b072abfd8084f9be", + "10": "0xaf0326d92b97df1221759476b072abfd8084f9be", + }, + "name": "WagmiMintExample", + }, +] +`; + +exports[`tryFetchProxyImplementation: fetches ABI 1`] = ` +[ + { + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor", + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address", + }, + { + "indexed": true, + "internalType": "address", + "name": "approved", + "type": "address", + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "Approval", + "type": "event", + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address", + }, + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address", + }, + { + "indexed": false, + "internalType": "bool", + "name": "approved", + "type": "bool", + }, + ], + "name": "ApprovalForAll", + "type": "event", + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address", + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address", + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "Transfer", + "type": "event", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address", + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "approve", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address", + }, + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "getApproved", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address", + }, + { + "internalType": "address", + "name": "operator", + "type": "address", + }, + ], + "name": "isApprovedForAll", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "ownerOf", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address", + }, + { + "internalType": "address", + "name": "to", + "type": "address", + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address", + }, + { + "internalType": "address", + "name": "to", + "type": "address", + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes", + }, + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operator", + "type": "address", + }, + { + "internalType": "bool", + "name": "approved", + "type": "bool", + }, + ], + "name": "setApprovalForAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4", + }, + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "tokenURI", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string", + }, + ], + "stateMutability": "pure", + "type": "function", + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address", + }, + { + "internalType": "address", + "name": "to", + "type": "address", + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "transferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + ], + "address": { + "1": "0xaf0326d92b97df1221759476b072abfd8084f9be", + }, + "name": "WagmiMintExample", + }, +] +`; + +exports[`tryFetchProxyImplementation: fetches implementation ABI 1`] = ` +[ + { + "abi": [ + { + "constant": false, + "inputs": [ + { + "name": "newImplementation", + "type": "address", + }, + ], + "name": "upgradeTo", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + }, + { + "constant": false, + "inputs": [ + { + "name": "newImplementation", + "type": "address", + }, + { + "name": "data", + "type": "bytes", + }, + ], + "name": "upgradeToAndCall", + "outputs": [], + "payable": true, + "stateMutability": "payable", + "type": "function", + }, + { + "constant": true, + "inputs": [], + "name": "implementation", + "outputs": [ + { + "name": "", + "type": "address", + }, + ], + "payable": false, + "stateMutability": "view", + "type": "function", + }, + { + "constant": false, + "inputs": [ + { + "name": "newAdmin", + "type": "address", + }, + ], + "name": "changeAdmin", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + }, + { + "constant": true, + "inputs": [], + "name": "admin", + "outputs": [ + { + "name": "", + "type": "address", + }, + ], + "payable": false, + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "name": "_implementation", + "type": "address", + }, + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "constructor", + }, + { + "payable": true, + "stateMutability": "payable", + "type": "fallback", + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "previousAdmin", + "type": "address", + }, + { + "indexed": false, + "name": "newAdmin", + "type": "address", + }, + ], + "name": "AdminChanged", + "type": "event", + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "implementation", + "type": "address", + }, + ], + "name": "Upgraded", + "type": "event", + }, + ], + "address": { + "1": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", + }, + "name": "FiatToken", + }, +] +`; diff --git a/wagmi-project/packages/cli/src/plugins/__snapshots__/fetch.test.ts.snap b/wagmi-project/packages/cli/src/plugins/__snapshots__/fetch.test.ts.snap new file mode 100644 index 000000000..83c4e81f5 --- /dev/null +++ b/wagmi-project/packages/cli/src/plugins/__snapshots__/fetch.test.ts.snap @@ -0,0 +1,367 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`fetches ABI 1`] = ` +[ + { + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor", + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address", + }, + { + "indexed": true, + "internalType": "address", + "name": "approved", + "type": "address", + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "Approval", + "type": "event", + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address", + }, + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address", + }, + { + "indexed": false, + "internalType": "bool", + "name": "approved", + "type": "bool", + }, + ], + "name": "ApprovalForAll", + "type": "event", + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address", + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address", + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "Transfer", + "type": "event", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address", + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "approve", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address", + }, + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "getApproved", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address", + }, + { + "internalType": "address", + "name": "operator", + "type": "address", + }, + ], + "name": "isApprovedForAll", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "ownerOf", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address", + }, + { + "internalType": "address", + "name": "to", + "type": "address", + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address", + }, + { + "internalType": "address", + "name": "to", + "type": "address", + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes", + }, + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operator", + "type": "address", + }, + { + "internalType": "bool", + "name": "approved", + "type": "bool", + }, + ], + "name": "setApprovalForAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4", + }, + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "tokenURI", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string", + }, + ], + "stateMutability": "pure", + "type": "function", + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address", + }, + { + "internalType": "address", + "name": "to", + "type": "address", + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "transferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + ], + "address": "0xaf0326d92b97df1221759476b072abfd8084f9be", + "name": "WagmiMintExample", + }, +] +`; diff --git a/wagmi-project/packages/cli/src/plugins/__snapshots__/sourcify.test.ts.snap b/wagmi-project/packages/cli/src/plugins/__snapshots__/sourcify.test.ts.snap new file mode 100644 index 000000000..77e82fecd --- /dev/null +++ b/wagmi-project/packages/cli/src/plugins/__snapshots__/sourcify.test.ts.snap @@ -0,0 +1,214 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`fetches ABI 1`] = ` +[ + { + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor", + }, + { + "inputs": [ + { + "name": "pubkey", + "type": "bytes", + }, + { + "name": "withdrawal_credentials", + "type": "bytes", + }, + { + "name": "amount", + "type": "bytes", + }, + { + "name": "signature", + "type": "bytes", + }, + { + "name": "index", + "type": "bytes", + }, + ], + "name": "DepositEvent", + "type": "event", + }, + { + "inputs": [ + { + "name": "pubkey", + "type": "bytes", + }, + { + "name": "withdrawal_credentials", + "type": "bytes", + }, + { + "name": "signature", + "type": "bytes", + }, + { + "name": "deposit_data_root", + "type": "bytes32", + }, + ], + "name": "deposit", + "outputs": [], + "stateMutability": "payable", + "type": "function", + }, + { + "inputs": [], + "name": "get_deposit_count", + "outputs": [ + { + "type": "bytes", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [], + "name": "get_deposit_root", + "outputs": [ + { + "type": "bytes32", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "name": "interfaceId", + "type": "bytes4", + }, + ], + "name": "supportsInterface", + "outputs": [ + { + "type": "bool", + }, + ], + "stateMutability": "pure", + "type": "function", + }, + ], + "address": { + "1": "0x00000000219ab540356cbb839cbe05303d7705fa", + }, + "name": "DepositContract", + }, +] +`; + +exports[`fetches ABI with multichain deployment 1`] = ` +[ + { + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor", + }, + { + "inputs": [ + { + "name": "pubkey", + "type": "bytes", + }, + { + "name": "withdrawal_credentials", + "type": "bytes", + }, + { + "name": "amount", + "type": "bytes", + }, + { + "name": "signature", + "type": "bytes", + }, + { + "name": "index", + "type": "bytes", + }, + ], + "name": "DepositEvent", + "type": "event", + }, + { + "inputs": [ + { + "name": "pubkey", + "type": "bytes", + }, + { + "name": "withdrawal_credentials", + "type": "bytes", + }, + { + "name": "signature", + "type": "bytes", + }, + { + "name": "deposit_data_root", + "type": "bytes32", + }, + ], + "name": "deposit", + "outputs": [], + "stateMutability": "payable", + "type": "function", + }, + { + "inputs": [], + "name": "get_deposit_count", + "outputs": [ + { + "type": "bytes", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [], + "name": "get_deposit_root", + "outputs": [ + { + "type": "bytes32", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "name": "interfaceId", + "type": "bytes4", + }, + ], + "name": "supportsInterface", + "outputs": [ + { + "type": "bool", + }, + ], + "stateMutability": "pure", + "type": "function", + }, + ], + "address": { + "100": "0xC4c622862a8F548997699bE24EA4bc504e5cA865", + "137": "0xC4c622862a8F548997699bE24EA4bc504e5cA865", + }, + "name": "Community", + }, +] +`; diff --git a/wagmi-project/packages/cli/src/plugins/actions.test.ts b/wagmi-project/packages/cli/src/plugins/actions.test.ts new file mode 100644 index 000000000..51b445b61 --- /dev/null +++ b/wagmi-project/packages/cli/src/plugins/actions.test.ts @@ -0,0 +1,359 @@ +import { erc20Abi } from 'viem' +import { expect, test } from 'vitest' + +import { actions } from './actions.js' + +test('default', async () => { + const result = await actions().run?.({ + contracts: [ + { + name: 'erc20', + abi: erc20Abi, + content: '', + meta: { + abiName: 'erc20Abi', + }, + }, + ], + isTypeScript: true, + outputs: [], + }) + + expect(result?.imports).toMatchInlineSnapshot(` + "import { createReadContract, createWriteContract, createSimulateContract, createWatchContractEvent } from '@wagmi/core/codegen' + " + `) + expect(result?.content).toMatchInlineSnapshot(` + "/** + * Wraps __{@link readContract}__ with \`abi\` set to __{@link erc20Abi}__ + */ + export const readErc20 = /*#__PURE__*/ createReadContract({ abi: erc20Abi }) + + /** + * Wraps __{@link readContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"allowance"\` + */ + export const readErc20Allowance = /*#__PURE__*/ createReadContract({ abi: erc20Abi, functionName: 'allowance' }) + + /** + * Wraps __{@link readContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"balanceOf"\` + */ + export const readErc20BalanceOf = /*#__PURE__*/ createReadContract({ abi: erc20Abi, functionName: 'balanceOf' }) + + /** + * Wraps __{@link readContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"decimals"\` + */ + export const readErc20Decimals = /*#__PURE__*/ createReadContract({ abi: erc20Abi, functionName: 'decimals' }) + + /** + * Wraps __{@link readContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"name"\` + */ + export const readErc20Name = /*#__PURE__*/ createReadContract({ abi: erc20Abi, functionName: 'name' }) + + /** + * Wraps __{@link readContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"symbol"\` + */ + export const readErc20Symbol = /*#__PURE__*/ createReadContract({ abi: erc20Abi, functionName: 'symbol' }) + + /** + * Wraps __{@link readContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"totalSupply"\` + */ + export const readErc20TotalSupply = /*#__PURE__*/ createReadContract({ abi: erc20Abi, functionName: 'totalSupply' }) + + /** + * Wraps __{@link writeContract}__ with \`abi\` set to __{@link erc20Abi}__ + */ + export const writeErc20 = /*#__PURE__*/ createWriteContract({ abi: erc20Abi }) + + /** + * Wraps __{@link writeContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"approve"\` + */ + export const writeErc20Approve = /*#__PURE__*/ createWriteContract({ abi: erc20Abi, functionName: 'approve' }) + + /** + * Wraps __{@link writeContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"transfer"\` + */ + export const writeErc20Transfer = /*#__PURE__*/ createWriteContract({ abi: erc20Abi, functionName: 'transfer' }) + + /** + * Wraps __{@link writeContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"transferFrom"\` + */ + export const writeErc20TransferFrom = /*#__PURE__*/ createWriteContract({ abi: erc20Abi, functionName: 'transferFrom' }) + + /** + * Wraps __{@link simulateContract}__ with \`abi\` set to __{@link erc20Abi}__ + */ + export const simulateErc20 = /*#__PURE__*/ createSimulateContract({ abi: erc20Abi }) + + /** + * Wraps __{@link simulateContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"approve"\` + */ + export const simulateErc20Approve = /*#__PURE__*/ createSimulateContract({ abi: erc20Abi, functionName: 'approve' }) + + /** + * Wraps __{@link simulateContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"transfer"\` + */ + export const simulateErc20Transfer = /*#__PURE__*/ createSimulateContract({ abi: erc20Abi, functionName: 'transfer' }) + + /** + * Wraps __{@link simulateContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"transferFrom"\` + */ + export const simulateErc20TransferFrom = /*#__PURE__*/ createSimulateContract({ abi: erc20Abi, functionName: 'transferFrom' }) + + /** + * Wraps __{@link watchContractEvent}__ with \`abi\` set to __{@link erc20Abi}__ + */ + export const watchErc20Event = /*#__PURE__*/ createWatchContractEvent({ abi: erc20Abi }) + + /** + * Wraps __{@link watchContractEvent}__ with \`abi\` set to __{@link erc20Abi}__ and \`eventName\` set to \`"Approval"\` + */ + export const watchErc20ApprovalEvent = /*#__PURE__*/ createWatchContractEvent({ abi: erc20Abi, eventName: 'Approval' }) + + /** + * Wraps __{@link watchContractEvent}__ with \`abi\` set to __{@link erc20Abi}__ and \`eventName\` set to \`"Transfer"\` + */ + export const watchErc20TransferEvent = /*#__PURE__*/ createWatchContractEvent({ abi: erc20Abi, eventName: 'Transfer' })" + `) +}) + +test('address', async () => { + const result = await actions().run?.({ + contracts: [ + { + name: 'erc20', + abi: erc20Abi, + content: '', + meta: { + abiName: 'erc20Abi', + addressName: 'erc20Address', + }, + }, + ], + isTypeScript: true, + outputs: [], + }) + + expect(result?.content).toMatchInlineSnapshot(` + "/** + * Wraps __{@link readContract}__ with \`abi\` set to __{@link erc20Abi}__ + */ + export const readErc20 = /*#__PURE__*/ createReadContract({ abi: erc20Abi, address: erc20Address }) + + /** + * Wraps __{@link readContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"allowance"\` + */ + export const readErc20Allowance = /*#__PURE__*/ createReadContract({ abi: erc20Abi, address: erc20Address, functionName: 'allowance' }) + + /** + * Wraps __{@link readContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"balanceOf"\` + */ + export const readErc20BalanceOf = /*#__PURE__*/ createReadContract({ abi: erc20Abi, address: erc20Address, functionName: 'balanceOf' }) + + /** + * Wraps __{@link readContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"decimals"\` + */ + export const readErc20Decimals = /*#__PURE__*/ createReadContract({ abi: erc20Abi, address: erc20Address, functionName: 'decimals' }) + + /** + * Wraps __{@link readContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"name"\` + */ + export const readErc20Name = /*#__PURE__*/ createReadContract({ abi: erc20Abi, address: erc20Address, functionName: 'name' }) + + /** + * Wraps __{@link readContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"symbol"\` + */ + export const readErc20Symbol = /*#__PURE__*/ createReadContract({ abi: erc20Abi, address: erc20Address, functionName: 'symbol' }) + + /** + * Wraps __{@link readContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"totalSupply"\` + */ + export const readErc20TotalSupply = /*#__PURE__*/ createReadContract({ abi: erc20Abi, address: erc20Address, functionName: 'totalSupply' }) + + /** + * Wraps __{@link writeContract}__ with \`abi\` set to __{@link erc20Abi}__ + */ + export const writeErc20 = /*#__PURE__*/ createWriteContract({ abi: erc20Abi, address: erc20Address }) + + /** + * Wraps __{@link writeContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"approve"\` + */ + export const writeErc20Approve = /*#__PURE__*/ createWriteContract({ abi: erc20Abi, address: erc20Address, functionName: 'approve' }) + + /** + * Wraps __{@link writeContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"transfer"\` + */ + export const writeErc20Transfer = /*#__PURE__*/ createWriteContract({ abi: erc20Abi, address: erc20Address, functionName: 'transfer' }) + + /** + * Wraps __{@link writeContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"transferFrom"\` + */ + export const writeErc20TransferFrom = /*#__PURE__*/ createWriteContract({ abi: erc20Abi, address: erc20Address, functionName: 'transferFrom' }) + + /** + * Wraps __{@link simulateContract}__ with \`abi\` set to __{@link erc20Abi}__ + */ + export const simulateErc20 = /*#__PURE__*/ createSimulateContract({ abi: erc20Abi, address: erc20Address }) + + /** + * Wraps __{@link simulateContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"approve"\` + */ + export const simulateErc20Approve = /*#__PURE__*/ createSimulateContract({ abi: erc20Abi, address: erc20Address, functionName: 'approve' }) + + /** + * Wraps __{@link simulateContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"transfer"\` + */ + export const simulateErc20Transfer = /*#__PURE__*/ createSimulateContract({ abi: erc20Abi, address: erc20Address, functionName: 'transfer' }) + + /** + * Wraps __{@link simulateContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"transferFrom"\` + */ + export const simulateErc20TransferFrom = /*#__PURE__*/ createSimulateContract({ abi: erc20Abi, address: erc20Address, functionName: 'transferFrom' }) + + /** + * Wraps __{@link watchContractEvent}__ with \`abi\` set to __{@link erc20Abi}__ + */ + export const watchErc20Event = /*#__PURE__*/ createWatchContractEvent({ abi: erc20Abi, address: erc20Address }) + + /** + * Wraps __{@link watchContractEvent}__ with \`abi\` set to __{@link erc20Abi}__ and \`eventName\` set to \`"Approval"\` + */ + export const watchErc20ApprovalEvent = /*#__PURE__*/ createWatchContractEvent({ abi: erc20Abi, address: erc20Address, eventName: 'Approval' }) + + /** + * Wraps __{@link watchContractEvent}__ with \`abi\` set to __{@link erc20Abi}__ and \`eventName\` set to \`"Transfer"\` + */ + export const watchErc20TransferEvent = /*#__PURE__*/ createWatchContractEvent({ abi: erc20Abi, address: erc20Address, eventName: 'Transfer' })" + `) +}) + +test('legacy hook names', async () => { + const result = await actions({ getActionName: 'legacy' }).run?.({ + contracts: [ + { + name: 'erc20', + abi: erc20Abi, + content: '', + meta: { + abiName: 'erc20Abi', + addressName: 'erc20Address', + }, + }, + ], + isTypeScript: true, + outputs: [], + }) + + expect(result?.content).toMatchInlineSnapshot(` + "/** + * Wraps __{@link readContract}__ with \`abi\` set to __{@link erc20Abi}__ + */ + export const readErc20 = /*#__PURE__*/ createReadContract({ abi: erc20Abi, address: erc20Address }) + + /** + * Wraps __{@link readContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"allowance"\` + */ + export const readErc20Allowance = /*#__PURE__*/ createReadContract({ abi: erc20Abi, address: erc20Address, functionName: 'allowance' }) + + /** + * Wraps __{@link readContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"balanceOf"\` + */ + export const readErc20BalanceOf = /*#__PURE__*/ createReadContract({ abi: erc20Abi, address: erc20Address, functionName: 'balanceOf' }) + + /** + * Wraps __{@link readContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"decimals"\` + */ + export const readErc20Decimals = /*#__PURE__*/ createReadContract({ abi: erc20Abi, address: erc20Address, functionName: 'decimals' }) + + /** + * Wraps __{@link readContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"name"\` + */ + export const readErc20Name = /*#__PURE__*/ createReadContract({ abi: erc20Abi, address: erc20Address, functionName: 'name' }) + + /** + * Wraps __{@link readContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"symbol"\` + */ + export const readErc20Symbol = /*#__PURE__*/ createReadContract({ abi: erc20Abi, address: erc20Address, functionName: 'symbol' }) + + /** + * Wraps __{@link readContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"totalSupply"\` + */ + export const readErc20TotalSupply = /*#__PURE__*/ createReadContract({ abi: erc20Abi, address: erc20Address, functionName: 'totalSupply' }) + + /** + * Wraps __{@link writeContract}__ with \`abi\` set to __{@link erc20Abi}__ + */ + export const writeErc20 = /*#__PURE__*/ createWriteContract({ abi: erc20Abi, address: erc20Address }) + + /** + * Wraps __{@link writeContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"approve"\` + */ + export const writeErc20Approve = /*#__PURE__*/ createWriteContract({ abi: erc20Abi, address: erc20Address, functionName: 'approve' }) + + /** + * Wraps __{@link writeContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"transfer"\` + */ + export const writeErc20Transfer = /*#__PURE__*/ createWriteContract({ abi: erc20Abi, address: erc20Address, functionName: 'transfer' }) + + /** + * Wraps __{@link writeContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"transferFrom"\` + */ + export const writeErc20TransferFrom = /*#__PURE__*/ createWriteContract({ abi: erc20Abi, address: erc20Address, functionName: 'transferFrom' }) + + /** + * Wraps __{@link simulateContract}__ with \`abi\` set to __{@link erc20Abi}__ + */ + export const prepareWriteErc20 = /*#__PURE__*/ createSimulateContract({ abi: erc20Abi, address: erc20Address }) + + /** + * Wraps __{@link simulateContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"approve"\` + */ + export const prepareWriteErc20Approve = /*#__PURE__*/ createSimulateContract({ abi: erc20Abi, address: erc20Address, functionName: 'approve' }) + + /** + * Wraps __{@link simulateContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"transfer"\` + */ + export const prepareWriteErc20Transfer = /*#__PURE__*/ createSimulateContract({ abi: erc20Abi, address: erc20Address, functionName: 'transfer' }) + + /** + * Wraps __{@link simulateContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"transferFrom"\` + */ + export const prepareWriteErc20TransferFrom = /*#__PURE__*/ createSimulateContract({ abi: erc20Abi, address: erc20Address, functionName: 'transferFrom' }) + + /** + * Wraps __{@link watchContractEvent}__ with \`abi\` set to __{@link erc20Abi}__ + */ + export const watchErc20Event = /*#__PURE__*/ createWatchContractEvent({ abi: erc20Abi, address: erc20Address }) + + /** + * Wraps __{@link watchContractEvent}__ with \`abi\` set to __{@link erc20Abi}__ and \`eventName\` set to \`"Approval"\` + */ + export const watchErc20ApprovalEvent = /*#__PURE__*/ createWatchContractEvent({ abi: erc20Abi, address: erc20Address, eventName: 'Approval' }) + + /** + * Wraps __{@link watchContractEvent}__ with \`abi\` set to __{@link erc20Abi}__ and \`eventName\` set to \`"Transfer"\` + */ + export const watchErc20TransferEvent = /*#__PURE__*/ createWatchContractEvent({ abi: erc20Abi, address: erc20Address, eventName: 'Transfer' })" + `) +}) + +test('override package name', async () => { + const result = await actions({ overridePackageName: 'wagmi' }).run?.({ + contracts: [ + { + name: 'erc20', + abi: erc20Abi, + content: '', + meta: { + abiName: 'erc20Abi', + }, + }, + ], + isTypeScript: true, + outputs: [], + }) + + expect(result?.imports).toMatchInlineSnapshot(` + "import { createReadContract, createWriteContract, createSimulateContract, createWatchContractEvent } from 'wagmi/codegen' + " + `) +}) diff --git a/wagmi-project/packages/cli/src/plugins/actions.ts b/wagmi-project/packages/cli/src/plugins/actions.ts new file mode 100644 index 000000000..01c804fd9 --- /dev/null +++ b/wagmi-project/packages/cli/src/plugins/actions.ts @@ -0,0 +1,321 @@ +import { pascalCase } from 'change-case' + +import type { Contract, Plugin } from '../config.js' +import type { Compute, RequiredBy } from '../types.js' +import { getAddressDocString } from '../utils/getAddressDocString.js' +import { getIsPackageInstalled } from '../utils/packages.js' + +export type ActionsConfig = { + getActionName?: + | 'legacy' // TODO: Deprecate `'legacy'` option + | ((options: { + contractName: string + itemName?: string | undefined + type: 'read' | 'simulate' | 'watch' | 'write' + }) => string) + overridePackageName?: '@wagmi/core' | 'wagmi' | undefined +} + +type ActionsResult = Compute> + +export function actions(config: ActionsConfig = {}): ActionsResult { + return { + name: 'Action', + async run({ contracts }) { + const imports = new Set([]) + const content: string[] = [] + const pure = '/*#__PURE__*/' + + const actionNames = new Set() + for (const contract of contracts) { + let hasReadFunction = false + let hasWriteFunction = false + let hasEvent = false + const readItems = [] + const writeItems = [] + const eventItems = [] + for (const item of contract.abi) { + if (item.type === 'function') + if ( + item.stateMutability === 'view' || + item.stateMutability === 'pure' + ) { + hasReadFunction = true + readItems.push(item) + } else { + hasWriteFunction = true + writeItems.push(item) + } + else if (item.type === 'event') { + hasEvent = true + eventItems.push(item) + } + } + + let innerContent: string + if (contract.meta.addressName) + innerContent = `abi: ${contract.meta.abiName}, address: ${contract.meta.addressName}` + else innerContent = `abi: ${contract.meta.abiName}` + + if (hasReadFunction) { + const actionName = getActionName( + config, + actionNames, + 'read', + contract.name, + ) + const docString = genDocString('readContract', contract) + const functionName = 'createReadContract' + imports.add(functionName) + content.push( + `${docString} +export const ${actionName} = ${pure} ${functionName}({ ${innerContent} })`, + ) + + const names = new Set() + for (const item of readItems) { + if (item.type !== 'function') continue + if ( + item.stateMutability !== 'pure' && + item.stateMutability !== 'view' + ) + continue + + // Skip overrides since they are captured by same hook + if (names.has(item.name)) continue + names.add(item.name) + + const hookName = getActionName( + config, + actionNames, + 'read', + contract.name, + item.name, + ) + const docString = genDocString('readContract', contract, { + name: 'functionName', + value: item.name, + }) + content.push( + `${docString} +export const ${hookName} = ${pure} ${functionName}({ ${innerContent}, functionName: '${item.name}' })`, + ) + } + } + + if (hasWriteFunction) { + { + const actionName = getActionName( + config, + actionNames, + 'write', + contract.name, + ) + const docString = genDocString('writeContract', contract) + const functionName = 'createWriteContract' + imports.add(functionName) + content.push( + `${docString} +export const ${actionName} = ${pure} ${functionName}({ ${innerContent} })`, + ) + + const names = new Set() + for (const item of writeItems) { + if (item.type !== 'function') continue + if ( + item.stateMutability !== 'nonpayable' && + item.stateMutability !== 'payable' + ) + continue + + // Skip overrides since they are captured by same hook + if (names.has(item.name)) continue + names.add(item.name) + + const actionName = getActionName( + config, + actionNames, + 'write', + contract.name, + item.name, + ) + const docString = genDocString('writeContract', contract, { + name: 'functionName', + value: item.name, + }) + content.push( + `${docString} +export const ${actionName} = ${pure} ${functionName}({ ${innerContent}, functionName: '${item.name}' })`, + ) + } + } + + { + const actionName = getActionName( + config, + actionNames, + 'simulate', + contract.name, + ) + const docString = genDocString('simulateContract', contract) + const functionName = 'createSimulateContract' + imports.add(functionName) + content.push( + `${docString} +export const ${actionName} = ${pure} ${functionName}({ ${innerContent} })`, + ) + + const names = new Set() + for (const item of writeItems) { + if (item.type !== 'function') continue + if ( + item.stateMutability !== 'nonpayable' && + item.stateMutability !== 'payable' + ) + continue + + // Skip overrides since they are captured by same hook + if (names.has(item.name)) continue + names.add(item.name) + + const actionName = getActionName( + config, + actionNames, + 'simulate', + contract.name, + item.name, + ) + const docString = genDocString('simulateContract', contract, { + name: 'functionName', + value: item.name, + }) + content.push( + `${docString} +export const ${actionName} = ${pure} ${functionName}({ ${innerContent}, functionName: '${item.name}' })`, + ) + } + } + } + + if (hasEvent) { + const actionName = getActionName( + config, + actionNames, + 'watch', + contract.name, + ) + const docString = genDocString('watchContractEvent', contract) + const functionName = 'createWatchContractEvent' + imports.add(functionName) + content.push( + `${docString} +export const ${actionName} = ${pure} ${functionName}({ ${innerContent} })`, + ) + + const names = new Set() + for (const item of eventItems) { + if (item.type !== 'event') continue + + // Skip overrides since they are captured by same hook + if (names.has(item.name)) continue + names.add(item.name) + + const actionName = getActionName( + config, + actionNames, + 'watch', + contract.name, + item.name, + ) + const docString = genDocString('watchContractEvent', contract, { + name: 'eventName', + value: item.name, + }) + content.push( + `${docString} +export const ${actionName} = ${pure} ${functionName}({ ${innerContent}, eventName: '${item.name}' })`, + ) + } + } + } + + const importValues = [...imports.values()] + + let packageName = '@wagmi/core/codegen' + if (config.overridePackageName) { + switch (config.overridePackageName) { + case '@wagmi/core': + packageName = '@wagmi/core/codegen' + break + case 'wagmi': + packageName = 'wagmi/codegen' + break + } + } else if (await getIsPackageInstalled({ packageName: 'wagmi' })) + packageName = 'wagmi/codegen' + else if (await getIsPackageInstalled({ packageName: '@wagmi/core' })) + packageName = '@wagmi/core/codegen' + + return { + imports: importValues.length + ? `import { ${importValues.join(', ')} } from '${packageName}'\n` + : '', + content: content.join('\n\n'), + } + }, + } +} + +function genDocString( + actionName: string, + contract: Contract, + item?: { name: string; value: string }, +) { + let description = `Wraps __{@link ${actionName}}__ with \`abi\` set to __{@link ${contract.meta.abiName}}__` + if (item) description += ` and \`${item.name}\` set to \`"${item.value}"\`` + + const docString = getAddressDocString({ address: contract.address }) + if (docString) + return `/** + * ${description} + * + ${docString} + */` + + return `/** + * ${description} + */` +} + +function getActionName( + config: ActionsConfig, + actionNames: Set, + type: 'read' | 'simulate' | 'watch' | 'write', + contractName: string, + itemName?: string | undefined, +) { + const ContractName = pascalCase(contractName) + const ItemName = itemName ? pascalCase(itemName) : undefined + + let actionName: string + if (typeof config.getActionName === 'function') + actionName = config.getActionName({ + type, + contractName: ContractName, + itemName: ItemName, + }) + else if (typeof config.getActionName === 'string' && type === 'simulate') { + actionName = `prepareWrite${ContractName}${ItemName ?? ''}` + } else { + actionName = `${type}${ContractName}${ItemName ?? ''}` + if (type === 'watch') actionName = `${actionName}Event` + } + + if (actionNames.has(actionName)) + throw new Error( + `Action name "${actionName}" must be unique for contract "${contractName}". Try using \`getActionName\` to create a unique name.`, + ) + + actionNames.add(actionName) + return actionName +} diff --git a/wagmi-project/packages/cli/src/plugins/blockExplorer.test.ts b/wagmi-project/packages/cli/src/plugins/blockExplorer.test.ts new file mode 100644 index 000000000..13372f53e --- /dev/null +++ b/wagmi-project/packages/cli/src/plugins/blockExplorer.test.ts @@ -0,0 +1,53 @@ +import { setupServer } from 'msw/node' +import { afterAll, afterEach, beforeAll, expect, test } from 'vitest' + +import { + address, + apiKey, + baseUrl, + handlers, + unverifiedContractAddress, +} from '../../test/utils.js' +import { blockExplorer } from './blockExplorer.js' + +const server = setupServer(...handlers) + +beforeAll(() => server.listen()) +afterEach(() => server.resetHandlers()) +afterAll(() => server.close()) + +test('fetches ABI', async () => { + await expect( + blockExplorer({ + apiKey, + baseUrl, + contracts: [{ name: 'WagmiMintExample', address }], + }).contracts!(), + ).resolves.toMatchSnapshot() +}) + +test('fetches ABI with multichain deployment', async () => { + await expect( + blockExplorer({ + apiKey, + baseUrl, + contracts: [ + { name: 'WagmiMintExample', address: { 1: address, 10: address } }, + ], + }).contracts?.(), + ).resolves.toMatchSnapshot() +}) + +test('fails to fetch for unverified contract', async () => { + await expect( + blockExplorer({ + apiKey, + baseUrl, + contracts: [ + { name: 'WagmiMintExample', address: unverifiedContractAddress }, + ], + }).contracts?.(), + ).rejects.toThrowErrorMatchingInlineSnapshot( + '[Error: Contract source code not verified]', + ) +}) diff --git a/wagmi-project/packages/cli/src/plugins/blockExplorer.ts b/wagmi-project/packages/cli/src/plugins/blockExplorer.ts new file mode 100644 index 000000000..2518b6e93 --- /dev/null +++ b/wagmi-project/packages/cli/src/plugins/blockExplorer.ts @@ -0,0 +1,107 @@ +import { camelCase } from 'change-case' +import type { Address } from 'viem' +import { z } from 'zod' + +import type { ContractConfig } from '../config.js' +import { fromZodError } from '../errors.js' +import type { Compute } from '../types.js' +import { fetch } from './fetch.js' + +export type BlockExplorerConfig = { + /** + * API key for block explorer. Appended to the request URL as query param `&apikey=${apiKey}`. + */ + apiKey?: string | undefined + /** + * Base URL for block explorer. + */ + baseUrl: string + /** + * Duration in milliseconds to cache ABIs. + * + * @default 1_800_000 // 30m in ms + */ + cacheDuration?: number | undefined + /** + * Chain ID for block explorer. Appended to the request URL as query param `&chainId=${chainId}`. + */ + chainId?: number | undefined + /** + * Contracts to fetch ABIs for. + */ + contracts: Compute>[] + /** + * Function to get address from contract config. + */ + getAddress?: + | ((config: { + address: NonNullable + }) => Address) + | undefined + /** + * Name of source. + */ + name?: ContractConfig['name'] | undefined +} + +const BlockExplorerResponse = z.discriminatedUnion('status', [ + z.object({ + status: z.literal('1'), + message: z.literal('OK'), + result: z + .string() + .transform((val) => JSON.parse(val) as ContractConfig['abi']), + }), + z.object({ + status: z.literal('0'), + message: z.literal('NOTOK'), + result: z.string(), + }), +]) + +/** + * Fetches contract ABIs from block explorers, supporting `?module=contract&action=getabi` requests. + */ +export function blockExplorer(config: BlockExplorerConfig) { + const { + apiKey, + baseUrl, + cacheDuration, + chainId, + contracts, + getAddress = ({ address }) => { + if (typeof address === 'string') return address + return Object.values(address)[0]! + }, + name = 'Block Explorer', + } = config + + return fetch({ + cacheDuration, + contracts, + name, + getCacheKey({ contract }) { + if (typeof contract.address === 'string') + return `${camelCase(name)}:${contract.address}` + return `${camelCase(name)}:${JSON.stringify(contract.address)}` + }, + async parse({ response }) { + const json = await response.json() + const parsed = await BlockExplorerResponse.safeParseAsync(json) + if (!parsed.success) + throw fromZodError(parsed.error, { prefix: 'Invalid response' }) + if (parsed.data.status === '0') throw new Error(parsed.data.result) + return parsed.data.result + }, + request({ address }) { + if (!address) throw new Error('address is required') + return { + url: `${baseUrl}?${chainId ? `chainId=${chainId}&` : ''}module=contract&action=getabi&address=${getAddress( + { + address, + }, + )}${apiKey ? `&apikey=${apiKey}` : ''}`, + } + }, + }) +} diff --git a/wagmi-project/packages/cli/src/plugins/etherscan.test.ts b/wagmi-project/packages/cli/src/plugins/etherscan.test.ts new file mode 100644 index 000000000..dc496f463 --- /dev/null +++ b/wagmi-project/packages/cli/src/plugins/etherscan.test.ts @@ -0,0 +1,112 @@ +import { mkdir, rm } from 'node:fs/promises' +import { setupServer } from 'msw/node' +import { afterAll, afterEach, beforeAll, expect, test } from 'vitest' + +import { + address, + apiKey, + handlers, + invalidApiKey, + proxyAddress, + timeoutAddress, + unverifiedContractAddress, +} from '../../test/utils.js' +import { etherscan } from './etherscan.js' +import { getCacheDir } from './fetch.js' + +const server = setupServer(...handlers) + +beforeAll(() => server.listen()) +afterEach(() => server.resetHandlers()) +afterAll(() => server.close()) + +test('fetches ABI', async () => { + await expect( + etherscan({ + apiKey, + chainId: 1, + contracts: [{ name: 'WagmiMintExample', address }], + }).contracts?.(), + ).resolves.toMatchSnapshot() +}) + +test('fetches ABI with multichain deployment', async () => { + await expect( + etherscan({ + apiKey, + chainId: 1, + contracts: [ + { name: 'WagmiMintExample', address: { 1: address, 10: address } }, + ], + }).contracts?.(), + ).resolves.toMatchSnapshot() +}) + +test('fails to fetch for unverified contract', async () => { + await expect( + etherscan({ + apiKey, + chainId: 1, + contracts: [ + { name: 'WagmiMintExample', address: unverifiedContractAddress }, + ], + }).contracts?.(), + ).rejects.toThrowErrorMatchingInlineSnapshot( + '[Error: Contract source code not verified]', + ) +}) + +test('missing address for chainId', async () => { + await expect( + etherscan({ + apiKey, + chainId: 1, + // @ts-expect-error `chainId` and `keyof typeof contracts[number].address` mismatch + contracts: [{ name: 'WagmiMintExample', address: { 10: address } }], + }).contracts?.(), + ).rejects.toThrowErrorMatchingInlineSnapshot( + `[Error: No address found for chainId "1". Make sure chainId "1" is set as an address.]`, + ) +}) + +test('invalid api key', async () => { + await expect( + etherscan({ + apiKey: invalidApiKey, + chainId: 1, + contracts: [{ name: 'WagmiMintExample', address: timeoutAddress }], + }).contracts?.(), + ).rejects.toThrowErrorMatchingInlineSnapshot('[Error: Invalid API Key]') +}) + +test('tryFetchProxyImplementation: fetches ABI', async () => { + const cacheDir = getCacheDir() + await mkdir(cacheDir, { recursive: true }) + + await expect( + etherscan({ + apiKey, + chainId: 1, + contracts: [{ name: 'WagmiMintExample', address }], + tryFetchProxyImplementation: true, + }).contracts?.(), + ).resolves.toMatchSnapshot() + + await rm(cacheDir, { recursive: true }) +}) + +test('tryFetchProxyImplementation: fetches implementation ABI', async () => { + const cacheDir = getCacheDir() + await mkdir(cacheDir, { recursive: true }) + + await expect( + etherscan({ + apiKey, + chainId: 1, + contracts: [{ name: 'FiatToken', address: proxyAddress }], + tryFetchProxyImplementation: true, + }).contracts?.(), + ).resolves.toMatchSnapshot() + + await rm(cacheDir, { recursive: true }) +}) diff --git a/wagmi-project/packages/cli/src/plugins/etherscan.ts b/wagmi-project/packages/cli/src/plugins/etherscan.ts new file mode 100644 index 000000000..fda375c24 --- /dev/null +++ b/wagmi-project/packages/cli/src/plugins/etherscan.ts @@ -0,0 +1,268 @@ +import { mkdir, writeFile } from 'node:fs/promises' +import { Address as AddressSchema } from 'abitype/zod' +import { camelCase } from 'change-case' +import { join } from 'pathe' +import type { Abi, Address } from 'viem' +import { z } from 'zod' + +import type { ContractConfig } from '../config.js' +import { fromZodError } from '../errors.js' +import type { Compute } from '../types.js' +import { fetch, getCacheDir } from './fetch.js' + +export type EtherscanConfig = { + /** + * Etherscan API key. + * + * Create or manage keys at https://etherscan.io/myapikey + */ + apiKey: string + /** + * Duration in milliseconds to cache ABIs. + * + * @default 1_800_000 // 30m in ms + */ + cacheDuration?: number | undefined + /** + * Chain ID to use for fetching ABI. + * + * If `address` is an object, `chainId` is used to select the address. + * + * View supported chains on the [Etherscan docs](https://docs.etherscan.io/etherscan-v2/getting-started/supported-chains). + */ + chainId: (chainId extends ChainId ? chainId : never) | (ChainId & {}) + /** + * Contracts to fetch ABIs for. + */ + contracts: Compute, 'abi'>>[] + /** + * Whether to try fetching proxy implementation address of the contract + * + * @default false + */ + tryFetchProxyImplementation?: boolean | undefined +} + +/** + * Fetches contract ABIs from Etherscan. + */ +export function etherscan( + config: EtherscanConfig, +) { + const { + apiKey, + cacheDuration = 1_800_000, + chainId, + tryFetchProxyImplementation = false, + } = config + + const contracts = config.contracts.map((x) => ({ + ...x, + address: + typeof x.address === 'string' ? { [chainId]: x.address } : x.address, + })) as Omit[] + + const name = 'Etherscan' + + const getCacheKey: Parameters[0]['getCacheKey'] = ({ + contract, + }) => { + if (typeof contract.address === 'string') + return `${camelCase(name)}:${contract.address}` + return `${camelCase(name)}:${JSON.stringify(contract.address)}` + } + + return fetch({ + cacheDuration, + contracts, + name, + getCacheKey, + async parse({ response }) { + const json = await response.json() + const parsed = await GetAbiResponse.safeParseAsync(json) + if (!parsed.success) + throw fromZodError(parsed.error, { prefix: 'Invalid response' }) + if (parsed.data.status === '0') throw new Error(parsed.data.result) + return parsed.data.result + }, + async request(contract) { + if (!contract.address) throw new Error('address is required') + + const resolvedAddress = (() => { + if (!contract.address) throw new Error('address is required') + if (typeof contract.address === 'string') return contract.address + const contractAddress = contract.address[chainId] + if (!contractAddress) + throw new Error( + `No address found for chainId "${chainId}". Make sure chainId "${chainId}" is set as an address.`, + ) + return contractAddress + })() + + const options = { + address: resolvedAddress, + apiKey, + chainId, + } + + let abi: Abi | undefined + const implementationAddress = await (async () => { + if (!tryFetchProxyImplementation) return + const json = await globalThis + .fetch(buildUrl({ ...options, action: 'getsourcecode' })) + .then((res) => res.json()) + const parsed = await GetSourceCodeResponse.safeParseAsync(json) + if (!parsed.success) + throw fromZodError(parsed.error, { prefix: 'Invalid response' }) + if (parsed.data.status === '0') throw new Error(parsed.data.result) + if (!parsed.data.result[0]) return + abi = parsed.data.result[0].ABI + return parsed.data.result[0].Implementation as Address + })() + + if (abi) { + const cacheDir = getCacheDir() + await mkdir(cacheDir, { recursive: true }) + const cacheKey = getCacheKey({ contract }) + const cacheFilePath = join(cacheDir, `${cacheKey}.json`) + await writeFile( + cacheFilePath, + `${JSON.stringify({ abi, timestamp: Date.now() + cacheDuration }, undefined, 2)}\n`, + ) + } + + return { + url: buildUrl({ + ...options, + action: 'getabi', + address: implementationAddress || resolvedAddress, + }), + } + }, + }) +} + +function buildUrl(options: { + action: 'getabi' | 'getsourcecode' + address: Address + apiKey: string + chainId: ChainId | undefined +}) { + const baseUrl = 'https://api.etherscan.io/v2/api' + const { action, address, apiKey, chainId } = options + return `${baseUrl}?${chainId ? `chainId=${chainId}&` : ''}module=contract&action=${action}&address=${address}${apiKey ? `&apikey=${apiKey}` : ''}` +} + +const GetAbiResponse = z.discriminatedUnion('status', [ + z.object({ + status: z.literal('1'), + message: z.literal('OK'), + result: z.string().transform((val) => JSON.parse(val) as Abi), + }), + z.object({ + status: z.literal('0'), + message: z.literal('NOTOK'), + result: z.string(), + }), +]) + +const GetSourceCodeResponse = z.discriminatedUnion('status', [ + z.object({ + status: z.literal('1'), + message: z.literal('OK'), + result: z.array( + z.discriminatedUnion('Proxy', [ + z.object({ + ABI: z.string().transform((val) => JSON.parse(val) as Abi), + Implementation: AddressSchema, + Proxy: z.literal('1'), + }), + z.object({ + ABI: z.string().transform((val) => JSON.parse(val) as Abi), + Implementation: z.string(), + Proxy: z.literal('0'), + }), + ]), + ), + }), + z.object({ + status: z.literal('0'), + message: z.literal('NOTOK'), + result: z.string(), + }), +]) + +// Supported chains +// https://docs.etherscan.io/etherscan-v2/getting-started/supported-chains +type ChainId = + | 1 // Ethereum Mainnet + | 11155111 // Sepolia Testnet + | 17000 // Holesky Testnet + | 560048 // Hoodi Testnet + | 56 // BNB Smart Chain Mainnet + | 97 // BNB Smart Chain Testnet + | 137 // Polygon Mainnet + | 80002 // Polygon Amoy Testnet + | 1101 // Polygon zkEVM Mainnet + | 2442 // Polygon zkEVM Cardona Testnet + | 8453 // Base Mainnet + | 84532 // Base Sepolia Testnet + | 42161 // Arbitrum One Mainnet + | 42170 // Arbitrum Nova Mainnet + | 421614 // Arbitrum Sepolia Testnet + | 59144 // Linea Mainnet + | 59141 // Linea Sepolia Testnet + | 250 // Fantom Opera Mainnet + | 4002 // Fantom Testnet + | 81457 // Blast Mainnet + | 168587773 // Blast Sepolia Testnet + | 10 // OP Mainnet + | 11155420 // OP Sepolia Testnet + | 43114 // Avalanche C-Chain + | 43113 // Avalanche Fuji Testnet + | 199 // BitTorrent Chain Mainnet + | 1028 // BitTorrent Chain Testnet + | 42220 // Celo Mainnet + | 44787 // Celo Alfajores Testnet + | 25 // Cronos Mainnet + | 252 // Fraxtal Mainnet + | 2522 // Fraxtal Testnet + | 100 // Gnosis + | 255 // Kroma Mainnet + | 2358 // Kroma Sepolia Testnet + | 5000 // Mantle Mainnet + | 5003 // Mantle Sepolia Testnet + | 1284 // Moonbeam Mainnet + | 1285 // Moonriver Mainnet + | 1287 // Moonbase Alpha Testnet + | 204 // opBNB Mainnet + | 5611 // opBNB Testnet + | 534352 // Scroll Mainnet + | 534351 // Scroll Sepolia Testnet + | 167000 // Taiko Mainnet + | 167009 // Taiko Hekla L2 Testnet + | 1111 // WEMIX3.0 Mainnet + | 1112 // WEMIX3.0 Testnet + | 324 // zkSync Mainnet + | 300 // zkSync Sepolia Testnet + | 660279 // Xai Mainnet + | 37714555429 // Xai Sepolia Testnet + | 50 // XDC Mainnet + | 51 // XDC Apothem Testnet + | 33139 // ApeChain Mainnet + | 33111 // ApeChain Curtis Testnet + | 480 // World Mainnet + | 4801 // World Sepolia Testnet + | 50104 // Sophon Mainnet + | 531050104 // Sophon Sepolia Testnet + | 146 // Sonic Mainnet + | 57054 // Sonic Blaze Testnet + | 130 // Unichain Mainnet + | 1301 // Unichain Sepolia Testnet + | 2741 // Abstract Mainnet + | 11124 // Abstract Sepolia Testnet + | 80094 // Berachain Mainnet + | 80069 // Berachain Bepolia Testnet + | 1923 // Swellchain Mainnet + | 1924 // Swellchain Testnet + | 10143 // Monad Testnet diff --git a/wagmi-project/packages/cli/src/plugins/fetch.test.ts b/wagmi-project/packages/cli/src/plugins/fetch.test.ts new file mode 100644 index 000000000..600cbfeda --- /dev/null +++ b/wagmi-project/packages/cli/src/plugins/fetch.test.ts @@ -0,0 +1,186 @@ +import { mkdir, rm, writeFile } from 'node:fs/promises' +import { homedir } from 'node:os' +import { setupServer } from 'msw/node' +import { afterAll, afterEach, beforeAll, expect, test } from 'vitest' + +import { + address, + apiKey, + baseUrl, + handlers, + timeoutAddress, + unverifiedContractAddress, +} from '../../test/utils.js' +import { fetch, getCacheDir } from './fetch.js' + +const server = setupServer(...handlers) + +beforeAll(() => server.listen()) +afterEach(() => server.resetHandlers()) +afterAll(() => server.close()) + +type Fetch = Parameters[0] +const request: Fetch['request'] = ({ address }) => { + return { + url: `${baseUrl}?module=contract&action=getabi&address=${address}&apikey=${apiKey}`, + } +} +const parse: Fetch['parse'] = async ({ response }) => { + const data = (await response.json()) as + | { status: '1'; message: 'OK'; result: string } + | { status: '0'; message: 'NOTOK'; result: string } + if (data.status === '0') throw new Error(data.result) + return JSON.parse(data.result) +} + +test('fetches ABI', async () => { + await expect( + fetch({ + contracts: [{ name: 'WagmiMintExample', address }], + request, + parse, + }).contracts?.(), + ).resolves.toMatchSnapshot() +}) + +test('fails to fetch for unverified contract', async () => { + await expect( + fetch({ + contracts: [ + { name: 'WagmiMintExample', address: unverifiedContractAddress }, + ], + request, + parse, + }).contracts?.(), + ).rejects.toThrowErrorMatchingInlineSnapshot( + '[Error: Contract source code not verified]', + ) +}) + +test('aborts request', async () => { + await expect( + fetch({ + contracts: [{ name: 'WagmiMintExample', address: timeoutAddress }], + request, + parse, + timeoutDuration: 1_000, + }).contracts?.(), + ).rejects.toThrowErrorMatchingInlineSnapshot( + '[AbortError: This operation was aborted]', + ) +}) + +test('reads from cache', async () => { + const cacheDir = `${homedir}/.wagmi-cli/plugins/fetch/cache` + await mkdir(cacheDir, { recursive: true }) + + const contract = { + name: 'WagmiMintExample', + address: timeoutAddress, + } as const + const cacheKey = JSON.stringify(contract) + const cacheFilePath = `${cacheDir}/${cacheKey}.json` + await writeFile( + cacheFilePath, + JSON.stringify( + { + abi: [ + { + inputs: [], + name: 'mint', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + ], + timestamp: Date.now() + 30_000, + }, + null, + 2, + ), + ) + + await expect( + fetch({ + contracts: [contract], + request, + parse, + }).contracts?.(), + ).resolves.toMatchInlineSnapshot(` + [ + { + "abi": [ + { + "inputs": [], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + ], + "address": "0xecb504d39723b0be0e3a9aa33d646642d1051ee1", + "name": "WagmiMintExample", + }, + ] + `) + + await rm(cacheDir, { recursive: true }) +}) + +test('fails and reads from cache', async () => { + const cacheDir = getCacheDir() + await mkdir(cacheDir, { recursive: true }) + + const contract = { + name: 'WagmiMintExample', + address: timeoutAddress, + } as const + const cacheKey = JSON.stringify(contract) + const cacheFilePath = `${cacheDir}/${cacheKey}.json` + await writeFile( + cacheFilePath, + JSON.stringify( + { + abi: [ + { + inputs: [], + name: 'mint', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + ], + timestamp: Date.now() - 30_000, + }, + null, + 2, + ), + ) + + await expect( + fetch({ + contracts: [contract], + request, + parse, + timeoutDuration: 1, + }).contracts?.(), + ).resolves.toMatchInlineSnapshot(` + [ + { + "abi": [ + { + "inputs": [], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + ], + "address": "0xecb504d39723b0be0e3a9aa33d646642d1051ee1", + "name": "WagmiMintExample", + }, + ] + `) + + await rm(cacheDir, { recursive: true }) +}) diff --git a/wagmi-project/packages/cli/src/plugins/fetch.ts b/wagmi-project/packages/cli/src/plugins/fetch.ts new file mode 100644 index 000000000..778d4a816 --- /dev/null +++ b/wagmi-project/packages/cli/src/plugins/fetch.ts @@ -0,0 +1,127 @@ +import { mkdir, readFile, writeFile } from 'node:fs/promises' +import { homedir } from 'node:os' +import { join } from 'pathe' + +import type { Abi } from 'viem' +import type { ContractConfig, Plugin } from '../config.js' +import type { Compute, RequiredBy } from '../types.js' + +export type FetchConfig = { + /** + * Duration in milliseconds to cache ABIs from request. + * + * @default 1_800_000 // 30m in ms + */ + cacheDuration?: number | undefined + /** + * Contracts to fetch ABIs for. + */ + contracts: Compute>[] + /** + * Function for creating a cache key for contract. + */ + getCacheKey?: + | ((config: { contract: Compute> }) => string) + | undefined + /** + * Name of source. + */ + name?: ContractConfig['name'] | undefined + /** + * Function for parsing ABI from fetch response. + * + * @default ({ response }) => response.json() + */ + parse?: + | ((config: { + response: Response + }) => ContractConfig['abi'] | Promise) + | undefined + /** + * Function for returning a request to fetch ABI from. + */ + request: (config: { + address?: ContractConfig['address'] | undefined + name: ContractConfig['name'] + }) => + | { url: RequestInfo; init?: RequestInit | undefined } + | Promise<{ url: RequestInfo; init?: RequestInit | undefined }> + /** + * Duration in milliseconds before request times out. + * + * @default 5_000 // 5s in ms + */ + timeoutDuration?: number | undefined +} + +type FetchResult = Compute> + +/** Fetches and parses contract ABIs from network resource with `fetch`. */ +export function fetch(config: FetchConfig): FetchResult { + const { + cacheDuration = 1_800_000, + contracts: contractConfigs, + getCacheKey = ({ contract }) => JSON.stringify(contract), + name = 'Fetch', + parse = ({ response }) => response.json(), + request, + timeoutDuration = 5_000, + } = config + + return { + async contracts() { + const cacheDir = getCacheDir() + await mkdir(cacheDir, { recursive: true }) + + const timestamp = Date.now() + cacheDuration + const contracts = [] + for (const contract of contractConfigs) { + const cacheKey = getCacheKey({ contract }) + const cacheFilePath = join(cacheDir, `${cacheKey}.json`) + const cachedFile = JSON.parse( + await readFile(cacheFilePath, 'utf8').catch(() => 'null'), + ) + + let abi: Abi | undefined + if (cachedFile?.timestamp > Date.now()) abi = cachedFile.abi + else { + try { + const controller = new globalThis.AbortController() + const timeout = setTimeout( + () => controller.abort(), + timeoutDuration, + ) + + const { url, init } = await request(contract) + const response = await globalThis.fetch(url, { + ...init, + signal: controller.signal, + }) + clearTimeout(timeout) + + abi = await parse({ response }) + await writeFile( + cacheFilePath, + `${JSON.stringify({ abi, timestamp }, undefined, 2)}\n`, + ) + } catch (error) { + try { + // Attempt to read from cache if fetch fails. + abi = JSON.parse(await readFile(cacheFilePath, 'utf8')).abi + } catch {} + if (!abi) throw error + } + } + + if (!abi) throw Error('Failed to fetch ABI for contract.') + contracts.push({ abi, address: contract.address, name: contract.name }) + } + return contracts + }, + name, + } +} + +export function getCacheDir() { + return join(homedir(), '.wagmi-cli/plugins/fetch/cache') +} diff --git a/wagmi-project/packages/cli/src/plugins/foundry.test.ts b/wagmi-project/packages/cli/src/plugins/foundry.test.ts new file mode 100644 index 000000000..75e5ec73e --- /dev/null +++ b/wagmi-project/packages/cli/src/plugins/foundry.test.ts @@ -0,0 +1,153 @@ +import fixtures from 'fixturez' +import { dirname, resolve } from 'pathe' +import { afterEach, expect, test, vi } from 'vitest' + +import { foundry } from './foundry.js' + +const f = fixtures(__dirname) + +afterEach(() => { + vi.restoreAllMocks() +}) + +test('forge not installed', async () => { + const dir = f.temp() + expect( + foundry({ + project: dir, + forge: { + path: '/path/to/forge', + }, + }).validate?.(), + ).rejects.toThrowErrorMatchingInlineSnapshot(` + [Error: forge must be installed to use Foundry plugin. + To install, follow the instructions at https://book.getfoundry.sh/getting-started/installation] + `) +}) + +test('project does not exist', async () => { + const dir = f.temp() + const spy = vi.spyOn(process, 'cwd') + spy.mockImplementation(() => dir) + + try { + await foundry({ project: '../path/to/project' }).validate?.() + } catch (error) { + expect( + (error as Error).message.replace(dirname(dir), '..'), + ).toMatchInlineSnapshot('"Foundry project ../path/to/project not found."') + } +}) + +test('validates without project', async () => { + const dir = resolve(__dirname, '__fixtures__/foundry/') + const spy = vi.spyOn(process, 'cwd') + spy.mockImplementation(() => dir) + + await expect(foundry().validate?.()).resolves.toBeUndefined() +}) + +test('contracts', async () => { + await expect( + foundry({ + project: resolve(__dirname, '__fixtures__/foundry/'), + exclude: ['Foo.sol/**'], + }).contracts?.(), + ).resolves.toMatchInlineSnapshot(` + [ + { + "abi": [ + { + "inputs": [], + "name": "increment", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [], + "name": "number", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newNumber", + "type": "uint256", + }, + ], + "name": "setNumber", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + ], + "address": undefined, + "name": "Counter", + }, + ] + `) +}) + +test('contracts without project', async () => { + const dir = resolve(__dirname, '__fixtures__/foundry/') + const spy = vi.spyOn(process, 'cwd') + spy.mockImplementation(() => dir) + + await expect( + foundry({ + exclude: ['Foo.sol/**'], + }).contracts?.(), + ).resolves.toMatchInlineSnapshot(` + [ + { + "abi": [ + { + "inputs": [], + "name": "increment", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [], + "name": "number", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newNumber", + "type": "uint256", + }, + ], + "name": "setNumber", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + ], + "address": undefined, + "name": "Counter", + }, + ] + `) +}) diff --git a/wagmi-project/packages/cli/src/plugins/foundry.ts b/wagmi-project/packages/cli/src/plugins/foundry.ts new file mode 100644 index 000000000..dab307a58 --- /dev/null +++ b/wagmi-project/packages/cli/src/plugins/foundry.ts @@ -0,0 +1,263 @@ +import { execSync, spawn, spawnSync } from 'node:child_process' +import { existsSync } from 'node:fs' +import { readFile } from 'node:fs/promises' +import dedent from 'dedent' +import { fdir } from 'fdir' +import { basename, extname, join, resolve } from 'pathe' +import pc from 'picocolors' +import { z } from 'zod' + +import type { ContractConfig, Plugin } from '../config.js' +import * as logger from '../logger.js' +import type { Compute, RequiredBy } from '../types.js' + +export const foundryDefaultExcludes = [ + 'Base.sol/**', + 'Common.sol/**', + 'Components.sol/**', + 'IERC165.sol/**', + 'IERC20.sol/**', + 'IERC721.sol/**', + 'IMulticall2.sol/**', + 'MockERC20.sol/**', + 'MockERC721.sol/**', + 'Script.sol/**', + 'StdAssertions.sol/**', + 'StdChains.sol/**', + 'StdCheats.sol/**', + 'StdError.sol/**', + 'StdInvariant.sol/**', + 'StdJson.sol/**', + 'StdMath.sol/**', + 'StdStorage.sol/**', + 'StdStyle.sol/**', + 'StdToml.sol/**', + 'StdUtils.sol/**', + 'Test.sol/**', + 'Vm.sol/**', + 'build-info/**', + 'console.sol/**', + 'console2.sol/**', + 'safeconsole.sol/**', + '**.s.sol/*.json', + '**.t.sol/*.json', +] + +export type FoundryConfig = { + /** + * Project's artifacts directory. + * + * Same as your project's `--out` (`-o`) option. + * + * @default foundry.config#out | 'out' + */ + artifacts?: string | undefined + /** Mapping of addresses to attach to artifacts. */ + deployments?: { [key: string]: ContractConfig['address'] } | undefined + /** Artifact files to exclude. */ + exclude?: string[] | undefined + /** [Forge](https://book.getfoundry.sh/forge) configuration */ + forge?: + | { + /** + * Remove build artifacts and cache directories on start up. + * + * @default false + */ + clean?: boolean | undefined + /** + * Build Foundry project before fetching artifacts. + * + * @default true + */ + build?: boolean | undefined + /** + * Path to `forge` executable command + * + * @default "forge" + */ + path?: string | undefined + /** + * Rebuild every time a watched file or directory is changed. + * + * @default true + */ + rebuild?: boolean | undefined + } + | undefined + /** Artifact files to include. */ + include?: string[] | undefined + /** Optional prefix to prepend to artifact names. */ + namePrefix?: string | undefined + /** Path to foundry project. */ + project?: string | undefined +} + +type FoundryResult = Compute< + RequiredBy +> + +const FoundryConfigSchema = z.object({ + out: z.string().default('out'), + src: z.string().default('src'), +}) + +/** Resolves ABIs from [Foundry](https://github.com/foundry-rs/foundry) project. */ +export function foundry(config: FoundryConfig = {}): FoundryResult { + const { + artifacts, + deployments = {}, + exclude = foundryDefaultExcludes, + forge: { + clean = false, + build = true, + path: forgeExecutable = 'forge', + rebuild = true, + } = {}, + include = ['*.json'], + namePrefix = '', + } = config + + function getContractName(artifactPath: string, usePrefix = true) { + const filename = basename(artifactPath) + const extension = extname(artifactPath) + return `${usePrefix ? namePrefix : ''}${filename.replace(extension, '')}` + } + + async function getContract(artifactPath: string) { + const artifact = await JSON.parse(await readFile(artifactPath, 'utf8')) + return { + abi: artifact.abi, + address: (deployments as Record)[ + getContractName(artifactPath, false) + ], + name: getContractName(artifactPath), + } + } + + function getArtifactPaths(artifactsDirectory: string) { + const crawler = new fdir().withBasePath().globWithOptions( + include.map((x) => `${artifactsDirectory}/**/${x}`), + { + dot: true, + ignore: exclude.map((x) => `${artifactsDirectory}/**/${x}`), + }, + ) + return crawler.crawl(artifactsDirectory).withPromise() + } + + const project = resolve(process.cwd(), config.project ?? '') + + let foundryConfig: z.infer = { + out: 'out', + src: 'src', + } + try { + const result = spawnSync( + forgeExecutable, + ['config', '--json', '--root', project], + { + encoding: 'utf-8', + shell: true, + }, + ) + if (result.error) throw result.error + if (result.status !== 0) + throw new Error(`Failed with code ${result.status}`) + if (result.signal) throw new Error('Process terminated by signal') + foundryConfig = FoundryConfigSchema.parse(JSON.parse(result.stdout)) + } catch { + } finally { + foundryConfig = { + ...foundryConfig, + out: artifacts ?? foundryConfig.out, + } + } + + const artifactsDirectory = join(project, foundryConfig.out) + + return { + async contracts() { + if (clean) + execSync(`${forgeExecutable} clean --root ${project}`, { + encoding: 'utf-8', + stdio: 'pipe', + }) + if (build) + execSync(`${forgeExecutable} build --root ${project}`, { + encoding: 'utf-8', + stdio: 'pipe', + }) + if (!existsSync(artifactsDirectory)) + throw new Error('Artifacts not found.') + + const artifactPaths = await getArtifactPaths(artifactsDirectory) + const contracts = [] + for (const artifactPath of artifactPaths) { + const contract = await getContract(artifactPath) + if (!contract.abi?.length) continue + contracts.push(contract) + } + return contracts + }, + name: 'Foundry', + async validate() { + // Check that project directory exists + if (!existsSync(project)) + throw new Error(`Foundry project ${pc.gray(config.project)} not found.`) + + // Ensure forge is installed + if (clean || build || rebuild) + try { + execSync(`${forgeExecutable} --version`, { + encoding: 'utf-8', + stdio: 'pipe', + }) + } catch (_error) { + throw new Error(dedent` + forge must be installed to use Foundry plugin. + To install, follow the instructions at https://book.getfoundry.sh/getting-started/installation + `) + } + }, + watch: { + command: rebuild + ? async () => { + logger.log( + `${pc.magenta('Foundry')} Watching project at ${pc.gray( + project, + )}`, + ) + const subprocess = spawn(forgeExecutable, [ + 'build', + '--watch', + '--root', + project, + ]) + subprocess.stdout?.on('data', (data) => { + process.stdout.write(`${pc.magenta('Foundry')} ${data}`) + }) + + process.once('SIGINT', shutdown) + process.once('SIGTERM', shutdown) + function shutdown() { + subprocess?.kill() + } + } + : undefined, + paths: [ + ...include.map((x) => `${artifactsDirectory}/**/${x}`), + ...exclude.map((x) => `!${artifactsDirectory}/**/${x}`), + ], + async onAdd(path) { + return getContract(path) + }, + async onChange(path) { + return getContract(path) + }, + async onRemove(path) { + return getContractName(path) + }, + }, + } +} diff --git a/wagmi-project/packages/cli/src/plugins/hardhat.test.ts b/wagmi-project/packages/cli/src/plugins/hardhat.test.ts new file mode 100644 index 000000000..efb416c5e --- /dev/null +++ b/wagmi-project/packages/cli/src/plugins/hardhat.test.ts @@ -0,0 +1,85 @@ +import fixtures from 'fixturez' +import { dirname, resolve } from 'pathe' +import { afterEach, expect, test, vi } from 'vitest' + +import { hardhat } from './hardhat.js' + +const f = fixtures(__dirname) + +afterEach(() => { + vi.restoreAllMocks() +}) + +test('validate', async () => { + const temp = f.temp() + expect( + hardhat({ project: temp }).validate?.(), + ).rejects.toThrowErrorMatchingInlineSnapshot( + '[Error: hardhat must be installed to use Hardhat plugin.]', + ) +}) + +test('project does not exist', async () => { + const dir = f.temp() + const spy = vi.spyOn(process, 'cwd') + spy.mockImplementation(() => dir) + + try { + await hardhat({ project: '../path/to/project' }).validate?.() + } catch (error) { + expect( + (error as Error).message.replace(dirname(dir), '..'), + ).toMatchInlineSnapshot('"Hardhat project ../path/to/project not found."') + } +}) + +test('contracts', async () => { + expect( + hardhat({ + project: resolve(__dirname, '__fixtures__/hardhat/'), + exclude: ['Foo.sol/**'], + }).contracts?.(), + ).resolves.toMatchInlineSnapshot(` + [ + { + "abi": [ + { + "inputs": [], + "name": "increment", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [], + "name": "number", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newNumber", + "type": "uint256", + }, + ], + "name": "setNumber", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + ], + "address": undefined, + "name": "Counter", + }, + ] + `) +}, 10_000) diff --git a/wagmi-project/packages/cli/src/plugins/hardhat.ts b/wagmi-project/packages/cli/src/plugins/hardhat.ts new file mode 100644 index 000000000..a4feb6efd --- /dev/null +++ b/wagmi-project/packages/cli/src/plugins/hardhat.ts @@ -0,0 +1,235 @@ +import { execSync, spawn } from 'node:child_process' +import { existsSync } from 'node:fs' +import { readFile } from 'node:fs/promises' +import { fdir } from 'fdir' +import { basename, extname, join, resolve } from 'pathe' +import pc from 'picocolors' + +import type { ContractConfig, Plugin } from '../config.js' +import * as logger from '../logger.js' +import type { Compute, RequiredBy } from '../types.js' +import { getIsPackageInstalled, getPackageManager } from '../utils/packages.js' + +export const hardhatDefaultExcludes = ['build-info/**', '*.dbg.json'] + +export type HardhatConfig = { + /** + * Project's artifacts directory. + * + * Same as your project's `artifacts` [path configuration](https://hardhat.org/hardhat-runner/docs/config#path-configuration) option. + * + * @default 'artifacts/' + */ + artifacts?: string | undefined + /** Mapping of addresses to attach to artifacts. */ + deployments?: { [key: string]: ContractConfig['address'] } | undefined + /** Artifact files to exclude. */ + exclude?: string[] | undefined + /** Commands to run */ + commands?: + | { + /** + * Remove build artifacts and cache directories on start up. + * + * @default `${packageManger} hardhat clean` + */ + clean?: string | boolean | undefined + /** + * Build Hardhat project before fetching artifacts. + * + * @default `${packageManger} hardhat compile` + */ + build?: string | boolean | undefined + /** + * Command to run when watched file or directory is changed. + * + * @default `${packageManger} hardhat compile` + */ + rebuild?: string | boolean | undefined + } + | undefined + /** Artifact files to include. */ + include?: string[] | undefined + /** Optional prefix to prepend to artifact names. */ + namePrefix?: string | undefined + /** Path to Hardhat project. */ + project: string + /** + * Project's artifacts directory. + * + * Same as your project's `sources` [path configuration](https://hardhat.org/hardhat-runner/docs/config#path-configuration) option. + * + * @default 'contracts/' + */ + sources?: string | undefined +} + +type HardhatResult = Compute< + RequiredBy +> + +/** Resolves ABIs from [Hardhat](https://github.com/NomicFoundation/hardhat) project. */ +export function hardhat(config: HardhatConfig): HardhatResult { + const { + artifacts = 'artifacts', + deployments = {}, + exclude = hardhatDefaultExcludes, + commands = {}, + include = ['*.json'], + namePrefix = '', + sources = 'contracts', + } = config + + function getContractName(artifact: { contractName: string }) { + return `${namePrefix}${artifact.contractName}` + } + + async function getContract(artifactPath: string) { + const artifact = await JSON.parse(await readFile(artifactPath, 'utf8')) + return { + abi: artifact.abi, + address: deployments[artifact.contractName], + name: getContractName(artifact), + } + } + + function getArtifactPaths(artifactsDirectory: string) { + const crawler = new fdir().withBasePath().globWithOptions( + include.map((x) => `${artifactsDirectory}/**/${x}`), + { + dot: true, + ignore: exclude.map((x) => `${artifactsDirectory}/**/${x}`), + }, + ) + return crawler.crawl(artifactsDirectory).withPromise() + } + + const project = resolve(process.cwd(), config.project) + const artifactsDirectory = join(project, artifacts) + const sourcesDirectory = join(project, sources) + + const { build = true, clean = false, rebuild = true } = commands + return { + async contracts() { + if (clean) { + const packageManager = await getPackageManager(true) + const [command, ...options] = ( + typeof clean === 'boolean' ? `${packageManager} hardhat clean` : clean + ).split(' ') + execSync(`${command!} ${options.join(' ')}`, { + cwd: project, + encoding: 'utf-8', + stdio: 'pipe', + }) + } + if (build) { + const packageManager = await getPackageManager(true) + const [command, ...options] = ( + typeof build === 'boolean' + ? `${packageManager} hardhat compile` + : build + ).split(' ') + execSync(`${command!} ${options.join(' ')}`, { + cwd: project, + encoding: 'utf-8', + stdio: 'pipe', + }) + } + if (!existsSync(artifactsDirectory)) + throw new Error('Artifacts not found.') + + const artifactPaths = await getArtifactPaths(artifactsDirectory) + const contracts = [] + for (const artifactPath of artifactPaths) { + const contract = await getContract(artifactPath) + if (!contract.abi?.length) continue + contracts.push(contract) + } + return contracts + }, + name: 'Hardhat', + async validate() { + // Check that project directory exists + if (!existsSync(project)) + throw new Error(`Hardhat project ${pc.gray(project)} not found.`) + + // Check that `hardhat` is installed + const packageName = 'hardhat' + const isPackageInstalled = await getIsPackageInstalled({ + packageName, + cwd: project, + }) + if (isPackageInstalled) return + throw new Error(`${packageName} must be installed to use Hardhat plugin.`) + }, + watch: { + command: rebuild + ? async () => { + logger.log( + `${pc.blue('Hardhat')} Watching project at ${pc.gray(project)}`, + ) + + const [command, ...options] = ( + typeof rebuild === 'boolean' + ? `${await getPackageManager(true)} hardhat compile` + : rebuild + ).split(' ') + + const { watch } = await import('chokidar') + const watcher = watch(sourcesDirectory, { + atomic: true, + awaitWriteFinish: true, + ignoreInitial: true, + persistent: true, + }) + watcher.on('all', async (event, path) => { + if (event !== 'change' && event !== 'add' && event !== 'unlink') + return + logger.log( + `${pc.blue('Hardhat')} Detected ${event} at ${basename(path)}`, + ) + const subprocess = spawn(command!, options, { + cwd: project, + }) + subprocess.stdout?.on('data', (data) => { + process.stdout.write(`${pc.blue('Hardhat')} ${data}`) + }) + }) + + process.once('SIGINT', shutdown) + process.once('SIGTERM', shutdown) + async function shutdown() { + await watcher.close() + } + } + : undefined, + paths: [ + artifactsDirectory, + ...include.map((x) => `${artifactsDirectory}/**/${x}`), + ...exclude.map((x) => `!${artifactsDirectory}/**/${x}`), + ], + async onAdd(path) { + return getContract(path) + }, + async onChange(path) { + return getContract(path) + }, + async onRemove(path) { + const filename = basename(path) + const extension = extname(path) + // Since we can't use `getContractName`, guess from path + const removedContractName = `${namePrefix}${filename.replace( + extension, + '', + )}` + const artifactPaths = await getArtifactPaths(artifactsDirectory) + for (const artifactPath of artifactPaths) { + const contract = await getContract(artifactPath) + // If contract with same name exists, don't remove + if (contract.name === removedContractName) return + } + return removedContractName + }, + }, + } +} diff --git a/wagmi-project/packages/cli/src/plugins/react.test.ts b/wagmi-project/packages/cli/src/plugins/react.test.ts new file mode 100644 index 000000000..939a5299a --- /dev/null +++ b/wagmi-project/packages/cli/src/plugins/react.test.ts @@ -0,0 +1,337 @@ +import { erc20Abi } from 'viem' +import { expect, test } from 'vitest' + +import { react } from './react.js' + +test('default', async () => { + const result = await react().run?.({ + contracts: [ + { + name: 'erc20', + abi: erc20Abi, + content: '', + meta: { + abiName: 'erc20Abi', + }, + }, + ], + isTypeScript: true, + outputs: [], + }) + + expect(result?.imports).toMatchInlineSnapshot(` + "import { createUseReadContract, createUseWriteContract, createUseSimulateContract, createUseWatchContractEvent } from 'wagmi/codegen' + " + `) + expect(result?.content).toMatchInlineSnapshot(` + "/** + * Wraps __{@link useReadContract}__ with \`abi\` set to __{@link erc20Abi}__ + */ + export const useReadErc20 = /*#__PURE__*/ createUseReadContract({ abi: erc20Abi }) + + /** + * Wraps __{@link useReadContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"allowance"\` + */ + export const useReadErc20Allowance = /*#__PURE__*/ createUseReadContract({ abi: erc20Abi, functionName: 'allowance' }) + + /** + * Wraps __{@link useReadContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"balanceOf"\` + */ + export const useReadErc20BalanceOf = /*#__PURE__*/ createUseReadContract({ abi: erc20Abi, functionName: 'balanceOf' }) + + /** + * Wraps __{@link useReadContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"decimals"\` + */ + export const useReadErc20Decimals = /*#__PURE__*/ createUseReadContract({ abi: erc20Abi, functionName: 'decimals' }) + + /** + * Wraps __{@link useReadContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"name"\` + */ + export const useReadErc20Name = /*#__PURE__*/ createUseReadContract({ abi: erc20Abi, functionName: 'name' }) + + /** + * Wraps __{@link useReadContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"symbol"\` + */ + export const useReadErc20Symbol = /*#__PURE__*/ createUseReadContract({ abi: erc20Abi, functionName: 'symbol' }) + + /** + * Wraps __{@link useReadContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"totalSupply"\` + */ + export const useReadErc20TotalSupply = /*#__PURE__*/ createUseReadContract({ abi: erc20Abi, functionName: 'totalSupply' }) + + /** + * Wraps __{@link useWriteContract}__ with \`abi\` set to __{@link erc20Abi}__ + */ + export const useWriteErc20 = /*#__PURE__*/ createUseWriteContract({ abi: erc20Abi }) + + /** + * Wraps __{@link useWriteContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"approve"\` + */ + export const useWriteErc20Approve = /*#__PURE__*/ createUseWriteContract({ abi: erc20Abi, functionName: 'approve' }) + + /** + * Wraps __{@link useWriteContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"transfer"\` + */ + export const useWriteErc20Transfer = /*#__PURE__*/ createUseWriteContract({ abi: erc20Abi, functionName: 'transfer' }) + + /** + * Wraps __{@link useWriteContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"transferFrom"\` + */ + export const useWriteErc20TransferFrom = /*#__PURE__*/ createUseWriteContract({ abi: erc20Abi, functionName: 'transferFrom' }) + + /** + * Wraps __{@link useSimulateContract}__ with \`abi\` set to __{@link erc20Abi}__ + */ + export const useSimulateErc20 = /*#__PURE__*/ createUseSimulateContract({ abi: erc20Abi }) + + /** + * Wraps __{@link useSimulateContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"approve"\` + */ + export const useSimulateErc20Approve = /*#__PURE__*/ createUseSimulateContract({ abi: erc20Abi, functionName: 'approve' }) + + /** + * Wraps __{@link useSimulateContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"transfer"\` + */ + export const useSimulateErc20Transfer = /*#__PURE__*/ createUseSimulateContract({ abi: erc20Abi, functionName: 'transfer' }) + + /** + * Wraps __{@link useSimulateContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"transferFrom"\` + */ + export const useSimulateErc20TransferFrom = /*#__PURE__*/ createUseSimulateContract({ abi: erc20Abi, functionName: 'transferFrom' }) + + /** + * Wraps __{@link useWatchContractEvent}__ with \`abi\` set to __{@link erc20Abi}__ + */ + export const useWatchErc20Event = /*#__PURE__*/ createUseWatchContractEvent({ abi: erc20Abi }) + + /** + * Wraps __{@link useWatchContractEvent}__ with \`abi\` set to __{@link erc20Abi}__ and \`eventName\` set to \`"Approval"\` + */ + export const useWatchErc20ApprovalEvent = /*#__PURE__*/ createUseWatchContractEvent({ abi: erc20Abi, eventName: 'Approval' }) + + /** + * Wraps __{@link useWatchContractEvent}__ with \`abi\` set to __{@link erc20Abi}__ and \`eventName\` set to \`"Transfer"\` + */ + export const useWatchErc20TransferEvent = /*#__PURE__*/ createUseWatchContractEvent({ abi: erc20Abi, eventName: 'Transfer' })" + `) +}) + +test('address', async () => { + const result = await react().run?.({ + contracts: [ + { + name: 'erc20', + abi: erc20Abi, + content: '', + meta: { + abiName: 'erc20Abi', + addressName: 'erc20Address', + }, + }, + ], + isTypeScript: true, + outputs: [], + }) + + expect(result?.content).toMatchInlineSnapshot(` + "/** + * Wraps __{@link useReadContract}__ with \`abi\` set to __{@link erc20Abi}__ + */ + export const useReadErc20 = /*#__PURE__*/ createUseReadContract({ abi: erc20Abi, address: erc20Address }) + + /** + * Wraps __{@link useReadContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"allowance"\` + */ + export const useReadErc20Allowance = /*#__PURE__*/ createUseReadContract({ abi: erc20Abi, address: erc20Address, functionName: 'allowance' }) + + /** + * Wraps __{@link useReadContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"balanceOf"\` + */ + export const useReadErc20BalanceOf = /*#__PURE__*/ createUseReadContract({ abi: erc20Abi, address: erc20Address, functionName: 'balanceOf' }) + + /** + * Wraps __{@link useReadContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"decimals"\` + */ + export const useReadErc20Decimals = /*#__PURE__*/ createUseReadContract({ abi: erc20Abi, address: erc20Address, functionName: 'decimals' }) + + /** + * Wraps __{@link useReadContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"name"\` + */ + export const useReadErc20Name = /*#__PURE__*/ createUseReadContract({ abi: erc20Abi, address: erc20Address, functionName: 'name' }) + + /** + * Wraps __{@link useReadContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"symbol"\` + */ + export const useReadErc20Symbol = /*#__PURE__*/ createUseReadContract({ abi: erc20Abi, address: erc20Address, functionName: 'symbol' }) + + /** + * Wraps __{@link useReadContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"totalSupply"\` + */ + export const useReadErc20TotalSupply = /*#__PURE__*/ createUseReadContract({ abi: erc20Abi, address: erc20Address, functionName: 'totalSupply' }) + + /** + * Wraps __{@link useWriteContract}__ with \`abi\` set to __{@link erc20Abi}__ + */ + export const useWriteErc20 = /*#__PURE__*/ createUseWriteContract({ abi: erc20Abi, address: erc20Address }) + + /** + * Wraps __{@link useWriteContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"approve"\` + */ + export const useWriteErc20Approve = /*#__PURE__*/ createUseWriteContract({ abi: erc20Abi, address: erc20Address, functionName: 'approve' }) + + /** + * Wraps __{@link useWriteContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"transfer"\` + */ + export const useWriteErc20Transfer = /*#__PURE__*/ createUseWriteContract({ abi: erc20Abi, address: erc20Address, functionName: 'transfer' }) + + /** + * Wraps __{@link useWriteContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"transferFrom"\` + */ + export const useWriteErc20TransferFrom = /*#__PURE__*/ createUseWriteContract({ abi: erc20Abi, address: erc20Address, functionName: 'transferFrom' }) + + /** + * Wraps __{@link useSimulateContract}__ with \`abi\` set to __{@link erc20Abi}__ + */ + export const useSimulateErc20 = /*#__PURE__*/ createUseSimulateContract({ abi: erc20Abi, address: erc20Address }) + + /** + * Wraps __{@link useSimulateContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"approve"\` + */ + export const useSimulateErc20Approve = /*#__PURE__*/ createUseSimulateContract({ abi: erc20Abi, address: erc20Address, functionName: 'approve' }) + + /** + * Wraps __{@link useSimulateContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"transfer"\` + */ + export const useSimulateErc20Transfer = /*#__PURE__*/ createUseSimulateContract({ abi: erc20Abi, address: erc20Address, functionName: 'transfer' }) + + /** + * Wraps __{@link useSimulateContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"transferFrom"\` + */ + export const useSimulateErc20TransferFrom = /*#__PURE__*/ createUseSimulateContract({ abi: erc20Abi, address: erc20Address, functionName: 'transferFrom' }) + + /** + * Wraps __{@link useWatchContractEvent}__ with \`abi\` set to __{@link erc20Abi}__ + */ + export const useWatchErc20Event = /*#__PURE__*/ createUseWatchContractEvent({ abi: erc20Abi, address: erc20Address }) + + /** + * Wraps __{@link useWatchContractEvent}__ with \`abi\` set to __{@link erc20Abi}__ and \`eventName\` set to \`"Approval"\` + */ + export const useWatchErc20ApprovalEvent = /*#__PURE__*/ createUseWatchContractEvent({ abi: erc20Abi, address: erc20Address, eventName: 'Approval' }) + + /** + * Wraps __{@link useWatchContractEvent}__ with \`abi\` set to __{@link erc20Abi}__ and \`eventName\` set to \`"Transfer"\` + */ + export const useWatchErc20TransferEvent = /*#__PURE__*/ createUseWatchContractEvent({ abi: erc20Abi, address: erc20Address, eventName: 'Transfer' })" + `) +}) + +test('legacy hook names', async () => { + const result = await react({ getHookName: 'legacy' }).run?.({ + contracts: [ + { + name: 'erc20', + abi: erc20Abi, + content: '', + meta: { + abiName: 'erc20Abi', + addressName: 'erc20Address', + }, + }, + ], + isTypeScript: true, + outputs: [], + }) + + expect(result?.content).toMatchInlineSnapshot(` + "/** + * Wraps __{@link useReadContract}__ with \`abi\` set to __{@link erc20Abi}__ + */ + export const useErc20Read = /*#__PURE__*/ createUseReadContract({ abi: erc20Abi, address: erc20Address }) + + /** + * Wraps __{@link useReadContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"allowance"\` + */ + export const useErc20Allowance = /*#__PURE__*/ createUseReadContract({ abi: erc20Abi, address: erc20Address, functionName: 'allowance' }) + + /** + * Wraps __{@link useReadContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"balanceOf"\` + */ + export const useErc20BalanceOf = /*#__PURE__*/ createUseReadContract({ abi: erc20Abi, address: erc20Address, functionName: 'balanceOf' }) + + /** + * Wraps __{@link useReadContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"decimals"\` + */ + export const useErc20Decimals = /*#__PURE__*/ createUseReadContract({ abi: erc20Abi, address: erc20Address, functionName: 'decimals' }) + + /** + * Wraps __{@link useReadContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"name"\` + */ + export const useErc20Name = /*#__PURE__*/ createUseReadContract({ abi: erc20Abi, address: erc20Address, functionName: 'name' }) + + /** + * Wraps __{@link useReadContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"symbol"\` + */ + export const useErc20Symbol = /*#__PURE__*/ createUseReadContract({ abi: erc20Abi, address: erc20Address, functionName: 'symbol' }) + + /** + * Wraps __{@link useReadContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"totalSupply"\` + */ + export const useErc20TotalSupply = /*#__PURE__*/ createUseReadContract({ abi: erc20Abi, address: erc20Address, functionName: 'totalSupply' }) + + /** + * Wraps __{@link useWriteContract}__ with \`abi\` set to __{@link erc20Abi}__ + */ + export const useErc20Write = /*#__PURE__*/ createUseWriteContract({ abi: erc20Abi, address: erc20Address }) + + /** + * Wraps __{@link useWriteContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"approve"\` + */ + export const useErc20Approve = /*#__PURE__*/ createUseWriteContract({ abi: erc20Abi, address: erc20Address, functionName: 'approve' }) + + /** + * Wraps __{@link useWriteContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"transfer"\` + */ + export const useErc20Transfer = /*#__PURE__*/ createUseWriteContract({ abi: erc20Abi, address: erc20Address, functionName: 'transfer' }) + + /** + * Wraps __{@link useWriteContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"transferFrom"\` + */ + export const useErc20TransferFrom = /*#__PURE__*/ createUseWriteContract({ abi: erc20Abi, address: erc20Address, functionName: 'transferFrom' }) + + /** + * Wraps __{@link useSimulateContract}__ with \`abi\` set to __{@link erc20Abi}__ + */ + export const usePrepareErc20Write = /*#__PURE__*/ createUseSimulateContract({ abi: erc20Abi, address: erc20Address }) + + /** + * Wraps __{@link useSimulateContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"approve"\` + */ + export const usePrepareErc20Approve = /*#__PURE__*/ createUseSimulateContract({ abi: erc20Abi, address: erc20Address, functionName: 'approve' }) + + /** + * Wraps __{@link useSimulateContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"transfer"\` + */ + export const usePrepareErc20Transfer = /*#__PURE__*/ createUseSimulateContract({ abi: erc20Abi, address: erc20Address, functionName: 'transfer' }) + + /** + * Wraps __{@link useSimulateContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"transferFrom"\` + */ + export const usePrepareErc20TransferFrom = /*#__PURE__*/ createUseSimulateContract({ abi: erc20Abi, address: erc20Address, functionName: 'transferFrom' }) + + /** + * Wraps __{@link useWatchContractEvent}__ with \`abi\` set to __{@link erc20Abi}__ + */ + export const useErc20Event = /*#__PURE__*/ createUseWatchContractEvent({ abi: erc20Abi, address: erc20Address }) + + /** + * Wraps __{@link useWatchContractEvent}__ with \`abi\` set to __{@link erc20Abi}__ and \`eventName\` set to \`"Approval"\` + */ + export const useErc20ApprovalEvent = /*#__PURE__*/ createUseWatchContractEvent({ abi: erc20Abi, address: erc20Address, eventName: 'Approval' }) + + /** + * Wraps __{@link useWatchContractEvent}__ with \`abi\` set to __{@link erc20Abi}__ and \`eventName\` set to \`"Transfer"\` + */ + export const useErc20TransferEvent = /*#__PURE__*/ createUseWatchContractEvent({ abi: erc20Abi, address: erc20Address, eventName: 'Transfer' })" + `) +}) diff --git a/wagmi-project/packages/cli/src/plugins/react.ts b/wagmi-project/packages/cli/src/plugins/react.ts new file mode 100644 index 000000000..b76ea006a --- /dev/null +++ b/wagmi-project/packages/cli/src/plugins/react.ts @@ -0,0 +1,312 @@ +import { pascalCase } from 'change-case' + +import type { Contract, Plugin } from '../config.js' +import type { Compute, RequiredBy } from '../types.js' +import { getAddressDocString } from '../utils/getAddressDocString.js' + +export type ReactConfig = { + getHookName?: + | 'legacy' // TODO: Deprecate `'legacy'` option + | ((options: { + contractName: string + itemName?: string | undefined + type: 'read' | 'simulate' | 'watch' | 'write' + }) => `use${string}`) +} + +type ReactResult = Compute> + +export function react(config: ReactConfig = {}): ReactResult { + return { + name: 'React', + async run({ contracts }) { + const imports = new Set([]) + const content: string[] = [] + const pure = '/*#__PURE__*/' + + const hookNames = new Set() + for (const contract of contracts) { + let hasReadFunction = false + let hasWriteFunction = false + let hasEvent = false + const readItems = [] + const writeItems = [] + const eventItems = [] + for (const item of contract.abi) { + if (item.type === 'function') + if ( + item.stateMutability === 'view' || + item.stateMutability === 'pure' + ) { + hasReadFunction = true + readItems.push(item) + } else { + hasWriteFunction = true + writeItems.push(item) + } + else if (item.type === 'event') { + hasEvent = true + eventItems.push(item) + } + } + + let innerContent: string + if (contract.meta.addressName) + innerContent = `abi: ${contract.meta.abiName}, address: ${contract.meta.addressName}` + else innerContent = `abi: ${contract.meta.abiName}` + + if (hasReadFunction) { + const hookName = getHookName(config, hookNames, 'read', contract.name) + const docString = genDocString('useReadContract', contract) + const functionName = 'createUseReadContract' + imports.add(functionName) + content.push( + `${docString} +export const ${hookName} = ${pure} ${functionName}({ ${innerContent} })`, + ) + + const names = new Set() + for (const item of readItems) { + if (item.type !== 'function') continue + if ( + item.stateMutability !== 'pure' && + item.stateMutability !== 'view' + ) + continue + + // Skip overrides since they are captured by same hook + if (names.has(item.name)) continue + names.add(item.name) + + const hookName = getHookName( + config, + hookNames, + 'read', + contract.name, + item.name, + ) + const docString = genDocString('useReadContract', contract, { + name: 'functionName', + value: item.name, + }) + content.push( + `${docString} +export const ${hookName} = ${pure} ${functionName}({ ${innerContent}, functionName: '${item.name}' })`, + ) + } + } + + if (hasWriteFunction) { + { + const hookName = getHookName( + config, + hookNames, + 'write', + contract.name, + ) + const docString = genDocString('useWriteContract', contract) + const functionName = 'createUseWriteContract' + imports.add(functionName) + content.push( + `${docString} +export const ${hookName} = ${pure} ${functionName}({ ${innerContent} })`, + ) + + const names = new Set() + for (const item of writeItems) { + if (item.type !== 'function') continue + if ( + item.stateMutability !== 'nonpayable' && + item.stateMutability !== 'payable' + ) + continue + + // Skip overrides since they are captured by same hook + if (names.has(item.name)) continue + names.add(item.name) + + const hookName = getHookName( + config, + hookNames, + 'write', + contract.name, + item.name, + ) + const docString = genDocString('useWriteContract', contract, { + name: 'functionName', + value: item.name, + }) + content.push( + `${docString} +export const ${hookName} = ${pure} ${functionName}({ ${innerContent}, functionName: '${item.name}' })`, + ) + } + } + + { + const hookName = getHookName( + config, + hookNames, + 'simulate', + contract.name, + ) + const docString = genDocString('useSimulateContract', contract) + const functionName = 'createUseSimulateContract' + imports.add(functionName) + content.push( + `${docString} +export const ${hookName} = ${pure} ${functionName}({ ${innerContent} })`, + ) + + const names = new Set() + for (const item of writeItems) { + if (item.type !== 'function') continue + if ( + item.stateMutability !== 'nonpayable' && + item.stateMutability !== 'payable' + ) + continue + + // Skip overrides since they are captured by same hook + if (names.has(item.name)) continue + names.add(item.name) + + const hookName = getHookName( + config, + hookNames, + 'simulate', + contract.name, + item.name, + ) + const docString = genDocString('useSimulateContract', contract, { + name: 'functionName', + value: item.name, + }) + content.push( + `${docString} +export const ${hookName} = ${pure} ${functionName}({ ${innerContent}, functionName: '${item.name}' })`, + ) + } + } + } + + if (hasEvent) { + const hookName = getHookName( + config, + hookNames, + 'watch', + contract.name, + ) + const docString = genDocString('useWatchContractEvent', contract) + const functionName = 'createUseWatchContractEvent' + imports.add(functionName) + content.push( + `${docString} +export const ${hookName} = ${pure} ${functionName}({ ${innerContent} })`, + ) + + const names = new Set() + for (const item of eventItems) { + if (item.type !== 'event') continue + + // Skip overrides since they are captured by same hook + if (names.has(item.name)) continue + names.add(item.name) + + const hookName = getHookName( + config, + hookNames, + 'watch', + contract.name, + item.name, + ) + const docString = genDocString('useWatchContractEvent', contract, { + name: 'eventName', + value: item.name, + }) + content.push( + `${docString} +export const ${hookName} = ${pure} ${functionName}({ ${innerContent}, eventName: '${item.name}' })`, + ) + } + } + } + + const importValues = [...imports.values()] + + return { + imports: importValues.length + ? `import { ${importValues.join(', ')} } from 'wagmi/codegen'\n` + : '', + content: content.join('\n\n'), + } + }, + } +} + +function genDocString( + hookName: string, + contract: Contract, + item?: { name: string; value: string }, +) { + let description = `Wraps __{@link ${hookName}}__ with \`abi\` set to __{@link ${contract.meta.abiName}}__` + if (item) description += ` and \`${item.name}\` set to \`"${item.value}"\`` + + const docString = getAddressDocString({ address: contract.address }) + if (docString) + return `/** + * ${description} + * + ${docString} + */` + + return `/** + * ${description} + */` +} + +function getHookName( + config: ReactConfig, + hookNames: Set, + type: 'read' | 'simulate' | 'watch' | 'write', + contractName: string, + itemName?: string | undefined, +) { + const ContractName = pascalCase(contractName) + const ItemName = itemName ? pascalCase(itemName) : undefined + + let hookName: string + if (typeof config.getHookName === 'function') + hookName = config.getHookName({ + type, + contractName: ContractName, + itemName: ItemName, + }) + else if (typeof config.getHookName === 'string') { + switch (type) { + case 'read': + hookName = `use${ContractName}${ItemName ?? 'Read'}` + break + case 'simulate': + hookName = `usePrepare${ContractName}${ItemName ?? 'Write'}` + break + case 'watch': + hookName = `use${ContractName}${ItemName ?? ''}Event` + break + case 'write': + hookName = `use${ContractName}${ItemName ?? 'Write'}` + break + } + } else { + hookName = `use${pascalCase(type)}${ContractName}${ItemName ?? ''}` + if (type === 'watch') hookName = `${hookName}Event` + } + + if (hookNames.has(hookName)) + throw new Error( + `Hook name "${hookName}" must be unique for contract "${contractName}". Try using \`getHookName\` to create a unique name.`, + ) + + hookNames.add(hookName) + return hookName +} diff --git a/wagmi-project/packages/cli/src/plugins/sourcify.test.ts b/wagmi-project/packages/cli/src/plugins/sourcify.test.ts new file mode 100644 index 000000000..842a29114 --- /dev/null +++ b/wagmi-project/packages/cli/src/plugins/sourcify.test.ts @@ -0,0 +1,83 @@ +import { http, HttpResponse } from 'msw' +import { setupServer } from 'msw/node' +import { afterAll, afterEach, beforeAll, expect, test } from 'vitest' + +import { depositAbi } from '../../test/constants.js' +import { sourcify } from './sourcify.js' + +const baseUrl = 'https://sourcify.dev/server/v2/contract' +const address = '0x00000000219ab540356cbb839cbe05303d7705fa' +const chainId = 1 +const multichainAddress = '0xC4c622862a8F548997699bE24EA4bc504e5cA865' +const multichainIdGnosis = 100 +const multichainIdPolygon = 137 +const successJson = { + abi: depositAbi, +} + +const handlers = [ + http.get(`${baseUrl}/${chainId}/${address}`, () => + HttpResponse.json(successJson), + ), + http.get(`${baseUrl}/${multichainIdGnosis}/${address}`, () => + HttpResponse.json({}, { status: 404 }), + ), + http.get(`${baseUrl}/${multichainIdGnosis}/${multichainAddress}`, () => + HttpResponse.json(successJson), + ), + http.get(`${baseUrl}/${multichainIdPolygon}/${multichainAddress}`, () => + HttpResponse.json(successJson), + ), +] + +const server = setupServer(...handlers) + +beforeAll(() => server.listen()) +afterEach(() => server.resetHandlers()) +afterAll(() => server.close()) + +test('fetches ABI', () => { + expect( + sourcify({ + chainId: chainId, + contracts: [{ name: 'DepositContract', address }], + }).contracts?.(), + ).resolves.toMatchSnapshot() +}) + +test('fetches ABI with multichain deployment', () => { + expect( + sourcify({ + chainId: 100, + contracts: [ + { + name: 'Community', + address: { 100: multichainAddress, 137: multichainAddress }, + }, + ], + }).contracts?.(), + ).resolves.toMatchSnapshot() +}) + +test('fails to fetch for unverified contract', () => { + expect( + sourcify({ + chainId: 100, + contracts: [{ name: 'DepositContract', address }], + }).contracts?.(), + ).rejects.toThrowErrorMatchingInlineSnapshot( + '[Error: Contract not found in Sourcify repository.]', + ) +}) + +test('missing address for chainId', () => { + expect( + sourcify({ + chainId: 1, + // @ts-expect-error `chainId` and `keyof typeof contracts[number].address` mismatch + contracts: [{ name: 'DepositContract', address: { 10: address } }], + }).contracts?.(), + ).rejects.toThrowErrorMatchingInlineSnapshot( + `[Error: No address found for chainId "1". Make sure chainId "1" is set as an address.]`, + ) +}) diff --git a/wagmi-project/packages/cli/src/plugins/sourcify.ts b/wagmi-project/packages/cli/src/plugins/sourcify.ts new file mode 100644 index 000000000..0d452046c --- /dev/null +++ b/wagmi-project/packages/cli/src/plugins/sourcify.ts @@ -0,0 +1,312 @@ +import { Abi as AbiSchema } from 'abitype/zod' +import type { Address } from 'viem' +import { z } from 'zod' + +import type { ContractConfig } from '../config.js' +import { fromZodError } from '../errors.js' +import type { Compute } from '../types.js' +import { fetch } from './fetch.js' + +export type SourcifyConfig = { + /** + * Duration in milliseconds to cache ABIs. + * + * @default 1_800_000 // 30m in ms + */ + cacheDuration?: number | undefined + /** + * Chain id to use for fetching ABI. + * + * If `address` is an object, `chainId` is used to select the address. + * + * See https://docs.sourcify.dev/docs/chains for supported chains. + */ + chainId: (chainId extends ChainId ? chainId : never) | (ChainId & {}) + /** + * Contracts to fetch ABIs for. + */ + contracts: Compute, 'abi'>>[] +} + +const SourcifyResponse = z.object({ + abi: AbiSchema, +}) + +/** Fetches contract ABIs from Sourcify. */ +export function sourcify( + config: SourcifyConfig, +) { + const { cacheDuration, chainId, contracts: contracts_ } = config + + const contracts = contracts_.map((x) => ({ + ...x, + address: + typeof x.address === 'string' ? { [chainId]: x.address } : x.address, + })) as Omit[] + + return fetch({ + cacheDuration, + contracts, + async parse({ response }) { + if (response.status === 404) + throw new Error('Contract not found in Sourcify repository.') + + const json = await response.json() + const parsed = await SourcifyResponse.safeParseAsync(json) + if (!parsed.success) + throw fromZodError(parsed.error, { prefix: 'Invalid response' }) + + if (parsed.data.abi) return parsed.data.abi as ContractConfig['abi'] + throw new Error('contract not found') + }, + request({ address }) { + if (!address) throw new Error('address is required') + + let contractAddress: Address | undefined + if (typeof address === 'string') contractAddress = address + else if (typeof address === 'object') contractAddress = address[chainId] + + if (!contractAddress) + throw new Error( + `No address found for chainId "${chainId}". Make sure chainId "${chainId}" is set as an address.`, + ) + return { + url: `https://sourcify.dev/server/v2/contract/${chainId}/${contractAddress}?fields=abi`, + } + }, + }) +} + +// Supported chains +// https://docs.sourcify.dev/docs/chains +type ChainId = + | 1 // Ethereum Mainnet + | 17000 // Ethereum Testnet Holesky + | 5 // Ethereum Testnet Goerli + | 11155111 // Ethereum Testnet Sepolia + | 3 // Ethereum Testnet Ropsten + | 4 // Ethereum Testnet Rinkeby + | 10 // OP Mainnet + | 100 // Gnosis + | 100009 // VeChain + | 100010 // VeChain Testnet + | 1001 // Kaia Kairos Testnet + | 10200 // Gnosis Chiado Testnet + | 10242 // Arthera Mainnet + | 10243 // Arthera Testnet + | 1030 // Conflux eSpace + | 103090 // Crystaleum + | 105105 // Stratis Mainnet + | 106 // Velas EVM Mainnet + | 10849 // Lamina1 + | 10850 // Lamina1 Identity + | 1088 // Metis Andromeda Mainnet + | 1101 // Polygon zkEVM + | 111000 // Siberium Test Network + | 11111 // WAGMI + | 1114 // Core Blockchain Testnet2 + | 1115 // Core Blockchain Testnet + | 11155420 // OP Sepolia Testnet + | 1116 // Core Blockchain Mainnet + | 11235 // Haqq Network + | 1127469 // Tiltyard Subnet + | 11297108099 // Palm Testnet + | 11297108109 // Palm + | 1149 // Symplexia Smart Chain + | 122 // Fuse Mainnet + | 1284 // Moonbeam + | 1285 // Moonriver + | 1287 // Moonbase Alpha + | 12898 // PlayFair Testnet Subnet + | 1291 // Swisstronik Testnet + | 1313161554 // Aurora Mainnet + | 1313161555 // Aurora Testnet + | 13337 // Beam Testnet + | 13381 // Phoenix Mainnet + | 1339 // Elysium Mainnet + | 137 // Polygon Mainnet + | 14 // Flare Mainnet + | 1433 // Rikeza Network Mainnet + | 1516 // Story Odyssey Testnet + | 16180 // PLYR PHI + | 16350 // Incentiv Devnet + | 167005 // Taiko Grimsvotn L2 + | 167006 // Taiko Eldfell L3 + | 17069 // Garnet Holesky + | 180 // AME Chain Mainnet + | 1890 // Lightlink Phoenix Mainnet + | 1891 // Lightlink Pegasus Testnet + | 19 // Songbird Canary-Network + | 19011 // HOME Verse Mainnet + | 192837465 // Gather Mainnet Network + | 2000 // Dogechain Mainnet + | 200810 // Bitlayer Testnet + | 200901 // Bitlayer Mainnet + | 2017 // Adiri + | 2020 // Ronin Mainnet + | 2021 // Edgeware EdgeEVM Mainnet + | 202401 // YMTECH-BESU Testnet + | 2037 // Kiwi Subnet + | 2038 // Shrapnel Testnet + | 2044 // Shrapnel Subnet + | 2047 // Stratos Testnet + | 2048 // Stratos + | 205205 // Auroria Testnet + | 212 // MAPO Makalu + | 216 // Happychain Testnet + | 222000222 // Kanazawa + | 2221 // Kava Testnet + | 2222 // Kava + | 223 // B2 Mainnet + | 22776 // MAP Protocol + | 23294 // Oasis Sapphire + | 23295 // Oasis Sapphire Testnet + | 2358 // Kroma Sepolia + | 2442 // Polygon zkEVM Cardona Testnet + | 246 // Energy Web Chain + | 25 // Cronos Mainnet + | 250 // Fantom Opera + | 252 // Fraxtal + | 2522 // Fraxtal Testnet + | 255 // Kroma + | 25925 // KUB Testnet + | 26100 // Ferrum Quantum Portal Network + | 28 // Boba Network Rinkeby Testnet + | 28528 // Optimism Bedrock (Goerli Alpha Testnet) + | 288 // Boba Network + | 295 // Hedera Mainnet + | 30 // Rootstock Mainnet + | 300 // zkSync Sepolia Testnet + | 311752642 // OneLedger Mainnet + | 314 // Filecoin - Mainnet + | 314159 // Filecoin - Calibration testnet + | 32769 // Zilliqa EVM + | 32770 // Zilliqa 2 EVM proto-mainnet + | 33101 // Zilliqa EVM Testnet + | 33103 // Zilliqa 2 EVM proto-testnet + | 33111 // Curtis + | 333000333 // Meld + | 335 // DFK Chain Test + | 336 // Shiden + | 34443 // Mode + | 35441 // Q Mainnet + | 35443 // Q Testnet + | 356256156 // Gather Testnet Network + | 369 // PulseChain + | 3737 // Crossbell + | 37714555429 // Xai Testnet v2 + | 383414847825 // Zeniq + | 39797 // Energi Mainnet + | 40 // Telos EVM Mainnet + | 4000 // Ozone Chain Mainnet + | 41 // Telos EVM Testnet + | 4157 // CrossFi Testnet + | 420 // Optimism Goerli Testnet + | 4200 // Merlin Mainnet + | 420420 // Kekchain + | 420666 // Kekchain (kektest) + | 42161 // Arbitrum One + | 421611 // Arbitrum Rinkeby + | 421613 // Arbitrum Goerli + | 4216137055 // OneLedger Testnet Frankenstein + | 421614 // Arbitrum Sepolia + | 42170 // Arbitrum Nova + | 42220 // Celo Mainnet + | 42261 // Oasis Emerald Testnet + | 42262 // Oasis Emerald + | 42766 // ZKFair Mainnet + | 43 // Darwinia Pangolin Testnet + | 43113 // Avalanche Fuji Testnet + | 43114 // Avalanche C-Chain + | 432201 // Dexalot Subnet Testnet + | 432204 // Dexalot Subnet + | 4337 // Beam + | 44 // Crab Network + | 44787 // Celo Alfajores Testnet + | 46 // Darwinia Network + | 486217935 // Gather Devnet Network + | 48898 // Zircuit Garfield Testnet + | 48899 // Zircuit Testnet + | 48900 // Zircuit Mainnet + | 49797 // Energi Testnet + | 50 // XDC Network + | 5000 // Mantle + | 5003 // Mantle Sepolia Testnet + | 51 // XDC Apothem Network + | 5115 // Citrea Testnet + | 534 // Candle + | 534351 // Scroll Sepolia Testnet + | 534352 // Scroll + | 53935 // DFK Chain + | 54211 // Haqq Chain Testnet + | 56 // BNB Smart Chain Mainnet + | 560048 // Hoodi testnet + | 57 // Syscoin Mainnet + | 570 // Rollux Mainnet + | 5700 // Syscoin Tanenbaum Testnet + | 57000 // Rollux Testnet + | 5845 // Tangle + | 59141 // Linea Sepolia + | 59144 // Linea + | 592 // Astar + | 59902 // Metis Sepolia Testnet + | 61 // Ethereum Classic + | 6119 // UPTN + | 62320 // Celo Baklava Testnet + | 62621 // MultiVAC Mainnet + | 62831 // PLYR TAU Testnet + | 6321 // Aura Euphoria Testnet + | 6322 // Aura Mainnet + | 641230 // Bear Network Chain Mainnet + | 648 // Endurance Smart Chain Mainnet + | 660279 // Xai Mainnet + | 666666666 // Degen Chain + | 69 // Optimism Kovan + | 690 // Redstone + | 7000 // ZetaChain Mainnet + | 7001 // ZetaChain Testnet + | 7078815900 // Mekong + | 710420 // Tiltyard Mainnet Subnet + | 71401 // Godwoken Testnet v1 + | 71402 // Godwoken Mainnet + | 7171 // Bitrock Mainnet + | 7200 // exSat Mainnet + | 723107 // TixChain Testnet + | 73799 // Energy Web Volta Testnet + | 764984 // Lamina1 Testnet + | 7668 // The Root Network - Mainnet + | 7672 // The Root Network - Porcini Testnet + | 767368 // Lamina1 Identity Testnet + | 77 // POA Network Sokol + | 7700 // Canto + | 7701 // Canto Tesnet + | 7771 // Bitrock Testnet + | 7777777 // Zora + | 78430 // Amplify Subnet + | 78431 // Bulletin Subnet + | 78432 // Conduit Subnet + | 8 // Ubiq + | 80001 // Mumbai + | 80002 // Amoy + | 82 // Meter Mainnet + | 8217 // Kaia Mainnet + | 83 // Meter Testnet + | 839999 // exSat Testnet + | 841 // Taraxa Mainnet + | 842 // Taraxa Testnet + | 8453 // Base + | 84531 // Base Goerli Testnet + | 84532 // Base Sepolia Testnet + | 888 // Wanchain + | 9000 // Evmos Testnet + | 9001 // Evmos + | 919 // Mode Testnet + | 957 // Lyra Chain + | 96 // KUB Mainnet + | 97 // BNB Smart Chain Testnet + | 970 // Oort Mainnet + | 99 // POA Network Core + | 9977 // Mind Smart Chain Testnet + | 999 // Wanchain Testnet + | 9996 // Mind Smart Chain Mainnet + | 999999999 // Zora Sepolia Testnet diff --git a/wagmi-project/packages/cli/src/types.ts b/wagmi-project/packages/cli/src/types.ts new file mode 100644 index 000000000..adb288934 --- /dev/null +++ b/wagmi-project/packages/cli/src/types.ts @@ -0,0 +1,10 @@ +export type Compute = { [key in keyof type]: type[key] } & unknown + +export type MaybeArray = T | T[] + +export type MaybePromise = T | Promise + +export type RequiredBy = Required< + Pick +> & + Omit diff --git a/wagmi-project/packages/cli/src/utils/findConfig.test.ts b/wagmi-project/packages/cli/src/utils/findConfig.test.ts new file mode 100644 index 000000000..52c206677 --- /dev/null +++ b/wagmi-project/packages/cli/src/utils/findConfig.test.ts @@ -0,0 +1,42 @@ +import { afterEach, expect, test, vi } from 'vitest' + +import { createFixture } from '../../test/utils.js' +import { findConfig } from './findConfig.js' + +afterEach(() => { + vi.restoreAllMocks() +}) + +test('finds config file', async () => { + const { dir, paths } = await createFixture({ + files: { 'wagmi.config.ts': '' }, + }) + const spy = vi.spyOn(process, 'cwd') + spy.mockImplementation(() => dir) + + await expect(findConfig()).resolves.toBe(paths['wagmi.config.ts']) +}) + +test('finds config file at location', async () => { + const { dir, paths } = await createFixture({ + files: { 'wagmi.config.ts': '' }, + }) + const spy = vi.spyOn(process, 'cwd') + spy.mockImplementation(() => dir) + + await expect(findConfig({ config: paths['wagmi.config.ts'] })).resolves.toBe( + paths['wagmi.config.ts'], + ) +}) + +test('finds config file at root', async () => { + const { dir, paths } = await createFixture({ + files: { 'wagmi.config.ts': '' }, + }) + const spy = vi.spyOn(process, 'cwd') + spy.mockImplementation(() => dir) + + await expect(findConfig({ root: dir })).resolves.toBe( + paths['wagmi.config.ts'], + ) +}) diff --git a/wagmi-project/packages/cli/src/utils/findConfig.ts b/wagmi-project/packages/cli/src/utils/findConfig.ts new file mode 100644 index 000000000..2e94e2d5a --- /dev/null +++ b/wagmi-project/packages/cli/src/utils/findConfig.ts @@ -0,0 +1,39 @@ +import { existsSync } from 'node:fs' +import escalade from 'escalade' +import { resolve } from 'pathe' + +// Do not reorder +// In order of preference files are checked +const configFiles = [ + 'wagmi.config.ts', + 'wagmi.config.js', + 'wagmi.config.mjs', + 'wagmi.config.mts', +] + +type FindConfigParameters = { + /** Config file name */ + config?: string | undefined + /** Config file directory */ + root?: string | undefined +} + +/** + * Resolves path to wagmi CLI config file. + */ +export async function findConfig(parameters: FindConfigParameters = {}) { + const { config, root } = parameters + const rootDir = resolve(root || process.cwd()) + if (config) { + const path = resolve(rootDir, config) + if (existsSync(path)) return path + return + } + const configPath = await escalade(rootDir, (_dir, names) => { + for (const name of names) { + if (configFiles.includes(name)) return name + } + return undefined + }) + return configPath +} diff --git a/wagmi-project/packages/cli/src/utils/format.test.ts b/wagmi-project/packages/cli/src/utils/format.test.ts new file mode 100644 index 000000000..6d04eb546 --- /dev/null +++ b/wagmi-project/packages/cli/src/utils/format.test.ts @@ -0,0 +1,12 @@ +import { expect, test } from 'vitest' + +import { format } from './format.js' + +test('formats code', async () => { + await expect( + format(`const foo = "bar"`), + ).resolves.toMatchInlineSnapshot(` + "const foo = 'bar' + " + `) +}) diff --git a/wagmi-project/packages/cli/src/utils/format.ts b/wagmi-project/packages/cli/src/utils/format.ts new file mode 100644 index 000000000..d440e6047 --- /dev/null +++ b/wagmi-project/packages/cli/src/utils/format.ts @@ -0,0 +1,17 @@ +import prettier from 'prettier' + +export async function format(content: string) { + const config = await prettier.resolveConfig(process.cwd()) + return prettier.format(content, { + arrowParens: 'always', + endOfLine: 'lf', + parser: 'typescript', + printWidth: 80, + semi: false, + singleQuote: true, + tabWidth: 2, + trailingComma: 'all', + ...config, + plugins: [], + }) +} diff --git a/wagmi-project/packages/cli/src/utils/getAddressDocString.test.ts b/wagmi-project/packages/cli/src/utils/getAddressDocString.test.ts new file mode 100644 index 000000000..798e6e14e --- /dev/null +++ b/wagmi-project/packages/cli/src/utils/getAddressDocString.test.ts @@ -0,0 +1,40 @@ +import { expect, test } from 'vitest' + +import { getAddressDocString } from './getAddressDocString.js' + +test('address', async () => { + expect( + getAddressDocString({ + address: '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e', + }), + ).toMatchInlineSnapshot('""') +}) + +test('multichain address with known chain ids', async () => { + expect( + getAddressDocString({ + address: { + 1: '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e', + 5: '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e', + 10: '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e', + }, + }), + ).toMatchInlineSnapshot(` + "* - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e) + * - [__View Contract on Goerli Etherscan__](https://goerli.etherscan.io/address/0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e) + * - [__View Contract on Op Mainnet Optimism Explorer__](https://optimistic.etherscan.io/address/0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e)" + `) +}) + +test('multichain address with unknown chain id', async () => { + expect( + getAddressDocString({ + address: { + 1: '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e', + 2: '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e', + }, + }), + ).toMatchInlineSnapshot( + '"* [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e)"', + ) +}) diff --git a/wagmi-project/packages/cli/src/utils/getAddressDocString.ts b/wagmi-project/packages/cli/src/utils/getAddressDocString.ts new file mode 100644 index 000000000..d0e137928 --- /dev/null +++ b/wagmi-project/packages/cli/src/utils/getAddressDocString.ts @@ -0,0 +1,53 @@ +import { capitalCase } from 'change-case' +import dedent from 'dedent' +import * as allChains from 'viem/chains' + +import type { Contract } from '../config.js' + +const chainMap: Record = {} +for (const chain of Object.values(allChains)) { + if (typeof chain !== 'object') continue + if (!('id' in chain)) continue + chainMap[chain.id] = chain +} + +export function getAddressDocString(parameters: { + address: Contract['address'] +}) { + const { address } = parameters + if (!address || typeof address === 'string') return '' + + if (Object.keys(address).length === 1) + return `* ${getLink({ + address: address[Number.parseInt(Object.keys(address)[0]!)]!, + chainId: Number.parseInt(Object.keys(address)[0]!), + })}` + + const addresses = Object.entries(address).filter( + (x) => chainMap[Number.parseInt(x[0])], + ) + if (addresses.length === 0) return '' + if (addresses.length === 1 && addresses[0]) + return `* ${getLink({ + address: addresses[0][1], + chainId: Number.parseInt(addresses[0][0])!, + })}` + + return dedent` + ${addresses.reduce((prev, curr) => { + const chainId = Number.parseInt(curr[0]) + const address = curr[1] + return `${prev}\n* - ${getLink({ address, chainId })}` + }, '')} + ` +} + +function getLink({ address, chainId }: { address: string; chainId: number }) { + const chain = chainMap[chainId] + if (!chain) return '' + const blockExplorer = chain.blockExplorers?.default + if (!blockExplorer) return '' + return `[__View Contract on ${capitalCase(chain.name)} ${capitalCase( + blockExplorer.name, + )}__](${blockExplorer.url}/address/${address})` +} diff --git a/wagmi-project/packages/cli/src/utils/getIsUsingTypeScript.test.ts b/wagmi-project/packages/cli/src/utils/getIsUsingTypeScript.test.ts new file mode 100644 index 000000000..3ba7c86a6 --- /dev/null +++ b/wagmi-project/packages/cli/src/utils/getIsUsingTypeScript.test.ts @@ -0,0 +1,43 @@ +import { afterEach, expect, test, vi } from 'vitest' + +import { createFixture } from '../../test/utils.js' +import { getIsUsingTypeScript } from './getIsUsingTypeScript.js' + +afterEach(() => { + vi.restoreAllMocks() +}) + +test('true if has tsconfig', async () => { + const { dir } = await createFixture({ + files: { + 'tsconfig.json': '', + }, + }) + + const spy = vi.spyOn(process, 'cwd') + spy.mockImplementation(() => dir) + + await expect(getIsUsingTypeScript()).resolves.toBe(true) +}) + +test('true if has wagmi.config', async () => { + const { dir } = await createFixture({ + files: { + 'wagmi.config.ts': '', + }, + }) + + const spy = vi.spyOn(process, 'cwd') + spy.mockImplementation(() => dir) + + await expect(getIsUsingTypeScript()).resolves.toBe(true) +}) + +test('false', async () => { + const { dir } = await createFixture() + + const spy = vi.spyOn(process, 'cwd') + spy.mockImplementation(() => dir) + + await expect(getIsUsingTypeScript()).resolves.toBe(false) +}) diff --git a/wagmi-project/packages/cli/src/utils/getIsUsingTypeScript.ts b/wagmi-project/packages/cli/src/utils/getIsUsingTypeScript.ts new file mode 100644 index 000000000..bd2383b0e --- /dev/null +++ b/wagmi-project/packages/cli/src/utils/getIsUsingTypeScript.ts @@ -0,0 +1,33 @@ +import escalade from 'escalade' + +export async function getIsUsingTypeScript() { + try { + const cwd = process.cwd() + const tsconfig = await escalade(cwd, (_dir, names) => { + const files = [ + 'tsconfig.json', + 'tsconfig.base.json', + 'tsconfig.lib.json', + 'tsconfig.node.json', + ] + for (const name of names) { + if (files.includes(name)) return name + } + return undefined + }) + if (tsconfig) return true + + const wagmiConfig = await escalade(cwd, (_dir, names) => { + const files = ['wagmi.config.ts', 'wagmi.config.mts'] + for (const name of names) { + if (files.includes(name)) return name + } + return undefined + }) + if (wagmiConfig) return true + + return false + } catch { + return false + } +} diff --git a/wagmi-project/packages/cli/src/utils/loadEnv.test.ts b/wagmi-project/packages/cli/src/utils/loadEnv.test.ts new file mode 100644 index 000000000..d577778eb --- /dev/null +++ b/wagmi-project/packages/cli/src/utils/loadEnv.test.ts @@ -0,0 +1,77 @@ +import { afterEach, expect, test, vi } from 'vitest' + +import { createFixture } from '../../test/utils.js' +import { loadEnv } from './loadEnv.js' + +afterEach(() => { + vi.restoreAllMocks() +}) + +test('loads env', async () => { + const { dir } = await createFixture({ + files: { + '.env': ` + FOO=bar + SOME_ENV_VAR=1 + `, + }, + }) + const spy = vi.spyOn(process, 'cwd') + spy.mockImplementation(() => dir) + + expect(loadEnv()).toMatchInlineSnapshot(` + { + "FOO": "bar", + "SOME_ENV_VAR": "1", + } + `) +}) + +test('loads env from envDir', async () => { + const { dir } = await createFixture({ + files: { + '.env': ` + FOO=bar + SOME_ENV_VAR=1 + `, + }, + }) + const spy = vi.spyOn(process, 'cwd') + spy.mockImplementation(() => dir) + + expect(loadEnv({ envDir: dir })).toMatchInlineSnapshot(` + { + "FOO": "bar", + "SOME_ENV_VAR": "1", + } + `) +}) + +test('loads env with mode', async () => { + const mode = 'dev' + const { dir } = await createFixture({ + files: { + [`.env.${mode}`]: ` + FOO=bar + SOME_ENV_VAR=1 + `, + }, + }) + const spy = vi.spyOn(process, 'cwd') + spy.mockImplementation(() => dir) + + expect(loadEnv({ mode })).toMatchInlineSnapshot(` + { + "FOO": "bar", + "SOME_ENV_VAR": "1", + } + `) +}) + +test('throws error when mode is "local"', async () => { + expect(() => { + loadEnv({ mode: 'local' }) + }).toThrowErrorMatchingInlineSnapshot( + `[Error: "local" cannot be used as a mode name because it conflicts with the .local postfix for .env files.]`, + ) +}) diff --git a/wagmi-project/packages/cli/src/utils/loadEnv.ts b/wagmi-project/packages/cli/src/utils/loadEnv.ts new file mode 100644 index 000000000..d7ffa9991 --- /dev/null +++ b/wagmi-project/packages/cli/src/utils/loadEnv.ts @@ -0,0 +1,90 @@ +import { parse } from 'dotenv' +import { expand } from 'dotenv-expand' + +import { existsSync, readFileSync, statSync } from 'node:fs' +import { dirname, join } from 'node:path' + +// https://github.com/vitejs/vite/blob/main/packages/vite/src/node/env.ts#L7 +export function loadEnv( + config: { + mode?: string + envDir?: string + } = {}, +): Record { + const mode = config.mode + if (mode === 'local') { + throw new Error( + `"local" cannot be used as a mode name because it conflicts with the .local postfix for .env files.`, + ) + } + + const envFiles = [ + /** default file */ '.env', + /** local file */ '.env.local', + ...(mode + ? [ + /** mode file */ `.env.${mode}`, + /** mode local file */ `.env.${mode}.local`, + ] + : []), + ] + + const envDir = config.envDir ?? process.cwd() + const parsed = Object.fromEntries( + envFiles.flatMap((file) => { + const path = lookupFile(envDir, [file], { + pathOnly: true, + rootDir: envDir, + }) + if (!path) return [] + return Object.entries(parse(readFileSync(path))) + }), + ) + + try { + // let environment variables use each other + expand({ parsed }) + } catch (error) { + // custom error handling until https://github.com/motdotla/dotenv-expand/issues/65 is fixed upstream + // check for message "TypeError: Cannot read properties of undefined (reading 'split')" + if ((error as Error).message.includes('split')) { + throw new Error( + 'dotenv-expand failed to expand env vars. Maybe you need to escape `$`?', + ) + } + throw error + } + + return parsed +} + +function lookupFile( + dir: string, + formats: string[], + options?: { + pathOnly?: boolean + rootDir?: string + predicate?: (file: string) => boolean + }, +): string | undefined { + for (const format of formats) { + const fullPath = join(dir, format) + if (existsSync(fullPath) && statSync(fullPath).isFile()) { + const result = options?.pathOnly + ? fullPath + : readFileSync(fullPath, 'utf-8') + if (!options?.predicate || options.predicate(result)) { + return result + } + } + } + + const parentDir = dirname(dir) + if ( + parentDir !== dir && + (!options?.rootDir || parentDir.startsWith(options?.rootDir)) + ) + return lookupFile(parentDir, formats, options) + + return undefined +} diff --git a/wagmi-project/packages/cli/src/utils/packages.test.ts b/wagmi-project/packages/cli/src/utils/packages.test.ts new file mode 100644 index 000000000..96ea2e26e --- /dev/null +++ b/wagmi-project/packages/cli/src/utils/packages.test.ts @@ -0,0 +1,19 @@ +import { expect, test } from 'vitest' + +import { getIsPackageInstalled, getPackageManager } from './packages.js' + +test('getIsPackageInstalled: true', async () => { + await expect(getIsPackageInstalled({ packageName: 'vitest' })).resolves.toBe( + true, + ) +}) + +test('getIsPackageInstalled: false', async () => { + await expect( + getIsPackageInstalled({ packageName: 'vitest-unknown' }), + ).resolves.toBe(false) +}) + +test('getPackageManager', async () => { + await expect(getPackageManager()).resolves.toMatchInlineSnapshot('"pnpm"') +}) diff --git a/wagmi-project/packages/cli/src/utils/packages.ts b/wagmi-project/packages/cli/src/utils/packages.ts new file mode 100644 index 000000000..e55eeaf0e --- /dev/null +++ b/wagmi-project/packages/cli/src/utils/packages.ts @@ -0,0 +1,124 @@ +import { execSync } from 'node:child_process' +import { promises as fs } from 'node:fs' +import { resolve } from 'node:path' + +export async function getIsPackageInstalled(parameters: { + packageName: string + cwd?: string +}) { + const { packageName, cwd = process.cwd() } = parameters + try { + const packageManager = await getPackageManager() + const command = (() => { + switch (packageManager) { + case 'yarn': + return ['why', packageName] + case 'bun': + return ['pm', 'ls', '--all'] + default: + return ['ls', packageName] + } + })() + + const result = execSync(`${packageManager} ${command.join(' ')}`, { + cwd, + encoding: 'utf-8', + stdio: 'pipe', + }) + + // For Bun, we need to check if the package name is in the output + if (packageManager === 'bun') return result.includes(packageName) + + return result !== '' + } catch (_error) { + return false + } +} + +export async function getPackageManager(executable?: boolean | undefined) { + const userAgent = process.env.npm_config_user_agent + if (userAgent) { + if (userAgent.includes('pnpm')) return 'pnpm' + // The yarn@^3 user agent includes npm, so yarn must be checked first. + if (userAgent.includes('yarn')) return 'yarn' + if (userAgent.includes('npm')) return executable ? 'npx' : 'npm' + if (userAgent.includes('bun')) return executable ? 'bunx' : 'bun' + } + + const packageManager = await detect() + if (packageManager === 'npm' && executable) return 'npx' + return packageManager +} + +type PackageManager = 'npm' | 'yarn' | 'pnpm' | 'bun' + +async function detect( + parameters: { cwd?: string; includeGlobalBun?: boolean } = {}, +) { + const { cwd, includeGlobalBun } = parameters + const type = await getTypeofLockFile(cwd) + if (type) { + return type + } + const [hasYarn, hasPnpm, hasBun] = await Promise.all([ + hasGlobalInstallation('yarn'), + hasGlobalInstallation('pnpm'), + includeGlobalBun && hasGlobalInstallation('bun'), + ]) + if (hasYarn) return 'yarn' + if (hasPnpm) return 'pnpm' + if (hasBun) return 'bun' + return 'npm' +} + +const cache = new Map() + +function hasGlobalInstallation(pm: PackageManager): boolean { + const key = `has_global_${pm}` + if (cache.has(key)) return cache.get(key) + + try { + const result = execSync(`${pm} --version`, { + encoding: 'utf-8', + stdio: 'pipe', + }) + const isGlobal = /^\d+.\d+.\d+$/.test(result) + cache.set(key, isGlobal) + return isGlobal + } catch { + return false + } +} + +function getTypeofLockFile(cwd = '.'): Promise { + const key = `lockfile_${cwd}` + if (cache.has(key)) { + return Promise.resolve(cache.get(key)) + } + + return Promise.all([ + pathExists(resolve(cwd, 'yarn.lock')), + pathExists(resolve(cwd, 'package-lock.json')), + pathExists(resolve(cwd, 'pnpm-lock.yaml')), + pathExists(resolve(cwd, 'bun.lockb')), + ]).then(([isYarn, isNpm, isPnpm, isBun]) => { + let value: PackageManager | null = null + + if (isYarn) value = 'yarn' + else if (isPnpm) value = 'pnpm' + else if (isBun) value = 'bun' + else if (isNpm) value = 'npm' + + cache.set(key, value) + return value + }) +} + +async function pathExists(p: string) { + try { + await fs.access(p) + return true + } catch { + return false + } +} diff --git a/wagmi-project/packages/cli/src/utils/resolveConfig.test.ts b/wagmi-project/packages/cli/src/utils/resolveConfig.test.ts new file mode 100644 index 000000000..6669edc9b --- /dev/null +++ b/wagmi-project/packages/cli/src/utils/resolveConfig.test.ts @@ -0,0 +1,83 @@ +import { expect, test } from 'vitest' + +import { createFixture } from '../../test/utils.js' +import { defaultConfig } from '../config.js' +import { findConfig } from './findConfig.js' +import { resolveConfig } from './resolveConfig.js' + +test.skip('resolves config', async () => { + const { paths } = await createFixture({ + files: { + 'wagmi.config.ts': ` + import { defineConfig } from '@wagmi/cli' + + export default defineConfig(${JSON.stringify(defaultConfig)}) + `, + }, + }) + + const configPath = await findConfig({ + config: paths['wagmi.config.ts'], + }) + await expect( + resolveConfig({ configPath: configPath! }), + ).resolves.toMatchInlineSnapshot(` + { + "contracts": [], + "out": "src/generated.ts", + "plugins": [], + } + `) +}) + +test.skip('resolves function config', async () => { + const { paths } = await createFixture({ + files: { + 'wagmi.config.ts': ` + import { defineConfig } from '@wagmi/cli' + + export default defineConfig(() => (${JSON.stringify(defaultConfig)})) + `, + }, + }) + + const configPath = await findConfig({ + config: paths['wagmi.config.ts'], + }) + await expect( + resolveConfig({ configPath: configPath! }), + ).resolves.toMatchInlineSnapshot(` + { + "contracts": [], + "out": "src/generated.ts", + "plugins": [], + } + `) +}) + +test.skip('resolves array config', async () => { + const { paths } = await createFixture({ + files: { + 'wagmi.config.ts': ` + import { defineConfig } from '@wagmi/cli' + + export default defineConfig([${JSON.stringify(defaultConfig)}]) + `, + }, + }) + + const configPath = await findConfig({ + config: paths['wagmi.config.ts'], + }) + await expect( + resolveConfig({ configPath: configPath! }), + ).resolves.toMatchInlineSnapshot(` + [ + { + "contracts": [], + "out": "src/generated.ts", + "plugins": [], + }, + ] + `) +}) diff --git a/wagmi-project/packages/cli/src/utils/resolveConfig.ts b/wagmi-project/packages/cli/src/utils/resolveConfig.ts new file mode 100644 index 000000000..048b1c337 --- /dev/null +++ b/wagmi-project/packages/cli/src/utils/resolveConfig.ts @@ -0,0 +1,21 @@ +import { bundleRequire } from 'bundle-require' + +import type { Config } from '../config.js' +import type { MaybeArray } from '../types.js' + +type ResolveConfigParameters = { + /** Path to config file */ + configPath: string +} + +/** Bundles and returns wagmi config object from path. */ +export async function resolveConfig( + parameters: ResolveConfigParameters, +): Promise> { + const { configPath } = parameters + const res = await bundleRequire({ filepath: configPath }) + let config = res.mod.default + if (config.default) config = config.default + if (typeof config !== 'function') return config + return await config() +} diff --git a/wagmi-project/packages/cli/src/version.ts b/wagmi-project/packages/cli/src/version.ts new file mode 100644 index 000000000..166b988cc --- /dev/null +++ b/wagmi-project/packages/cli/src/version.ts @@ -0,0 +1 @@ +export const version = '2.3.1' diff --git a/wagmi-project/packages/cli/test/constants.ts b/wagmi-project/packages/cli/test/constants.ts new file mode 100644 index 000000000..9b84c5bb1 --- /dev/null +++ b/wagmi-project/packages/cli/test/constants.ts @@ -0,0 +1,32 @@ +import { parseAbi } from 'viem' + +export const wagmiAbi = parseAbi([ + 'constructor()', + 'event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId)', + 'event ApprovalForAll(address indexed owner, address indexed operator, bool approved)', + 'event Transfer(address indexed from, address indexed to, uint256 indexed tokenId)', + 'function approve(address to, uint256 tokenId)', + 'function balanceOf(address owner) view returns (uint256)', + 'function getApproved(uint256 tokenId) view returns (address)', + 'function isApprovedForAll(address owner, address operator) view returns (bool)', + 'function mint()', + 'function name() view returns (string)', + 'function ownerOf(uint256 tokenId) view returns (address)', + 'function safeTransferFrom(address from, address to, uint256 tokenId)', + 'function safeTransferFrom(address from, address to, uint256 tokenId, bytes _data)', + 'function setApprovalForAll(address operator, bool approved)', + 'function supportsInterface(bytes4 interfaceId) view returns (bool)', + 'function symbol() view returns (string)', + 'function tokenURI(uint256 tokenId) pure returns (string)', + 'function totalSupply() view returns (uint256)', + 'function transferFrom(address from, address to, uint256 tokenId)', +]) + +export const depositAbi = parseAbi([ + 'constructor()', + 'event DepositEvent(bytes pubkey, bytes withdrawal_credentials, bytes amount, bytes signature, bytes index)', + 'function deposit(bytes pubkey, bytes withdrawal_credentials, bytes signature, bytes32 deposit_data_root) payable', + 'function get_deposit_count() view returns (bytes)', + 'function get_deposit_root() view returns (bytes32)', + 'function supportsInterface(bytes4 interfaceId) pure returns (bool)', +]) diff --git a/wagmi-project/packages/cli/test/setup.ts b/wagmi-project/packages/cli/test/setup.ts new file mode 100644 index 000000000..d2eed4a5e --- /dev/null +++ b/wagmi-project/packages/cli/test/setup.ts @@ -0,0 +1,57 @@ +import { mkdir } from 'node:fs/promises' +import { homedir } from 'node:os' +import type { createSpinner as nanospinner_createSpinner } from 'nanospinner' +import { join } from 'pathe' +import { vi } from 'vitest' + +const cacheDir = join(homedir(), '.wagmi-cli/plugins/fetch/cache') +await mkdir(cacheDir, { recursive: true }) + +vi.mock('nanospinner', async (importOriginal) => { + const mod = await importOriginal<{ + createSpinner: typeof nanospinner_createSpinner + }>() + + function createSpinner( + initialText: string, + opts: Parameters[1], + ) { + let currentText = '' + const spinner = mod.createSpinner(initialText, opts) + return { + ...spinner, + start(text = initialText) { + // biome-ignore lint/suspicious/noConsoleLog: console.log is used for logging + console.log(`- ${text}`) + spinner.start(text) + currentText = text + }, + success(text = currentText) { + // biome-ignore lint/suspicious/noConsoleLog: console.log is used for logging + console.log(`√ ${text}`) + spinner.success(text) + }, + error(text = currentText) { + console.error(`× ${text}`) + spinner.error(text) + }, + } + } + return { createSpinner } +}) + +vi.mock('picocolors', async () => { + function pass(input: string | number | null | undefined) { + return input + } + return { + default: { + blue: pass, + gray: pass, + green: pass, + red: pass, + white: pass, + yellow: pass, + }, + } +}) diff --git a/wagmi-project/packages/cli/test/utils.ts b/wagmi-project/packages/cli/test/utils.ts new file mode 100644 index 000000000..4ea6c6051 --- /dev/null +++ b/wagmi-project/packages/cli/test/utils.ts @@ -0,0 +1,292 @@ +import { spawnSync } from 'node:child_process' +import { cp, mkdir, symlink, writeFile } from 'node:fs/promises' +import fixtures from 'fixturez' +import { http, HttpResponse } from 'msw' +import * as path from 'pathe' +import { vi } from 'vitest' + +const f = fixtures(__dirname) + +type Json = + | string + | number + | boolean + | null + | { [property: string]: Json } + | Json[] + +export async function createFixture< + TFiles extends { [filename: string]: string | Json } & { + tsconfig?: true + }, +>( + config: { + copyNodeModules?: boolean + dir?: string + files?: TFiles + } = {}, +) { + const dir = config.dir ?? f.temp() + await mkdir(dir, { recursive: true }) + + // Create test files + const paths: { [_ in keyof TFiles]: string } = {} as any + await Promise.all( + (Object.keys(config.files ?? {}) as (keyof TFiles)[]).map( + async (filename_) => { + let file: Json | true | undefined + let filename = filename_ + if (filename === 'tsconfig') { + filename = 'tsconfig.json' + file = getTsConfig(dir) + } else file = config.files![filename] + + const filePath = path.join(dir, filename.toString()) + await mkdir(path.dirname(filePath), { recursive: true }) + + await writeFile( + filePath, + typeof file === 'string' ? file : JSON.stringify(file, null, 2), + ) + paths[filename === 'tsconfig.json' ? 'tsconfig' : filename] = filePath + }, + ), + ) + + if (config.copyNodeModules) { + await symlink( + path.join(__dirname, '../node_modules'), + path.join(dir, 'node_modules'), + 'dir', + ) + await cp( + path.join(__dirname, '../package.json'), + path.join(dir, 'package.json'), + ) + } + + return { + dir, + paths: paths, + } +} + +type TsConfig = { + compilerOptions: { [property: string]: any } + exclude: string[] + include: string[] +} +function getTsConfig(baseUrl: string) { + return { + compilerOptions: { + allowJs: true, + baseUrl: '.', + esModuleInterop: true, + forceConsistentCasingInFileNames: true, + incremental: true, + isolatedModules: true, + jsx: 'preserve', + lib: ['dom', 'dom.iterable', 'esnext'], + module: 'esnext', + moduleResolution: 'node', + noEmit: true, + paths: { + '@wagmi/cli': [path.relative(baseUrl, 'packages/cli/src')], + '@wagmi/cli/*': [path.relative(baseUrl, 'packages/cli/src/*')], + '@wagmi/connectors': [ + path.relative(baseUrl, 'packages/connectors/src'), + ], + '@wagmi/connectors/*': [ + path.relative(baseUrl, 'packages/connectors/src/*'), + ], + '@wagmi/core': [path.relative(baseUrl, 'packages/core/src')], + '@wagmi/core/*': [path.relative(baseUrl, 'packages/core/src/*')], + wagmi: [path.relative(baseUrl, 'packages/react/src')], + 'wagmi/*': [path.relative(baseUrl, 'packages/react/src/*')], + }, + resolveJsonModule: true, + skipLibCheck: true, + strict: true, + target: 'es6', + }, + include: [`${baseUrl}/**/*.ts`, `${baseUrl}/**/*.tsx`], + exclude: ['node_modules'], + } as TsConfig +} + +export function watchConsole() { + type Console = 'info' | 'log' | 'warn' | 'error' + const output: { [_ in Console | 'all']: string[] } = { + info: [], + log: [], + warn: [], + error: [], + all: [], + } + function handleOutput(method: Console) { + return (message: string) => { + output[method].push(message) + output.all.push(message) + } + } + return { + debug: console.debug, + info: vi.spyOn(console, 'info').mockImplementation(handleOutput('info')), + log: vi.spyOn(console, 'log').mockImplementation(handleOutput('log')), + warn: vi.spyOn(console, 'warn').mockImplementation(handleOutput('warn')), + error: vi.spyOn(console, 'error').mockImplementation(handleOutput('error')), + output, + get formatted() { + return output.all.join('\n') + }, + } +} + +export async function typecheck(project: string) { + try { + const result = spawnSync( + 'tsc', + ['--noEmit', '--target', 'es2021', '--pretty', 'false', '-p', project], + { + encoding: 'utf-8', + stdio: 'pipe', + }, + ) + if (result.error) throw result.error + if (result.status !== 0) + throw new Error(`Failed with code ${result.status}`) + if (result.signal) throw new Error('Process terminated by signal') + return result.stdout + } catch (error) { + throw new Error( + (error as Error).message.replaceAll( + path.dirname(project), + '/path/to/project', + ), + ) + } +} + +export const baseUrl = 'https://api.etherscan.io/v2/api' +export const apiKey = 'abc' +export const invalidApiKey = 'xyz' +export const address = '0xaf0326d92b97df1221759476b072abfd8084f9be' +export const proxyAddress = '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48' +export const implementationAddress = + '0x43506849d7c04f9138d1a2050bbf3a0c054402dd' +export const unverifiedContractAddress = + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e' +export const timeoutAddress = '0xecb504d39723b0be0e3a9aa33d646642d1051ee1' + +export const handlers = [ + http.get(baseUrl, async ({ request }) => { + const url = new URL(request.url) + const search = url.search.replace(/^\?chainId=\d&/, '?') + + if ( + search === + `?module=contract&action=getabi&address=${unverifiedContractAddress}&apikey=${apiKey}` + ) + return HttpResponse.json({ + status: '0', + message: 'NOTOK', + result: 'Contract source code not verified', + }) + + if ( + search === + `?module=contract&action=getabi&address=${timeoutAddress}&apikey=${invalidApiKey}` + ) + return HttpResponse.json({ + status: '0', + message: 'NOTOK', + result: 'Invalid API Key', + }) + + if ( + search === + `?module=contract&action=getabi&address=${address}&apikey=${apiKey}` + ) + return HttpResponse.json({ + status: '1', + message: 'OK', + result: + '[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"}]', + }) + + if ( + search === + `?module=contract&action=getabi&address=${timeoutAddress}&apikey=${apiKey}` + ) { + await new Promise((resolve) => setTimeout(resolve, 10_000)) + return HttpResponse.json({}) + } + + if ( + search === + `?module=contract&action=getabi&address=${implementationAddress}&apikey=${apiKey}` + ) + return HttpResponse.json({ + status: '1', + message: 'OK', + result: + '[{"constant":false,"inputs":[{"name":"newImplementation","type":"address"}],"name":"upgradeTo","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"newImplementation","type":"address"},{"name":"data","type":"bytes"}],"name":"upgradeToAndCall","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"implementation","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"newAdmin","type":"address"}],"name":"changeAdmin","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"admin","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"_implementation","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":false,"name":"previousAdmin","type":"address"},{"indexed":false,"name":"newAdmin","type":"address"}],"name":"AdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"implementation","type":"address"}],"name":"Upgraded","type":"event"}]', + }) + + if ( + search === + `?module=contract&action=getsourcecode&address=${proxyAddress}&apikey=${apiKey}` + ) + return HttpResponse.json({ + status: '1', + message: 'OK', + result: [ + { + SourceCode: '...', + ABI: '[{"constant":false,"inputs":[{"name":"newImplementation","type":"address"}],"name":"upgradeTo","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"newImplementation","type":"address"},{"name":"data","type":"bytes"}],"name":"upgradeToAndCall","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"implementation","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"newAdmin","type":"address"}],"name":"changeAdmin","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"admin","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"_implementation","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":false,"name":"previousAdmin","type":"address"},{"indexed":false,"name":"newAdmin","type":"address"}],"name":"AdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"implementation","type":"address"}],"name":"Upgraded","type":"event"}]', + ContractName: 'FiatTokenProxy', + CompilerVersion: 'v0.4.24+commit.e67f0147', + OptimizationUsed: '0', + Runs: '200', + ConstructorArguments: + '0000000000000000000000000882477e7895bdc5cea7cb1552ed914ab157fe56', + EVMVersion: 'Default', + Library: '', + LicenseType: '', + Proxy: '1', + Implementation: '0x43506849d7c04f9138d1a2050bbf3a0c054402dd', + SwarmSource: + 'bzzr://a4a547cfc7202c5acaaae74d428e988bc62ad5024eb0165532d3a8f91db4ed24', + }, + ], + }) + + if ( + search === + `?module=contract&action=getsourcecode&address=${address}&apikey=${apiKey}` + ) + return HttpResponse.json({ + status: '1', + message: 'OK', + result: [ + { + SourceCode: '...', + ABI: '[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"}]', + ContractName: 'WagmiMintExample', + CompilerVersion: 'v0.8.11+commit.d7f03943', + OptimizationUsed: '1', + Runs: '10000', + ConstructorArguments: '', + EVMVersion: 'Default', + Library: '', + LicenseType: '', + Proxy: '0', + Implementation: '', + SwarmSource: '', + }, + ], + }) + + throw new Error(`Unhandled request: ${search}`) + }), +] diff --git a/wagmi-project/packages/cli/tsconfig.build.json b/wagmi-project/packages/cli/tsconfig.build.json new file mode 100644 index 000000000..3a046d812 --- /dev/null +++ b/wagmi-project/packages/cli/tsconfig.build.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.base.json", + "include": ["src/**/*.ts"], + "exclude": ["src/**/*.test.ts"], + "compilerOptions": { + "sourceMap": true, + "types": ["@types/node"] + } +} diff --git a/wagmi-project/packages/cli/tsconfig.json b/wagmi-project/packages/cli/tsconfig.json new file mode 100644 index 000000000..4054dee11 --- /dev/null +++ b/wagmi-project/packages/cli/tsconfig.json @@ -0,0 +1,5 @@ +{ + "extends": "./tsconfig.build.json", + "include": ["src/**/*.ts", "test/**/*.ts", "types/**/*.d.ts"], + "exclude": [] +} diff --git a/wagmi-project/packages/cli/types/fixturez.d.ts b/wagmi-project/packages/cli/types/fixturez.d.ts new file mode 100644 index 000000000..f96282756 --- /dev/null +++ b/wagmi-project/packages/cli/types/fixturez.d.ts @@ -0,0 +1,18 @@ +declare module 'fixturez' { + interface FixturezOpts { + glob?: string + cleanup?: boolean + root?: string + } + + interface Fixturez { + find(basename: string): string + copy(basename: string): string + temp(): string + cleanup(): void + } + + function fixturez(dirname: string, opts?: FixturezOpts): Fixturez + + export = fixturez +} diff --git a/wagmi-project/packages/connectors/CHANGELOG.md b/wagmi-project/packages/connectors/CHANGELOG.md new file mode 100644 index 000000000..c67e25dcb --- /dev/null +++ b/wagmi-project/packages/connectors/CHANGELOG.md @@ -0,0 +1,1640 @@ +# @wagmi/connectors + +## 5.8.3 + +### Patch Changes + +- [#4660](https://github.com/wevm/wagmi/pull/4660) [`42b1fed58e9ac09da0f8ebf3e9271f98a707aaac`](https://github.com/wevm/wagmi/commit/42b1fed58e9ac09da0f8ebf3e9271f98a707aaac) Thanks [@ganchoradkov](https://github.com/ganchoradkov)! - Updated `@walletconnect/ethereum-provider` version to `2.20.2` + +## 5.8.2 + +### Patch Changes + +- Updated dependencies [[`29297a48af72b537173d948ccd2fe37d39914c66`](https://github.com/wevm/wagmi/commit/29297a48af72b537173d948ccd2fe37d39914c66), [`07370106d5fb6b8fe300992d93abf25b3d0eaf57`](https://github.com/wevm/wagmi/commit/07370106d5fb6b8fe300992d93abf25b3d0eaf57)]: + - @wagmi/core@2.17.2 + +## 5.8.1 + +### Patch Changes + +- Updated dependencies [[`01f64e64fa4f85cdd30023903f972f4f9023681f`](https://github.com/wevm/wagmi/commit/01f64e64fa4f85cdd30023903f972f4f9023681f)]: + - @wagmi/core@2.17.1 + +## 5.8.0 + +### Minor Changes + +- [#4644](https://github.com/wevm/wagmi/pull/4644) [`cc5517ff6880bb630f1b201930acc20dd1a0b451`](https://github.com/wevm/wagmi/commit/cc5517ff6880bb630f1b201930acc20dd1a0b451) Thanks [@lukaisailovic](https://github.com/lukaisailovic)! - Updated `@walletconnect/etherereum-provider` to `2.20.0`. + +## 5.7.13 + +### Patch Changes + +- [#4622](https://github.com/wevm/wagmi/pull/4622) [`88427b2bcd13ec375ef519e9ad1ccffef9f02a7b`](https://github.com/wevm/wagmi/commit/88427b2bcd13ec375ef519e9ad1ccffef9f02a7b) Thanks [@dan1kov](https://github.com/dan1kov)! - Added `rdns` property to Coinbase Wallet v3 connector + +- [#4605](https://github.com/wevm/wagmi/pull/4605) [`3f8b2edc4f237cccff1009bcef03d51ca27a7324`](https://github.com/wevm/wagmi/commit/3f8b2edc4f237cccff1009bcef03d51ca27a7324) Thanks [@chybisov](https://github.com/chybisov)! - Bumped `@safe-global/safe-apps-provider` version to `0.18.6`. + +- Updated dependencies [[`799ee4d4b23c2ecd64e3f3668e67634e81939719`](https://github.com/wevm/wagmi/commit/799ee4d4b23c2ecd64e3f3668e67634e81939719)]: + - @wagmi/core@2.17.0 + +## 5.7.12 + +### Patch Changes + +- [#4608](https://github.com/wevm/wagmi/pull/4608) [`b59c024b23c69f5459b17390531207cfdf126ce4`](https://github.com/wevm/wagmi/commit/b59c024b23c69f5459b17390531207cfdf126ce4) Thanks [@jxom](https://github.com/jxom)! - Updated `@walletconnect/ethereum-provider`. + +## 5.7.11 + +### Patch Changes + +- Updated dependencies [[`a4bd0623eed28e3761a27295831a60ad835f0ee0`](https://github.com/wevm/wagmi/commit/a4bd0623eed28e3761a27295831a60ad835f0ee0)]: + - @wagmi/core@2.16.7 + +## 5.7.10 + +### Patch Changes + +- [#4573](https://github.com/wevm/wagmi/pull/4573) [`e944812ebc234a72c1417b77cff341166f5e0fef`](https://github.com/wevm/wagmi/commit/e944812ebc234a72c1417b77cff341166f5e0fef) Thanks [@ganchoradkov](https://github.com/ganchoradkov)! - updated `@walletconnect/ethereum-provider` to `2.19.1` + +- Updated dependencies [[`edf47477b2f6385a1c3ae01d36a8498c47f30a0b`](https://github.com/wevm/wagmi/commit/edf47477b2f6385a1c3ae01d36a8498c47f30a0b)]: + - @wagmi/core@2.16.6 + +## 5.7.9 + +### Patch Changes + +- [#4571](https://github.com/wevm/wagmi/pull/4571) [`5b7101fddb61df56e34b2e02b46bc409e496eaf9`](https://github.com/wevm/wagmi/commit/5b7101fddb61df56e34b2e02b46bc409e496eaf9) Thanks [@ganchoradkov](https://github.com/ganchoradkov)! - Updated `@walletconnect/ethereum-provider` to `2.19.0` + +## 5.7.8 + +### Patch Changes + +- Updated dependencies [[`d0c9a86921a4e939373cc6e763284e53f2a2e93c`](https://github.com/wevm/wagmi/commit/d0c9a86921a4e939373cc6e763284e53f2a2e93c)]: + - @wagmi/core@2.16.5 + +## 5.7.7 + +### Patch Changes + +- [`507f864d91238bfd423d0e36d3619eb9f6e52eec`](https://github.com/wevm/wagmi/commit/507f864d91238bfd423d0e36d3619eb9f6e52eec) Thanks [@jxom](https://github.com/jxom)! - Updated `@coinbase/wallet-sdk`. + +- Updated dependencies [[`507f864d91238bfd423d0e36d3619eb9f6e52eec`](https://github.com/wevm/wagmi/commit/507f864d91238bfd423d0e36d3619eb9f6e52eec)]: + - @wagmi/core@2.16.4 + +## 5.7.6 + +### Patch Changes + +- [#4524](https://github.com/wevm/wagmi/pull/4524) [`639952c97f0fe3927106f42d3c9f7f366cdf7f7a`](https://github.com/wevm/wagmi/commit/639952c97f0fe3927106f42d3c9f7f366cdf7f7a) Thanks [@chakra-guy](https://github.com/chakra-guy)! - Updated MetaMask SDK. + +- [#4525](https://github.com/wevm/wagmi/pull/4525) [`5aa2c095f7bfb6dfcf91c6945c3e1f9c9dd05766`](https://github.com/wevm/wagmi/commit/5aa2c095f7bfb6dfcf91c6945c3e1f9c9dd05766) Thanks [@EdouardBougon](https://github.com/EdouardBougon)! - Added Phantom flag to Injected Connector. + +## 5.7.5 + +### Patch Changes + +- [#4512](https://github.com/wevm/wagmi/pull/4512) [`a257e8d4f97431a4af872cda1817b4ae17c7bbed`](https://github.com/wevm/wagmi/commit/a257e8d4f97431a4af872cda1817b4ae17c7bbed) Thanks [@EdouardBougon](https://github.com/EdouardBougon)! - Fixed MetaMask switchChain/addChain handling. + +## 5.7.4 + +### Patch Changes + +- [#4505](https://github.com/wevm/wagmi/pull/4505) [`c8a257e0f6d2ece013b873895c35769a8a804fdc`](https://github.com/wevm/wagmi/commit/c8a257e0f6d2ece013b873895c35769a8a804fdc) Thanks [@chakra-guy](https://github.com/chakra-guy)! - Bumped Metamask SDK Version (changes include [bug fixes and minor changes](https://github.com/MetaMask/metamask-sdk/pull/1194)). + +## 5.7.3 + +### Patch Changes + +- [#4480](https://github.com/wevm/wagmi/pull/4480) [`384a1d91597622eb59e1c05dc13ce25017c5b6d8`](https://github.com/wevm/wagmi/commit/384a1d91597622eb59e1c05dc13ce25017c5b6d8) Thanks [@RodeRickIsWatching](https://github.com/RodeRickIsWatching)! - Fixed invocation of default storage. + +- Updated dependencies [[`384a1d91597622eb59e1c05dc13ce25017c5b6d8`](https://github.com/wevm/wagmi/commit/384a1d91597622eb59e1c05dc13ce25017c5b6d8)]: + - @wagmi/core@2.16.3 + +## 5.7.2 + +### Patch Changes + +- [`012907032b532a438fce48f407470250cbc8f0c6`](https://github.com/wevm/wagmi/commit/012907032b532a438fce48f407470250cbc8f0c6) Thanks [@jxom](https://github.com/jxom)! - Fixed assignment in `getDefaultStorage`. + +- Updated dependencies [[`012907032b532a438fce48f407470250cbc8f0c6`](https://github.com/wevm/wagmi/commit/012907032b532a438fce48f407470250cbc8f0c6)]: + - @wagmi/core@2.16.2 + +## 5.7.1 + +### Patch Changes + +- [#4471](https://github.com/wevm/wagmi/pull/4471) [`9c8c35a3b829f2c58edcd3a29e2dcd99974d7470`](https://github.com/wevm/wagmi/commit/9c8c35a3b829f2c58edcd3a29e2dcd99974d7470) Thanks [@EdouardBougon](https://github.com/EdouardBougon)! - Improved MetaMask chain switching behavior. + +- Updated dependencies [[`3892ebd21c06beef4b28ece4e70d2a38807bce6f`](https://github.com/wevm/wagmi/commit/3892ebd21c06beef4b28ece4e70d2a38807bce6f)]: + - @wagmi/core@2.16.1 + +## 5.7.0 + +### Minor Changes + +- [#4440](https://github.com/wevm/wagmi/pull/4440) [`e3f63a02c1f7d80481804584f262bc98dab0400d`](https://github.com/wevm/wagmi/commit/e3f63a02c1f7d80481804584f262bc98dab0400d) Thanks [@johanneskares](https://github.com/johanneskares)! - Added Coinbase Smart Wallet "Instant Onboarding" mode to `coinbaseWallet`. + +## 5.6.2 + +### Patch Changes + +- [#4437](https://github.com/wevm/wagmi/pull/4437) [`adf2253b10c6d4fc583e4bc9f01a8ef5ca267c85`](https://github.com/wevm/wagmi/commit/adf2253b10c6d4fc583e4bc9f01a8ef5ca267c85) Thanks [@chybisov](https://github.com/chybisov)! - Bumped `@safe-global/safe-apps-provider` version to `0.18.5`. + +## 5.6.1 + +### Patch Changes + +- [#4458](https://github.com/wevm/wagmi/pull/4458) [`987404f590c1d29ebb3cb68928f5e54aa032793d`](https://github.com/wevm/wagmi/commit/987404f590c1d29ebb3cb68928f5e54aa032793d) Thanks [@EdouardBougon](https://github.com/EdouardBougon)! - Fixed MetaMask internal metadata handling. + +## 5.6.0 + +### Minor Changes + +- [#4453](https://github.com/wevm/wagmi/pull/4453) [`070e48480194c8d7f45bda1d7dd1346e6f5d7227`](https://github.com/wevm/wagmi/commit/070e48480194c8d7f45bda1d7dd1346e6f5d7227) Thanks [@tmm](https://github.com/tmm)! - Added narrowing to `config.connectors`. + +### Patch Changes + +- [#4456](https://github.com/wevm/wagmi/pull/4456) [`8b0726c1106fce88b782e676498eabf0718b2619`](https://github.com/wevm/wagmi/commit/8b0726c1106fce88b782e676498eabf0718b2619) Thanks [@EdouardBougon](https://github.com/EdouardBougon)! - Bumped MetaMask SDK and fixed internal metadata handling. +- Updated dependencies [[`afea6b67822a7a2b96901ec851441d27ee0f7a52`](https://github.com/wevm/wagmi/commit/afea6b67822a7a2b96901ec851441d27ee0f7a52), [`070e48480194c8d7f45bda1d7dd1346e6f5d7227`](https://github.com/wevm/wagmi/commit/070e48480194c8d7f45bda1d7dd1346e6f5d7227)]: + - @wagmi/core@2.16.0 + +## 5.5.3 + +### Patch Changes + +- [#4433](https://github.com/wevm/wagmi/pull/4433) [`06e186cd679b27fe195309110e766fcf46d4efbc`](https://github.com/wevm/wagmi/commit/06e186cd679b27fe195309110e766fcf46d4efbc) Thanks [@Aerilym](https://github.com/Aerilym)! - Bumped Metamask SDK version to `0.31.1`. + +- Updated dependencies [[`06e186cd679b27fe195309110e766fcf46d4efbc`](https://github.com/wevm/wagmi/commit/06e186cd679b27fe195309110e766fcf46d4efbc)]: + - @wagmi/core@2.15.2 + +## 5.5.2 + +### Patch Changes + +- [#4422](https://github.com/wevm/wagmi/pull/4422) [`e563ef69130a511fd6f3f72ed4cd4fbe1390541f`](https://github.com/wevm/wagmi/commit/e563ef69130a511fd6f3f72ed4cd4fbe1390541f) Thanks [@abretonc7s](https://github.com/abretonc7s)! - Bumped MetaMask SDK. + +## 5.5.1 + +### Patch Changes + +- Updated dependencies [[`b8bbb409f4934538e3dd6cac5aaf7346292d0693`](https://github.com/wevm/wagmi/commit/b8bbb409f4934538e3dd6cac5aaf7346292d0693)]: + - @wagmi/core@2.15.1 + +## 5.5.0 + +### Minor Changes + +- [#4417](https://github.com/wevm/wagmi/pull/4417) [`42e65ea4fea99c639817088bba915e0933d17141`](https://github.com/wevm/wagmi/commit/42e65ea4fea99c639817088bba915e0933d17141) Thanks [@jxom](https://github.com/jxom)! - Removed simulation in `writeContract` & `sendTransaction`. + +### Patch Changes + +- Updated dependencies [[`42e65ea4fea99c639817088bba915e0933d17141`](https://github.com/wevm/wagmi/commit/42e65ea4fea99c639817088bba915e0933d17141)]: + - @wagmi/core@2.15.0 + +## 5.4.0 + +### Minor Changes + +- [#4409](https://github.com/wevm/wagmi/pull/4409) [`7ca62b44cd997d48f92c2b81343726a5908aa00b`](https://github.com/wevm/wagmi/commit/7ca62b44cd997d48f92c2b81343726a5908aa00b) Thanks [@fan-zhang-sv](https://github.com/fan-zhang-sv)! - Added `preference` object for Coinbase Wallet connector. + +## 5.3.10 + +### Patch Changes + +- [#4406](https://github.com/wevm/wagmi/pull/4406) [`a13aa8d7c38eb3cc8171a02d6302e6d12cf6bcb3`](https://github.com/wevm/wagmi/commit/a13aa8d7c38eb3cc8171a02d6302e6d12cf6bcb3) Thanks [@tmm](https://github.com/tmm)! - Added additional RDNS to MetaMask Connector. + +- Updated dependencies [[`a13aa8d7c38eb3cc8171a02d6302e6d12cf6bcb3`](https://github.com/wevm/wagmi/commit/a13aa8d7c38eb3cc8171a02d6302e6d12cf6bcb3)]: + - @wagmi/core@2.14.6 + +## 5.3.9 + +### Patch Changes + +- [`b12a04eeec985c48d2feac94b011d41fb29ca23e`](https://github.com/wevm/wagmi/commit/b12a04eeec985c48d2feac94b011d41fb29ca23e) Thanks [@tmm](https://github.com/tmm)! - Bumped Coinbase Wallet SDK version. + +## 5.3.8 + +### Patch Changes + +- [#4390](https://github.com/wevm/wagmi/pull/4390) [`dac62dc99a0679fa632a0fae49873d6053d06b35`](https://github.com/wevm/wagmi/commit/dac62dc99a0679fa632a0fae49873d6053d06b35) Thanks [@chybisov](https://github.com/chybisov)! - Bumped Safe Apps Provider version. + +- Updated dependencies [[`6b9bbacdc7bffd44fc2165362a5e65fd434e7646`](https://github.com/wevm/wagmi/commit/6b9bbacdc7bffd44fc2165362a5e65fd434e7646)]: + - @wagmi/core@2.14.5 + +## 5.3.7 + +### Patch Changes + +- Updated dependencies [[`e08681c81fbdf475213e2d0f4c5517d0abf4e743`](https://github.com/wevm/wagmi/commit/e08681c81fbdf475213e2d0f4c5517d0abf4e743)]: + - @wagmi/core@2.14.4 + +## 5.3.6 + +### Patch Changes + +- [#4385](https://github.com/wevm/wagmi/pull/4385) [`7558ff3133c11bc4c49473d08ee9a47eaa12df5b`](https://github.com/wevm/wagmi/commit/7558ff3133c11bc4c49473d08ee9a47eaa12df5b) Thanks [@cb-jake](https://github.com/cb-jake)! - Bumped Coinbase Wallet SDK version. + +## 5.3.5 + +### Patch Changes + +- [`7fe78f2d09778fc01fd0cffe85ba198e64999275`](https://github.com/wevm/wagmi/commit/7fe78f2d09778fc01fd0cffe85ba198e64999275) Thanks [@tmm](https://github.com/tmm)! - Fixed MetaMask connector not returning provider in some cases. + +- Updated dependencies [[`cb7dd2ebb871d0be8f1a11a8cd8ce592cd74b7c7`](https://github.com/wevm/wagmi/commit/cb7dd2ebb871d0be8f1a11a8cd8ce592cd74b7c7)]: + - @wagmi/core@2.14.3 + +## 5.3.4 + +### Patch Changes + +- [#4371](https://github.com/wevm/wagmi/pull/4371) [`b6861a4c378dab78d8751ae0ac2aa425f3c24b8f`](https://github.com/wevm/wagmi/commit/b6861a4c378dab78d8751ae0ac2aa425f3c24b8f) Thanks [@iceanddust](https://github.com/iceanddust)! - Fixed Safe connector not working in some Vite apps + +- Updated dependencies [[`d0d0963bb5904a15cf0355862d62dd141ce0c31c`](https://github.com/wevm/wagmi/commit/d0d0963bb5904a15cf0355862d62dd141ce0c31c), [`ecac0ba36243d94c9199d0bd21937104c835d9a0`](https://github.com/wevm/wagmi/commit/ecac0ba36243d94c9199d0bd21937104c835d9a0)]: + - @wagmi/core@2.14.2 + +## 5.3.3 + +### Patch Changes + +- [#4362](https://github.com/wevm/wagmi/pull/4362) [`83c6d16b7d6dddfa6bda036e04f00ec313c6248c`](https://github.com/wevm/wagmi/commit/83c6d16b7d6dddfa6bda036e04f00ec313c6248c) Thanks [@EdouardBougon](https://github.com/EdouardBougon)! - Fixed MetaMask connector internal logic. + +## 5.3.2 + +### Patch Changes + +- [#4357](https://github.com/wevm/wagmi/pull/4357) [`8970cc51398e1ac713435533096215c6d31ffdf9`](https://github.com/wevm/wagmi/commit/8970cc51398e1ac713435533096215c6d31ffdf9) Thanks [@tmm](https://github.com/tmm)! - Bumped dependencies. + +## 5.3.1 + +### Patch Changes + +- Updated dependencies [[`052e72e1f8c1c14fcbdce04a9f8fa7ec28d83702`](https://github.com/wevm/wagmi/commit/052e72e1f8c1c14fcbdce04a9f8fa7ec28d83702), [`b250fc21ee577b2a75c5a34ff684f62fb4ad771a`](https://github.com/wevm/wagmi/commit/b250fc21ee577b2a75c5a34ff684f62fb4ad771a)]: + - @wagmi/core@2.14.1 + +## 5.3.0 + +### Minor Changes + +- [#4343](https://github.com/wevm/wagmi/pull/4343) [`f43e074f473820b208a6295d7c97f847332f1a1d`](https://github.com/wevm/wagmi/commit/f43e074f473820b208a6295d7c97f847332f1a1d) Thanks [@tmm](https://github.com/tmm)! - Added `rdns` property to connector interface. This is used to filter out duplicate [EIP-6963](https://eips.ethereum.org/EIPS/eip-6963) injected providers when [`createConfig#multiInjectedProviderDiscovery`](https://wagmi.sh/core/api/createConfig#multiinjectedproviderdiscovery) is enabled and `createConfig#connectors` already matches EIP-6963 providers' `rdns` property. + +### Patch Changes + +- Updated dependencies [[`f43e074f473820b208a6295d7c97f847332f1a1d`](https://github.com/wevm/wagmi/commit/f43e074f473820b208a6295d7c97f847332f1a1d)]: + - @wagmi/core@2.14.0 + +## 5.2.2 + +### Patch Changes + +- [#4347](https://github.com/wevm/wagmi/pull/4347) [`5ae49af590ff168426c9c283d54c34ae5148fcd9`](https://github.com/wevm/wagmi/commit/5ae49af590ff168426c9c283d54c34ae5148fcd9) Thanks [@EdouardBougon](https://github.com/EdouardBougon)! - Added workaround for MetaMask mobile sometimes disconnecting. + +- [#4350](https://github.com/wevm/wagmi/pull/4350) [`f3182b22e6e454d9bd74f1b940ef34431fd9555d`](https://github.com/wevm/wagmi/commit/f3182b22e6e454d9bd74f1b940ef34431fd9555d) Thanks [@abretonc7s](https://github.com/abretonc7s)! - Updated MetaMask SDK. + +- Updated dependencies [[`c05caabc20c3ced9682cfc7ba1f3f7dcfece0703`](https://github.com/wevm/wagmi/commit/c05caabc20c3ced9682cfc7ba1f3f7dcfece0703)]: + - @wagmi/core@2.13.9 + +## 5.2.1 + +### Patch Changes + +- [#4345](https://github.com/wevm/wagmi/pull/4345) [`91a40f2db08e3a91db421b8732a5511a1e6c88fd`](https://github.com/wevm/wagmi/commit/91a40f2db08e3a91db421b8732a5511a1e6c88fd) Thanks [@tmm](https://github.com/tmm)! - Bumped MetaMask SDK. + +## 5.2.0 + +### Minor Changes + +- [#4337](https://github.com/wevm/wagmi/pull/4337) [`34a0c3b7eea778aee7c27f7ace5e4b2be4e8a0a4`](https://github.com/wevm/wagmi/commit/34a0c3b7eea778aee7c27f7ace5e4b2be4e8a0a4) Thanks [@tmm](https://github.com/tmm)! - Added "Connect and Sign" behavior to MetaMask Connector. + +## 5.1.15 + +### Patch Changes + +- [`3b2123664b7ac66848390739e855c3b9702ab60c`](https://github.com/wevm/wagmi/commit/3b2123664b7ac66848390739e855c3b9702ab60c) Thanks [@tmm](https://github.com/tmm)! - Bumped WalletConnect Provider. + +## 5.1.14 + +### Patch Changes + +- [#4207](https://github.com/wevm/wagmi/pull/4207) [`56f2482508f2ba71bd6b0295c70c6abca7101e57`](https://github.com/wevm/wagmi/commit/56f2482508f2ba71bd6b0295c70c6abca7101e57) Thanks [@Smert](https://github.com/Smert)! - Updated chain switch listener for `injected` and `metaMask` to be more robust. + +- Updated dependencies [[`56f2482508f2ba71bd6b0295c70c6abca7101e57`](https://github.com/wevm/wagmi/commit/56f2482508f2ba71bd6b0295c70c6abca7101e57)]: + - @wagmi/core@2.13.8 + +## 5.1.13 + +### Patch Changes + +- Updated dependencies [[`be75c2d4ef636d7362420ab0a106bfdf63f5d1e6`](https://github.com/wevm/wagmi/commit/be75c2d4ef636d7362420ab0a106bfdf63f5d1e6)]: + - @wagmi/core@2.13.7 + +## 5.1.12 + +### Patch Changes + +- Updated dependencies [[`edcbf5d6fbe92f639bead800502edda9e0aa39f1`](https://github.com/wevm/wagmi/commit/edcbf5d6fbe92f639bead800502edda9e0aa39f1)]: + - @wagmi/core@2.13.6 + +## 5.1.11 + +### Patch Changes + +- [#4271](https://github.com/wevm/wagmi/pull/4271) [`82404c960e04c83e0bae6e1e12459ef9debf9554`](https://github.com/wevm/wagmi/commit/82404c960e04c83e0bae6e1e12459ef9debf9554) Thanks [@omridan159](https://github.com/omridan159)! - Bumped MetaMask SDK. + +- [#4227](https://github.com/wevm/wagmi/pull/4227) [`d07ad7f63a018256908a673d078aaf79e47ac703`](https://github.com/wevm/wagmi/commit/d07ad7f63a018256908a673d078aaf79e47ac703) Thanks [@xianchenxc](https://github.com/xianchenxc)! - Fixed MetaMask Connector throwing error after switching to a chain that was just added via `'wallet_addEthereumChain'`. + +## 5.1.10 + +### Patch Changes + +- [#4255](https://github.com/wevm/wagmi/pull/4255) [`81de006e66121a18c61945c1f9b8426c83a5713c`](https://github.com/wevm/wagmi/commit/81de006e66121a18c61945c1f9b8426c83a5713c) Thanks [@tomiir](https://github.com/tomiir)! - Bumped `@walletconnect/ethereum-provider` from version `2.15.3` to version `2.16.1`. + +- Updated dependencies [[`f47ce8f6d263e49fdff90b8edb3190142d2657bb`](https://github.com/wevm/wagmi/commit/f47ce8f6d263e49fdff90b8edb3190142d2657bb)]: + - @wagmi/core@2.13.5 + +## 5.1.9 + +### Patch Changes + +- [#4243](https://github.com/wevm/wagmi/pull/4243) [`21bd0e473d374cbbd7a01bececa6022d529026ba`](https://github.com/wevm/wagmi/commit/21bd0e473d374cbbd7a01bececa6022d529026ba) Thanks [@tomiir](https://github.com/tomiir)! - Bumped `@walletconnect/ethereum-provider` from version `2.15.2` to version `2.15.3` + +- [#4251](https://github.com/wevm/wagmi/pull/4251) [`5c89c6853e616437a3be2b019db895451fecfb3c`](https://github.com/wevm/wagmi/commit/5c89c6853e616437a3be2b019db895451fecfb3c) Thanks [@tmm](https://github.com/tmm)! - Bumped MM SDK. + +## 5.1.8 + +### Patch Changes + +- [`b580ad4edff1721e0b9d138cf5ae2ec74d2374c7`](https://github.com/wevm/wagmi/commit/b580ad4edff1721e0b9d138cf5ae2ec74d2374c7) Thanks [@tmm](https://github.com/tmm)! - Bumped WalletConnect Provider. + +## 5.1.7 + +### Patch Changes + +- [#4213](https://github.com/wevm/wagmi/pull/4213) [`91fd81a068789c5020e891f539bcad8f54a7a52f`](https://github.com/wevm/wagmi/commit/91fd81a068789c5020e891f539bcad8f54a7a52f) Thanks [@tomiir](https://github.com/tomiir)! - Updated `@walletconnect/ethereum-provider` from version `2.15.0` to version `2.15.1`. + +## 5.1.6 + +### Patch Changes + +- [#4208](https://github.com/wevm/wagmi/pull/4208) [`3168616298cbb6135d0ffda771cba4126e83eba8`](https://github.com/wevm/wagmi/commit/3168616298cbb6135d0ffda771cba4126e83eba8) Thanks [@tomiir](https://github.com/tomiir)! - Updated WalletConnect Ethereum Provider version from `2.14.0` to `2.15.0`. + +- [#4211](https://github.com/wevm/wagmi/pull/4211) [`d7608ef9a79459465dc8c06a2ab740465c881907`](https://github.com/wevm/wagmi/commit/d7608ef9a79459465dc8c06a2ab740465c881907) Thanks [@tmm](https://github.com/tmm)! - Added default name for MetaMask Connector. + +## 5.1.5 + +### Patch Changes + +- Updated dependencies [[`b4c8971788c70b09479946ecfa998cff2f1b3953`](https://github.com/wevm/wagmi/commit/b4c8971788c70b09479946ecfa998cff2f1b3953)]: + - @wagmi/core@2.13.4 + +## 5.1.4 + +### Patch Changes + +- Updated dependencies [[`871dbdbfe59ac8ad01d1ec6150ea7b091b7b7de4`](https://github.com/wevm/wagmi/commit/871dbdbfe59ac8ad01d1ec6150ea7b091b7b7de4)]: + - @wagmi/core@2.13.3 + +## 5.1.3 + +### Patch Changes + +- Updated dependencies [[`1b9b523fa9b9dfe839aecdf4b40caa9547d7e594`](https://github.com/wevm/wagmi/commit/1b9b523fa9b9dfe839aecdf4b40caa9547d7e594)]: + - @wagmi/core@2.13.2 + +## 5.1.2 + +### Patch Changes + +- [`abb490dac4f0f02f46cb0878e7ca9a0db6aada56`](https://github.com/wevm/wagmi/commit/abb490dac4f0f02f46cb0878e7ca9a0db6aada56) Thanks [@tmm](https://github.com/tmm)! - Bumped MetaMask SDK version. + +- [`28e0e5c9a4f856583f9d36a807502bd51a0c6ec2`](https://github.com/wevm/wagmi/commit/28e0e5c9a4f856583f9d36a807502bd51a0c6ec2) Thanks [@tmm](https://github.com/tmm)! - Bumped WalletConnect Ethereum Provider version. + +## 5.1.1 + +### Patch Changes + +- Updated dependencies [[`07c1227f306d0efb9421d4bb77a774f92f5fcf45`](https://github.com/wevm/wagmi/commit/07c1227f306d0efb9421d4bb77a774f92f5fcf45)]: + - @wagmi/core@2.13.1 + +## 5.1.0 + +### Minor Changes + +- [#4162](https://github.com/wevm/wagmi/pull/4162) [`a73a7737b756886b388f120ae423e72cca53e8a0`](https://github.com/wevm/wagmi/commit/a73a7737b756886b388f120ae423e72cca53e8a0) Thanks [@jxom](https://github.com/jxom)! - Added functionality for consumer-defined RPC URLs (`config.transports`) to be propagated to the WalletConnect & MetaMask Connectors. + +### Patch Changes + +- Updated dependencies [[`a73a7737b756886b388f120ae423e72cca53e8a0`](https://github.com/wevm/wagmi/commit/a73a7737b756886b388f120ae423e72cca53e8a0)]: + - @wagmi/core@2.13.0 + +## 5.0.26 + +### Patch Changes + +- [`8d81df5cc884d0a210dedd3c1ea0e2e9e52b83c5`](https://github.com/wevm/wagmi/commit/8d81df5cc884d0a210dedd3c1ea0e2e9e52b83c5) Thanks [@tmm](https://github.com/tmm)! - Fixed `metaMask` connector switch chain issue. + +- Updated dependencies [[`5bc8c8877810b2eec24a829df87dce40a51e6f20`](https://github.com/wevm/wagmi/commit/5bc8c8877810b2eec24a829df87dce40a51e6f20)]: + - @wagmi/core@2.12.2 + +## 5.0.25 + +### Patch Changes + +- [#4146](https://github.com/wevm/wagmi/pull/4146) [`cc996e08e930c9e88cf753a1e874652059e81a3b`](https://github.com/wevm/wagmi/commit/cc996e08e930c9e88cf753a1e874652059e81a3b) Thanks [@jxom](https://github.com/jxom)! - Updated `@safe-global/safe-apps-sdk` + `@safe-global/safe-apps-provider` dependencies. + +- Updated dependencies [[`cc996e08e930c9e88cf753a1e874652059e81a3b`](https://github.com/wevm/wagmi/commit/cc996e08e930c9e88cf753a1e874652059e81a3b)]: + - @wagmi/core@2.12.1 + +## 5.0.24 + +### Patch Changes + +- Updated dependencies [[`5581a810ef70308e99c6f8b630cd4bca59f64afc`](https://github.com/wevm/wagmi/commit/5581a810ef70308e99c6f8b630cd4bca59f64afc)]: + - @wagmi/core@2.12.0 + +## 5.0.23 + +### Patch Changes + +- [`d3814ab4b88f9f0e052b53bc3d458df87b43f01d`](https://github.com/wevm/wagmi/commit/d3814ab4b88f9f0e052b53bc3d458df87b43f01d) Thanks [@jxom](https://github.com/jxom)! - Updated `mipd` dependency. + +- Updated dependencies [[`b08013eaa9ce97c02f8a7128ea400e3da7ef74bb`](https://github.com/wevm/wagmi/commit/b08013eaa9ce97c02f8a7128ea400e3da7ef74bb), [`d3814ab4b88f9f0e052b53bc3d458df87b43f01d`](https://github.com/wevm/wagmi/commit/d3814ab4b88f9f0e052b53bc3d458df87b43f01d)]: + - @wagmi/core@2.11.8 + +## 5.0.22 + +### Patch Changes + +- [`0bb8b562ae04ecfeb2d6b2f1b980ebae31dc127e`](https://github.com/wevm/wagmi/commit/0bb8b562ae04ecfeb2d6b2f1b980ebae31dc127e) Thanks [@tmm](https://github.com/tmm)! - Improved TypeScript `'exactOptionalPropertyTypes'` support. + +- Updated dependencies [[`0bb8b562ae04ecfeb2d6b2f1b980ebae31dc127e`](https://github.com/wevm/wagmi/commit/0bb8b562ae04ecfeb2d6b2f1b980ebae31dc127e)]: + - @wagmi/core@2.11.7 + +## 5.0.21 + +### Patch Changes + +- [#4094](https://github.com/wevm/wagmi/pull/4094) [`ff0760b5900114bcfdf420a9fba3cc278ac95afe`](https://github.com/wevm/wagmi/commit/ff0760b5900114bcfdf420a9fba3cc278ac95afe) Thanks [@omridan159](https://github.com/omridan159)! - Bumped MetaMask SDK to fix `metaMask` connector error bubbling. + +- Updated dependencies [[`95965c1f19d480b97f2b297a077a9e607dee32ad`](https://github.com/wevm/wagmi/commit/95965c1f19d480b97f2b297a077a9e607dee32ad)]: + - @wagmi/core@2.11.6 + +## 5.0.20 + +### Patch Changes + +- [`43fa971d34cac57fa5a2898ad4d839b95d7af37c`](https://github.com/wevm/wagmi/commit/43fa971d34cac57fa5a2898ad4d839b95d7af37c) Thanks [@tmm](https://github.com/tmm)! - Bumped Coinbase Wallet SDK and fixed `metaMask` connector hang on mobile. + +## 5.0.19 + +### Patch Changes + +- [#4083](https://github.com/wevm/wagmi/pull/4083) [`b7ad208030d9f2e3f89912ff76b16cdbd848feda`](https://github.com/wevm/wagmi/commit/b7ad208030d9f2e3f89912ff76b16cdbd848feda) Thanks [@omridan159](https://github.com/omridan159)! - Bumped MetaMask SDK + +## 5.0.18 + +### Patch Changes + +- [#4081](https://github.com/wevm/wagmi/pull/4081) [`44d24620c9e3957f3245d14d6a042736371df70b`](https://github.com/wevm/wagmi/commit/44d24620c9e3957f3245d14d6a042736371df70b) Thanks [@tmm](https://github.com/tmm)! - Bumped MetaMask SDK + +## 5.0.17 + +### Patch Changes + +- Updated dependencies [[`04f2b846b113f3d300d82c9fa75212f1805817c5`](https://github.com/wevm/wagmi/commit/04f2b846b113f3d300d82c9fa75212f1805817c5)]: + - @wagmi/core@2.11.5 + +## 5.0.16 + +### Patch Changes + +- [#4071](https://github.com/wevm/wagmi/pull/4071) [`02c38c28d1aa0ad7a61c33775de603ed974c5c1b`](https://github.com/wevm/wagmi/commit/02c38c28d1aa0ad7a61c33775de603ed974c5c1b) Thanks [@omridan159](https://github.com/omridan159)! - Bumped MetaMask SDK + +- Updated dependencies [[`9e8345cd56186b997b5e56deaa2cfc69b30d15f6`](https://github.com/wevm/wagmi/commit/9e8345cd56186b997b5e56deaa2cfc69b30d15f6)]: + - @wagmi/core@2.11.4 + +## 5.0.15 + +### Patch Changes + +- Updated dependencies [[`8974e6269bb5d7bfaa90db0246bc7d13e8bff798`](https://github.com/wevm/wagmi/commit/8974e6269bb5d7bfaa90db0246bc7d13e8bff798)]: + - @wagmi/core@2.11.3 + +## 5.0.14 + +### Patch Changes + +- Updated dependencies [[`b4d9ef79deb554ee20fed6666a474be5e7cdd522`](https://github.com/wevm/wagmi/commit/b4d9ef79deb554ee20fed6666a474be5e7cdd522)]: + - @wagmi/core@2.11.2 + +## 5.0.13 + +### Patch Changes + +- [`9c862d8d63e3d692a22cef2a90782b74a9103f17`](https://github.com/wevm/wagmi/commit/9c862d8d63e3d692a22cef2a90782b74a9103f17) Thanks [@tmm](https://github.com/tmm)! - Reverted internal module loading utility. + +- Updated dependencies [[`9c862d8d63e3d692a22cef2a90782b74a9103f17`](https://github.com/wevm/wagmi/commit/9c862d8d63e3d692a22cef2a90782b74a9103f17)]: + - @wagmi/core@2.11.1 + +## 5.0.12 + +### Patch Changes + +- Updated dependencies [[`06bb598a7f04c7b167f5b7ff6d46bd15886a6a14`](https://github.com/wevm/wagmi/commit/06bb598a7f04c7b167f5b7ff6d46bd15886a6a14), [`24a45b269bd0214a29d6f82a84ac66ef8c3f3822`](https://github.com/wevm/wagmi/commit/24a45b269bd0214a29d6f82a84ac66ef8c3f3822)]: + - @wagmi/core@2.11.0 + +## 5.0.11 + +### Patch Changes + +- [#4020](https://github.com/wevm/wagmi/pull/4020) [`e3b124ce414b8fd1b2214e2c5a28dc72158a13d1`](https://github.com/wevm/wagmi/commit/e3b124ce414b8fd1b2214e2c5a28dc72158a13d1) Thanks [@tmm](https://github.com/tmm)! - Added reconnection support to `metaMask` on mobile and use deeplinks by default. + +- Updated dependencies [[`f2a7cefab96691ebed8b8e45ffde071c47b58dbe`](https://github.com/wevm/wagmi/commit/f2a7cefab96691ebed8b8e45ffde071c47b58dbe), [`f0ea0b2a7fe193dadfeb49a4c8031ee451c638b5`](https://github.com/wevm/wagmi/commit/f0ea0b2a7fe193dadfeb49a4c8031ee451c638b5)]: + - @wagmi/core@2.10.6 + +## 5.0.10 + +### Patch Changes + +- [`560952acd4bfe33db6c7c07b35c613cef278677c`](https://github.com/wevm/wagmi/commit/560952acd4bfe33db6c7c07b35c613cef278677c) Thanks [@tmm](https://github.com/tmm)! - Captured Coinbase Smart Wallet error when closing window as EIP-1193 `4001` error. + +## 5.0.9 + +### Patch Changes + +- [`32cdd7b7dc5aff916c040628519562c3a99d418d`](https://github.com/wevm/wagmi/commit/32cdd7b7dc5aff916c040628519562c3a99d418d) Thanks [@tmm](https://github.com/tmm)! - Bumped `@metamask/sdk` to remove peer dependency install warning. + +## 5.0.8 + +### Patch Changes + +- [#3997](https://github.com/wevm/wagmi/pull/3997) [`c1952d1ff7f0a491dc88595a49159451b07b5621`](https://github.com/wevm/wagmi/commit/c1952d1ff7f0a491dc88595a49159451b07b5621) Thanks [@nateReiners](https://github.com/nateReiners)! - Bumped Coinbase Wallet SDK. + +## 5.0.7 + +### Patch Changes + +- Updated dependencies [[`030c7c2cb380dfd67a2182f62e2aa7a6e1601898`](https://github.com/wevm/wagmi/commit/030c7c2cb380dfd67a2182f62e2aa7a6e1601898)]: + - @wagmi/core@2.10.5 + +## 5.0.6 + +### Patch Changes + +- Updated dependencies [[`51fde8a0433b4fff357c1a8d7e08b41b4c86c968`](https://github.com/wevm/wagmi/commit/51fde8a0433b4fff357c1a8d7e08b41b4c86c968)]: + - @wagmi/core@2.10.4 + +## 5.0.5 + +### Patch Changes + +- [#3979](https://github.com/wevm/wagmi/pull/3979) [`70dd28669dd8d2ce08217cd02e29a8fbba7a08d4`](https://github.com/wevm/wagmi/commit/70dd28669dd8d2ce08217cd02e29a8fbba7a08d4) Thanks [@tmm](https://github.com/tmm)! - Fixed `walletConnect` connector. + +## 5.0.4 + +### Patch Changes + +- [#3972](https://github.com/wevm/wagmi/pull/3972) [`be9e1b8a9818b92eb0654a20d9471e9e39329e7e`](https://github.com/wevm/wagmi/commit/be9e1b8a9818b92eb0654a20d9471e9e39329e7e) Thanks [@nateReiners](https://github.com/nateReiners)! - Bumped Coinbase Wallet SDK. + +## 5.0.3 + +### Patch Changes + +- [#3962](https://github.com/wevm/wagmi/pull/3962) [`2804a8a583b1874271154898b4bae38756ef581c`](https://github.com/wevm/wagmi/commit/2804a8a583b1874271154898b4bae38756ef581c) Thanks [@tmm](https://github.com/tmm)! - Added timeout to `getInfo` called in `safe` connector since [non-Safe App iFrames cause it to not resolve](https://github.com/safe-global/safe-apps-sdk/issues/263#issuecomment-1029835840). + +- Updated dependencies [[`2804a8a583b1874271154898b4bae38756ef581c`](https://github.com/wevm/wagmi/commit/2804a8a583b1874271154898b4bae38756ef581c)]: + - @wagmi/core@2.10.3 + +## 5.0.2 + +### Patch Changes + +- [#3940](https://github.com/wevm/wagmi/pull/3940) [`a5071f581dfdfb961718873643a2fc629101c72a`](https://github.com/wevm/wagmi/commit/a5071f581dfdfb961718873643a2fc629101c72a) Thanks [@jxom](https://github.com/jxom)! - Fixed usage of `metaMask` connector in Vite environments. + +- Updated dependencies [[`a5071f581dfdfb961718873643a2fc629101c72a`](https://github.com/wevm/wagmi/commit/a5071f581dfdfb961718873643a2fc629101c72a)]: + - @wagmi/core@2.10.2 + +## 5.0.1 + +### Patch Changes + +- Bumped versions. + +- Updated dependencies []: + - @wagmi/core@2.10.1 + +## 5.0.0 + +### Major Changes + +- [#3928](https://github.com/wevm/wagmi/pull/3928) [`3117e71825f9c58a0d718f3d1686f1a191fa9cb1`](https://github.com/wevm/wagmi/commit/3117e71825f9c58a0d718f3d1686f1a191fa9cb1) Thanks [@tmm](https://github.com/tmm)! - **Breaking:** Updated default Coinbase SDK in `coinbaseWallet` Connector to v4.x. + + Added a `version` property (defaults to `'4'`) to the `coinbaseWallet` Connector to target a version of the Coinbase SDK: + + ```diff + coinbaseWallet({ + + version: '3' | '4', + }) + ``` + + If `headlessMode` property is set to `true`, then the Connector will target v3 of the Coinbase SDK. + + The following properties are removed in v4 of the `coinbaseWallet` Connector: + + - `chainId` + - `darkMode` + - `diagnosticLogger` + - `enableMobileDeepLink` + - `jsonRpcUrl` + - `linkApiUrl` + - `overrideIsCoinbaseBrowser` + - `overrideIsCoinbaseWallet` + - `overrideIsMetaMask` + - `reloadOnDisconnect` + - `uiConstructor` + + Consumers can still use the above properties in v3 by passing `version: '3'` to the Connector. However, please note that v3 of the Coinbase SDK is deprecated and will be removed in a future release. + +### Patch Changes + +- Updated dependencies [[`3117e71825f9c58a0d718f3d1686f1a191fa9cb1`](https://github.com/wevm/wagmi/commit/3117e71825f9c58a0d718f3d1686f1a191fa9cb1)]: + - @wagmi/core@2.10.0 + +## 4.3.10 + +### Patch Changes + +- [#3906](https://github.com/wevm/wagmi/pull/3906) [`32fcb4a31dde6b0206961d8ffe9c651f8a459c67`](https://github.com/wevm/wagmi/commit/32fcb4a31dde6b0206961d8ffe9c651f8a459c67) Thanks [@tmm](https://github.com/tmm)! - Added support for Vue. + +- Updated dependencies [[`32fcb4a31dde6b0206961d8ffe9c651f8a459c67`](https://github.com/wevm/wagmi/commit/32fcb4a31dde6b0206961d8ffe9c651f8a459c67)]: + - @wagmi/core@2.9.8 + +## 4.3.9 + +### Patch Changes + +- [#3924](https://github.com/wevm/wagmi/pull/3924) [`1f58734f88458e0f6adb05c99f0c90f36ab286b8`](https://github.com/wevm/wagmi/commit/1f58734f88458e0f6adb05c99f0c90f36ab286b8) Thanks [@jxom](https://github.com/jxom)! - Refactored `isChainsStale` logic in `walletConnect` connector. + +- Updated dependencies [[`1f58734f88458e0f6adb05c99f0c90f36ab286b8`](https://github.com/wevm/wagmi/commit/1f58734f88458e0f6adb05c99f0c90f36ab286b8)]: + - @wagmi/core@2.9.7 + +## 4.3.8 + +### Patch Changes + +- [#3917](https://github.com/wevm/wagmi/pull/3917) [`05948fdad5bb4a56b08916d45b3dec2cb1e5f55b`](https://github.com/wevm/wagmi/commit/05948fdad5bb4a56b08916d45b3dec2cb1e5f55b) Thanks [@jxom](https://github.com/jxom)! - Updated `@metamask/sdk`. + +- Updated dependencies [[`05948fdad5bb4a56b08916d45b3dec2cb1e5f55b`](https://github.com/wevm/wagmi/commit/05948fdad5bb4a56b08916d45b3dec2cb1e5f55b)]: + - @wagmi/core@2.9.6 + +## 4.3.7 + +### Patch Changes + +- Updated dependencies [[`4fecbbb66d0aacd03b8c62a6455d11a33cde8f85`](https://github.com/wevm/wagmi/commit/4fecbbb66d0aacd03b8c62a6455d11a33cde8f85)]: + - @wagmi/core@2.9.5 + +## 4.3.6 + +### Patch Changes + +- Updated dependencies [[`e6139a97c4b8804d734b1547b5e3921ce01fbe24`](https://github.com/wevm/wagmi/commit/e6139a97c4b8804d734b1547b5e3921ce01fbe24)]: + - @wagmi/core@2.9.4 + +## 4.3.5 + +### Patch Changes + +- [#3904](https://github.com/wevm/wagmi/pull/3904) [`addca28ebc20f1a4367c35fe9ef786decff9c87e`](https://github.com/wevm/wagmi/commit/addca28ebc20f1a4367c35fe9ef786decff9c87e) Thanks [@jxom](https://github.com/jxom)! - Updated `@walletconnect/ethereum-provider`. + +- Updated dependencies [[`addca28ebc20f1a4367c35fe9ef786decff9c87e`](https://github.com/wevm/wagmi/commit/addca28ebc20f1a4367c35fe9ef786decff9c87e)]: + - @wagmi/core@2.9.3 + +## 4.3.4 + +### Patch Changes + +- [#3902](https://github.com/wevm/wagmi/pull/3902) [`204b7b624612405500ec098fb9e35facd3f74ca4`](https://github.com/wevm/wagmi/commit/204b7b624612405500ec098fb9e35facd3f74ca4) Thanks [@jxom](https://github.com/jxom)! - Made third-party SDK imports type-only. + +- Updated dependencies [[`204b7b624612405500ec098fb9e35facd3f74ca4`](https://github.com/wevm/wagmi/commit/204b7b624612405500ec098fb9e35facd3f74ca4)]: + - @wagmi/core@2.9.2 + +## 4.3.3 + +### Patch Changes + +- Updated dependencies [[`cda6a5d5`](https://github.com/wevm/wagmi/commit/cda6a5d56328330fbde050b4ef40b01c58d2519a)]: + - @wagmi/core@2.9.1 + +## 4.3.2 + +### Patch Changes + +- Updated dependencies [[`017828fc`](https://github.com/wevm/wagmi/commit/017828fc027c7a84b54ea9d627e9389f4d60d6c2)]: + - @wagmi/core@2.9.0 + +## 4.3.1 + +### Patch Changes + +- Updated dependencies [[`d4a78eb0`](https://github.com/wevm/wagmi/commit/d4a78eb07119d2e5617e52481ac7d6c6d1583ddc)]: + - @wagmi/core@2.8.1 + +## 4.3.0 + +### Minor Changes + +- [#3868](https://github.com/wevm/wagmi/pull/3868) [`c2af20b8`](https://github.com/wevm/wagmi/commit/c2af20b88cf16970d087faaec10b463357a5836e) Thanks [@jxom](https://github.com/jxom)! - Added `supportsSimulation` property to connectors that indicates if the connector's wallet supports contract simulation. + +### Patch Changes + +- Updated dependencies [[`0d141f17`](https://github.com/wevm/wagmi/commit/0d141f171d6ec44bcbfc9c876565b5e2fb8af6de), [`c2af20b8`](https://github.com/wevm/wagmi/commit/c2af20b88cf16970d087faaec10b463357a5836e)]: + - @wagmi/core@2.8.0 + +## 4.2.0 + +### Minor Changes + +- [#3857](https://github.com/wevm/wagmi/pull/3857) [`d4274c03`](https://github.com/wevm/wagmi/commit/d4274c03a6af5f2d26d31432016ebc14950a330e) Thanks [@tmm](https://github.com/tmm)! - Added `addEthereumChainParameter` to `switchChain`-related methods. + +### Patch Changes + +- Updated dependencies [[`d4274c03`](https://github.com/wevm/wagmi/commit/d4274c03a6af5f2d26d31432016ebc14950a330e), [`4781a405`](https://github.com/wevm/wagmi/commit/4781a4056d4ffc2c74f96a75429e9b2cd2417ad8), [`400c960b`](https://github.com/wevm/wagmi/commit/400c960b30d701c134850c695ae903a382c29b5b)]: + - @wagmi/core@2.7.0 + +## 4.1.28 + +### Patch Changes + +- [`e3c832a1`](https://github.com/wevm/wagmi/commit/e3c832a12c301f9b0ee129d877b3101d220ba8b2) Thanks [@jxom](https://github.com/jxom)! - Fixed undefined `navigator` issue in MetaMask connector. + +- Updated dependencies [[`e3c832a1`](https://github.com/wevm/wagmi/commit/e3c832a12c301f9b0ee129d877b3101d220ba8b2)]: + - @wagmi/core@2.6.19 + +## 4.1.27 + +### Patch Changes + +- [#3848](https://github.com/wevm/wagmi/pull/3848) [`dd40a41c`](https://github.com/wevm/wagmi/commit/dd40a41c526ab60a288aff2250ed8dba92a27b16) Thanks [@jxom](https://github.com/jxom)! - Updated MetaMask SDK. + +- Updated dependencies [[`dd40a41c`](https://github.com/wevm/wagmi/commit/dd40a41c526ab60a288aff2250ed8dba92a27b16)]: + - @wagmi/core@2.6.18 + +## 4.1.26 + +### Patch Changes + +- Updated dependencies [[`a97bfbae`](https://github.com/wevm/wagmi/commit/a97bfbaeb615cfef04665e5e7348d85d17f960f0)]: + - @wagmi/core@2.6.17 + +## 4.1.25 + +### Patch Changes + +- [#3788](https://github.com/wevm/wagmi/pull/3788) [`42ad380d`](https://github.com/wevm/wagmi/commit/42ad380d9a5d8bc0f61d73612142dea9d098de5e) Thanks [@tmm](https://github.com/tmm)! - Refactored connectors to remove unnecessarily event listeners. + +- Updated dependencies [[`42ad380d`](https://github.com/wevm/wagmi/commit/42ad380d9a5d8bc0f61d73612142dea9d098de5e)]: + - @wagmi/core@2.6.16 + +## 4.1.24 + +### Patch Changes + +- Updated dependencies [[`b907d5ac`](https://github.com/wevm/wagmi/commit/b907d5ac3a746bcbccc06d1fe78c5bd8f9a7d685)]: + - @wagmi/core@2.6.15 + +## 4.1.23 + +### Patch Changes + +- Updated dependencies [[`b3b54ef1`](https://github.com/wevm/wagmi/commit/b3b54ef179c5fa0d1694d38d4b808549a0550409), [`3da20bb8`](https://github.com/wevm/wagmi/commit/3da20bb80e7c3efeef8227ced66ad615370fc242), [`a3d1858f`](https://github.com/wevm/wagmi/commit/a3d1858fce448d2b70e36ee692ef1589b74e9d3f)]: + - @wagmi/core@2.6.14 + +## 4.1.22 + +### Patch Changes + +- Updated dependencies [[`b80236dc`](https://github.com/wevm/wagmi/commit/b80236dc623095fe8f1e1d10957d7776fb6ab48b)]: + - @wagmi/core@2.6.13 + +## 4.1.21 + +### Patch Changes + +- Updated dependencies [[`a59069e9`](https://github.com/wevm/wagmi/commit/a59069e9fab45dd606bb89a7f829fe94c51a5494), [`0acd3132`](https://github.com/wevm/wagmi/commit/0acd31320f534993af566be5490c2978b6184f66)]: + - @wagmi/core@2.6.12 + +## 4.1.20 + +### Patch Changes + +- [`e1ca4e63`](https://github.com/wevm/wagmi/commit/e1ca4e637ae6cec7f5902b0a2c0e0efc3b751a1d) Thanks [@tmm](https://github.com/tmm)! - Deprecated `normalizeChainId`. Use `Number` instead. + +- Updated dependencies [[`e1ca4e63`](https://github.com/wevm/wagmi/commit/e1ca4e637ae6cec7f5902b0a2c0e0efc3b751a1d)]: + - @wagmi/core@2.6.11 + +## 4.1.19 + +### Patch Changes + +- Updated dependencies [[`dbdca8fd`](https://github.com/wevm/wagmi/commit/dbdca8fd14b90c166222a66a373c1b33c06ce019)]: + - @wagmi/core@2.6.10 + +## 4.1.18 + +### Patch Changes + +- Updated dependencies [[`d56edf4f`](https://github.com/wevm/wagmi/commit/d56edf4f27c52acc7a0f57114454b0d3e22cacd6)]: + - @wagmi/core@2.6.9 + +## 4.1.17 + +### Patch Changes + +- Updated dependencies [[`e46bcd47`](https://github.com/wevm/wagmi/commit/e46bcd4738a18da15b53f6612b614379c1985374)]: + - @wagmi/core@2.6.8 + +## 4.1.16 + +### Patch Changes + +- [`1c1fee6a`](https://github.com/wevm/wagmi/commit/1c1fee6ab8f01f7734ac6ce05093fa8e388beb3e) Thanks [@jxom](https://github.com/jxom)! - Updated `@walletconnect/ethereum-provider`. + +- [#3653](https://github.com/wevm/wagmi/pull/3653) [`88a2d744`](https://github.com/wevm/wagmi/commit/88a2d744a1315908c9e54156026df3ad2435ad44) Thanks [@tash-2s](https://github.com/tash-2s)! - Fixed error occurring when adding chains without explorers to MetaMask. + +- Updated dependencies [[`b479b5e8`](https://github.com/wevm/wagmi/commit/b479b5e8a5866cba792862f22e6352c4fb566137), [`f5648dd2`](https://github.com/wevm/wagmi/commit/f5648dd28b3576b628f57732b89287f55acbb1c1), [`1c1fee6a`](https://github.com/wevm/wagmi/commit/1c1fee6ab8f01f7734ac6ce05093fa8e388beb3e), [`88a2d744`](https://github.com/wevm/wagmi/commit/88a2d744a1315908c9e54156026df3ad2435ad44)]: + - @wagmi/core@2.6.7 + +## 4.1.15 + +### Patch Changes + +- Updated dependencies [[`a91c0b64`](https://github.com/wevm/wagmi/commit/a91c0b64ba8b3e6537a560e69724eb601f26af27)]: + - @wagmi/core@2.6.6 + +## 4.1.14 + +### Patch Changes + +- [#3591](https://github.com/wevm/wagmi/pull/3591) [`ca5decdb`](https://github.com/wevm/wagmi/commit/ca5decdb712f81e3f5dab933a94b967bca5b6af4) Thanks [@tmm](https://github.com/tmm)! - Fixed Coinbase Wallet import. + +- Updated dependencies [[`c677dcd2`](https://github.com/wevm/wagmi/commit/c677dcd245dccdf69289a3d66dded237b09570a2)]: + - @wagmi/core@2.6.5 + +## 4.1.13 + +### Patch Changes + +- [#3569](https://github.com/wevm/wagmi/pull/3569) [`fa25b448`](https://github.com/wevm/wagmi/commit/fa25b4482504b4d9729a5687ea6d6dc959265bc0) Thanks [@svenvoskamp](https://github.com/svenvoskamp)! - Updated dependencies. + +- [#3558](https://github.com/wevm/wagmi/pull/3558) [`895f28e8`](https://github.com/wevm/wagmi/commit/895f28e873af7c8eda5ca85734ff67c8979fd950) Thanks [@tmm](https://github.com/tmm)! - Fixed connector warnings. + +- Updated dependencies [[`7c6618e6`](https://github.com/wevm/wagmi/commit/7c6618e6a0eb1ff39cf8f66b34d3ddc14be538fe), [`895f28e8`](https://github.com/wevm/wagmi/commit/895f28e873af7c8eda5ca85734ff67c8979fd950)]: + - @wagmi/core@2.6.4 + +## 4.1.12 + +### Patch Changes + +- Updated dependencies [[`9c3b85dd`](https://github.com/wevm/wagmi/commit/9c3b85dd0a9a4a593e1d7e029345275735330e32), [`2a72214a`](https://github.com/wevm/wagmi/commit/2a72214a2901d6b6ddd39f80238aa0bd4db670a7)]: + - @wagmi/core@2.6.3 + +## 4.1.11 + +### Patch Changes + +- [#3518](https://github.com/wevm/wagmi/pull/3518) [`338e857d`](https://github.com/wevm/wagmi/commit/338e857d8cb2fe85e13d9207bef14cada1c1962d) Thanks [@tmm](https://github.com/tmm)! - Bumped dependencies. + +- Updated dependencies [[`414eb048`](https://github.com/wevm/wagmi/commit/414eb048af492caac70c0e874dfc87c30702804a), [`338e857d`](https://github.com/wevm/wagmi/commit/338e857d8cb2fe85e13d9207bef14cada1c1962d)]: + - @wagmi/core@2.6.2 + +## 4.1.10 + +### Patch Changes + +- [#3510](https://github.com/wevm/wagmi/pull/3510) [`660ff80d`](https://github.com/wevm/wagmi/commit/660ff80d5b046967a446eba43ee54b8359a37d0d) Thanks [@tmm](https://github.com/tmm)! - Fixed issue where connectors returning multiple addresses didn't checksum correctly. + +- Updated dependencies [[`660ff80d`](https://github.com/wevm/wagmi/commit/660ff80d5b046967a446eba43ee54b8359a37d0d), [`101a7dd1`](https://github.com/wevm/wagmi/commit/101a7dd131b0cae2dc25579ecab9044290efd37b)]: + - @wagmi/core@2.6.1 + +## 4.1.9 + +### Patch Changes + +- [#3496](https://github.com/wevm/wagmi/pull/3496) [`ba7f8a75`](https://github.com/wevm/wagmi/commit/ba7f8a758efb07664c6e401b5e7e325e7c62341b) Thanks [@tmm](https://github.com/tmm)! - Bumped dependencies. + +- Updated dependencies [[`ba7f8a75`](https://github.com/wevm/wagmi/commit/ba7f8a758efb07664c6e401b5e7e325e7c62341b)]: + - @wagmi/core@2.6.0 + +## 4.1.8 + +### Patch Changes + +- Updated dependencies [[`ca98041d`](https://github.com/wevm/wagmi/commit/ca98041d1b39893d90246929485f4db0d1c6f9f7)]: + - @wagmi/core@2.5.0 + +## 4.1.7 + +### Patch Changes + +- [#3427](https://github.com/wevm/wagmi/pull/3427) [`370f1b4a`](https://github.com/wevm/wagmi/commit/370f1b4a3f154d181acf381c31c2e7862e22c0e4) Thanks [@marthendalnunes](https://github.com/marthendalnunes)! - Bumped dependencies. + +- Updated dependencies [[`370f1b4a`](https://github.com/wevm/wagmi/commit/370f1b4a3f154d181acf381c31c2e7862e22c0e4)]: + - @wagmi/core@2.4.0 + +## 4.1.6 + +### Patch Changes + +- Updated dependencies [[`3be5bb7b`](https://github.com/wevm/wagmi/commit/3be5bb7b0b38646e12e6da5c762ef74dff66bcc2)]: + - @wagmi/core@2.3.1 + +## 4.1.5 + +### Patch Changes + +- [#3459](https://github.com/wevm/wagmi/pull/3459) [`d950b666`](https://github.com/wevm/wagmi/commit/d950b666b56700ca039ce16cdfdf34564991e7f5) Thanks [@marthendalnunes](https://github.com/marthendalnunes)! - Bumped dependencies + +- [`1cfb6e5a`](https://github.com/wevm/wagmi/commit/1cfb6e5a875e707abcee00dd5739e87da05e8c90) Thanks [@jxom](https://github.com/jxom)! - Bumped listener limit on WalletConnect connector. + +- Updated dependencies [[`d950b666`](https://github.com/wevm/wagmi/commit/d950b666b56700ca039ce16cdfdf34564991e7f5), [`90ef39bb`](https://github.com/wevm/wagmi/commit/90ef39bb0f4ecb3c914d317875348e35ba0f4524), [`1cfb6e5a`](https://github.com/wevm/wagmi/commit/1cfb6e5a875e707abcee00dd5739e87da05e8c90)]: + - @wagmi/core@2.3.0 + +## 4.1.4 + +### Patch Changes + +- [#3443](https://github.com/wevm/wagmi/pull/3443) [`007024a6`](https://github.com/wevm/wagmi/commit/007024a684ddbecf924cdc06dd6a8854fc3d5eeb) Thanks [@jmrossy](https://github.com/jmrossy)! - Bumped dependencies. + +- [#3447](https://github.com/wevm/wagmi/pull/3447) [`a02a26ad`](https://github.com/wevm/wagmi/commit/a02a26ad030d3afb78f744377d61b5c60b65d97a) Thanks [@tmm](https://github.com/tmm)! - Bumped dependencies. + +- Updated dependencies [[`a02a26ad`](https://github.com/wevm/wagmi/commit/a02a26ad030d3afb78f744377d61b5c60b65d97a), [`007024a6`](https://github.com/wevm/wagmi/commit/007024a684ddbecf924cdc06dd6a8854fc3d5eeb)]: + - @wagmi/core@2.2.1 + +## 4.1.3 + +### Patch Changes + +- Updated dependencies [[`00bf10a4`](https://github.com/wevm/wagmi/commit/00bf10a428b0d1c5dac35ebf25b19571e033ac26), [`64c073f6`](https://github.com/wevm/wagmi/commit/64c073f6c2720961e2d6aff986670b73dbfab9c3), [`fb6c4148`](https://github.com/wevm/wagmi/commit/fb6c4148d9e9e2fccfbe74c8f343b444dc68dec5)]: + - @wagmi/core@2.2.0 + +## 4.1.2 + +### Patch Changes + +- Updated dependencies [[`e00b8205`](https://github.com/wevm/wagmi/commit/e00b82058685751637edfa9a6b2d196a12549fe7)]: + - @wagmi/core@2.1.2 + +## 4.1.1 + +### Patch Changes + +- [`ec0d8b41`](https://github.com/wevm/wagmi/commit/ec0d8b4112181fefb11025e436a94a6114761d37) Thanks [@tmm](https://github.com/tmm)! - Added note to `metaMask` connector. + +- Updated dependencies [[`64b82282`](https://github.com/wevm/wagmi/commit/64b82282c1e57e77c25aa0814673780e4d11edd4), [`ec0d8b41`](https://github.com/wevm/wagmi/commit/ec0d8b4112181fefb11025e436a94a6114761d37)]: + - @wagmi/core@2.1.1 + +## 4.1.0 + +### Minor Changes + +- Updated dependencies [[`c9cd302e`](https://github.com/wevm/wagmi/commit/c9cd302e1c65c980deaee2e12567c2a8ec08b399)]: + - @wagmi/core@2.1.0 + +## 4.0.2 + +### Patch Changes + +- [#3384](https://github.com/wevm/wagmi/pull/3384) [`ee868c33`](https://github.com/wevm/wagmi/commit/ee868c3385dae511230b6ddcb5627c1293cc1844) Thanks [@tmm](https://github.com/tmm)! - Fixed connectors not bubbling error when connecting with `chainId` and subsequent user rejection. + +- Updated dependencies [[`ee868c33`](https://github.com/wevm/wagmi/commit/ee868c3385dae511230b6ddcb5627c1293cc1844)]: + - @wagmi/core@2.0.2 + +## 4.0.1 + +### Major Changes + +- [#3333](https://github.com/wevm/wagmi/pull/3333) [`b3a0baaa`](https://github.com/wevm/wagmi/commit/b3a0baaaee7decf750d376aab2502cd33ca4825a) Thanks [@tmm](https://github.com/tmm)! - Added support for Wagmi 2.0. + +### Patch Changes + +- Updated dependencies [[`b3a0baaa`](https://github.com/wevm/wagmi/commit/b3a0baaaee7decf750d376aab2502cd33ca4825a)]: + - @wagmi/core@2.0.0 + +## 3.1.11 + +### Patch Changes + +- [#3361](https://github.com/wevm/wagmi/pull/3361) [`bbbbf587`](https://github.com/wevm/wagmi/commit/bbbbf587e41bae12b072b7a7c897d580fc07cd2b) Thanks [@0xAsimetriq](https://github.com/0xAsimetriq)! - Updated WalletConnect connector dependencies + +## 3.1.10 + +### Patch Changes + +- [`53ca1f7e`](https://github.com/wevm/wagmi/commit/53ca1f7eb411d912e11fcce7e03bd61ed067959c) Thanks [@tmm](https://github.com/tmm)! - Removed LedgerConnector due to security vulnerability + +## 3.1.9 + +### Patch Changes + +- [#3114](https://github.com/wevm/wagmi/pull/3114) [`51eca0fb`](https://github.com/wevm/wagmi/commit/51eca0fbaea6932f31a5b8b4213f0252280053e2) Thanks [@akathecoder](https://github.com/akathecoder)! - Added Okto Wallet to Injected Wallets Connector + +- [#3299](https://github.com/wevm/wagmi/pull/3299) [`b02020b3`](https://github.com/wevm/wagmi/commit/b02020b3724e0228198f35817611bb063295906e) Thanks [@dasanra](https://github.com/dasanra)! - Fixed issue with [Safe SDK](https://github.com/wevm/viem/issues/579) by bumping `@safe-global/safe-apps-provider@0.18.1` + +## 3.1.8 + +### Patch Changes + +- [#3197](https://github.com/wevm/wagmi/pull/3197) [`e8f7bcbc`](https://github.com/wevm/wagmi/commit/e8f7bcbcd9c038a901c29e71769682c088efe2ac) Thanks [@ByteZhang1024](https://github.com/ByteZhang1024)! - Added OneKey Wallet to injected connector flags. + +## 3.1.7 + +### Patch Changes + +- [#3276](https://github.com/wevm/wagmi/pull/3276) [`83223a06`](https://github.com/wevm/wagmi/commit/83223a0659e2f675d897a1d3374c7af752c16abf) Thanks [@glitch-txs](https://github.com/glitch-txs)! - Removed required namespaces from WalletConnect connector + +## 3.1.6 + +### Patch Changes + +- [#3236](https://github.com/wevm/wagmi/pull/3236) [`cc7e18f2`](https://github.com/wevm/wagmi/commit/cc7e18f2e7f6b8b989f60f0b05aee70e996a9975) Thanks [@0xAsimetriq](https://github.com/0xAsimetriq)! - Updated @walletconnect/ethereum-provider + +- [#3236](https://github.com/wevm/wagmi/pull/3236) [`cc7e18f2`](https://github.com/wevm/wagmi/commit/cc7e18f2e7f6b8b989f60f0b05aee70e996a9975) Thanks [@0xAsimetriq](https://github.com/0xAsimetriq)! - Updated @walletconnect/ethereum-provider + +## 3.1.5 + +### Patch Changes + +- [#3220](https://github.com/wagmi-dev/wagmi/pull/3220) [`a1950449`](https://github.com/wagmi-dev/wagmi/commit/a1950449127ddf72fff8ecd1fc34c3690befbb05) Thanks [@rkalis](https://github.com/rkalis)! - Fixed a bug where injected walets with an empty providers array could not connect + +## 3.1.4 + +### Patch Changes + +- [#3115](https://github.com/wagmi-dev/wagmi/pull/3115) [`4e6ec415`](https://github.com/wagmi-dev/wagmi/commit/4e6ec4151baece94e940e227e0e3711c7f8534d9) Thanks [@bifot](https://github.com/bifot)! - Added SafePal injected name mapping. + +## 3.1.3 + +### Patch Changes + +- [#3141](https://github.com/wagmi-dev/wagmi/pull/3141) [`e78aa337`](https://github.com/wagmi-dev/wagmi/commit/e78aa337c454f04b41a3cbd381d25270dd4a0afd) Thanks [@einaralex](https://github.com/einaralex)! - Updated WalletConnect libraries. + +## 3.1.2 + +### Patch Changes + +- [#3009](https://github.com/wagmi-dev/wagmi/pull/3009) [`3aaba328`](https://github.com/wagmi-dev/wagmi/commit/3aaba32808ddb4035ec885f96992c91078056715) Thanks [@0xAsimetriq](https://github.com/0xAsimetriq)! - Update WalletConnect dependencies + +## 3.1.1 + +### Patch Changes + +- [#2973](https://github.com/wevm/wagmi/pull/2973) [`bf831bb3`](https://github.com/wevm/wagmi/commit/bf831bb30df8037cc4312342d0fe3c045408c2fe) Thanks [@masm](https://github.com/masm)! - Added Zeal wallet + +## 3.1.0 + +### Minor Changes + +- [#2956](https://github.com/wevm/wagmi/pull/2956) [`2abeb285`](https://github.com/wevm/wagmi/commit/2abeb285674af3e539cc2550b1f5027b1eb0c895) Thanks [@tmm](https://github.com/tmm)! - Replaced `@wagmi/chains` with `viem/chains`. + +## 3.0.0 + +### Patch Changes + +- 0306383: Updated WalletConnect dependencies +- Updated dependencies [d1ef9b4] +- Updated dependencies [484c846] + - @wagmi/chains@1.8.0 + +## 2.7.0 + +### Minor Changes + +- a270cb9: Updated WalletConnect dependencies. + +### Patch Changes + +- 06cc1b4: Add SubWallet injected flags +- 131a337: Added Desig Wallet name mapping. +- e089d7d: Added Fordefi Wallet name mapping. +- ce84d0a: Added Coin98 Wallet injected flags. +- Updated dependencies [8fdacd8] +- Updated dependencies [2e9283a] +- Updated dependencies [a432a2b] +- Updated dependencies [408740a] +- Updated dependencies [6794a61] +- Updated dependencies [0c5a32b] +- Updated dependencies [ebc85ec] +- Updated dependencies [5683df2] +- Updated dependencies [414ff36] +- Updated dependencies [4f514c6] +- Updated dependencies [1cf72bc] +- Updated dependencies [cd68471] +- Updated dependencies [baf3143] +- Updated dependencies [9737f24] +- Updated dependencies [7797238] +- Updated dependencies [3846811] +- Updated dependencies [0ea344c] + - @wagmi/chains@1.7.0 + +## 2.6.6 + +### Patch Changes + +- 56c127d: Updated WalletConnect dependencies. +- Updated dependencies [4b411d2] +- Updated dependencies [df697ac] +- Updated dependencies [186f5a7] +- Updated dependencies [a96b514] +- Updated dependencies [0a6e6da] + - @wagmi/chains@1.5.0 + +## 2.6.5 + +### Patch Changes + +- 51e346e: Updated WalletConnectConnector logic to handle individual namespaces like eip155:\* + +## 2.6.4 + +### Patch Changes + +- 0a57de2: Added conditional for WalletConnectConnector optionalChains + +## 2.6.3 + +### Patch Changes + +- f2d532d: Updated WalletConnect dependencies, exposed `relayUrl` option for `WalletConnectConnector` +- ff53857: Fixed issue importing `EthereumProvider` in Vite environments. +- Updated dependencies [d642e1d] +- Updated dependencies [3027d7b] +- Updated dependencies [97dbd44] + - @wagmi/chains@1.4.0 + +## 2.6.2 + +### Patch Changes + +- 27bb1b3: Added explicit type annotations for the `getWalletClient()` method. + +## 2.6.1 + +### Patch Changes + +- a3507a9: Updated @walletconnect/ethereum-provider dependency + +## 2.6.0 + +### Minor Changes + +- 32dc317: Updated @walletconnect/ethereum-provider and @walletconnect/modal dependencies + +## 2.5.0 + +### Minor Changes + +- 57e674e: Updated `@safe-global/safe-apps-sdk` & `@safe-global/safe-apps-provider` + +## 2.4.0 + +### Patch Changes + +- f21c8e0: Added WalletConnect v2 support to Ledger connector. +- 27482bb: Add HAQQ Wallet detection +- 7d6aa43: Exported `normalizeChainId`. +- Updated dependencies [62b8209] +- Updated dependencies [106ac13] +- Updated dependencies [8b3f5e5] + - @wagmi/chains@1.3.0 + +## 2.3.0 + +### Minor Changes + +- 28219ae: Added metadata property to WalletConnect init function +- 6fef949: Updated @walletconnect/modal and @walletconnect/ethereum-provider deps + +### Patch Changes + +- 72f6465: Added `TTWallet` to `getInjectedName` list +- Updated dependencies [a7cbd04] +- Updated dependencies [f6ee133] + - @wagmi/chains@1.2.0 + +## 2.2.0 + +### Minor Changes + +- 6c841d4: Changed `Address` type import from ABIType to viem. + +### Patch Changes + +- 09c83f8: Update @walletconnect/ethereum-provider, Replace @web3modal/standalone with @walletconnect/modal, Fix issue with wallet_addEthereumChain method in WalletConnectConnector + +## 2.1.1 + +### Patch Changes + +- c24de75: Updated `@walletconnect/ethereum-provider` and `@web3modal/standalone` dependencies. +- 605c422: Bumped `viem` peer dependency. +- dc1c546: Throw ResourceUnavailableError on -30002 errors. + +## 2.1.0 + +### Minor Changes + +- b001569: Bumped minimum TypeScript version to v5.0.4. + +### Patch Changes + +- 0f05b2b: Updated `abitype` to `0.8.7`. +- 6aea7ee: Fixed internal types. +- b187cb0: Added `isNovaWallet` injected flag. +- 5e44429: Added Edgeware mainnet and testnet +- b18b314: Updated @walletconnect/ethereum-provider and @web3modal/standalone dependencies +- Updated dependencies [b62a199] +- Updated dependencies [b001569] +- Updated dependencies [260ab59] +- Updated dependencies [6aea7ee] +- Updated dependencies [5e44429] + - @wagmi/chains@1.0.0 + +## 2.0.0 + +### Patch Changes + +- Updated dependencies [36c14b2] + - @wagmi/chains@0.3.0 + +## 1.0.5 + +### Patch Changes + +- fa61dfe: Updated viem. +- Updated dependencies [577d2a0] + - @wagmi/chains@0.2.25 + +## 1.0.4 + +### Patch Changes + +- bbbd11b: Corrected Rabby Wallet name +- Updated dependencies [0639a1f] + - @wagmi/chains@0.2.24 + +## 1.0.3 + +### Patch Changes + +- 64dfe61: Update @web3modal/standalone to v2.4.1, Update @walletconnect/ethereum-provider to 2.7.4 +- bab7ad8: Added Defiant to injected connector flags +- 44cde07: Added Talisman wallet flag + +## 1.0.2 + +### Patch Changes + +- bce5a0c: Removed chain fallback when instantiating a Wallet Client. + +## 1.0.1 + +### Patch Changes + +- [`ea651cd7`](https://github.com/wevm/wagmi/commit/ea651cd7fc75b7866272605467db11fd6e1d81af) Thanks [@jxom](https://github.com/jxom)! - Downgraded abitype. + +## 1.0.0 + +### Major Changes + +- 7e274f5: Released v1. + +### Patch Changes + +- 0966bf7: Changed Kucoin Wallet name mapping to Halo Wallet + +## 1.0.0-next.5 + +### Major Changes + +- Updated references. + +## 1.0.0-next.4 + +### Major Changes + +- Updated references. + +## 1.0.0-next.3 + +### Patch Changes + +- Updated dependencies []: + - @wagmi/chains@1.0.0-next.0 + +## 1.0.0-next.2 + +### Major Changes + +- updated viem + +## 1.0.0-next.1 + +### Major Changes + +- [`a7dda00c`](https://github.com/wevm/wagmi/commit/a7dda00c5b546f8b2c42b527e4d9ac1b9e9ab1fb) Thanks [@jxom](https://github.com/jxom)! - Released v1. + +## 1.0.0-next.0 + +### Major Changes + +- 33488cf: Released v1. + +## 0.3.19 + +### Patch Changes + +- 274eef3: - Updated @web3modal/standalone to 2.3.7 + - Updated @walletconnect/ethereum-provider to 2.7.1 +- 41697df: Updated @walletconnect/ethereum-provider version to 2.7.2 +- 82dcb72: Added Enkrypt extension detection + +## 0.3.18 + +### Patch Changes + +- f66e065: Added BlockWallet to injected connector flags. + +## 0.3.17 + +### Patch Changes + +- 12ab5d1: Updated @coinbase/wallet-sdk to 3.6.6 + +## 0.3.16 + +### Patch Changes + +- c1e3ddf: Reverted ABIType version change. + +## 0.3.15 + +### Patch Changes + +- d4825e6: Fixed ABIType version to match downstream packages. + +## 0.3.14 + +### Patch Changes + +- c25ac82: Added more flags to `MetaMaskConnector` `getProvider` check. +- b19a932: Updated @web3modal/standalone to 2.3.0, @walletconnect/ethereum-provider to 2.7.0 +- cdc387e: Added `ImToken` to `getInjectedName` list + +## 0.3.13 + +### Patch Changes + +- 2a21d27: Updated `@coinbase/wallet-sdk` to `3.6.4` + +## 0.3.12 + +### Patch Changes + +- 9bb22b6: Updated `@walletconnect/ethereum-provider` to `2.6.2`, relaxed `@web3modal/standalone` version requirement +- 0d7625b: Added Rabby to injected connector flags +- f63d7fd: Added correct error to switch network cause. + +## 0.3.11 + +### Patch Changes + +- 0778abc: Renamed `isTally` injected provider to `Taho` + +## 0.3.10 + +### Patch Changes + +- 4267020: Added `qrModalOptions` option to `WalletConnectConnector` +- e78fb0a: Pinned WalletConnect dependencies + +## 0.3.9 + +### Patch Changes + +- 5cd0afc: Added `isZerion` to `InjectedProviderFlags` and `getInjectedName` +- be4825e: Added GameStop Wallet to injected connector flags + +## 0.3.8 + +### Patch Changes + +- 11f3fe2: Fixed issue where `UNSTABLE_shimOnConnectSelectAccount` would not bubble up error for MetaMask if request to connect was already active. + +## 0.3.7 + +### Patch Changes + +- 04c0e47: Fixed issue switching chain after adding to MetaMask. + +## 0.3.6 + +### Patch Changes + +- 85330c1: Removed `InjectedConnector` `shimChainChangedDisconnect` shim (no longer necessary). + +## 0.3.5 + +### Patch Changes + +- 8b1a526: Added Dawn wallet flag + +## 0.3.4 + +### Patch Changes + +- 6b15d6f: Updated `@walletconnect/ethereum-provider` to `2.5.1`. +- 1f452e7: Added OKX Wallet to injected connector flags. +- a4d9083: Added Backpack wallet to injected connector flags. +- 6a4af48: Enabled support for programmatic chain switching on `LedgerConnector` & added `"ledger"` to the switch chain regex on `WalletConnectLegacyConnector`. + +## 0.3.3 + +### Patch Changes + +- f24ce0c: Updated @walletconnect/ethereum-provider to 2.4.8 +- e3a3fee: Added "uniswap wallet" to the regex that determines wallets allowed to switch chains in the WalletConnect legacy connector +- 641af48: Added name mapping for Bifrost Wallet +- 4d2c90a: Added name mapping for Phantom +- 3d276d0: Added Status as the name of the injected connector for the Status App + +## 0.3.2 + +### Patch Changes + +- 13a6a07: Updated `@walletconnect/ethereum-provider` to `2.4.7`. + +## 0.3.1 + +### Patch Changes + +- a23c40f: Added name mapping for [Frontier](https://frontier.xyz) Wallet +- d779fb3: Added name mapping for HyperPay. + +## 0.3.0 + +### Minor Changes + +- c4d5bb5: **Breaking:** Removed the `version` config option for `WalletConnectConnector`. + + `WalletConnectConnector` now uses WalletConnect v2 by default. WalletConnect v1 is now `WalletConnectLegacyConnector`. + + ### WalletConnect v2 + + ```diff + import { WalletConnectConnector } from '@wagmi/connectors/walletConnect' + + const connector = new WalletConnectConnector({ + options: { + - version: '2', + projectId: 'abc', + }, + }) + ``` + + ### WalletConnect v1 + + ```diff + -import { WalletConnectConnector } from '@wagmi/connectors/walletConnect' + +import { WalletConnectLegacyConnector } from '@wagmi/connectors/walletConnectLegacy' + + -const connector = new WalletConnectConnector({ + +const connector = new WalletConnectLegacyConnector({ + options: { + qrcode: true, + }, + }) + ``` + +## 0.2.7 + +### Patch Changes + +- 57f1226: Added name mapping for XDEFI + +## 0.2.6 + +### Patch Changes + +- bb1b88c: Added name mapping for Bitski injected wallet +- fcb5595: Fixed shim disconnect key to read from defined Connector ID. +- 49f8853: Fixed `SafeConnector` import type error that existed for specific build environments. + +## 0.2.5 + +### Patch Changes + +- 5d121f2: Added `isApexWallet` to injected `window.ethereum` flags. +- e3566eb: Updated `@web3modal/standalone` to `2.1.1` for WalletConnectConnector. + +## 0.2.4 + +### Patch Changes + +- a4f31bc: Added Connector for [Safe](https://safe.global) wallet +- d5e25d9: Locked ethers peer dependency version to >=5.5.1 <6 + +## 0.2.3 + +### Patch Changes + +- 6fa74dd: Updated `@walletconnect/universal-provider` + Added more signable methods to WC v2. + +## 0.2.2 + +### Patch Changes + +- 6b0725b: Fixed race condition between `switchNetwork` and mutation Hooks that use `chainId` (e.g. `sendTransaction`). + +## 0.2.1 + +### Patch Changes + +- 942fcde: Updated `@walletconnect/universal-provider` and `@web3modal/standalone` packages for WalletConnectConnector (v2). + + Improved initialization flow for `@walletconnect/universal-provider` for WalletConnectConnector (v2). + +## 0.2.0 + +### Minor Changes + +- be33c7d: Chains are now narrowed to their most specific type using the TypeScript [`satisfies`](https://devblogs.microsoft.com/typescript/announcing-typescript-4-9/#the-satisfies-operator) operator. + +## 0.1.10 + +### Patch Changes + +- d75e8d2: Fixed ABIType version mismatch between packages. + +## 0.1.9 + +### Patch Changes + +- 8c3fc00: Added public RPC URL to Connector fallback chains + +## 0.1.8 + +### Patch Changes + +- 5e6dc30: Replaced legacy qrcodemodal with web3modal for WalletConnect v2. + +## 0.1.7 + +### Patch Changes + +- be4add2: Added `isRainbow` flag to `InjectedConnector`. + +## 0.1.6 + +### Patch Changes + +- 3dfc558: Add `switchSigner` method to `MockProvider`. + +## 0.1.5 + +### Patch Changes + +- 7dce4b5: Bumped WalletConnect Universal Provider version. + +## 0.1.4 + +### Patch Changes + +- 4cec598: Added CJS escape hatch bundle under the "cjs" tag. + +## 0.1.3 + +### Patch Changes + +- 822bc88: The `WalletConnectConnector` now supports WalletConnect v2. + + It can be enabled by setting `version` to `'2'` and supplying a [WalletConnect Cloud `projectId`](https://cloud.walletconnect.com/sign-in). + +## 0.1.2 + +### Patch Changes + +- 5e5f37f: Fixed issue where connecting to MetaMask may return with a stale address + +## 0.1.1 + +### Patch Changes + +- 919790c: Updated `@ledgerhq/connect-kit-loader` to `1.0.1` + +## 0.1.0 + +### Minor Changes + +- 5db7cba: Added `LedgerConnector` +- 55a0ca2: Initial release of the `@wagmi/connectors` package – a collection of Connectors for wagmi. diff --git a/wagmi-project/packages/connectors/README.md b/wagmi-project/packages/connectors/README.md new file mode 100644 index 000000000..05418ec15 --- /dev/null +++ b/wagmi-project/packages/connectors/README.md @@ -0,0 +1,13 @@ +# @wagmi/connectors + +Collection of connectors for Wagmi + +## Installation + +```bash +pnpm add @wagmi/connectors @wagmi/core viem +``` + +## Documentation + +For documentation and guides, visit [wagmi.sh](https://wagmi.sh). diff --git a/wagmi-project/packages/connectors/package.json b/wagmi-project/packages/connectors/package.json new file mode 100644 index 000000000..de6d0f0dc --- /dev/null +++ b/wagmi-project/packages/connectors/package.json @@ -0,0 +1,71 @@ +{ + "name": "@wagmi/connectors", + "description": "Collection of connectors for Wagmi", + "version": "5.8.3", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/wevm/wagmi.git", + "directory": "packages/connectors" + }, + "scripts": { + "build": "pnpm run clean && pnpm run build:esm+types", + "build:esm+types": "tsc --project tsconfig.build.json --outDir ./dist/esm --declaration --declarationMap --declarationDir ./dist/types", + "check:types": "tsc --noEmit", + "clean": "rm -rf dist tsconfig.tsbuildinfo", + "test:build": "publint --strict && attw --pack --ignore-rules cjs-resolves-to-esm" + }, + "files": [ + "dist/**", + "!dist/**/*.tsbuildinfo", + "src/**/*.ts", + "!src/**/*.test.ts", + "!src/**/*.test-d.ts" + ], + "sideEffects": false, + "type": "module", + "main": "./dist/esm/exports/index.js", + "types": "./dist/types/exports/index.d.ts", + "typings": "./dist/types/exports/index.d.ts", + "exports": { + ".": { + "types": "./dist/types/exports/index.d.ts", + "default": "./dist/esm/exports/index.js" + }, + "./package.json": "./package.json" + }, + "peerDependencies": { + "@wagmi/core": "workspace:*", + "typescript": ">=5.0.4", + "viem": "2.x" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + }, + "dependencies": { + "@coinbase/wallet-sdk": "4.3.0", + "@metamask/sdk": "0.32.1", + "@safe-global/safe-apps-provider": "0.18.6", + "@safe-global/safe-apps-sdk": "9.1.0", + "@walletconnect/ethereum-provider": "2.20.2", + "cbw-sdk": "npm:@coinbase/wallet-sdk@3.9.3" + }, + "devDependencies": { + "@wagmi/core": "workspace:*", + "msw": "^2.4.9" + }, + "contributors": ["awkweb.eth ", "jxom.eth "], + "funding": "https://github.com/sponsors/wevm", + "keywords": [ + "react", + "hooks", + "eth", + "ethereum", + "dapps", + "wallet", + "web3", + "abi" + ] +} diff --git a/wagmi-project/packages/connectors/src/coinbaseWallet.test.ts b/wagmi-project/packages/connectors/src/coinbaseWallet.test.ts new file mode 100644 index 000000000..99b141e49 --- /dev/null +++ b/wagmi-project/packages/connectors/src/coinbaseWallet.test.ts @@ -0,0 +1,17 @@ +import { config } from '@wagmi/test' +import { expect, expectTypeOf, test } from 'vitest' + +import { coinbaseWallet } from './coinbaseWallet.js' + +test('setup', () => { + const connectorFn = coinbaseWallet({ appName: 'wagmi', version: '4' }) + const connector = config._internal.connectors.setup(connectorFn) + expect(connector.name).toEqual('Coinbase Wallet') + + type ConnectFnParameters = NonNullable< + Parameters<(typeof connector)['connect']>[0] + > + expectTypeOf().toMatchTypeOf< + boolean | undefined + >() +}) diff --git a/wagmi-project/packages/connectors/src/coinbaseWallet.ts b/wagmi-project/packages/connectors/src/coinbaseWallet.ts new file mode 100644 index 000000000..630c91261 --- /dev/null +++ b/wagmi-project/packages/connectors/src/coinbaseWallet.ts @@ -0,0 +1,546 @@ +import type { + Preference, + ProviderInterface, + createCoinbaseWalletSDK, +} from '@coinbase/wallet-sdk' +import { + ChainNotConfiguredError, + type Connector, + createConnector, +} from '@wagmi/core' +import type { Compute, Mutable, Omit } from '@wagmi/core/internal' +import type { + CoinbaseWalletProvider as CBW_Provider, + CoinbaseWalletSDK as CBW_SDK, +} from 'cbw-sdk' +import { + type AddEthereumChainParameter, + type Address, + type Hex, + type ProviderRpcError, + SwitchChainError, + UserRejectedRequestError, + getAddress, + numberToHex, +} from 'viem' + +type Version = '3' | '4' + +export type CoinbaseWalletParameters = + version extends '4' + ? Compute< + { + headlessMode?: false | undefined + /** Coinbase Wallet SDK version */ + version?: version | '3' | undefined + } & Version4Parameters + > + : Compute< + { + /** + * @deprecated `headlessMode` will be removed in the next major version. Upgrade to `version: '4'`. + */ + headlessMode?: true | undefined + /** + * Coinbase Wallet SDK version + * @deprecated Version 3 will be removed in the next major version. Upgrade to `version: '4'`. + * @default '4' + */ + version?: version | '4' | undefined + } & Version3Parameters + > + +coinbaseWallet.type = 'coinbaseWallet' as const +export function coinbaseWallet( + parameters: CoinbaseWalletParameters = {} as any, +): version extends '4' + ? ReturnType + : ReturnType { + if (parameters.version === '3' || parameters.headlessMode) + return version3(parameters as Version3Parameters) as any + return version4(parameters as Version4Parameters) as any +} + +type Version4Parameters = Mutable< + Omit< + Parameters[0], + | 'appChainIds' // set via wagmi config + | 'preference' + > & { + // TODO(v3): Remove `Preference['options']` + /** + * Preference for the type of wallet to display. + * @default 'all' + */ + preference?: Preference['options'] | Compute | undefined + } +> + +function version4(parameters: Version4Parameters) { + type Provider = ProviderInterface & { + // for backwards compatibility + close?(): void + } + type Properties = { + connect(parameters?: { + chainId?: number | undefined + instantOnboarding?: boolean | undefined + isReconnecting?: boolean | undefined + }): Promise<{ + accounts: readonly Address[] + chainId: number + }> + } + + let walletProvider: Provider | undefined + + let accountsChanged: Connector['onAccountsChanged'] | undefined + let chainChanged: Connector['onChainChanged'] | undefined + let disconnect: Connector['onDisconnect'] | undefined + + return createConnector((config) => ({ + id: 'coinbaseWalletSDK', + name: 'Coinbase Wallet', + rdns: 'com.coinbase.wallet', + type: coinbaseWallet.type, + async connect({ chainId, ...rest } = {}) { + try { + const provider = await this.getProvider() + const accounts = ( + (await provider.request({ + method: 'eth_requestAccounts', + params: + 'instantOnboarding' in rest && rest.instantOnboarding + ? [{ onboarding: 'instant' }] + : [], + })) as string[] + ).map((x) => getAddress(x)) + + if (!accountsChanged) { + accountsChanged = this.onAccountsChanged.bind(this) + provider.on('accountsChanged', accountsChanged) + } + if (!chainChanged) { + chainChanged = this.onChainChanged.bind(this) + provider.on('chainChanged', chainChanged) + } + if (!disconnect) { + disconnect = this.onDisconnect.bind(this) + provider.on('disconnect', disconnect) + } + + // Switch to chain if provided + let currentChainId = await this.getChainId() + if (chainId && currentChainId !== chainId) { + const chain = await this.switchChain!({ chainId }).catch((error) => { + if (error.code === UserRejectedRequestError.code) throw error + return { id: currentChainId } + }) + currentChainId = chain?.id ?? currentChainId + } + + return { accounts, chainId: currentChainId } + } catch (error) { + if ( + /(user closed modal|accounts received is empty|user denied account|request rejected)/i.test( + (error as Error).message, + ) + ) + throw new UserRejectedRequestError(error as Error) + throw error + } + }, + async disconnect() { + const provider = await this.getProvider() + + if (accountsChanged) { + provider.removeListener('accountsChanged', accountsChanged) + accountsChanged = undefined + } + if (chainChanged) { + provider.removeListener('chainChanged', chainChanged) + chainChanged = undefined + } + if (disconnect) { + provider.removeListener('disconnect', disconnect) + disconnect = undefined + } + + provider.disconnect() + provider.close?.() + }, + async getAccounts() { + const provider = await this.getProvider() + return ( + (await provider.request({ + method: 'eth_accounts', + })) as string[] + ).map((x) => getAddress(x)) + }, + async getChainId() { + const provider = await this.getProvider() + const chainId = (await provider.request({ + method: 'eth_chainId', + })) as Hex + return Number(chainId) + }, + async getProvider() { + if (!walletProvider) { + const preference = (() => { + if (typeof parameters.preference === 'string') + return { options: parameters.preference } + return { + ...parameters.preference, + options: parameters.preference?.options ?? 'all', + } + })() + + const { createCoinbaseWalletSDK } = await import('@coinbase/wallet-sdk') + const sdk = createCoinbaseWalletSDK({ + ...parameters, + appChainIds: config.chains.map((x) => x.id), + preference, + }) + + walletProvider = sdk.getProvider() + } + + return walletProvider + }, + async isAuthorized() { + try { + const accounts = await this.getAccounts() + return !!accounts.length + } catch { + return false + } + }, + async switchChain({ addEthereumChainParameter, chainId }) { + const chain = config.chains.find((chain) => chain.id === chainId) + if (!chain) throw new SwitchChainError(new ChainNotConfiguredError()) + + const provider = await this.getProvider() + + try { + await provider.request({ + method: 'wallet_switchEthereumChain', + params: [{ chainId: numberToHex(chain.id) }], + }) + return chain + } catch (error) { + // Indicates chain is not added to provider + if ((error as ProviderRpcError).code === 4902) { + try { + let blockExplorerUrls: string[] | undefined + if (addEthereumChainParameter?.blockExplorerUrls) + blockExplorerUrls = addEthereumChainParameter.blockExplorerUrls + else + blockExplorerUrls = chain.blockExplorers?.default.url + ? [chain.blockExplorers?.default.url] + : [] + + let rpcUrls: readonly string[] + if (addEthereumChainParameter?.rpcUrls?.length) + rpcUrls = addEthereumChainParameter.rpcUrls + else rpcUrls = [chain.rpcUrls.default?.http[0] ?? ''] + + const addEthereumChain = { + blockExplorerUrls, + chainId: numberToHex(chainId), + chainName: addEthereumChainParameter?.chainName ?? chain.name, + iconUrls: addEthereumChainParameter?.iconUrls, + nativeCurrency: + addEthereumChainParameter?.nativeCurrency ?? + chain.nativeCurrency, + rpcUrls, + } satisfies AddEthereumChainParameter + + await provider.request({ + method: 'wallet_addEthereumChain', + params: [addEthereumChain], + }) + + return chain + } catch (error) { + throw new UserRejectedRequestError(error as Error) + } + } + + throw new SwitchChainError(error as Error) + } + }, + onAccountsChanged(accounts) { + if (accounts.length === 0) this.onDisconnect() + else + config.emitter.emit('change', { + accounts: accounts.map((x) => getAddress(x)), + }) + }, + onChainChanged(chain) { + const chainId = Number(chain) + config.emitter.emit('change', { chainId }) + }, + async onDisconnect(_error) { + config.emitter.emit('disconnect') + + const provider = await this.getProvider() + if (accountsChanged) { + provider.removeListener('accountsChanged', accountsChanged) + accountsChanged = undefined + } + if (chainChanged) { + provider.removeListener('chainChanged', chainChanged) + chainChanged = undefined + } + if (disconnect) { + provider.removeListener('disconnect', disconnect) + disconnect = undefined + } + }, + })) +} + +type Version3Parameters = Mutable< + Omit< + ConstructorParameters[0], + 'reloadOnDisconnect' // remove property since TSDoc says default is `true` + > +> & { + /** + * Fallback Ethereum JSON RPC URL + * @default "" + */ + jsonRpcUrl?: string | undefined + /** + * Fallback Ethereum Chain ID + * @default 1 + */ + chainId?: number | undefined + /** + * Whether or not to reload dapp automatically after disconnect. + * @default false + */ + reloadOnDisconnect?: boolean | undefined +} + +function version3(parameters: Version3Parameters) { + const reloadOnDisconnect = false + + type Provider = CBW_Provider + + let sdk: CBW_SDK | undefined + let walletProvider: Provider | undefined + + let accountsChanged: Connector['onAccountsChanged'] | undefined + let chainChanged: Connector['onChainChanged'] | undefined + let disconnect: Connector['onDisconnect'] | undefined + + return createConnector((config) => ({ + id: 'coinbaseWalletSDK', + name: 'Coinbase Wallet', + rdns: 'com.coinbase.wallet', + type: coinbaseWallet.type, + async connect({ chainId } = {}) { + try { + const provider = await this.getProvider() + const accounts = ( + (await provider.request({ + method: 'eth_requestAccounts', + })) as string[] + ).map((x) => getAddress(x)) + + if (!accountsChanged) { + accountsChanged = this.onAccountsChanged.bind(this) + provider.on('accountsChanged', accountsChanged) + } + if (!chainChanged) { + chainChanged = this.onChainChanged.bind(this) + provider.on('chainChanged', chainChanged) + } + if (!disconnect) { + disconnect = this.onDisconnect.bind(this) + provider.on('disconnect', disconnect) + } + + // Switch to chain if provided + let currentChainId = await this.getChainId() + if (chainId && currentChainId !== chainId) { + const chain = await this.switchChain!({ chainId }).catch((error) => { + if (error.code === UserRejectedRequestError.code) throw error + return { id: currentChainId } + }) + currentChainId = chain?.id ?? currentChainId + } + + return { accounts, chainId: currentChainId } + } catch (error) { + if ( + /(user closed modal|accounts received is empty|user denied account)/i.test( + (error as Error).message, + ) + ) + throw new UserRejectedRequestError(error as Error) + throw error + } + }, + async disconnect() { + const provider = await this.getProvider() + + if (accountsChanged) { + provider.removeListener('accountsChanged', accountsChanged) + accountsChanged = undefined + } + if (chainChanged) { + provider.removeListener('chainChanged', chainChanged) + chainChanged = undefined + } + if (disconnect) { + provider.removeListener('disconnect', disconnect) + disconnect = undefined + } + + provider.disconnect() + provider.close() + }, + async getAccounts() { + const provider = await this.getProvider() + return ( + await provider.request({ + method: 'eth_accounts', + }) + ).map((x) => getAddress(x)) + }, + async getChainId() { + const provider = await this.getProvider() + const chainId = await provider.request({ + method: 'eth_chainId', + }) + return Number(chainId) + }, + async getProvider() { + if (!walletProvider) { + // Unwrapping import for Vite compatibility. + // See: https://github.com/vitejs/vite/issues/9703 + const CoinbaseWalletSDK = await (async () => { + const { default: SDK } = await import('cbw-sdk') + if (typeof SDK !== 'function' && typeof SDK.default === 'function') + return SDK.default + return SDK as unknown as typeof SDK.default + })() + + sdk = new CoinbaseWalletSDK({ ...parameters, reloadOnDisconnect }) + + // Force types to retrieve private `walletExtension` method from the Coinbase Wallet SDK. + const walletExtensionChainId = ( + sdk as unknown as { + get walletExtension(): { getChainId(): number } | undefined + } + ).walletExtension?.getChainId() + + const chain = + config.chains.find((chain) => + parameters.chainId + ? chain.id === parameters.chainId + : chain.id === walletExtensionChainId, + ) || config.chains[0] + const chainId = parameters.chainId || chain?.id + const jsonRpcUrl = + parameters.jsonRpcUrl || chain?.rpcUrls.default.http[0] + + walletProvider = sdk.makeWeb3Provider(jsonRpcUrl, chainId) + } + + return walletProvider + }, + async isAuthorized() { + try { + const accounts = await this.getAccounts() + return !!accounts.length + } catch { + return false + } + }, + async switchChain({ addEthereumChainParameter, chainId }) { + const chain = config.chains.find((chain) => chain.id === chainId) + if (!chain) throw new SwitchChainError(new ChainNotConfiguredError()) + + const provider = await this.getProvider() + + try { + await provider.request({ + method: 'wallet_switchEthereumChain', + params: [{ chainId: numberToHex(chain.id) }], + }) + return chain + } catch (error) { + // Indicates chain is not added to provider + if ((error as ProviderRpcError).code === 4902) { + try { + let blockExplorerUrls: string[] | undefined + if (addEthereumChainParameter?.blockExplorerUrls) + blockExplorerUrls = addEthereumChainParameter.blockExplorerUrls + else + blockExplorerUrls = chain.blockExplorers?.default.url + ? [chain.blockExplorers?.default.url] + : [] + + let rpcUrls: readonly string[] + if (addEthereumChainParameter?.rpcUrls?.length) + rpcUrls = addEthereumChainParameter.rpcUrls + else rpcUrls = [chain.rpcUrls.default?.http[0] ?? ''] + + const addEthereumChain = { + blockExplorerUrls, + chainId: numberToHex(chainId), + chainName: addEthereumChainParameter?.chainName ?? chain.name, + iconUrls: addEthereumChainParameter?.iconUrls, + nativeCurrency: + addEthereumChainParameter?.nativeCurrency ?? + chain.nativeCurrency, + rpcUrls, + } satisfies AddEthereumChainParameter + + await provider.request({ + method: 'wallet_addEthereumChain', + params: [addEthereumChain], + }) + + return chain + } catch (error) { + throw new UserRejectedRequestError(error as Error) + } + } + + throw new SwitchChainError(error as Error) + } + }, + onAccountsChanged(accounts) { + if (accounts.length === 0) this.onDisconnect() + else + config.emitter.emit('change', { + accounts: accounts.map((x) => getAddress(x)), + }) + }, + onChainChanged(chain) { + const chainId = Number(chain) + config.emitter.emit('change', { chainId }) + }, + async onDisconnect(_error) { + config.emitter.emit('disconnect') + + const provider = await this.getProvider() + if (accountsChanged) { + provider.removeListener('accountsChanged', accountsChanged) + accountsChanged = undefined + } + if (chainChanged) { + provider.removeListener('chainChanged', chainChanged) + chainChanged = undefined + } + if (disconnect) { + provider.removeListener('disconnect', disconnect) + disconnect = undefined + } + }, + })) +} diff --git a/wagmi-project/packages/connectors/src/exports/index.test.ts b/wagmi-project/packages/connectors/src/exports/index.test.ts new file mode 100644 index 000000000..bcf100cb6 --- /dev/null +++ b/wagmi-project/packages/connectors/src/exports/index.test.ts @@ -0,0 +1,17 @@ +import { expect, test } from 'vitest' + +import * as connectors from './index.js' + +test('exports', () => { + expect(Object.keys(connectors)).toMatchInlineSnapshot(` + [ + "injected", + "mock", + "coinbaseWallet", + "metaMask", + "safe", + "walletConnect", + "version", + ] + `) +}) diff --git a/wagmi-project/packages/connectors/src/exports/index.ts b/wagmi-project/packages/connectors/src/exports/index.ts new file mode 100644 index 000000000..bac097595 --- /dev/null +++ b/wagmi-project/packages/connectors/src/exports/index.ts @@ -0,0 +1,23 @@ +// biome-ignore lint/performance/noBarrelFile: entrypoint module +export { + type InjectedParameters, + injected, + type MockParameters, + mock, +} from '@wagmi/core' + +export { + type CoinbaseWalletParameters, + coinbaseWallet, +} from '../coinbaseWallet.js' + +export { type MetaMaskParameters, metaMask } from '../metaMask.js' + +export { type SafeParameters, safe } from '../safe.js' + +export { + type WalletConnectParameters, + walletConnect, +} from '../walletConnect.js' + +export { version } from '../version.js' diff --git a/wagmi-project/packages/connectors/src/metaMask.test.ts b/wagmi-project/packages/connectors/src/metaMask.test.ts new file mode 100644 index 000000000..40c3f0f7f --- /dev/null +++ b/wagmi-project/packages/connectors/src/metaMask.test.ts @@ -0,0 +1,10 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { metaMask } from './metaMask.js' + +test('setup', () => { + const connectorFn = metaMask() + const connector = config._internal.connectors.setup(connectorFn) + expect(connector.name).toEqual('MetaMask') +}) diff --git a/wagmi-project/packages/connectors/src/metaMask.ts b/wagmi-project/packages/connectors/src/metaMask.ts new file mode 100644 index 000000000..02ab4c3fb --- /dev/null +++ b/wagmi-project/packages/connectors/src/metaMask.ts @@ -0,0 +1,505 @@ +import type { + MetaMaskSDK, + MetaMaskSDKOptions, + RPC_URLS_MAP, + SDKProvider, +} from '@metamask/sdk' +import { + ChainNotConfiguredError, + type Connector, + ProviderNotFoundError, + createConnector, + extractRpcUrls, +} from '@wagmi/core' +import type { + Compute, + ExactPartial, + OneOf, + RemoveUndefined, + UnionCompute, +} from '@wagmi/core/internal' +import { + type AddEthereumChainParameter, + type Address, + type Hex, + type ProviderConnectInfo, + type ProviderRpcError, + ResourceUnavailableRpcError, + type RpcError, + SwitchChainError, + UserRejectedRequestError, + getAddress, + hexToNumber, + numberToHex, + withRetry, + withTimeout, +} from 'viem' + +export type MetaMaskParameters = UnionCompute< + WagmiMetaMaskSDKOptions & + OneOf< + | { + /* Shortcut to connect and sign a message */ + connectAndSign?: string | undefined + } + | { + // TODO: Strongly type `method` and `params` + /* Allow `connectWith` any rpc method */ + connectWith?: { method: string; params: unknown[] } | undefined + } + > +> + +type WagmiMetaMaskSDKOptions = Compute< + ExactPartial< + Omit< + MetaMaskSDKOptions, + | '_source' + | 'forceDeleteProvider' + | 'forceInjectProvider' + | 'injectProvider' + | 'useDeeplink' + | 'readonlyRPCMap' + > + > & { + /** @deprecated */ + forceDeleteProvider?: MetaMaskSDKOptions['forceDeleteProvider'] + /** @deprecated */ + forceInjectProvider?: MetaMaskSDKOptions['forceInjectProvider'] + /** @deprecated */ + injectProvider?: MetaMaskSDKOptions['injectProvider'] + /** @deprecated */ + useDeeplink?: MetaMaskSDKOptions['useDeeplink'] + } +> + +metaMask.type = 'metaMask' as const +export function metaMask(parameters: MetaMaskParameters = {}) { + type Provider = SDKProvider + type Properties = { + onConnect(connectInfo: ProviderConnectInfo): void + onDisplayUri(uri: string): void + } + type Listener = Parameters[1] + + let sdk: MetaMaskSDK + let provider: Provider | undefined + let providerPromise: Promise + + let accountsChanged: Connector['onAccountsChanged'] | undefined + let chainChanged: Connector['onChainChanged'] | undefined + let connect: Connector['onConnect'] | undefined + let displayUri: ((uri: string) => void) | undefined + let disconnect: Connector['onDisconnect'] | undefined + + return createConnector((config) => ({ + id: 'metaMaskSDK', + name: 'MetaMask', + rdns: ['io.metamask', 'io.metamask.mobile'], + type: metaMask.type, + async setup() { + const provider = await this.getProvider() + if (provider?.on) { + if (!connect) { + connect = this.onConnect.bind(this) + provider.on('connect', connect as Listener) + } + + // We shouldn't need to listen for `'accountsChanged'` here since the `'connect'` event should suffice (and wallet shouldn't be connected yet). + // Some wallets, like MetaMask, do not implement the `'connect'` event and overload `'accountsChanged'` instead. + if (!accountsChanged) { + accountsChanged = this.onAccountsChanged.bind(this) + provider.on('accountsChanged', accountsChanged as Listener) + } + } + }, + async connect({ chainId, isReconnecting } = {}) { + const provider = await this.getProvider() + if (!displayUri) { + displayUri = this.onDisplayUri + provider.on('display_uri', displayUri as Listener) + } + + let accounts: readonly Address[] = [] + if (isReconnecting) accounts = await this.getAccounts().catch(() => []) + + try { + let signResponse: string | undefined + let connectWithResponse: unknown | undefined + if (!accounts?.length) { + if (parameters.connectAndSign || parameters.connectWith) { + if (parameters.connectAndSign) + signResponse = await sdk.connectAndSign({ + msg: parameters.connectAndSign, + }) + else if (parameters.connectWith) + connectWithResponse = await sdk.connectWith({ + method: parameters.connectWith.method, + params: parameters.connectWith.params, + }) + + accounts = await this.getAccounts() + } else { + const requestedAccounts = (await sdk.connect()) as string[] + accounts = requestedAccounts.map((x) => getAddress(x)) + } + } + // Switch to chain if provided + let currentChainId = (await this.getChainId()) as number + if (chainId && currentChainId !== chainId) { + const chain = await this.switchChain!({ chainId }).catch((error) => { + if (error.code === UserRejectedRequestError.code) throw error + return { id: currentChainId } + }) + currentChainId = chain?.id ?? currentChainId + } + + if (displayUri) { + provider.removeListener('display_uri', displayUri) + displayUri = undefined + } + + if (signResponse) + provider.emit('connectAndSign', { + accounts, + chainId: currentChainId, + signResponse, + }) + else if (connectWithResponse) + provider.emit('connectWith', { + accounts, + chainId: currentChainId, + connectWithResponse, + }) + + // Manage EIP-1193 event listeners + // https://eips.ethereum.org/EIPS/eip-1193#events + if (connect) { + provider.removeListener('connect', connect) + connect = undefined + } + if (!accountsChanged) { + accountsChanged = this.onAccountsChanged.bind(this) + provider.on('accountsChanged', accountsChanged as Listener) + } + if (!chainChanged) { + chainChanged = this.onChainChanged.bind(this) + provider.on('chainChanged', chainChanged as Listener) + } + if (!disconnect) { + disconnect = this.onDisconnect.bind(this) + provider.on('disconnect', disconnect as Listener) + } + + return { accounts, chainId: currentChainId } + } catch (err) { + const error = err as RpcError + if (error.code === UserRejectedRequestError.code) + throw new UserRejectedRequestError(error) + if (error.code === ResourceUnavailableRpcError.code) + throw new ResourceUnavailableRpcError(error) + throw error + } + }, + async disconnect() { + const provider = await this.getProvider() + + // Manage EIP-1193 event listeners + if (chainChanged) { + provider.removeListener('chainChanged', chainChanged) + chainChanged = undefined + } + if (disconnect) { + provider.removeListener('disconnect', disconnect) + disconnect = undefined + } + if (!connect) { + connect = this.onConnect.bind(this) + provider.on('connect', connect as Listener) + } + + await sdk.terminate() + }, + async getAccounts() { + const provider = await this.getProvider() + const accounts = (await provider.request({ + method: 'eth_accounts', + })) as string[] + return accounts.map((x) => getAddress(x)) + }, + async getChainId() { + const provider = await this.getProvider() + const chainId = + provider.getChainId() || + (await provider?.request({ method: 'eth_chainId' })) + return Number(chainId) + }, + async getProvider() { + async function initProvider() { + // Unwrapping import for Vite compatibility. + // See: https://github.com/vitejs/vite/issues/9703 + const MetaMaskSDK = await (async () => { + const { default: SDK } = await import('@metamask/sdk') + if (typeof SDK !== 'function' && typeof SDK.default === 'function') + return SDK.default + return SDK as unknown as typeof SDK.default + })() + + const readonlyRPCMap: RPC_URLS_MAP = {} + for (const chain of config.chains) + readonlyRPCMap[numberToHex(chain.id)] = extractRpcUrls({ + chain, + transports: config.transports, + })?.[0] + + sdk = new MetaMaskSDK({ + _source: 'wagmi', + forceDeleteProvider: false, + forceInjectProvider: false, + injectProvider: false, + // Workaround cast since MetaMask SDK does not support `'exactOptionalPropertyTypes'` + ...(parameters as RemoveUndefined), + readonlyRPCMap, + dappMetadata: { + ...parameters.dappMetadata, + // Test if name and url are set AND not empty + name: parameters.dappMetadata?.name + ? parameters.dappMetadata?.name + : 'wagmi', + url: parameters.dappMetadata?.url + ? parameters.dappMetadata?.url + : typeof window !== 'undefined' + ? window.location.origin + : 'https://wagmi.sh', + }, + useDeeplink: parameters.useDeeplink ?? true, + }) + const result = await sdk.init() + // On initial load, sometimes `sdk.getProvider` does not return provider. + // https://github.com/wevm/wagmi/issues/4367 + // Use result of `init` call if available. + const provider = (() => { + if (result?.activeProvider) return result.activeProvider + return sdk.getProvider() + })() + if (!provider) throw new ProviderNotFoundError() + return provider + } + + if (!provider) { + if (!providerPromise) providerPromise = initProvider() + provider = await providerPromise + } + return provider! + }, + async isAuthorized() { + try { + // MetaMask mobile provider sometimes fails to immediately resolve + // JSON-RPC requests on page load + const timeout = 200 + const accounts = await withRetry( + () => withTimeout(() => this.getAccounts(), { timeout }), + { + delay: timeout + 1, + retryCount: 3, + }, + ) + return !!accounts.length + } catch { + return false + } + }, + async switchChain({ addEthereumChainParameter, chainId }) { + const provider = await this.getProvider() + + const chain = config.chains.find((x) => x.id === chainId) + if (!chain) throw new SwitchChainError(new ChainNotConfiguredError()) + + try { + await provider.request({ + method: 'wallet_switchEthereumChain', + params: [{ chainId: numberToHex(chainId) }], + }) + + // During `'wallet_switchEthereumChain'`, MetaMask makes a `'net_version'` RPC call to the target chain. + // If this request fails, MetaMask does not emit the `'chainChanged'` event, but will still switch the chain. + // To counter this behavior, we request and emit the current chain ID to confirm the chain switch either via + // this callback or an externally emitted `'chainChanged'` event. + // https://github.com/MetaMask/metamask-extension/issues/24247 + await waitForChainIdToSync() + await sendAndWaitForChangeEvent(chainId) + + return chain + } catch (err) { + const error = err as RpcError + + if (error.code === UserRejectedRequestError.code) + throw new UserRejectedRequestError(error) + + // Indicates chain is not added to provider + if ( + error.code === 4902 || + // Unwrapping for MetaMask Mobile + // https://github.com/MetaMask/metamask-mobile/issues/2944#issuecomment-976988719 + (error as ProviderRpcError<{ originalError?: { code: number } }>) + ?.data?.originalError?.code === 4902 + ) { + try { + await provider.request({ + method: 'wallet_addEthereumChain', + params: [ + { + blockExplorerUrls: (() => { + const { default: blockExplorer, ...blockExplorers } = + chain.blockExplorers ?? {} + if (addEthereumChainParameter?.blockExplorerUrls) + return addEthereumChainParameter.blockExplorerUrls + if (blockExplorer) + return [ + blockExplorer.url, + ...Object.values(blockExplorers).map((x) => x.url), + ] + return + })(), + chainId: numberToHex(chainId), + chainName: addEthereumChainParameter?.chainName ?? chain.name, + iconUrls: addEthereumChainParameter?.iconUrls, + nativeCurrency: + addEthereumChainParameter?.nativeCurrency ?? + chain.nativeCurrency, + rpcUrls: (() => { + if (addEthereumChainParameter?.rpcUrls?.length) + return addEthereumChainParameter.rpcUrls + return [chain.rpcUrls.default?.http[0] ?? ''] + })(), + } satisfies AddEthereumChainParameter, + ], + }) + + await waitForChainIdToSync() + await sendAndWaitForChangeEvent(chainId) + + return chain + } catch (err) { + const error = err as RpcError + if (error.code === UserRejectedRequestError.code) + throw new UserRejectedRequestError(error) + throw new SwitchChainError(error) + } + } + + throw new SwitchChainError(error) + } + + async function waitForChainIdToSync() { + // On mobile, there is a race condition between the result of `'wallet_addEthereumChain'` and `'eth_chainId'`. + // To avoid this, we wait for `'eth_chainId'` to return the expected chain ID with a retry loop. + await withRetry( + async () => { + const value = hexToNumber( + // `'eth_chainId'` is cached by the MetaMask SDK side to avoid unnecessary deeplinks + (await provider.request({ method: 'eth_chainId' })) as Hex, + ) + // `value` doesn't match expected `chainId`, throw to trigger retry + if (value !== chainId) + throw new Error('User rejected switch after adding network.') + return value + }, + { + delay: 50, + retryCount: 20, // android device encryption is slower + }, + ) + } + + async function sendAndWaitForChangeEvent(chainId: number) { + await new Promise((resolve) => { + const listener = ((data) => { + if ('chainId' in data && data.chainId === chainId) { + config.emitter.off('change', listener) + resolve() + } + }) satisfies Parameters[1] + config.emitter.on('change', listener) + config.emitter.emit('change', { chainId }) + }) + } + }, + async onAccountsChanged(accounts) { + // Disconnect if there are no accounts + if (accounts.length === 0) { + // ... and using browser extension + if (sdk.isExtensionActive()) this.onDisconnect() + // FIXME(upstream): Mobile app sometimes emits invalid `accountsChanged` event with empty accounts array + else return + } + // Connect if emitter is listening for connect event (e.g. is disconnected and connects through wallet interface) + else if (config.emitter.listenerCount('connect')) { + const chainId = (await this.getChainId()).toString() + this.onConnect({ chainId }) + } + // Regular change event + else + config.emitter.emit('change', { + accounts: accounts.map((x) => getAddress(x)), + }) + }, + onChainChanged(chain) { + const chainId = Number(chain) + config.emitter.emit('change', { chainId }) + }, + async onConnect(connectInfo) { + const accounts = await this.getAccounts() + if (accounts.length === 0) return + + const chainId = Number(connectInfo.chainId) + config.emitter.emit('connect', { accounts, chainId }) + + const provider = await this.getProvider() + if (connect) { + provider.removeListener('connect', connect) + connect = undefined + } + if (!accountsChanged) { + accountsChanged = this.onAccountsChanged.bind(this) + provider.on('accountsChanged', accountsChanged as Listener) + } + if (!chainChanged) { + chainChanged = this.onChainChanged.bind(this) + provider.on('chainChanged', chainChanged as Listener) + } + if (!disconnect) { + disconnect = this.onDisconnect.bind(this) + provider.on('disconnect', disconnect as Listener) + } + }, + async onDisconnect(error) { + const provider = await this.getProvider() + + // If MetaMask emits a `code: 1013` error, wait for reconnection before disconnecting + // https://github.com/MetaMask/providers/pull/120 + if (error && (error as RpcError<1013>).code === 1013) { + if (provider && !!(await this.getAccounts()).length) return + } + + config.emitter.emit('disconnect') + + // Manage EIP-1193 event listeners + if (chainChanged) { + provider.removeListener('chainChanged', chainChanged) + chainChanged = undefined + } + if (disconnect) { + provider.removeListener('disconnect', disconnect) + disconnect = undefined + } + if (!connect) { + connect = this.onConnect.bind(this) + provider.on('connect', connect as Listener) + } + }, + onDisplayUri(uri) { + config.emitter.emit('message', { type: 'display_uri', data: uri }) + }, + })) +} diff --git a/wagmi-project/packages/connectors/src/safe.test.ts b/wagmi-project/packages/connectors/src/safe.test.ts new file mode 100644 index 000000000..0571115f3 --- /dev/null +++ b/wagmi-project/packages/connectors/src/safe.test.ts @@ -0,0 +1,23 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { safe } from './safe.js' + +/* + * To manually test the Safe connector: + * + * 1. Run the wagmi playground app (`pnpm dev`) + * 2. Add a custom Safe App with App URL set to `http://localhost:5173` (make sure there is a `manifest.json` file served by the playground) + * 3. Open the playground app at `https://app.safe.global/eth:0x4557B18E779944BFE9d78A672452331C186a9f48/apps?appUrl=http%3A%2F%2Flocalhost%3A5173` + * + * See https://docs.gnosis-safe.io/learn/safe-tools/sdks/safe-apps/releasing-your-safe-app for more info. + */ + +test('setup', () => { + const connectorFn = safe({ + allowedDomains: [/gnosis-safe.io$/, /app.safe.global$/], + debug: false, + }) + const connector = config._internal.connectors.setup(connectorFn) + expect(connector.name).toEqual('Safe') +}) diff --git a/wagmi-project/packages/connectors/src/safe.ts b/wagmi-project/packages/connectors/src/safe.ts new file mode 100644 index 000000000..13153e106 --- /dev/null +++ b/wagmi-project/packages/connectors/src/safe.ts @@ -0,0 +1,145 @@ +import type { SafeAppProvider } from '@safe-global/safe-apps-provider' +import type { Opts } from '@safe-global/safe-apps-sdk' +import { + type Connector, + ProviderNotFoundError, + createConnector, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { getAddress, withTimeout } from 'viem' + +export type SafeParameters = Compute< + Opts & { + /** + * Connector automatically connects when used as Safe App. + * + * This flag simulates the disconnect behavior by keeping track of connection status in storage + * and only autoconnecting when previously connected by user action (e.g. explicitly choosing to connect). + * + * @default false + */ + shimDisconnect?: boolean | undefined + /** + * Timeout in milliseconds for `getInfo` (from the Safe SDK) to resolve. + * + * `getInfo` does not resolve when not used in Safe App iFrame. This allows the connector to force a timeout. + * @default 10 + */ + unstable_getInfoTimeout?: number | undefined + } +> + +safe.type = 'safe' as const +export function safe(parameters: SafeParameters = {}) { + const { shimDisconnect = false } = parameters + + type Provider = SafeAppProvider | undefined + type Properties = Record + type StorageItem = { 'safe.disconnected': true } + + let provider_: Provider | undefined + + let disconnect: Connector['onDisconnect'] | undefined + + return createConnector((config) => ({ + id: 'safe', + name: 'Safe', + type: safe.type, + async connect() { + const provider = await this.getProvider() + if (!provider) throw new ProviderNotFoundError() + + const accounts = await this.getAccounts() + const chainId = await this.getChainId() + + if (!disconnect) { + disconnect = this.onDisconnect.bind(this) + provider.on('disconnect', disconnect) + } + + // Remove disconnected shim if it exists + if (shimDisconnect) await config.storage?.removeItem('safe.disconnected') + + return { accounts, chainId } + }, + async disconnect() { + const provider = await this.getProvider() + if (!provider) throw new ProviderNotFoundError() + + if (disconnect) { + provider.removeListener('disconnect', disconnect) + disconnect = undefined + } + + // Add shim signalling connector is disconnected + if (shimDisconnect) + await config.storage?.setItem('safe.disconnected', true) + }, + async getAccounts() { + const provider = await this.getProvider() + if (!provider) throw new ProviderNotFoundError() + return (await provider.request({ method: 'eth_accounts' })).map( + getAddress, + ) + }, + async getProvider() { + // Only allowed in iframe context + const isIframe = + typeof window !== 'undefined' && window?.parent !== window + if (!isIframe) return + + if (!provider_) { + const { default: SDK } = await import('@safe-global/safe-apps-sdk') + const sdk = new SDK(parameters) + + // `getInfo` hangs when not used in Safe App iFrame + // https://github.com/safe-global/safe-apps-sdk/issues/263#issuecomment-1029835840 + const safe = await withTimeout(() => sdk.safe.getInfo(), { + timeout: parameters.unstable_getInfoTimeout ?? 10, + }) + if (!safe) throw new Error('Could not load Safe information') + // Unwrapping import for Vite compatibility. + // See: https://github.com/vitejs/vite/issues/9703 + const SafeAppProvider = await (async () => { + const Provider = await import('@safe-global/safe-apps-provider') + if ( + typeof Provider.SafeAppProvider !== 'function' && + typeof Provider.default.SafeAppProvider === 'function' + ) + return Provider.default.SafeAppProvider + return Provider.SafeAppProvider + })() + provider_ = new SafeAppProvider(safe, sdk) + } + return provider_ + }, + async getChainId() { + const provider = await this.getProvider() + if (!provider) throw new ProviderNotFoundError() + return Number(provider.chainId) + }, + async isAuthorized() { + try { + const isDisconnected = + shimDisconnect && + // If shim exists in storage, connector is disconnected + (await config.storage?.getItem('safe.disconnected')) + if (isDisconnected) return false + + const accounts = await this.getAccounts() + return !!accounts.length + } catch { + return false + } + }, + onAccountsChanged() { + // Not relevant for Safe because changing account requires app reload. + }, + onChainChanged() { + // Not relevant for Safe because Safe smart contract wallets only exist on single chain. + }, + onDisconnect() { + config.emitter.emit('disconnect') + }, + })) +} diff --git a/wagmi-project/packages/connectors/src/version.ts b/wagmi-project/packages/connectors/src/version.ts new file mode 100644 index 000000000..11f81d1c3 --- /dev/null +++ b/wagmi-project/packages/connectors/src/version.ts @@ -0,0 +1 @@ +export const version = '5.8.3' diff --git a/wagmi-project/packages/connectors/src/walletConnect.test.ts b/wagmi-project/packages/connectors/src/walletConnect.test.ts new file mode 100644 index 000000000..4e8a74ebf --- /dev/null +++ b/wagmi-project/packages/connectors/src/walletConnect.test.ts @@ -0,0 +1,67 @@ +import { config, walletConnectProjectId } from '@wagmi/test' +import { http, HttpResponse } from 'msw' +import { setupServer } from 'msw/node' +import { + afterAll, + afterEach, + beforeAll, + expect, + expectTypeOf, + test, + vi, +} from 'vitest' + +import { walletConnect } from './walletConnect.js' + +const handlers = [ + http.get('https://relay.walletconnect.com', async () => + HttpResponse.json( + { + topic: '222781e3-3fad-4184-acde-077796bf0d3d', + type: 'sub', + payload: '', + silent: true, + }, + { status: 200 }, + ), + ), +] + +const server = setupServer(...handlers) + +beforeAll(() => { + server.listen({ + onUnhandledRequest: 'warn', + }) + + const matchMedia = vi.fn().mockImplementation((query) => { + return { + matches: false, + media: query, + onchange: null, + addListener: vi.fn(), // deprecated + removeListener: vi.fn(), // deprecated + addEventListener: vi.fn(), + removeEventListener: vi.fn(), + dispatchEvent: vi.fn(), + } + }) + vi.stubGlobal('matchMedia', matchMedia) +}) + +afterEach(() => server.resetHandlers()) + +afterAll(() => server.close()) + +test('setup', () => { + const connectorFn = walletConnect({ projectId: walletConnectProjectId }) + const connector = config._internal.connectors.setup(connectorFn) + expect(connector.name).toEqual('WalletConnect') + + type ConnectFnParameters = NonNullable< + Parameters<(typeof connector)['connect']>[0] + > + expectTypeOf().toMatchTypeOf< + string | undefined + >() +}) diff --git a/wagmi-project/packages/connectors/src/walletConnect.ts b/wagmi-project/packages/connectors/src/walletConnect.ts new file mode 100644 index 000000000..fc4f794c1 --- /dev/null +++ b/wagmi-project/packages/connectors/src/walletConnect.ts @@ -0,0 +1,468 @@ +import { + ChainNotConfiguredError, + type Connector, + ProviderNotFoundError, + createConnector, + extractRpcUrls, +} from '@wagmi/core' +import type { Compute, ExactPartial, Omit } from '@wagmi/core/internal' +import type { EthereumProvider } from '@walletconnect/ethereum-provider' +import { + type AddEthereumChainParameter, + type Address, + type ProviderConnectInfo, + type ProviderRpcError, + type RpcError, + SwitchChainError, + UserRejectedRequestError, + getAddress, + numberToHex, +} from 'viem' + +type WalletConnectConnector = Connector & { + onDisplayUri(uri: string): void + onSessionDelete(data: { topic: string }): void +} + +type EthereumProviderOptions = Parameters<(typeof EthereumProvider)['init']>[0] + +export type WalletConnectParameters = Compute< + { + /** + * If a new chain is added to a previously existing configured connector `chains`, this flag + * will determine if that chain should be considered as stale. A stale chain is a chain that + * WalletConnect has yet to establish a relationship with (e.g. the user has not approved or + * rejected the chain). + * + * This flag mainly affects the behavior when a wallet does not support dynamic chain authorization + * with WalletConnect v2. + * + * If `true` (default), the new chain will be treated as a stale chain. If the user + * has yet to establish a relationship (approved/rejected) with this chain in their WalletConnect + * session, the connector will disconnect upon the dapp auto-connecting, and the user will have to + * reconnect to the dapp (revalidate the chain) in order to approve the newly added chain. + * This is the default behavior to avoid an unexpected error upon switching chains which may + * be a confusing user experience (e.g. the user will not know they have to reconnect + * unless the dapp handles these types of errors). + * + * If `false`, the new chain will be treated as a potentially valid chain. This means that if the user + * has yet to establish a relationship with the chain in their WalletConnect session, wagmi will successfully + * auto-connect the user. This comes with the trade-off that the connector will throw an error + * when attempting to switch to the unapproved chain if the wallet does not support dynamic session updates. + * This may be useful in cases where a dapp constantly + * modifies their configured chains, and they do not want to disconnect the user upon + * auto-connecting. If the user decides to switch to the unapproved chain, it is important that the + * dapp handles this error and prompts the user to reconnect to the dapp in order to approve + * the newly added chain. + * + * @default true + */ + isNewChainsStale?: boolean + } & Omit< + EthereumProviderOptions, + | 'chains' + | 'events' + | 'optionalChains' + | 'optionalEvents' + | 'optionalMethods' + | 'methods' + | 'rpcMap' + | 'showQrModal' + > & + ExactPartial> +> + +walletConnect.type = 'walletConnect' as const +export function walletConnect(parameters: WalletConnectParameters) { + const isNewChainsStale = parameters.isNewChainsStale ?? true + + type Provider = Awaited> + type Properties = { + connect(parameters?: { + chainId?: number | undefined + isReconnecting?: boolean | undefined + pairingTopic?: string | undefined + }): Promise<{ + accounts: readonly Address[] + chainId: number + }> + getNamespaceChainsIds(): number[] + getRequestedChainsIds(): Promise + isChainsStale(): Promise + onConnect(connectInfo: ProviderConnectInfo): void + onDisplayUri(uri: string): void + onSessionDelete(data: { topic: string }): void + setRequestedChainsIds(chains: number[]): void + requestedChainsStorageKey: `${string}.requestedChains` + } + type StorageItem = { + [_ in Properties['requestedChainsStorageKey']]: number[] + } + + let provider_: Provider | undefined + let providerPromise: Promise + const NAMESPACE = 'eip155' + + let accountsChanged: WalletConnectConnector['onAccountsChanged'] | undefined + let chainChanged: WalletConnectConnector['onChainChanged'] | undefined + let connect: WalletConnectConnector['onConnect'] | undefined + let displayUri: WalletConnectConnector['onDisplayUri'] | undefined + let sessionDelete: WalletConnectConnector['onSessionDelete'] | undefined + let disconnect: WalletConnectConnector['onDisconnect'] | undefined + + return createConnector((config) => ({ + id: 'walletConnect', + name: 'WalletConnect', + type: walletConnect.type, + async setup() { + const provider = await this.getProvider().catch(() => null) + if (!provider) return + if (!connect) { + connect = this.onConnect.bind(this) + provider.on('connect', connect) + } + if (!sessionDelete) { + sessionDelete = this.onSessionDelete.bind(this) + provider.on('session_delete', sessionDelete) + } + }, + async connect({ chainId, ...rest } = {}) { + try { + const provider = await this.getProvider() + if (!provider) throw new ProviderNotFoundError() + if (!displayUri) { + displayUri = this.onDisplayUri + provider.on('display_uri', displayUri) + } + + let targetChainId = chainId + if (!targetChainId) { + const state = (await config.storage?.getItem('state')) ?? {} + const isChainSupported = config.chains.some( + (x) => x.id === state.chainId, + ) + if (isChainSupported) targetChainId = state.chainId + else targetChainId = config.chains[0]?.id + } + if (!targetChainId) throw new Error('No chains found on connector.') + + const isChainsStale = await this.isChainsStale() + // If there is an active session with stale chains, disconnect current session. + if (provider.session && isChainsStale) await provider.disconnect() + + // If there isn't an active session or chains are stale, connect. + if (!provider.session || isChainsStale) { + const optionalChains = config.chains + .filter((chain) => chain.id !== targetChainId) + .map((optionalChain) => optionalChain.id) + await provider.connect({ + optionalChains: [targetChainId, ...optionalChains], + ...('pairingTopic' in rest + ? { pairingTopic: rest.pairingTopic } + : {}), + }) + + this.setRequestedChainsIds(config.chains.map((x) => x.id)) + } + + // If session exists and chains are authorized, enable provider for required chain + const accounts = (await provider.enable()).map((x) => getAddress(x)) + const currentChainId = await this.getChainId() + + if (displayUri) { + provider.removeListener('display_uri', displayUri) + displayUri = undefined + } + if (connect) { + provider.removeListener('connect', connect) + connect = undefined + } + if (!accountsChanged) { + accountsChanged = this.onAccountsChanged.bind(this) + provider.on('accountsChanged', accountsChanged) + } + if (!chainChanged) { + chainChanged = this.onChainChanged.bind(this) + provider.on('chainChanged', chainChanged) + } + if (!disconnect) { + disconnect = this.onDisconnect.bind(this) + provider.on('disconnect', disconnect) + } + if (!sessionDelete) { + sessionDelete = this.onSessionDelete.bind(this) + provider.on('session_delete', sessionDelete) + } + + return { accounts, chainId: currentChainId } + } catch (error) { + if ( + /(user rejected|connection request reset)/i.test( + (error as ProviderRpcError)?.message, + ) + ) { + throw new UserRejectedRequestError(error as Error) + } + throw error + } + }, + async disconnect() { + const provider = await this.getProvider() + try { + await provider?.disconnect() + } catch (error) { + if (!/No matching key/i.test((error as Error).message)) throw error + } finally { + if (chainChanged) { + provider?.removeListener('chainChanged', chainChanged) + chainChanged = undefined + } + if (disconnect) { + provider?.removeListener('disconnect', disconnect) + disconnect = undefined + } + if (!connect) { + connect = this.onConnect.bind(this) + provider?.on('connect', connect) + } + if (accountsChanged) { + provider?.removeListener('accountsChanged', accountsChanged) + accountsChanged = undefined + } + if (sessionDelete) { + provider?.removeListener('session_delete', sessionDelete) + sessionDelete = undefined + } + + this.setRequestedChainsIds([]) + } + }, + async getAccounts() { + const provider = await this.getProvider() + return provider.accounts.map((x) => getAddress(x)) + }, + async getProvider({ chainId } = {}) { + async function initProvider() { + const optionalChains = config.chains.map((x) => x.id) as [number] + if (!optionalChains.length) return + const { EthereumProvider } = await import( + '@walletconnect/ethereum-provider' + ) + return await EthereumProvider.init({ + ...parameters, + disableProviderPing: true, + optionalChains, + projectId: parameters.projectId, + rpcMap: Object.fromEntries( + config.chains.map((chain) => { + const [url] = extractRpcUrls({ + chain, + transports: config.transports, + }) + return [chain.id, url] + }), + ), + showQrModal: parameters.showQrModal ?? true, + }) + } + + if (!provider_) { + if (!providerPromise) providerPromise = initProvider() + provider_ = await providerPromise + provider_?.events.setMaxListeners(Number.POSITIVE_INFINITY) + } + if (chainId) await this.switchChain?.({ chainId }) + return provider_! + }, + async getChainId() { + const provider = await this.getProvider() + return provider.chainId + }, + async isAuthorized() { + try { + const [accounts, provider] = await Promise.all([ + this.getAccounts(), + this.getProvider(), + ]) + + // If an account does not exist on the session, then the connector is unauthorized. + if (!accounts.length) return false + + // If the chains are stale on the session, then the connector is unauthorized. + const isChainsStale = await this.isChainsStale() + if (isChainsStale && provider.session) { + await provider.disconnect().catch(() => {}) + return false + } + return true + } catch { + return false + } + }, + async switchChain({ addEthereumChainParameter, chainId }) { + const provider = await this.getProvider() + if (!provider) throw new ProviderNotFoundError() + + const chain = config.chains.find((x) => x.id === chainId) + if (!chain) throw new SwitchChainError(new ChainNotConfiguredError()) + + try { + await Promise.all([ + new Promise((resolve) => { + const listener = ({ + chainId: currentChainId, + }: { chainId?: number | undefined }) => { + if (currentChainId === chainId) { + config.emitter.off('change', listener) + resolve() + } + } + config.emitter.on('change', listener) + }), + provider.request({ + method: 'wallet_switchEthereumChain', + params: [{ chainId: numberToHex(chainId) }], + }), + ]) + + const requestedChains = await this.getRequestedChainsIds() + this.setRequestedChainsIds([...requestedChains, chainId]) + + return chain + } catch (err) { + const error = err as RpcError + + if (/(user rejected)/i.test(error.message)) + throw new UserRejectedRequestError(error) + + // Indicates chain is not added to provider + try { + let blockExplorerUrls: string[] | undefined + if (addEthereumChainParameter?.blockExplorerUrls) + blockExplorerUrls = addEthereumChainParameter.blockExplorerUrls + else + blockExplorerUrls = chain.blockExplorers?.default.url + ? [chain.blockExplorers?.default.url] + : [] + + let rpcUrls: readonly string[] + if (addEthereumChainParameter?.rpcUrls?.length) + rpcUrls = addEthereumChainParameter.rpcUrls + else rpcUrls = [...chain.rpcUrls.default.http] + + const addEthereumChain = { + blockExplorerUrls, + chainId: numberToHex(chainId), + chainName: addEthereumChainParameter?.chainName ?? chain.name, + iconUrls: addEthereumChainParameter?.iconUrls, + nativeCurrency: + addEthereumChainParameter?.nativeCurrency ?? chain.nativeCurrency, + rpcUrls, + } satisfies AddEthereumChainParameter + + await provider.request({ + method: 'wallet_addEthereumChain', + params: [addEthereumChain], + }) + + const requestedChains = await this.getRequestedChainsIds() + this.setRequestedChainsIds([...requestedChains, chainId]) + return chain + } catch (error) { + throw new UserRejectedRequestError(error as Error) + } + } + }, + onAccountsChanged(accounts) { + if (accounts.length === 0) this.onDisconnect() + else + config.emitter.emit('change', { + accounts: accounts.map((x) => getAddress(x)), + }) + }, + onChainChanged(chain) { + const chainId = Number(chain) + config.emitter.emit('change', { chainId }) + }, + async onConnect(connectInfo) { + const chainId = Number(connectInfo.chainId) + const accounts = await this.getAccounts() + config.emitter.emit('connect', { accounts, chainId }) + }, + async onDisconnect(_error) { + this.setRequestedChainsIds([]) + config.emitter.emit('disconnect') + + const provider = await this.getProvider() + if (accountsChanged) { + provider.removeListener('accountsChanged', accountsChanged) + accountsChanged = undefined + } + if (chainChanged) { + provider.removeListener('chainChanged', chainChanged) + chainChanged = undefined + } + if (disconnect) { + provider.removeListener('disconnect', disconnect) + disconnect = undefined + } + if (sessionDelete) { + provider.removeListener('session_delete', sessionDelete) + sessionDelete = undefined + } + if (!connect) { + connect = this.onConnect.bind(this) + provider.on('connect', connect) + } + }, + onDisplayUri(uri) { + config.emitter.emit('message', { type: 'display_uri', data: uri }) + }, + onSessionDelete() { + this.onDisconnect() + }, + getNamespaceChainsIds() { + if (!provider_) return [] + const chainIds = provider_.session?.namespaces[NAMESPACE]?.accounts?.map( + (account) => Number.parseInt(account.split(':')[1] || ''), + ) + return chainIds ?? [] + }, + async getRequestedChainsIds() { + return ( + (await config.storage?.getItem(this.requestedChainsStorageKey)) ?? [] + ) + }, + /** + * Checks if the target chains match the chains that were + * initially requested by the connector for the WalletConnect session. + * If there is a mismatch, this means that the chains on the connector + * are considered stale, and need to be revalidated at a later point (via + * connection). + * + * There may be a scenario where a dapp adds a chain to the + * connector later on, however, this chain will not have been approved or rejected + * by the wallet. In this case, the chain is considered stale. + */ + async isChainsStale() { + if (!isNewChainsStale) return false + + const connectorChains = config.chains.map((x) => x.id) + const namespaceChains = this.getNamespaceChainsIds() + if ( + namespaceChains.length && + !namespaceChains.some((id) => connectorChains.includes(id)) + ) + return false + + const requestedChains = await this.getRequestedChainsIds() + return !connectorChains.every((id) => requestedChains.includes(id)) + }, + async setRequestedChainsIds(chains) { + await config.storage?.setItem(this.requestedChainsStorageKey, chains) + }, + get requestedChainsStorageKey() { + return `${this.id}.requestedChains` as Properties['requestedChainsStorageKey'] + }, + })) +} diff --git a/wagmi-project/packages/connectors/tsconfig.build.json b/wagmi-project/packages/connectors/tsconfig.build.json new file mode 100644 index 000000000..fbed2b103 --- /dev/null +++ b/wagmi-project/packages/connectors/tsconfig.build.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.base.json", + "include": ["src/**/*.ts"], + "exclude": ["src/**/*.test.ts", "src/**/*.test-d.ts"], + "compilerOptions": { + "sourceMap": true + } +} diff --git a/wagmi-project/packages/connectors/tsconfig.json b/wagmi-project/packages/connectors/tsconfig.json new file mode 100644 index 000000000..bd33919ac --- /dev/null +++ b/wagmi-project/packages/connectors/tsconfig.json @@ -0,0 +1,5 @@ +{ + "extends": "./tsconfig.build.json", + "include": ["src/**/*.ts"], + "exclude": [] +} diff --git a/wagmi-project/packages/core/CHANGELOG.md b/wagmi-project/packages/core/CHANGELOG.md new file mode 100644 index 000000000..88b541e93 --- /dev/null +++ b/wagmi-project/packages/core/CHANGELOG.md @@ -0,0 +1,3365 @@ +# @wagmi/core + +## 2.17.2 + +### Patch Changes + +- [`29297a48af72b537173d948ccd2fe37d39914c66`](https://github.com/wevm/wagmi/commit/29297a48af72b537173d948ccd2fe37d39914c66) Thanks [@jxom](https://github.com/jxom)! - Fixed `sendCalls` generics. + +- [`07370106d5fb6b8fe300992d93abf25b3d0eaf57`](https://github.com/wevm/wagmi/commit/07370106d5fb6b8fe300992d93abf25b3d0eaf57) Thanks [@jxom](https://github.com/jxom)! - Fixed propagation of `waitForCallsStatus` parameters. + +## 2.17.1 + +### Patch Changes + +- [#4649](https://github.com/wevm/wagmi/pull/4649) [`01f64e64fa4f85cdd30023903f972f4f9023681f`](https://github.com/wevm/wagmi/commit/01f64e64fa4f85cdd30023903f972f4f9023681f) Thanks [@jxom](https://github.com/jxom)! - Added `chainId` parameter to `getCapabilities`/`useCapabilities`. + +## 2.17.0 + +### Minor Changes + +- [#4638](https://github.com/wevm/wagmi/pull/4638) [`799ee4d4b23c2ecd64e3f3668e67634e81939719`](https://github.com/wevm/wagmi/commit/799ee4d4b23c2ecd64e3f3668e67634e81939719) Thanks [@jxom](https://github.com/jxom)! - Stabilized EIP-5792 Actions & Hooks. + +## 2.16.7 + +### Patch Changes + +- [`a4bd0623eed28e3761a27295831a60ad835f0ee0`](https://github.com/wevm/wagmi/commit/a4bd0623eed28e3761a27295831a60ad835f0ee0) Thanks [@jxom](https://github.com/jxom)! - **Experimental (EIP-5792):** Updated `id` parameter to be optional on `useWaitForCallsStatus`. + +## 2.16.6 + +### Patch Changes + +- [#4586](https://github.com/wevm/wagmi/pull/4586) [`edf47477b2f6385a1c3ae01d36a8498c47f30a0b`](https://github.com/wevm/wagmi/commit/edf47477b2f6385a1c3ae01d36a8498c47f30a0b) Thanks [@jxom](https://github.com/jxom)! - **Experimental (EIP-5792):** Added `waitForCallsStatus` + `useWaitForCallsStatus`. + +## 2.16.5 + +### Patch Changes + +- [`d0c9a86921a4e939373cc6e763284e53f2a2e93c`](https://github.com/wevm/wagmi/commit/d0c9a86921a4e939373cc6e763284e53f2a2e93c) Thanks [@jxom](https://github.com/jxom)! - **Experimental (ERC-5792)**: Added support for `account: null` in `sendCalls` to cater for sending calls without a connected account (account will be filled by the wallet). + +## 2.16.4 + +### Patch Changes + +- [`507f864d91238bfd423d0e36d3619eb9f6e52eec`](https://github.com/wevm/wagmi/commit/507f864d91238bfd423d0e36d3619eb9f6e52eec) Thanks [@jxom](https://github.com/jxom)! - Updated `@coinbase/wallet-sdk`. + +## 2.16.3 + +### Patch Changes + +- [#4480](https://github.com/wevm/wagmi/pull/4480) [`384a1d91597622eb59e1c05dc13ce25017c5b6d8`](https://github.com/wevm/wagmi/commit/384a1d91597622eb59e1c05dc13ce25017c5b6d8) Thanks [@RodeRickIsWatching](https://github.com/RodeRickIsWatching)! - Fixed invocation of default storage. + +## 2.16.2 + +### Patch Changes + +- [`012907032b532a438fce48f407470250cbc8f0c6`](https://github.com/wevm/wagmi/commit/012907032b532a438fce48f407470250cbc8f0c6) Thanks [@jxom](https://github.com/jxom)! - Fixed assignment in `getDefaultStorage`. + +## 2.16.1 + +### Patch Changes + +- [#4472](https://github.com/wevm/wagmi/pull/4472) [`3892ebd21c06beef4b28ece4e70d2a38807bce6f`](https://github.com/wevm/wagmi/commit/3892ebd21c06beef4b28ece4e70d2a38807bce6f) Thanks [@tmm](https://github.com/tmm)! - Added handling to default storage for `setItem` errors, like `QuotaExceededError`, `SecurityError`, etc. + +## 2.16.0 + +### Minor Changes + +- [#4453](https://github.com/wevm/wagmi/pull/4453) [`070e48480194c8d7f45bda1d7dd1346e6f5d7227`](https://github.com/wevm/wagmi/commit/070e48480194c8d7f45bda1d7dd1346e6f5d7227) Thanks [@tmm](https://github.com/tmm)! - Added narrowing to `config.connectors`. + +### Patch Changes + +- [`afea6b67822a7a2b96901ec851441d27ee0f7a52`](https://github.com/wevm/wagmi/commit/afea6b67822a7a2b96901ec851441d27ee0f7a52) Thanks [@tmm](https://github.com/tmm)! - Passed through parameters to `connector.connect` in `connect` action. + +## 2.15.2 + +### Patch Changes + +- [#4433](https://github.com/wevm/wagmi/pull/4433) [`06e186cd679b27fe195309110e766fcf46d4efbc`](https://github.com/wevm/wagmi/commit/06e186cd679b27fe195309110e766fcf46d4efbc) Thanks [@Aerilym](https://github.com/Aerilym)! - Bumped Metamask SDK version to `0.31.1`. + +## 2.15.1 + +### Patch Changes + +- [`b8bbb409f4934538e3dd6cac5aaf7346292d0693`](https://github.com/wevm/wagmi/commit/b8bbb409f4934538e3dd6cac5aaf7346292d0693) Thanks [@jxom](https://github.com/jxom)! - Fixed issue where `null` gas would accidentally pass through. + +## 2.15.0 + +### Minor Changes + +- [#4417](https://github.com/wevm/wagmi/pull/4417) [`42e65ea4fea99c639817088bba915e0933d17141`](https://github.com/wevm/wagmi/commit/42e65ea4fea99c639817088bba915e0933d17141) Thanks [@jxom](https://github.com/jxom)! - Removed simulation in `writeContract` & `sendTransaction`. + +## 2.14.6 + +### Patch Changes + +- [#4406](https://github.com/wevm/wagmi/pull/4406) [`a13aa8d7c38eb3cc8171a02d6302e6d12cf6bcb3`](https://github.com/wevm/wagmi/commit/a13aa8d7c38eb3cc8171a02d6302e6d12cf6bcb3) Thanks [@tmm](https://github.com/tmm)! - Added support for multiple connector `rdns` entries. + +## 2.14.5 + +### Patch Changes + +- [#4400](https://github.com/wevm/wagmi/pull/4400) [`6b9bbacdc7bffd44fc2165362a5e65fd434e7646`](https://github.com/wevm/wagmi/commit/6b9bbacdc7bffd44fc2165362a5e65fd434e7646) Thanks [@AzzouQ](https://github.com/AzzouQ)! - Fixed `createWatchContractEvent` internal wiring, where `eventName` was incorrectly `functionName`. + +## 2.14.4 + +### Patch Changes + +- [#4311](https://github.com/wevm/wagmi/pull/4311) [`e08681c81fbdf475213e2d0f4c5517d0abf4e743`](https://github.com/wevm/wagmi/commit/e08681c81fbdf475213e2d0f4c5517d0abf4e743) Thanks [@chybisov](https://github.com/chybisov)! - Fixed `injected` connector race condition after calling `'wallet_addEthereumChain'` in `switchChain`. + +## 2.14.3 + +### Patch Changes + +- [`cb7dd2ebb871d0be8f1a11a8cd8ce592cd74b7c7`](https://github.com/wevm/wagmi/commit/cb7dd2ebb871d0be8f1a11a8cd8ce592cd74b7c7) Thanks [@tmm](https://github.com/tmm)! - Removed unnecessary internal deep equal check in `structuralSharing`. + +## 2.14.2 + +### Patch Changes + +- [#4339](https://github.com/wevm/wagmi/pull/4339) [`d0d0963bb5904a15cf0355862d62dd141ce0c31c`](https://github.com/wevm/wagmi/commit/d0d0963bb5904a15cf0355862d62dd141ce0c31c) Thanks [@AndriyAntonenko](https://github.com/AndriyAntonenko)! - Fixed bug in `waitForTransactionReceipt`, where transaction data wasn't passed to `'eth_call'` method as part of getting the revert reason. + +- [`ecac0ba36243d94c9199d0bd21937104c835d9a0`](https://github.com/wevm/wagmi/commit/ecac0ba36243d94c9199d0bd21937104c835d9a0) Thanks [@tmm](https://github.com/tmm)! - Fixed `getBalance` symbol error handling. + +## 2.14.1 + +### Patch Changes + +- [`052e72e1f8c1c14fcbdce04a9f8fa7ec28d83702`](https://github.com/wevm/wagmi/commit/052e72e1f8c1c14fcbdce04a9f8fa7ec28d83702) Thanks [@tmm](https://github.com/tmm)! - Added `defaultConnected` feature to `mock` connector. + +- [#4349](https://github.com/wevm/wagmi/pull/4349) [`b250fc21ee577b2a75c5a34ff684f62fb4ad771a`](https://github.com/wevm/wagmi/commit/b250fc21ee577b2a75c5a34ff684f62fb4ad771a) Thanks [@tmm](https://github.com/tmm)! - Bumped internal deps. + +## 2.14.0 + +### Minor Changes + +- [#4343](https://github.com/wevm/wagmi/pull/4343) [`f43e074f473820b208a6295d7c97f847332f1a1d`](https://github.com/wevm/wagmi/commit/f43e074f473820b208a6295d7c97f847332f1a1d) Thanks [@tmm](https://github.com/tmm)! - Added `rdns` property to connector interface. This is used to filter out duplicate [EIP-6963](https://eips.ethereum.org/EIPS/eip-6963) injected providers when [`createConfig#multiInjectedProviderDiscovery`](https://wagmi.sh/core/api/createConfig#multiinjectedproviderdiscovery) is enabled and `createConfig#connectors` already matches EIP-6963 providers' `rdns` property. + +## 2.13.9 + +### Patch Changes + +- [#4336](https://github.com/wevm/wagmi/pull/4336) [`c05caabc20c3ced9682cfc7ba1f3f7dcfece0703`](https://github.com/wevm/wagmi/commit/c05caabc20c3ced9682cfc7ba1f3f7dcfece0703) Thanks [@EdouardBougon](https://github.com/EdouardBougon)! - Added deprecation notice to `injected` target flags. + +## 2.13.8 + +### Patch Changes + +- [#4207](https://github.com/wevm/wagmi/pull/4207) [`56f2482508f2ba71bd6b0295c70c6abca7101e57`](https://github.com/wevm/wagmi/commit/56f2482508f2ba71bd6b0295c70c6abca7101e57) Thanks [@Smert](https://github.com/Smert)! - Updated chain switch listener for `injected` and `metaMask` to be more robust. + +## 2.13.7 + +### Patch Changes + +- [`be75c2d4ef636d7362420ab0a106bfdf63f5d1e6`](https://github.com/wevm/wagmi/commit/be75c2d4ef636d7362420ab0a106bfdf63f5d1e6) Thanks [@tmm](https://github.com/tmm)! - Added guard for missing `provider.on` for `injected` connector. + +## 2.13.6 + +### Patch Changes + +- [#4286](https://github.com/wevm/wagmi/pull/4286) [`edcbf5d6fbe92f639bead800502edda9e0aa39f1`](https://github.com/wevm/wagmi/commit/edcbf5d6fbe92f639bead800502edda9e0aa39f1) Thanks [@holic](https://github.com/holic)! - Removed duplicate code. + +## 2.13.5 + +### Patch Changes + +- [#4259](https://github.com/wevm/wagmi/pull/4259) [`f47ce8f6d263e49fdff90b8edb3190142d2657bb`](https://github.com/wevm/wagmi/commit/f47ce8f6d263e49fdff90b8edb3190142d2657bb) Thanks [@tmm](https://github.com/tmm)! - Added guard to `getConnectorClient` when reconnecting to check if connector is fully restored. + +## 2.13.4 + +### Patch Changes + +- [`b4c8971788c70b09479946ecfa998cff2f1b3953`](https://github.com/wevm/wagmi/commit/b4c8971788c70b09479946ecfa998cff2f1b3953) Thanks [@tmm](https://github.com/tmm)! - Made `serialize` and `deserialize` types more permissive. + +## 2.13.3 + +### Patch Changes + +- [`871dbdbfe59ac8ad01d1ec6150ea7b091b7b7de4`](https://github.com/wevm/wagmi/commit/871dbdbfe59ac8ad01d1ec6150ea7b091b7b7de4) Thanks [@tmm](https://github.com/tmm)! - Added validation to internal state for persisted `chainId`. + +## 2.13.2 + +### Patch Changes + +- [`1b9b523fa9b9dfe839aecdf4b40caa9547d7e594`](https://github.com/wevm/wagmi/commit/1b9b523fa9b9dfe839aecdf4b40caa9547d7e594) Thanks [@tmm](https://github.com/tmm)! - Fixed built-in cookie storage `removeItem` working for all paths. + +## 2.13.1 + +### Patch Changes + +- [`07c1227f306d0efb9421d4bb77a774f92f5fcf45`](https://github.com/wevm/wagmi/commit/07c1227f306d0efb9421d4bb77a774f92f5fcf45) Thanks [@tmm](https://github.com/tmm)! - Fixed internal `extractRpcUrls` usage with `unstable_connector`. + +## 2.13.0 + +### Minor Changes + +- [#4162](https://github.com/wevm/wagmi/pull/4162) [`a73a7737b756886b388f120ae423e72cca53e8a0`](https://github.com/wevm/wagmi/commit/a73a7737b756886b388f120ae423e72cca53e8a0) Thanks [@jxom](https://github.com/jxom)! - Added functionality for consumer-defined RPC URLs (`config.transports`) to be propagated to the WalletConnect & MetaMask Connectors. + +## 2.12.2 + +### Patch Changes + +- [`5bc8c8877810b2eec24a829df87dce40a51e6f20`](https://github.com/wevm/wagmi/commit/5bc8c8877810b2eec24a829df87dce40a51e6f20) Thanks [@tmm](https://github.com/tmm)! - Fixed reconnection when `status` is defined. + +## 2.12.1 + +### Patch Changes + +- [#4146](https://github.com/wevm/wagmi/pull/4146) [`cc996e08e930c9e88cf753a1e874652059e81a3b`](https://github.com/wevm/wagmi/commit/cc996e08e930c9e88cf753a1e874652059e81a3b) Thanks [@jxom](https://github.com/jxom)! - Updated `@safe-global/safe-apps-sdk` + `@safe-global/safe-apps-provider` dependencies. + +## 2.12.0 + +### Minor Changes + +- [#4128](https://github.com/wevm/wagmi/pull/4128) [`5581a810ef70308e99c6f8b630cd4bca59f64afc`](https://github.com/wevm/wagmi/commit/5581a810ef70308e99c6f8b630cd4bca59f64afc) Thanks [@dalechyn](https://github.com/dalechyn)! - Added `watchAsset` action. + +## 2.11.8 + +### Patch Changes + +- [`b08013eaa9ce97c02f8a7128ea400e3da7ef74bb`](https://github.com/wevm/wagmi/commit/b08013eaa9ce97c02f8a7128ea400e3da7ef74bb) Thanks [@tmm](https://github.com/tmm)! - Fixed injected accounts ordering for `'wallet_requestPermissions'`. + +- [`d3814ab4b88f9f0e052b53bc3d458df87b43f01d`](https://github.com/wevm/wagmi/commit/d3814ab4b88f9f0e052b53bc3d458df87b43f01d) Thanks [@jxom](https://github.com/jxom)! - Updated `mipd` dependency. + +## 2.11.7 + +### Patch Changes + +- [`0bb8b562ae04ecfeb2d6b2f1b980ebae31dc127e`](https://github.com/wevm/wagmi/commit/0bb8b562ae04ecfeb2d6b2f1b980ebae31dc127e) Thanks [@tmm](https://github.com/tmm)! - Improved TypeScript `'exactOptionalPropertyTypes'` support. + +## 2.11.6 + +### Patch Changes + +- [#4060](https://github.com/wevm/wagmi/pull/4060) [`95965c1f19d480b97f2b297a077a9e607dee32ad`](https://github.com/wevm/wagmi/commit/95965c1f19d480b97f2b297a077a9e607dee32ad) Thanks [@dalechyn](https://github.com/dalechyn)! - Bumped Tanstack Query dependencies to fix typing issues between exported Wagmi query options and TanStack Query suspense query methods (due to [`direction` property in `QueryFunctionContext` being deprecated](https://github.com/TanStack/query/pull/7410)). + +## 2.11.5 + +### Patch Changes + +- [#4079](https://github.com/wevm/wagmi/pull/4079) [`04f2b846b113f3d300d82c9fa75212f1805817c5`](https://github.com/wevm/wagmi/commit/04f2b846b113f3d300d82c9fa75212f1805817c5) Thanks [@tmm](https://github.com/tmm)! - Added revalidation for config chain ID in SSR and migration. + +## 2.11.4 + +### Patch Changes + +- [`9e8345cd56186b997b5e56deaa2cfc69b30d15f6`](https://github.com/wevm/wagmi/commit/9e8345cd56186b997b5e56deaa2cfc69b30d15f6) Thanks [@tmm](https://github.com/tmm)! - Switched `Register` to `interface` to fix declaration merging. + +## 2.11.3 + +### Patch Changes + +- [#4065](https://github.com/wevm/wagmi/pull/4065) [`8974e6269bb5d7bfaa90db0246bc7d13e8bff798`](https://github.com/wevm/wagmi/commit/8974e6269bb5d7bfaa90db0246bc7d13e8bff798) Thanks [@alx-khramov](https://github.com/alx-khramov)! - Added timeout to internal call of `'wallet_revokePermissions'` request during `injected#disconnect` as some wallets that do not support this method hang. + +## 2.11.2 + +### Patch Changes + +- [#4042](https://github.com/wevm/wagmi/pull/4042) [`b4d9ef79deb554ee20fed6666a474be5e7cdd522`](https://github.com/wevm/wagmi/commit/b4d9ef79deb554ee20fed6666a474be5e7cdd522) Thanks [@tmm](https://github.com/tmm)! - Removed `injected` connector `isAuthorized` timeout. + +## 2.11.1 + +### Patch Changes + +- [`9c862d8d63e3d692a22cef2a90782b74a9103f17`](https://github.com/wevm/wagmi/commit/9c862d8d63e3d692a22cef2a90782b74a9103f17) Thanks [@tmm](https://github.com/tmm)! - Reverted internal module loading utility. + +## 2.11.0 + +### Minor Changes + +- [#3816](https://github.com/wevm/wagmi/pull/3816) [`06bb598a7f04c7b167f5b7ff6d46bd15886a6a14`](https://github.com/wevm/wagmi/commit/06bb598a7f04c7b167f5b7ff6d46bd15886a6a14) Thanks [@marthendalnunes](https://github.com/marthendalnunes)! - Added `deployContract` action. + +### Patch Changes + +- [`24a45b269bd0214a29d6f82a84ac66ef8c3f3822`](https://github.com/wevm/wagmi/commit/24a45b269bd0214a29d6f82a84ac66ef8c3f3822) Thanks [@tmm](https://github.com/tmm)! - Added `SameSite` default to `cookieStorage` + +## 2.10.6 + +### Patch Changes + +- [#4009](https://github.com/wevm/wagmi/pull/4009) [`f2a7cefab96691ebed8b8e45ffde071c47b58dbe`](https://github.com/wevm/wagmi/commit/f2a7cefab96691ebed8b8e45ffde071c47b58dbe) Thanks [@roninjin10](https://github.com/roninjin10)! - Marked `to` as optional for `sendTransaction`. + +- [#4023](https://github.com/wevm/wagmi/pull/4023) [`f0ea0b2a7fe193dadfeb49a4c8031ee451c638b5`](https://github.com/wevm/wagmi/commit/f0ea0b2a7fe193dadfeb49a4c8031ee451c638b5) Thanks [@jxom](https://github.com/jxom)! - Added chain check to `getConnectorClient` since it's possible for connection state chain ID to get out of sync with the connector (e.g. [wallet bug](https://github.com/MetaMask/metamask-extension/issues/25097)). + +## 2.10.5 + +### Patch Changes + +- [#3970](https://github.com/wevm/wagmi/pull/3970) [`030c7c2cb380dfd67a2182f62e2aa7a6e1601898`](https://github.com/wevm/wagmi/commit/030c7c2cb380dfd67a2182f62e2aa7a6e1601898) Thanks [@nanxiaobei](https://github.com/nanxiaobei)! - Fixed `cookieStorage` not working across paths. + +## 2.10.4 + +### Patch Changes + +- [#3984](https://github.com/wevm/wagmi/pull/3984) [`51fde8a0433b4fff357c1a8d7e08b41b4c86c968`](https://github.com/wevm/wagmi/commit/51fde8a0433b4fff357c1a8d7e08b41b4c86c968) Thanks [@tmm](https://github.com/tmm)! - Fixed `writeContract` query types for `value` property. + +## 2.10.3 + +### Patch Changes + +- [#3962](https://github.com/wevm/wagmi/pull/3962) [`2804a8a583b1874271154898b4bae38756ef581c`](https://github.com/wevm/wagmi/commit/2804a8a583b1874271154898b4bae38756ef581c) Thanks [@tmm](https://github.com/tmm)! - Added catch to `reconnect`. + +## 2.10.2 + +### Patch Changes + +- [#3940](https://github.com/wevm/wagmi/pull/3940) [`a5071f581dfdfb961718873643a2fc629101c72a`](https://github.com/wevm/wagmi/commit/a5071f581dfdfb961718873643a2fc629101c72a) Thanks [@jxom](https://github.com/jxom)! - Fixed usage of `metaMask` connector in Vite environments. + +## 2.10.1 + +### Patch Changes + +- Bumped versions. + +## 2.10.0 + +### Minor Changes + +- [#3928](https://github.com/wevm/wagmi/pull/3928) [`3117e71825f9c58a0d718f3d1686f1a191fa9cb1`](https://github.com/wevm/wagmi/commit/3117e71825f9c58a0d718f3d1686f1a191fa9cb1) Thanks [@tmm](https://github.com/tmm)! - Updated the default Coinbase SDK in `coinbaseWallet` Connector to v4.x. + +## 2.9.8 + +### Patch Changes + +- [#3906](https://github.com/wevm/wagmi/pull/3906) [`32fcb4a31dde6b0206961d8ffe9c651f8a459c67`](https://github.com/wevm/wagmi/commit/32fcb4a31dde6b0206961d8ffe9c651f8a459c67) Thanks [@tmm](https://github.com/tmm)! - Added support for Vue. + +## 2.9.7 + +### Patch Changes + +- [#3924](https://github.com/wevm/wagmi/pull/3924) [`1f58734f88458e0f6adb05c99f0c90f36ab286b8`](https://github.com/wevm/wagmi/commit/1f58734f88458e0f6adb05c99f0c90f36ab286b8) Thanks [@jxom](https://github.com/jxom)! - Refactored `isChainsStale` logic in `walletConnect` connector. + +## 2.9.6 + +### Patch Changes + +- [#3917](https://github.com/wevm/wagmi/pull/3917) [`05948fdad5bb4a56b08916d45b3dec2cb1e5f55b`](https://github.com/wevm/wagmi/commit/05948fdad5bb4a56b08916d45b3dec2cb1e5f55b) Thanks [@jxom](https://github.com/jxom)! - Updated `@metamask/sdk`. + +## 2.9.5 + +### Patch Changes + +- [`4fecbbb66d0aacd03b8c62a6455d11a33cde8f85`](https://github.com/wevm/wagmi/commit/4fecbbb66d0aacd03b8c62a6455d11a33cde8f85) Thanks [@jxom](https://github.com/jxom)! - Fixed address comparison in `getConnectorClient`. + +## 2.9.4 + +### Patch Changes + +- [#3910](https://github.com/wevm/wagmi/pull/3910) [`e6139a97c4b8804d734b1547b5e3921ce01fbe24`](https://github.com/wevm/wagmi/commit/e6139a97c4b8804d734b1547b5e3921ce01fbe24) Thanks [@tmm](https://github.com/tmm)! - Added experimental `wallet_revokePermissions` support to `injected`. + +## 2.9.3 + +### Patch Changes + +- [#3904](https://github.com/wevm/wagmi/pull/3904) [`addca28ebc20f1a4367c35fe9ef786decff9c87e`](https://github.com/wevm/wagmi/commit/addca28ebc20f1a4367c35fe9ef786decff9c87e) Thanks [@jxom](https://github.com/jxom)! - Updated `@walletconnect/ethereum-provider`. + +## 2.9.2 + +### Patch Changes + +- [#3902](https://github.com/wevm/wagmi/pull/3902) [`204b7b624612405500ec098fb9e35facd3f74ca4`](https://github.com/wevm/wagmi/commit/204b7b624612405500ec098fb9e35facd3f74ca4) Thanks [@jxom](https://github.com/jxom)! - Made third-party SDK imports type-only. + +## 2.9.1 + +### Patch Changes + +- [`cda6a5d5`](https://github.com/wevm/wagmi/commit/cda6a5d56328330fbde050b4ef40b01c58d2519a) Thanks [@jxom](https://github.com/jxom)! - Updated packages. + +## 2.9.0 + +### Minor Changes + +- [#3878](https://github.com/wevm/wagmi/pull/3878) [`017828fc`](https://github.com/wevm/wagmi/commit/017828fc027c7a84b54ea9d627e9389f4d60d6c2) Thanks [@jxom](https://github.com/jxom)! - Added experimental EIP-5792 Actions & Hooks. + +## 2.8.1 + +### Patch Changes + +- [#3869](https://github.com/wevm/wagmi/pull/3869) [`d4a78eb0`](https://github.com/wevm/wagmi/commit/d4a78eb07119d2e5617e52481ac7d6c6d1583ddc) Thanks [@jxom](https://github.com/jxom)! - Fixed issue where `prepareTransactionRequest` would internally call unsupported wallet RPC methods. + +## 2.8.0 + +### Minor Changes + +- [#3868](https://github.com/wevm/wagmi/pull/3868) [`c2af20b8`](https://github.com/wevm/wagmi/commit/c2af20b88cf16970d087faaec10b463357a5836e) Thanks [@jxom](https://github.com/jxom)! - Added `supportsSimulation` property to connectors that indicates if the connector's wallet supports contract simulation. + +### Patch Changes + +- [#3858](https://github.com/wevm/wagmi/pull/3858) [`0d141f17`](https://github.com/wevm/wagmi/commit/0d141f171d6ec44bcbfc9c876565b5e2fb8af6de) Thanks [@yulafezmesi](https://github.com/yulafezmesi)! - Fixed accessing reverted reason property inside `waitForTransactionReceipt`. + +## 2.7.0 + +### Minor Changes + +- [#3857](https://github.com/wevm/wagmi/pull/3857) [`d4274c03`](https://github.com/wevm/wagmi/commit/d4274c03a6af5f2d26d31432016ebc14950a330e) Thanks [@tmm](https://github.com/tmm)! - Added `addEthereumChainParameter` to `switchChain`-related methods. + +### Patch Changes + +- [#3849](https://github.com/wevm/wagmi/pull/3849) [`4781a405`](https://github.com/wevm/wagmi/commit/4781a4056d4ffc2c74f96a75429e9b2cd2417ad8) Thanks [@tmm](https://github.com/tmm)! - Fixed `shimDisconnect: false` behavior. + +- [#3859](https://github.com/wevm/wagmi/pull/3859) [`400c960b`](https://github.com/wevm/wagmi/commit/400c960b30d701c134850c695ae903a382c29b5b) Thanks [@holic](https://github.com/holic)! - Added workaround to injected connector for MetaMask bug, where chain switching does not work if target chain RPC `'net_version'` request fails. + +## 2.6.19 + +### Patch Changes + +- [`e3c832a1`](https://github.com/wevm/wagmi/commit/e3c832a12c301f9b0ee129d877b3101d220ba8b2) Thanks [@jxom](https://github.com/jxom)! - Fixed undefined `navigator` issue in MetaMask connector. + +## 2.6.18 + +### Patch Changes + +- [#3848](https://github.com/wevm/wagmi/pull/3848) [`dd40a41c`](https://github.com/wevm/wagmi/commit/dd40a41c526ab60a288aff2250ed8dba92a27b16) Thanks [@jxom](https://github.com/jxom)! - Updated MetaMask SDK. + +## 2.6.17 + +### Patch Changes + +- [#3822](https://github.com/wevm/wagmi/pull/3822) [`a97bfbae`](https://github.com/wevm/wagmi/commit/a97bfbaeb615cfef04665e5e7348d85d17f960f0) Thanks [@jxom](https://github.com/jxom)! - Fixed an issue where Wagmi would not correctly rehydrate the active chain when a persisted store was being used. + +## 2.6.16 + +### Patch Changes + +- [#3788](https://github.com/wevm/wagmi/pull/3788) [`42ad380d`](https://github.com/wevm/wagmi/commit/42ad380d9a5d8bc0f61d73612142dea9d098de5e) Thanks [@tmm](https://github.com/tmm)! - Refactored connectors to remove unnecessarily event listeners. + +## 2.6.15 + +### Patch Changes + +- [#3782](https://github.com/wevm/wagmi/pull/3782) [`b907d5ac`](https://github.com/wevm/wagmi/commit/b907d5ac3a746bcbccc06d1fe78c5bd8f9a7d685) Thanks [@jxom](https://github.com/jxom)! - Refactored injected connector connection logic. + +## 2.6.14 + +### Patch Changes + +- [#3777](https://github.com/wevm/wagmi/pull/3777) [`b3b54ef1`](https://github.com/wevm/wagmi/commit/b3b54ef179c5fa0d1694d38d4b808549a0550409) Thanks [@desfero](https://github.com/desfero)! - Fixed `writeContract` to forward `chainIn` when simulating contract call + +- [#3779](https://github.com/wevm/wagmi/pull/3779) [`3da20bb8`](https://github.com/wevm/wagmi/commit/3da20bb80e7c3efeef8227ced66ad615370fc242) Thanks [@jxom](https://github.com/jxom)! - Fixed an issue where `eth_requestAccounts` would be called upon reconnect instead of `eth_accounts`. + +- [`a3d1858f`](https://github.com/wevm/wagmi/commit/a3d1858fce448d2b70e36ee692ef1589b74e9d3f) Thanks [@jxom](https://github.com/jxom)! - Fixed hydration conditional in `createConfig`. + +## 2.6.13 + +### Patch Changes + +- [`b80236dc`](https://github.com/wevm/wagmi/commit/b80236dc623095fe8f1e1d10957d7776fb6ab48b) Thanks [@jxom](https://github.com/jxom)! - Removed unneeded `uniqueBy` check on connectors state. + +## 2.6.12 + +### Patch Changes + +- [#3763](https://github.com/wevm/wagmi/pull/3763) [`a59069e9`](https://github.com/wevm/wagmi/commit/a59069e9fab45dd606bb89a7f829fe94c51a5494) Thanks [@tmm](https://github.com/tmm)! - Fixed `getConnectorClient` internal address comparison. + +- [#3608](https://github.com/wevm/wagmi/pull/3608) [`0acd3132`](https://github.com/wevm/wagmi/commit/0acd31320f534993af566be5490c2978b6184f66) Thanks [@mqklin](https://github.com/mqklin)! - Disabled `wallet_requestPermissions` prompt when `shimDisconnect` is `false`. + +## 2.6.11 + +### Patch Changes + +- [`e1ca4e63`](https://github.com/wevm/wagmi/commit/e1ca4e637ae6cec7f5902b0a2c0e0efc3b751a1d) Thanks [@tmm](https://github.com/tmm)! - Deprecated `normalizeChainId`. Use `Number` instead. + +## 2.6.10 + +### Patch Changes + +- [`dbdca8fd`](https://github.com/wevm/wagmi/commit/dbdca8fd14b90c166222a66a373c1b33c06ce019) Thanks [@jxom](https://github.com/jxom)! - Fixed issue where duplicate connectors could be instantiated if injected after page mount. + +## 2.6.9 + +### Patch Changes + +- [#3715](https://github.com/wevm/wagmi/pull/3715) [`d56edf4f`](https://github.com/wevm/wagmi/commit/d56edf4f27c52acc7a0f57114454b0d3e22cacd6) Thanks [@jxom](https://github.com/jxom)! - Fixed SSR hydration issues. + +## 2.6.8 + +### Patch Changes + +- [#3643](https://github.com/wevm/wagmi/pull/3643) [`e46bcd47`](https://github.com/wevm/wagmi/commit/e46bcd4738a18da15b53f6612b614379c1985374) Thanks [@TateB](https://github.com/TateB)! - Fixed race condition arising from `reconnect`. + +## 2.6.7 + +### Patch Changes + +- [#3642](https://github.com/wevm/wagmi/pull/3642) [`b479b5e8`](https://github.com/wevm/wagmi/commit/b479b5e8a5866cba792862f22e6352c4fb566137) Thanks [@johanneskares](https://github.com/johanneskares)! - Fixed a bug where minification caused the wrong functions to be called on the client. + +- [`f5648dd2`](https://github.com/wevm/wagmi/commit/f5648dd28b3576b628f57732b89287f55acbb1c1) Thanks [@jxom](https://github.com/jxom)! - Updated `prepareTransactionRequest` types for `viem@2.8.0`. + +- [`1c1fee6a`](https://github.com/wevm/wagmi/commit/1c1fee6ab8f01f7734ac6ce05093fa8e388beb3e) Thanks [@jxom](https://github.com/jxom)! - Updated `@walletconnect/ethereum-provider`. + +- [#3653](https://github.com/wevm/wagmi/pull/3653) [`88a2d744`](https://github.com/wevm/wagmi/commit/88a2d744a1315908c9e54156026df3ad2435ad44) Thanks [@tash-2s](https://github.com/tash-2s)! - Fixed error occurring when adding chains without explorers to MetaMask. + +## 2.6.6 + +### Patch Changes + +- [#3644](https://github.com/wevm/wagmi/pull/3644) [`a91c0b64`](https://github.com/wevm/wagmi/commit/a91c0b64ba8b3e6537a560e69724eb601f26af27) Thanks [@nishuzumi](https://github.com/nishuzumi)! - Exported types + +## 2.6.5 + +### Patch Changes + +- [#3580](https://github.com/wevm/wagmi/pull/3580) [`c677dcd2`](https://github.com/wevm/wagmi/commit/c677dcd245dccdf69289a3d66dded237b09570a2) Thanks [@tmm](https://github.com/tmm)! - Updated internals. + +## 2.6.4 + +### Patch Changes + +- [#3571](https://github.com/wevm/wagmi/pull/3571) [`7c6618e6`](https://github.com/wevm/wagmi/commit/7c6618e6a0eb1ff39cf8f66b34d3ddc14be538fe) Thanks [@tmm](https://github.com/tmm)! - Fixed `getClient` passthrough properties from `createConfig`. + +- [#3558](https://github.com/wevm/wagmi/pull/3558) [`895f28e8`](https://github.com/wevm/wagmi/commit/895f28e873af7c8eda5ca85734ff67c8979fd950) Thanks [@tmm](https://github.com/tmm)! - Fixed connector warnings. + +## 2.6.3 + +### Patch Changes + +- [#3533](https://github.com/wevm/wagmi/pull/3533) [`9c3b85dd`](https://github.com/wevm/wagmi/commit/9c3b85dd0a9a4a593e1d7e029345275735330e32) Thanks [@tmm](https://github.com/tmm)! - Fixed `account` property passthrough for actions. + +- [`2a72214a`](https://github.com/wevm/wagmi/commit/2a72214a2901d6b6ddd39f80238aa0bd4db670a7) Thanks [@tmm](https://github.com/tmm)! - Shimmed EIP-1193 `removeListener` for injected since some wallets do not follow spec. + +## 2.6.2 + +### Patch Changes + +- [#3519](https://github.com/wevm/wagmi/pull/3519) [`414eb048`](https://github.com/wevm/wagmi/commit/414eb048af492caac70c0e874dfc87c30702804a) Thanks [@tmm](https://github.com/tmm)! - Fixed multicall passing through all properties to Viem method. + +- [#3518](https://github.com/wevm/wagmi/pull/3518) [`338e857d`](https://github.com/wevm/wagmi/commit/338e857d8cb2fe85e13d9207bef14cada1c1962d) Thanks [@tmm](https://github.com/tmm)! - Fixed internal store migration between versions. + +## 2.6.1 + +### Patch Changes + +- [#3510](https://github.com/wevm/wagmi/pull/3510) [`660ff80d`](https://github.com/wevm/wagmi/commit/660ff80d5b046967a446eba43ee54b8359a37d0d) Thanks [@tmm](https://github.com/tmm)! - Fixed issue where connectors returning multiple addresses didn't checksum correctly. + +- [#3433](https://github.com/wevm/wagmi/pull/3433) [`101a7dd1`](https://github.com/wevm/wagmi/commit/101a7dd131b0cae2dc25579ecab9044290efd37b) Thanks [@tmm](https://github.com/tmm)! - Fixed `getClient` and `getPublicClient` throwing when used with unconfigured `chainId`. + +## 2.6.0 + +### Minor Changes + +- [#3496](https://github.com/wevm/wagmi/pull/3496) [`ba7f8a75`](https://github.com/wevm/wagmi/commit/ba7f8a758efb07664c6e401b5e7e325e7c62341b) Thanks [@tmm](https://github.com/tmm)! - Updated action internals to resolve Viem Client actions. + +## 2.5.0 + +### Minor Changes + +- [#3461](https://github.com/wevm/wagmi/pull/3461) [`ca98041d`](https://github.com/wevm/wagmi/commit/ca98041d1b39893d90246929485f4db0d1c6f9f7) Thanks [@marthendalnunes](https://github.com/marthendalnunes)! - Added `getTransactionConfirmations` action. + +## 2.4.0 + +### Minor Changes + +- [#3427](https://github.com/wevm/wagmi/pull/3427) [`370f1b4a`](https://github.com/wevm/wagmi/commit/370f1b4a3f154d181acf381c31c2e7862e22c0e4) Thanks [@marthendalnunes](https://github.com/marthendalnunes)! - Added `prepareTransactionRequest` action. + +## 2.3.1 + +### Patch Changes + +- [#3476](https://github.com/wevm/wagmi/pull/3476) [`3be5bb7b`](https://github.com/wevm/wagmi/commit/3be5bb7b0b38646e12e6da5c762ef74dff66bcc2) Thanks [@jxom](https://github.com/jxom)! - Modified persist strategy to only store "critical" properties that are needed before hydration. + +## 2.3.0 + +### Minor Changes + +- [#3459](https://github.com/wevm/wagmi/pull/3459) [`d950b666`](https://github.com/wevm/wagmi/commit/d950b666b56700ca039ce16cdfdf34564991e7f5) Thanks [@marthendalnunes](https://github.com/marthendalnunes)! - Added `getEnsText` action. + +### Patch Changes + +- [#3467](https://github.com/wevm/wagmi/pull/3467) [`90ef39bb`](https://github.com/wevm/wagmi/commit/90ef39bb0f4ecb3c914d317875348e35ba0f4524) Thanks [@jxom](https://github.com/jxom)! - Fixed an issue where connectors that share the same provider instance could reconnect when they have never been connected before. + +- [`1cfb6e5a`](https://github.com/wevm/wagmi/commit/1cfb6e5a875e707abcee00dd5739e87da05e8c90) Thanks [@jxom](https://github.com/jxom)! - Bumped listener limit on WalletConnect connector. + +## 2.2.1 + +### Patch Changes + +- [#3447](https://github.com/wevm/wagmi/pull/3447) [`a02a26ad`](https://github.com/wevm/wagmi/commit/a02a26ad030d3afb78f744377d61b5c60b65d97a) Thanks [@tmm](https://github.com/tmm)! - Fixed account typing. + +- [#3443](https://github.com/wevm/wagmi/pull/3443) [`007024a6`](https://github.com/wevm/wagmi/commit/007024a684ddbecf924cdc06dd6a8854fc3d5eeb) Thanks [@jmrossy](https://github.com/jmrossy)! - Fixed invalid `chainId` parameter passed through actions to Viem. + +## 2.2.0 + +### Minor Changes + +- [#3434](https://github.com/wevm/wagmi/pull/3434) [`00bf10a4`](https://github.com/wevm/wagmi/commit/00bf10a428b0d1c5dac35ebf25b19571e033ac26) Thanks [@marthendalnunes](https://github.com/marthendalnunes)! - Added `getBytecode` and `getStorageAt` actions. + +- [#3416](https://github.com/wevm/wagmi/pull/3416) [`64c073f6`](https://github.com/wevm/wagmi/commit/64c073f6c2720961e2d6aff986670b73dbfab9c3) Thanks [@marthendalnunes](https://github.com/marthendalnunes)! - Added `getTransactionReceipt` action. + +- [#3408](https://github.com/wevm/wagmi/pull/3408) [`fb6c4148`](https://github.com/wevm/wagmi/commit/fb6c4148d9e9e2fccfbe74c8f343b444dc68dec5) Thanks [@marthendalnunes](https://github.com/marthendalnunes)! - Added `getProof` action. + +## 2.1.2 + +### Patch Changes + +- [#3407](https://github.com/wevm/wagmi/pull/3407) [`e00b8205`](https://github.com/wevm/wagmi/commit/e00b82058685751637edfa9a6b2d196a12549fe7) Thanks [@jxom](https://github.com/jxom)! - Added a prelude gas estimate check to `sendTransaction`/`useSendTransaction`. + +## 2.1.1 + +### Patch Changes + +- [#3402](https://github.com/wevm/wagmi/pull/3402) [`64b82282`](https://github.com/wevm/wagmi/commit/64b82282c1e57e77c25aa0814673780e4d11edd4) Thanks [@Songkeys](https://github.com/Songkeys)! - Fixed SSR cookie support for cookies that have special characters, e.g. `=`. + +- [`ec0d8b41`](https://github.com/wevm/wagmi/commit/ec0d8b4112181fefb11025e436a94a6114761d37) Thanks [@tmm](https://github.com/tmm)! - Added note to `metaMask` connector. + +## 2.1.0 + +### Minor Changes + +- [#3387](https://github.com/wevm/wagmi/pull/3387) [`c9cd302e`](https://github.com/wevm/wagmi/commit/c9cd302e1c65c980deaee2e12567c2a8ec08b399) Thanks [@marthendalnunes](https://github.com/marthendalnunes)! - Added `call` action. + +## 2.0.2 + +### Patch Changes + +- [#3384](https://github.com/wevm/wagmi/pull/3384) [`ee868c33`](https://github.com/wevm/wagmi/commit/ee868c3385dae511230b6ddcb5627c1293cc1844) Thanks [@tmm](https://github.com/tmm)! - Fixed connectors not bubbling error when connecting with `chainId` and subsequent user rejection. + +## 2.0.1 + +### Major Changes + +- [#3333](https://github.com/wevm/wagmi/pull/3333) [`b3a0baaa`](https://github.com/wevm/wagmi/commit/b3a0baaaee7decf750d376aab2502cd33ca4825a) Thanks [@tmm](https://github.com/tmm)! - Wagmi Core 2.0 featuring: + + - Full TanStack Query support + queryKeys + - Connect multiple connectors + - Switch chains while disconnected + - EIP-6963 enabled + - Strongly typed chainId and chain properties + - Smaller bundle size + - Miscellaneous improvements and bug fixes + + [Breaking Changes & Migration Guide](https://wagmi.sh/core/guides/migrate-from-v1-to-v2) + +## 1.4.13 + +### Patch Changes + +- Updated dependencies [[`bbbbf587`](https://github.com/wevm/wagmi/commit/bbbbf587e41bae12b072b7a7c897d580fc07cd2b)]: + - @wagmi/connectors@3.1.11 + +## 1.4.12 + +### Patch Changes + +- [`53ca1f7e`](https://github.com/wevm/wagmi/commit/53ca1f7eb411d912e11fcce7e03bd61ed067959c) Thanks [@tmm](https://github.com/tmm)! - Removed LedgerConnector due to security vulnerability + +- Updated dependencies [[`53ca1f7e`](https://github.com/wevm/wagmi/commit/53ca1f7eb411d912e11fcce7e03bd61ed067959c)]: + - @wagmi/connectors@3.1.10 + +## 1.4.11 + +### Patch Changes + +- [#3299](https://github.com/wevm/wagmi/pull/3299) [`b02020b3`](https://github.com/wevm/wagmi/commit/b02020b3724e0228198f35817611bb063295906e) Thanks [@dasanra](https://github.com/dasanra)! - Fixed issue with [Safe SDK](https://github.com/wevm/viem/issues/579) by bumping `@safe-global/safe-apps-provider@0.18.1` + +- Updated dependencies [[`51eca0fb`](https://github.com/wevm/wagmi/commit/51eca0fbaea6932f31a5b8b4213f0252280053e2), [`b02020b3`](https://github.com/wevm/wagmi/commit/b02020b3724e0228198f35817611bb063295906e)]: + - @wagmi/connectors@3.1.9 + +## 1.4.10 + +### Patch Changes + +- Updated dependencies [[`e8f7bcbc`](https://github.com/wevm/wagmi/commit/e8f7bcbcd9c038a901c29e71769682c088efe2ac)]: + - @wagmi/connectors@3.1.8 + +## 1.4.9 + +### Patch Changes + +- [#3276](https://github.com/wevm/wagmi/pull/3276) [`83223a06`](https://github.com/wevm/wagmi/commit/83223a0659e2f675d897a1d3374c7af752c16abf) Thanks [@glitch-txs](https://github.com/glitch-txs)! - Removed required namespaces from WalletConnect connector + +- Updated dependencies [[`83223a06`](https://github.com/wevm/wagmi/commit/83223a0659e2f675d897a1d3374c7af752c16abf)]: + - @wagmi/connectors@3.1.7 + +## 1.4.8 + +### Patch Changes + +- Updated dependencies [[`cc7e18f2`](https://github.com/wevm/wagmi/commit/cc7e18f2e7f6b8b989f60f0b05aee70e996a9975), [`cc7e18f2`](https://github.com/wevm/wagmi/commit/cc7e18f2e7f6b8b989f60f0b05aee70e996a9975)]: + - @wagmi/connectors@3.1.6 + +## 1.4.7 + +### Patch Changes + +- Updated dependencies [[`a1950449`](https://github.com/wagmi-dev/wagmi/commit/a1950449127ddf72fff8ecd1fc34c3690befbb05)]: + - @wagmi/connectors@3.1.5 + +## 1.4.6 + +### Patch Changes + +- Updated dependencies [[`4e6ec415`](https://github.com/wagmi-dev/wagmi/commit/4e6ec4151baece94e940e227e0e3711c7f8534d9)]: + - @wagmi/connectors@3.1.4 + +## 1.4.5 + +### Patch Changes + +- Updated dependencies [[`e78aa337`](https://github.com/wagmi-dev/wagmi/commit/e78aa337c454f04b41a3cbd381d25270dd4a0afd)]: + - @wagmi/connectors@3.1.3 + +## 1.4.4 + +### Patch Changes + +- [#3125](https://github.com/wagmi-dev/wagmi/pull/3125) [`725e73fe`](https://github.com/wagmi-dev/wagmi/commit/725e73feb9143dbaa6d540bb76d2009cef29da0b) Thanks [@lukasrosario](https://github.com/lukasrosario)! - Fixed an issue where `dataSuffix` was not being passed down into viem's `simulateContract`, causing the data to be omitted from requests. + +## 1.4.3 + +### Patch Changes + +- [#3076](https://github.com/wagmi-dev/wagmi/pull/3076) [`4c36831b`](https://github.com/wagmi-dev/wagmi/commit/4c36831b7aa44d03b5c0decf64dcd20faae28a67) Thanks [@jxom](https://github.com/jxom)! - Pass `chain` to viem `sendTransaction`/`writeContract`. + +- [#3006](https://github.com/wagmi-dev/wagmi/pull/3006) [`f2ddce23`](https://github.com/wagmi-dev/wagmi/commit/f2ddce23324aff0a91e066100918dac552dc3b4a) Thanks [@jxom](https://github.com/jxom)! - Changed `normalize` to a dynamic import. + +## 1.4.2 + +### Patch Changes + +- Updated dependencies [[`3aaba328`](https://github.com/wagmi-dev/wagmi/commit/3aaba32808ddb4035ec885f96992c91078056715)]: + - @wagmi/connectors@3.1.2 + +## 1.4.1 + +### Patch Changes + +- Updated dependencies [[`bf831bb3`](https://github.com/wagmi-dev/wagmi/commit/bf831bb30df8037cc4312342d0fe3c045408c2fe)]: + - @wagmi/connectors@3.1.1 + +## 1.4.0 + +### Minor Changes + +- [#2956](https://github.com/wagmi-dev/wagmi/pull/2956) [`2abeb285`](https://github.com/wagmi-dev/wagmi/commit/2abeb285674af3e539cc2550b1f5027b1eb0c895) Thanks [@tmm](https://github.com/tmm)! - Replaced `@wagmi/chains` with `viem/chains`. + +### Patch Changes + +- Updated dependencies [[`2abeb285`](https://github.com/wagmi-dev/wagmi/commit/2abeb285674af3e539cc2550b1f5027b1eb0c895)]: + - @wagmi/connectors@3.1.0 + +## 1.3.10 + +### Patch Changes + +- [`557e6400`](https://github.com/wagmi-dev/wagmi/commit/557e6400b9cef3b2c5131739143956c37d7c934a) Thanks [@jxom](https://github.com/jxom)! - Updated references. + +## 1.3.9 + +### Patch Changes + +- [`247c5d11`](https://github.com/wagmi-dev/wagmi/commit/247c5d113e83acf3a6894264c00d4b125d455107) Thanks [@jxom](https://github.com/jxom)! - Updated references. + +## 1.3.8 + +### Patch Changes + +- [#2741](https://github.com/wagmi-dev/wagmi/pull/2741) [`5b1453d9`](https://github.com/wagmi-dev/wagmi/commit/5b1453d95973ed51f1c235a919fffb707eab9b70) Thanks [@jxom](https://github.com/jxom)! - Updated references + +## 1.3.7 + +### Patch Changes + +- [#2700](https://github.com/wagmi-dev/wagmi/pull/2700) [`30118e97`](https://github.com/wagmi-dev/wagmi/commit/30118e979b1b00302e035f31f58c15d1aed911d5) Thanks [@jxom](https://github.com/jxom)! - Updated references. + +## 1.3.6 + +### Patch Changes + +- [`7ad2fdb8`](https://github.com/wagmi-dev/wagmi/commit/7ad2fdb81c7734d0c8107670800c68390e3bad99) Thanks [@jxom](https://github.com/jxom)! - Updated references. + +## 1.3.5 + +### Patch Changes + +- [`aab63fc1`](https://github.com/wagmi-dev/wagmi/commit/aab63fc1f8949004573978ecd8574fada3360758) Thanks [@jxom](https://github.com/jxom)! - Updated references. + +## 1.3.4 + +### Patch Changes + +- [`22246d98`](https://github.com/wagmi-dev/wagmi/commit/22246d9884277d28ccad6ca2d9529b96b67d47fc) Thanks [@jxom](https://github.com/jxom)! - Updated references. + +## 1.3.3 + +### Patch Changes + +- [`1946aa43`](https://github.com/wagmi-dev/wagmi/commit/1946aa43a65b684ef41b7b4c43c67bf29c13e854) Thanks [@jxom](https://github.com/jxom)! - Updated references + +## 1.3.2 + +### Patch Changes + +- [`e86d0940`](https://github.com/wagmi-dev/wagmi/commit/e86d09409bb20b64d24e1263abcf0291314f03c7) Thanks [@jxom](https://github.com/jxom)! - Updated references + +## 1.3.1 + +### Patch Changes + +- [`964042fa`](https://github.com/wagmi-dev/wagmi/commit/964042fa94d682977923c595820c58283fb9244a) Thanks [@jxom](https://github.com/jxom)! - Updated references. + +## 1.3.0 + +### Minor Changes + +- [#2619](https://github.com/wagmi-dev/wagmi/pull/2619) [`0d79748c`](https://github.com/wagmi-dev/wagmi/commit/0d79748cec2b6ac2410ad2c9816cc662f2b70962) Thanks [@jxom](https://github.com/jxom)! - Updated references: + - Updated `@safe-global/safe-apps-sdk` to `^8.0.0` (the one with `viem` support) + +## 1.2.2 + +### Patch Changes + +- [#2611](https://github.com/wagmi-dev/wagmi/pull/2611) [`6d1ed7a1`](https://github.com/wagmi-dev/wagmi/commit/6d1ed7a156729b4df5d66fef3ae9a8b5762a2d34) Thanks [@jxom](https://github.com/jxom)! - Updated references. + +## 1.2.1 + +### Patch Changes + +- [#2589](https://github.com/wagmi-dev/wagmi/pull/2589) [`9680c347`](https://github.com/wagmi-dev/wagmi/commit/9680c347476500d28ceca20d23eeaed7931cb6e0) Thanks [@jxom](https://github.com/jxom)! - Fixed `writeContract` parameters to be compatible with `prepareWriteContract`. + +- [#2587](https://github.com/wagmi-dev/wagmi/pull/2587) [`cfff9994`](https://github.com/wagmi-dev/wagmi/commit/cfff999459384ac644ff7e62f53a7b787cf37507) Thanks [@jxom](https://github.com/jxom)! - Updated references + +## 1.2.0 + +### Minor Changes + +- [#2536](https://github.com/wagmi-dev/wagmi/pull/2536) [`85e9760a`](https://github.com/wagmi-dev/wagmi/commit/85e9760a140cb169ac6236d9466b96e2105dd193) Thanks [@tmm](https://github.com/tmm)! - Changed `Address` type import from ABIType to viem. + +### Patch Changes + +- [#2539](https://github.com/wagmi-dev/wagmi/pull/2539) [`96319c64`](https://github.com/wagmi-dev/wagmi/commit/96319c640b9d07b375821c08a5c213355d8c290b) Thanks [@jxom](https://github.com/jxom)! - Updated references + +## 1.1.1 + +### Patch Changes + +- [`02b98a9f`](https://github.com/wagmi-dev/wagmi/commit/02b98a9f9b2c503a47af4a8967e0202b5db21787) Thanks [@jxom](https://github.com/jxom)! - Updated `viem` peer dependency. + +- [`02b98a9f`](https://github.com/wagmi-dev/wagmi/commit/02b98a9f9b2c503a47af4a8967e0202b5db21787) Thanks [@jxom](https://github.com/jxom)! - Updated references. + +## 1.1.0 + +### Minor Changes + +- [#2482](https://github.com/wagmi-dev/wagmi/pull/2482) [`8764b54a`](https://github.com/wagmi-dev/wagmi/commit/8764b54aab68020063946112e8fe52aff650c99c) Thanks [@tmm](https://github.com/tmm)! - Bumped minimum TypeScript version to v5.0.4. + +### Patch Changes + +- [#2484](https://github.com/wagmi-dev/wagmi/pull/2484) [`3adf1f4f`](https://github.com/wagmi-dev/wagmi/commit/3adf1f4feab863cb7b5d52c81ad46f7e4eb56f09) Thanks [@jxom](https://github.com/jxom)! - Updated `abitype` to 0.8.7 + +- [#2484](https://github.com/wagmi-dev/wagmi/pull/2484) [`3adf1f4f`](https://github.com/wagmi-dev/wagmi/commit/3adf1f4feab863cb7b5d52c81ad46f7e4eb56f09) Thanks [@jxom](https://github.com/jxom)! - Updated references. + +## 1.0.8 + +### Patch Changes + +- [#2441](https://github.com/wagmi-dev/wagmi/pull/2441) [`326edee4`](https://github.com/wagmi-dev/wagmi/commit/326edee4bc85db84a7a4e3768e33785849ab8d8e) Thanks [@tmm](https://github.com/tmm)! - Fixed internal type issue + +## 1.0.7 + +### Patch Changes + +- [#2433](https://github.com/wagmi-dev/wagmi/pull/2433) [`54fcff5f`](https://github.com/wagmi-dev/wagmi/commit/54fcff5f02f6933bbbe045ee0c83c5a78b6bba49) Thanks [@jxom](https://github.com/jxom)! - Added ability to pass an `account` to `writeContract`/`prepareWriteContract`. + +## 1.0.6 + +### Patch Changes + +- [`ca2e1e96`](https://github.com/wagmi-dev/wagmi/commit/ca2e1e96149b87a7dc42c9db07e1f1ad2bb02c4a) Thanks [@jxom](https://github.com/jxom)! - Updated references. + +- [#2401](https://github.com/wagmi-dev/wagmi/pull/2401) [`0f9dc875`](https://github.com/wagmi-dev/wagmi/commit/0f9dc875e90cfdd7a2028e04b7204caf9ea313b2) Thanks [@jxom](https://github.com/jxom)! - Exposed `account` on `readContract`/`useContractRead`. + +## 1.0.5 + +### Patch Changes + +- [`90e2b3b3`](https://github.com/wagmi-dev/wagmi/commit/90e2b3b39efe0585fe28645ac2264109be17362a) Thanks [@jxom](https://github.com/jxom)! - Updated references. + +## 1.0.4 + +### Patch Changes + +- [#2344](https://github.com/wagmi-dev/wagmi/pull/2344) [`8a725458`](https://github.com/wagmi-dev/wagmi/commit/8a72545853ae1024acd9efd18c06142e8c6c5750) Thanks [@jxom](https://github.com/jxom)! - Added gas estimation back into `prepareSendTransaction`. + +## 1.0.3 + +### Patch Changes + +- [#2338](https://github.com/wagmi-dev/wagmi/pull/2338) [`92bfdc2c`](https://github.com/wagmi-dev/wagmi/commit/92bfdc2c744539558ba93c95f140b46ad331cee4) Thanks [@jxom](https://github.com/jxom)! - Fixed an issue where synchronous switch chain behavior (WalletConnect v2) would encounter chain id race conditions in `watchWalletClient`. + +## 1.0.2 + +### Patch Changes + +- [#2304](https://github.com/wevm/wagmi/pull/2304) [`09a4fd38`](https://github.com/wevm/wagmi/commit/09a4fd38f44eb176797925fd85314be17b610cd4) Thanks [@jxom](https://github.com/jxom)! - Removed assert chain workaround. + +## 1.0.1 + +### Patch Changes + +- [`ea651cd7`](https://github.com/wevm/wagmi/commit/ea651cd7fc75b7866272605467db11fd6e1d81af) Thanks [@jxom](https://github.com/jxom)! - Downgraded abitype. + +- Updated dependencies [[`ea651cd7`](https://github.com/wevm/wagmi/commit/ea651cd7fc75b7866272605467db11fd6e1d81af)]: + - @wagmi/connectors@1.0.1 + +## 1.0.0 + +### Major Changes + +- [#2235](https://github.com/wevm/wagmi/pull/2235) [`5be0655c`](https://github.com/wevm/wagmi/commit/5be0655c8e48b25d38009022461fbf611af54349) Thanks [@jxom](https://github.com/jxom)! - Released v1. Read [Migration Guide](https://next.wagmi.sh/react/migration-guide#1xx-breaking-changes). + +## 1.0.0-next.7 + +### Major Changes + +- [#2235](https://github.com/wevm/wagmi/pull/2235) [`708b2ce2`](https://github.com/wevm/wagmi/commit/708b2ce26efa8d3d910806a97cea5171dabc65de) Thanks [@jxom](https://github.com/jxom)! - Added `config.setPublicClient` & `config.setWebSocketPublicClient` + +- Updated references. + +### Patch Changes + +- Updated dependencies []: + - @wagmi/connectors@1.0.0-next.5 + +## 1.0.0-next.6 + +### Major Changes + +- [#2235](https://github.com/wevm/wagmi/pull/2235) [`708b2ce2`](https://github.com/wevm/wagmi/commit/708b2ce26efa8d3d910806a97cea5171dabc65de) Thanks [@jxom](https://github.com/jxom)! - Added `config.setPublicClient` & `config.setWebSocketPublicClient` + +- Added `config.setConnectors` + +### Patch Changes + +- Updated dependencies []: + - @wagmi/connectors@1.0.0-next.6 + +## 1.0.0-next.5 + +### Major Changes + +- [#2235](https://github.com/wevm/wagmi/pull/2235) [`708b2ce2`](https://github.com/wevm/wagmi/commit/708b2ce26efa8d3d910806a97cea5171dabc65de) Thanks [@jxom](https://github.com/jxom)! - Added `config.setPublicClient` & `config.setWebSocketPublicClient` + +## 1.0.0-next.4 + +### Major Changes + +- Updated viem. + Removed `goerli` export from main entrypoint. + +### Patch Changes + +- Updated dependencies []: + - @wagmi/connectors@1.0.0-next.5 + +## 1.0.0-next.3 + +### Major Changes + +- Updated references. + +### Patch Changes + +- Updated dependencies []: + - @wagmi/connectors@1.0.0-next.4 + +## 1.0.0-next.2 + +### Major Changes + +- **Breaking:** Renamed `createClient` to `createConfig` +- **Breaking:** Renamed `getClient` to `getConfig` +- **Breaking:** Removed `request` as an argument to `prepareSendTransaction` & `sendTransaction`. Arguments now belong on the root level of the Action. + +### Patch Changes + +- Updated dependencies []: + - @wagmi/chains@1.0.0-next.0 + - @wagmi/connectors@1.0.0-next.3 + +## 1.0.0-next.1 + +### Major Changes + +- updated viem + +### Patch Changes + +- Updated dependencies []: + - @wagmi/connectors@1.0.0-next.2 + +## 1.0.0-next.0 + +### Major Changes + +- [`a7dda00c`](https://github.com/wevm/wagmi/commit/a7dda00c5b546f8b2c42b527e4d9ac1b9e9ab1fb) Thanks [@jxom](https://github.com/jxom)! - Released v1. + +### Patch Changes + +- Updated dependencies [[`a7dda00c`](https://github.com/wevm/wagmi/commit/a7dda00c5b546f8b2c42b527e4d9ac1b9e9ab1fb)]: + - @wagmi/connectors@1.0.0-next.1 + +## 0.10.11 + +### Patch Changes + +- [#2270](https://github.com/wevm/wagmi/pull/2270) [`6d1fa9df`](https://github.com/wevm/wagmi/commit/6d1fa9df790287729c3b33d4f01fd23c2f8153f1) Thanks [@jxom](https://github.com/jxom)! - Updated references. + +- Updated dependencies []: + - @wagmi/connectors@0.3.19 + +## 0.10.10 + +### Patch Changes + +- [#2208](https://github.com/wevm/wagmi/pull/2208) [`cfc696d8`](https://github.com/wevm/wagmi/commit/cfc696d83c6f768a2e1a29c5197efeed7f1d40a1) Thanks [@bangtoven](https://github.com/bangtoven)! - Bumped references to apply coinbase wallet sdk updates + +- Updated dependencies []: + - @wagmi/connectors@0.3.16 + +## 0.10.9 + +### Patch Changes + +- [#2143](https://github.com/wevm/wagmi/pull/2143) [`26dc5326`](https://github.com/wevm/wagmi/commit/26dc53260fde1d3278018c0b20a6d48a093d9427) Thanks [@tmm](https://github.com/tmm)! - Exported Sepolia Chain. + +- [#2146](https://github.com/wevm/wagmi/pull/2146) [`21b6842e`](https://github.com/wevm/wagmi/commit/21b6842e8c296a0bbe71ebe0780d898abc4cf4a8) Thanks [@tmm](https://github.com/tmm)! - Bumped references + +- Updated dependencies []: + - @wagmi/connectors@0.3.12 + +## 0.10.8 + +### Patch Changes + +- [#2099](https://github.com/wevm/wagmi/pull/2099) [`f1fee5b3`](https://github.com/wevm/wagmi/commit/f1fee5b30a1bd13b5e66118bf9cdc44b0dc003a1) Thanks [@jxom](https://github.com/jxom)! - Added chains: + + - `nexi` + - `polygonZkEvm` + - `xdc` + - `xdcTestnet` + +- [#2085](https://github.com/wevm/wagmi/pull/2085) [`7d64e3f5`](https://github.com/wevm/wagmi/commit/7d64e3f538a6149777bfa84ea9435769b2a7db58) Thanks [@jxom](https://github.com/jxom)! - Fixed an issue where multicall would not throw if the target chain was not configured on the wagmi client. + +- Updated dependencies []: + - @wagmi/connectors@0.3.10 + +## 0.10.7 + +### Patch Changes + +- [#2082](https://github.com/wevm/wagmi/pull/2082) [`2ccc8a25`](https://github.com/wevm/wagmi/commit/2ccc8a255e93f0a2bb7b22101656b3905ec59abd) Thanks [@jxom](https://github.com/jxom)! - Updated references. + +- Updated dependencies []: + - @wagmi/connectors@0.3.10 + +## 0.10.6 + +### Patch Changes + +- [#2056](https://github.com/wevm/wagmi/pull/2056) [`944f6513`](https://github.com/wevm/wagmi/commit/944f6513adf09a6f0b3bd34f591d3bbd1f1ffd2e) Thanks [@tmm](https://github.com/tmm)! - Bumped references. + +- Updated dependencies []: + - @wagmi/connectors@0.3.8 + +## 0.10.5 + +### Patch Changes + +- [#2053](https://github.com/wevm/wagmi/pull/2053) [`665df1bf`](https://github.com/wevm/wagmi/commit/665df1bf2afccb533102069def395e19fb7194dd) Thanks [@tmm](https://github.com/tmm)! - Fixed issue where you add a new chain to MetaMask, but the switch after is rejected. + +- Updated dependencies []: + - @wagmi/connectors@0.3.7 + +## 0.10.4 + +### Patch Changes + +- [#2046](https://github.com/wevm/wagmi/pull/2046) [`90d8e9b8`](https://github.com/wevm/wagmi/commit/90d8e9b87962b72c54311649537e91a953660f9b) Thanks [@tmm](https://github.com/tmm)! - Exported internal type. + +- Updated dependencies []: + - @wagmi/connectors@0.3.6 + +## 0.10.3 + +### Patch Changes + +- [#2039](https://github.com/wevm/wagmi/pull/2039) [`bac893ab`](https://github.com/wevm/wagmi/commit/bac893ab26012d4d8741c4f80e8b8813aee26f0c) Thanks [@tmm](https://github.com/tmm)! - Updated references. + +- [#2043](https://github.com/wevm/wagmi/pull/2043) [`49a58320`](https://github.com/wevm/wagmi/commit/49a58320ab5f1f13bc4de25abcc028c8335e98f0) Thanks [@tmm](https://github.com/tmm)! - Removed `InjectedConnector` `shimChainChangedDisconnect` shim (no longer necessary). + +- Updated dependencies []: + - @wagmi/connectors@0.3.6 + +## 0.10.2 + +### Patch Changes + +- [#2016](https://github.com/wevm/wagmi/pull/2016) [`06bf61de`](https://github.com/wevm/wagmi/commit/06bf61dee6d2920777bd9392491e6b7aedebe7ab) Thanks [@jxom](https://github.com/jxom)! - Added chains: + + - `boba` + - `chronos` + - `crossbell` + - `dfk` + - `dogechain` + - `flare` + - `flareTestnet` + - `klaytn` + - `scrollTestnet` + - `shardeumSphinx` + - `skaleCalypso` + - `skaleCalypsoTestnet` + - `skaleChaosTestnet` + - `skaleCryptoBlades` + - `skaleCryptoColosseum` + - `skaleEuropa` + - `skaleEuropaTestnet` + - `skaleExorde` + - `skaleHumanProtocol` + - `skaleNebula` + - `skaleNebulaTestnet` + - `skaleRazor` + - `skaleTitan` + - `skaleTitanTestnet` + - `songbird` + - `songbirdTestnet` + - `titan` + - `titanTestnet` + - `wanchain` + - `wanchainTestnet` + +- [#2016](https://github.com/wevm/wagmi/pull/2016) [`06bf61de`](https://github.com/wevm/wagmi/commit/06bf61dee6d2920777bd9392491e6b7aedebe7ab) Thanks [@jxom](https://github.com/jxom)! - Updated references/ submodule. + +- Updated dependencies []: + - @wagmi/connectors@0.3.4 + +## 0.10.0 + +### Minor Changes + +- [#1902](https://github.com/wevm/wagmi/pull/1902) [`0994e896`](https://github.com/wevm/wagmi/commit/0994e8966349b8811db0a5886db3831dafc99245) Thanks [@jxom](https://github.com/jxom)! - **Breaking:** Removed the `version` config option for `WalletConnectConnector`. + + `WalletConnectConnector` now uses WalletConnect v2 by default. WalletConnect v1 is now `WalletConnectLegacyConnector`. + + ### WalletConnect v2 + + ```diff + import { WalletConnectConnector } from 'wagmi/connectors/walletConnect' + + const connector = new WalletConnectConnector({ + options: { + - version: '2', + projectId: 'abc', + }, + }) + ``` + + ### WalletConnect v1 + + ```diff + -import { WalletConnectConnector } from 'wagmi/connectors/walletConnect' + +import { WalletConnectConnector } from 'wagmi/connectors/walletConnectLegacy' + + -const connector = new WalletConnectConnector({ + +const connector = new WalletConnectLegacyConnector({ + options: { + qrcode: true, + }, + }) + ``` + +### Patch Changes + +- Updated dependencies []: + - @wagmi/connectors@0.3.2 + +## 0.9.7 + +### Patch Changes + +- [#1907](https://github.com/wevm/wagmi/pull/1907) [`cc4e74ee`](https://github.com/wevm/wagmi/commit/cc4e74ee19665eccb3767052dab6ab956ff4e676) Thanks [@jxom](https://github.com/jxom)! - Added the following chains to the `wagmi/chains` entrypoint: + + - `baseGoerli` + - `harmonyOne` + - `polygonZkEvmTestnet` + +- Updated dependencies []: + - @wagmi/connectors@0.2.7 + +## 0.9.6 + +### Patch Changes + +- [#1882](https://github.com/wevm/wagmi/pull/1882) [`282cc1b0`](https://github.com/wevm/wagmi/commit/282cc1b02003684d582cea411b11792a59c26fd0) Thanks [@tmm](https://github.com/tmm)! - Updated references. + +- Updated dependencies []: + - @wagmi/connectors@0.2.6 + +## 0.9.5 + +### Patch Changes + +- [#1812](https://github.com/wevm/wagmi/pull/1812) [`c7fd7fbd`](https://github.com/wevm/wagmi/commit/c7fd7fbde6f6c69a3a9a4f89d948c4dfb1d22679) Thanks [@jxom](https://github.com/jxom)! - Added the following chains to the `wagmi/chains` entrypoint: + + - `filecoinCalibration` + - `moonbaseAlpha` + - `moonbeam` + - `moonriver` + +- Updated dependencies []: + - @wagmi/connectors@0.2.5 + +## 0.9.4 + +### Patch Changes + +- [#1786](https://github.com/wevm/wagmi/pull/1786) [`b173a431`](https://github.com/wevm/wagmi/commit/b173a43165c7925a4e56ce1e0327a31917e7edc5) Thanks [@tmm](https://github.com/tmm)! - Locked ethers peer dependency version to >=5.5.1 <6 + +- [#1787](https://github.com/wevm/wagmi/pull/1787) [`f023fd8f`](https://github.com/wevm/wagmi/commit/f023fd8f66befb78b9a4df5ca971ceaa64e37ab4) Thanks [@tmm](https://github.com/tmm)! - Added `SafeConnector` + +- Updated dependencies []: + - @wagmi/connectors@0.2.4 + +## 0.9.3 + +### Patch Changes + +- [#1773](https://github.com/wevm/wagmi/pull/1773) [`9aaf1955`](https://github.com/wevm/wagmi/commit/9aaf195514d3b5f4d085c797fc5021d42a9efb6c) Thanks [@jxom](https://github.com/jxom)! - Updated `@walletconnect/universal-provider` on `WalletConnectConnector` v2. + Added more signable methods to `WalletConnectConnector` v2. + +- [#1773](https://github.com/wevm/wagmi/pull/1773) [`9aaf1955`](https://github.com/wevm/wagmi/commit/9aaf195514d3b5f4d085c797fc5021d42a9efb6c) Thanks [@jxom](https://github.com/jxom)! - Added Telos to the `wagmi/chains` entrypoint. Thanks @donnyquixotic! + +- Updated dependencies []: + - @wagmi/connectors@0.2.3 + +## 0.9.2 + +### Patch Changes + +- [#1756](https://github.com/wevm/wagmi/pull/1756) [`31d06b8c`](https://github.com/wevm/wagmi/commit/31d06b8ce1e7af5e9d1a7ba57f1743b2dff7a53d) Thanks [@jxom](https://github.com/jxom)! - Added OKC Chain. Thanks @clark-cui! + +- [#1756](https://github.com/wevm/wagmi/pull/1756) [`31d06b8c`](https://github.com/wevm/wagmi/commit/31d06b8ce1e7af5e9d1a7ba57f1743b2dff7a53d) Thanks [@jxom](https://github.com/jxom)! - Fixed race condition between `switchNetwork` and mutation Actions that use `chainId` (e.g. `sendTransaction`). Thanks @DanInTheD4rk! + +- Updated dependencies []: + - @wagmi/connectors@0.2.2 + +## 0.9.1 + +### Patch Changes + +- [#1752](https://github.com/wevm/wagmi/pull/1752) [`144a0e76`](https://github.com/wevm/wagmi/commit/144a0e76ef4bb9ba0650b5ffb9c63f95329819a4) Thanks [@jxom](https://github.com/jxom)! - Improved `WalletConnectConnector` (v2) initialization & updated dependencies. + +- [#1752](https://github.com/wevm/wagmi/pull/1752) [`144a0e76`](https://github.com/wevm/wagmi/commit/144a0e76ef4bb9ba0650b5ffb9c63f95329819a4) Thanks [@jxom](https://github.com/jxom)! - Added the following chains to the `wagmi/chains` entrypoint: + + - Aurora – thanks @salil-naik + - Bronos – thanks @chedetinaveen + - Canto – thanks @tster + - Celo – thanks @aaronmgdr + +- Updated dependencies []: + - @wagmi/connectors@0.2.1 + +## 0.9.0 + +### Minor Changes + +- [#1732](https://github.com/wevm/wagmi/pull/1732) [`01e21897`](https://github.com/wevm/wagmi/commit/01e2189747a5c22dc758c6d719b4145adc2a643c) Thanks [@tmm](https://github.com/tmm)! - Bumped minimum TypeScript version to typescript@>=4.9.4. TypeScript 5.0 is coming soon and has some great features we are excited to bring into wagmi. To prepare for this, update your TypeScript version to 4.9.4 or higher. There are likely no [breaking changes](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-9.html#correctness-fixes-and-breaking-changes) if you are coming from typescript@4.7.x || typescript@4.8.x. + +## 0.8.19 + +### Patch Changes + +- [#1718](https://github.com/wevm/wagmi/pull/1718) [`e62b5ef8`](https://github.com/wevm/wagmi/commit/e62b5ef8aaa8063abb5264790768899ea35bbd31) Thanks [@tmm](https://github.com/tmm)! - Updated references + +## 0.8.18 + +### Patch Changes + +- [#1708](https://github.com/wevm/wagmi/pull/1708) [`07fc3801`](https://github.com/wevm/wagmi/commit/07fc3801fa13c2cb5f7cf9b86ba8320b05a6a135) Thanks [@jxom](https://github.com/jxom)! - Updated `references/` submodule. + +## 0.8.17 + +### Patch Changes + +- [#1705](https://github.com/wevm/wagmi/pull/1705) [`9ff797dc`](https://github.com/wevm/wagmi/commit/9ff797dcb979dc86b798a432b74c98598165430d) Thanks [@jxom](https://github.com/jxom)! - Added the following chains to the `@wagmi/core/chains` entrypoint: + + - `crossbell` (thanks @Songkeys) + - `filecoin` & `filecoinHyperspace` (thanks @neil0x46dc) + - `gnosisChiado` (thanks @theNvN) + - `metis` & `metisGoerli` (thanks @CookedCookee) + +## 0.8.16 + +### Patch Changes + +- [#1699](https://github.com/wevm/wagmi/pull/1699) [`2f1e7950`](https://github.com/wevm/wagmi/commit/2f1e7950e55550d9b50ef5ccb97cb609f4af39b1) Thanks [@tmm](https://github.com/tmm)! - Added public RPC URL property to Chain + +## 0.8.15 + +### Patch Changes + +- [#1685](https://github.com/wevm/wagmi/pull/1685) [`917f5bc1`](https://github.com/wevm/wagmi/commit/917f5bc1fad578e35a8c6ee787e339bfdc156bab) Thanks [@jxom](https://github.com/jxom)! - Replaced qrcodemodal with web3modal for the WalletConnect v2 Connector. + +## 0.8.14 + +### Patch Changes + +- [#1646](https://github.com/wevm/wagmi/pull/1646) [`fcdbe353`](https://github.com/wevm/wagmi/commit/fcdbe3531e6d05cda4a4a511bae1ad4c9e426d88) Thanks [@jxom](https://github.com/jxom)! - Upgraded `zustand` to v4.3.1. + +## 0.8.13 + +### Patch Changes + +- [#1639](https://github.com/wevm/wagmi/pull/1639) [`c6869f06`](https://github.com/wevm/wagmi/commit/c6869f0604fffb197752a08256f31db77f52e746) Thanks [@jxom](https://github.com/jxom)! - Added `isRainbow` flag to `InjectedConnector`. + +## 0.8.12 + +### Patch Changes + +- [#1636](https://github.com/wevm/wagmi/pull/1636) [`025f6771`](https://github.com/wevm/wagmi/commit/025f6771b32ff7eed22f527be81c5141ddaf9c3d) Thanks [@DanielSinclair](https://github.com/DanielSinclair)! - Added `isRainbow` flag to injected `window.ethereum` types. + +## 0.8.11 + +### Patch Changes + +- [#1621](https://github.com/wevm/wagmi/pull/1621) [`5812b590`](https://github.com/wevm/wagmi/commit/5812b5909277bf2862cb57a31d52465b47291410) Thanks [@tmm](https://github.com/tmm)! - Bumped @wagmi/connectors + +## 0.8.10 + +### Patch Changes + +- [#1598](https://github.com/wevm/wagmi/pull/1598) [`fc10ebe6`](https://github.com/wevm/wagmi/commit/fc10ebe659dd5f3b7a8e00581f094652280a779b) Thanks [@jxom](https://github.com/jxom)! - Fixed CJS dependency version range + +## 0.8.9 + +### Patch Changes + +- [#1593](https://github.com/wevm/wagmi/pull/1593) [`216d555c`](https://github.com/wevm/wagmi/commit/216d555c62bd95c3c7c8f8e20f7269f6c8504610) Thanks [@jxom](https://github.com/jxom)! - Added CJS escape hatch bundle under the "cjs" tag. + +## 0.8.8 + +### Patch Changes + +- [#1573](https://github.com/wevm/wagmi/pull/1573) [`ef380d9c`](https://github.com/wevm/wagmi/commit/ef380d9c6d51ae0495b9c35925d2843c75d97fd4) Thanks [@tmm](https://github.com/tmm)! - Updated internal types. + +## 0.8.7 + +### Patch Changes + +- [#1570](https://github.com/wevm/wagmi/pull/1570) [`216f585b`](https://github.com/wevm/wagmi/commit/216f585be8a9e3a56e3243f49ccd54d655b5a6dd) Thanks [@wslyvh](https://github.com/wslyvh)! - Added `watchPendingTransactions` + +- [#1470](https://github.com/wevm/wagmi/pull/1470) [`3a1a6c9f`](https://github.com/wevm/wagmi/commit/3a1a6c9fe5db5c360adfd116f9a03a1238b5720c) Thanks [@jxom](https://github.com/jxom)! - The `WalletConnectConnector` now supports WalletConnect v2. + + It can be enabled by setting `version` to `'2'` and supplying a [WalletConnect Cloud `projectId`](https://cloud.walletconnect.com/sign-in). + +## 0.8.6 + +### Patch Changes + +- [#1539](https://github.com/wevm/wagmi/pull/1539) [`732da004`](https://github.com/wevm/wagmi/commit/732da0042c7e28091b2e36a484ea8239971306f5) Thanks [@0xFlicker](https://github.com/0xFlicker)! - All Providers (ie. Alchemy, Infura, Public) now use the ENS Registry address on the wagmi `Chain` object (`chain.contracts.ensRegistry`). + +- [#1574](https://github.com/wevm/wagmi/pull/1574) [`ecde3d10`](https://github.com/wevm/wagmi/commit/ecde3d1029ccdf90e2853ba0e9ae4f5f4ebb9c4c) Thanks [@jxom](https://github.com/jxom)! - Added the following chains: + + - `iotex` + - `iotexTestnet` + - `zkSync` + - `zkSyncTestnet` + +## 0.8.5 + +### Patch Changes + +- [#1542](https://github.com/wevm/wagmi/pull/1542) [`731b3b73`](https://github.com/wevm/wagmi/commit/731b3b733c6a093d1693d49de601705b7c730549) Thanks [@jxom](https://github.com/jxom)! - Added the following chains: + + - `evmos` + - `evmosTestnet` + - `gnosis` + +- [#1542](https://github.com/wevm/wagmi/pull/1542) [`731b3b73`](https://github.com/wevm/wagmi/commit/731b3b733c6a093d1693d49de601705b7c730549) Thanks [@jxom](https://github.com/jxom)! - Updated Goerli symbol to `"ETH"`. + +- [#1542](https://github.com/wevm/wagmi/pull/1542) [`731b3b73`](https://github.com/wevm/wagmi/commit/731b3b733c6a093d1693d49de601705b7c730549) Thanks [@jxom](https://github.com/jxom)! - Updated Arbitrum Goerli RPC and Block Explorer. + +- [#1542](https://github.com/wevm/wagmi/pull/1542) [`731b3b73`](https://github.com/wevm/wagmi/commit/731b3b733c6a093d1693d49de601705b7c730549) Thanks [@jxom](https://github.com/jxom)! - Fixed issue where connecting to MetaMask may return with a stale address. + +- [#1542](https://github.com/wevm/wagmi/pull/1542) [`731b3b73`](https://github.com/wevm/wagmi/commit/731b3b733c6a093d1693d49de601705b7c730549) Thanks [@jxom](https://github.com/jxom)! - Removed ENS registry for Sepolia. + +## 0.8.4 + +### Patch Changes + +- [#1508](https://github.com/wevm/wagmi/pull/1508) [`0b50b62f`](https://github.com/wevm/wagmi/commit/0b50b62f7389619e429509a3e337e451e823b059) Thanks [@jxom](https://github.com/jxom)! - Updated `@wagmi/chains` to `0.1.3`. + +- [#1504](https://github.com/wevm/wagmi/pull/1504) [`11b8b794`](https://github.com/wevm/wagmi/commit/11b8b794fbfd4a2b40f39962e2758e9fbf48cb54) Thanks [@tmm](https://github.com/tmm)! - Converted ethers custom "ACTION_REJECTED" error to standard RPC Error. + +## 0.8.3 + +### Patch Changes + +- [#1431](https://github.com/wevm/wagmi/pull/1431) [`af28f8f9`](https://github.com/wevm/wagmi/commit/af28f8f9cfc227e7c391927fdb934183edb5c2dc) Thanks [@jxom](https://github.com/jxom)! - Re-export connectors from `@wagmi/connectors` + +- [#1431](https://github.com/wevm/wagmi/pull/1431) [`af28f8f9`](https://github.com/wevm/wagmi/commit/af28f8f9cfc227e7c391927fdb934183edb5c2dc) Thanks [@jxom](https://github.com/jxom)! - Added `LedgerConnector` connector + +## 0.8.2 + +### Patch Changes + +- [#1442](https://github.com/wevm/wagmi/pull/1442) [`cde15289`](https://github.com/wevm/wagmi/commit/cde152899c758dea10787412b0aef669ed7202b2) Thanks [@0xproflupin](https://github.com/0xproflupin)! - Added Phantom wallet support to `InjectedConnector` + +- [#1448](https://github.com/wevm/wagmi/pull/1448) [`c6075f3a`](https://github.com/wevm/wagmi/commit/c6075f3a16885d850ad2656272351f9517c9f67b) Thanks [@tmm](https://github.com/tmm)! - Updated [ABIType](https://github.com/wevm/abitype) version. + +- [#1444](https://github.com/wevm/wagmi/pull/1444) [`310a8bc4`](https://github.com/wevm/wagmi/commit/310a8bc428ce4e7f68377f581b45dcdd64381cce) Thanks [@jxom](https://github.com/jxom)! - Assert that a `connector` exists before invoking the callback in `watchSigner`. + +- [#1434](https://github.com/wevm/wagmi/pull/1434) [`100e2a3b`](https://github.com/wevm/wagmi/commit/100e2a3b22f4602716554487b1d98738e053be76) Thanks [@tmm](https://github.com/tmm)! - Updated `MockConnector` `chainId` behavior to default to first chain from `chains` if not provided in `options`. + +## 0.8.1 + +### Patch Changes + +- [#1437](https://github.com/wevm/wagmi/pull/1437) [`c34a3dc6`](https://github.com/wevm/wagmi/commit/c34a3dc6396e6473d9f0505fad88ec910f8f5275) Thanks [@jxom](https://github.com/jxom)! - Omitted `"EIP712Domain"` type from `signTypedData` `types` arg since ethers throws an [internal error](https://github.com/ethers-io/ethers.js/blob/c80fcddf50a9023486e9f9acb1848aba4c19f7b6/packages/hash/src.ts/typed-data.ts#L466) if you include it. + +- [#1445](https://github.com/wevm/wagmi/pull/1445) [`51dd53cb`](https://github.com/wevm/wagmi/commit/51dd53cba3fe0f79fa1393270b738194577ddf54) Thanks [@jxom](https://github.com/jxom)! - Fixed an issue where the wagmi client wouldn't rehydrate the store in local storage when `autoConnect` is truthy. + +## 0.8.0 + +### Minor Changes + +- [#1344](https://github.com/wevm/wagmi/pull/1344) [`57a19374`](https://github.com/wevm/wagmi/commit/57a1937464a4ccf72719fc86c38d1734f6306652) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: the shape of the `Chain` type has been modified. + + #### RPC URLs + + The `rpcUrls` shape has changed to include an array of URLs, and also the transport method (`http` or `webSocket`): + + ```diff + type Chain = { + ... + rpcUrls: { + - [key: string]: string + + [key: string]: { + + http: string[] + + webSocket: string[] + + } + } + ... + } + ``` + + Note that you will also need to ensure that usage is migrated: + + ```diff + - const rpcUrl = mainnet.rpcUrls.alchemy + + const rpcUrl = mainnet.rpcUrls.alchemy.http[0] + ``` + + #### Contracts + + The `multicall` and `ens` attributes have been moved into the `contracts` object: + + ```diff + type Contract = { + address: Address + blockCreated?: number + } + + type Chain = { + ... + - multicall: Contract + - ens: Contract + + contracts: { + + multicall3: Contract + + ensRegistry: Contract + + } + ... + } + ``` + + Note that you will also need to ensure that usage is migrated: + + ```diff + - const multicallContract = mainnet.multicall + + const multicallContract = mainnet.contracts.multicall3 + ``` + +- [#1344](https://github.com/wevm/wagmi/pull/1344) [`57a19374`](https://github.com/wevm/wagmi/commit/57a1937464a4ccf72719fc86c38d1734f6306652) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: Upgraded `@coinbase/wallet-sdk` peer dependency to `3.6.0`. + + **Migration steps**: Update `@coinbase/wallet-sdk` to `^3.6.0`. + +- [#1344](https://github.com/wevm/wagmi/pull/1344) [`57a19374`](https://github.com/wevm/wagmi/commit/57a1937464a4ccf72719fc86c38d1734f6306652) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: Removed the `wait` argument on `waitForTransaction`. Use the transaction `hash` instead. + + ```diff + const data = await waitForTransaction({ + - wait: transaction.wait + + hash: transaction.hash + }) + ``` + +- [#1344](https://github.com/wevm/wagmi/pull/1344) [`57a19374`](https://github.com/wevm/wagmi/commit/57a1937464a4ccf72719fc86c38d1734f6306652) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: With the introduction of the [`@wagmi/core/chains` entrypoint](/core/chains), `@wagmi/core` no longer exports the following: + + - `chain` + - `allChains` + - `defaultChains` + - `defaultL2Chains` + - `chainId` + - `etherscanBlockExplorers` + - `alchemyRpcUrls`, `infuraRpcUrls`, `publicRpcUrls` + + Read below for migration steps. + + #### Removed `chain` + + The `chain` export has been removed. `@wagmi/core` now only exports the `mainnet` & `goerli` chains. If you need to use an alternative chain (`polygon`, `optimism`, etc), you will need to import it from the [`@wagmi/core/chains` entrypoint](/core/chains). + + ```diff + import { + - chain + configureChains + } from '@wagmi/core' + + import { mainnet, polygon, optimism } from '@wagmi/core/chains' + + const { ... } = configureChains( + - [chain.mainnet, chain.polygon, chain.optimism], + + [mainnet, polygon, optimism], + { + ... + } + ) + ``` + + #### Removed `allChains` + + The `allChains` export has been removed. If you need a list of all chains, you can utilize [`@wagmi/core/chains` entrypoint](/core/chains). + + ```diff + - import { allChains } from '@wagmi/core' + + import * as allChains from '@wagmi/core/chains' + + const { ... } = configureChains(allChains, ...) + ``` + + #### Removed `defaultChains` & `defaultL2Chains` + + The `defaultChains` & `defaultL2Chains` exports have been removed. If you still need the `defaultChains` or `defaultL2Chains` exports, you can build them yourself: + + ```diff + - import { defaultChains } from '@wagmi/core' + + import { mainnet, goerli } from '@wagmi/core/chains' + + + const defaultChains = [mainnet, goerli] + ``` + + > The `defaultChains` export was previously populated with `mainnet` & `goerli`. + + ```diff + - import { defaultL2Chains } from '@wagmi/core' + + import { + + arbitrum, + + arbitrumGoerli, + + polygon, + + polygonMumbai, + + optimism, + + optimismGoerli + + } from '@wagmi/core/chains' + + + const defaultL2Chains = [ + + arbitrum, + + arbitrumGoerli, + + polygon, + + polygonMumbai, + + optimism + + optimismGoerli + + ] + ``` + + > The `defaultL2Chains` export was previously populated with `arbitrum` & `optimism`. + + #### Removed `chainId` + + The `chainId` export has been removed. You can extract a chain ID from the chain itself. + + ```diff + - import { chainId } from '@wagmi/core' + + import { mainnet, polygon, optimism } from '@wagmi/core/chains' + + -const mainnetChainId = chainId.mainnet + -const polygonChainId = chainId.polygon + -const optimismChainId = chainId.optimism + +const mainnetChainId = mainnet.chainId + +const polygonChainId = polygon.chainId + +const optimismChainId = optimism.chainId + ``` + + #### Removed `etherscanBlockExplorers` + + The `etherscanBlockExplorers` export has been removed. You can extract a block explorer from the chain itself. + + ```diff + - import { etherscanBlockExplorers } from '@wagmi/core' + + import { mainnet, polygon, optimism } from '@wagmi/core/chains' + + -const mainnetEtherscanBlockExplorer = etherscanBlockExplorers.mainnet + -const polygonEtherscanBlockExplorer = etherscanBlockExplorers.polygon + -const optimismEtherscanBlockExplorer = etherscanBlockExplorers.optimism + +const mainnetEtherscanBlockExplorer = mainnet.blockExplorer + +const polygonEtherscanBlockExplorer = polygon.blockExplorer + +const optimismEtherscanBlockExplorer = optimism.blockExplorer + ``` + + #### Removed `alchemyRpcUrls`, `infuraRpcUrls` & `publicRpcUrls` + + The `alchemyRpcUrls`, `infuraRpcUrls` & `publicRpcUrls` exports have been removed. You can extract a RPC URL from the chain itself. + + ```diff + - import { alchemyRpcUrls, infuraRpcUrls, publicRpcUrls } from '@wagmi/core' + + import { mainnet } from '@wagmi/core/chains' + + -const mainnetAlchemyRpcUrl = alchemyRpcUrls.mainnet + -const mainnetInfuraRpcUrl = infuraRpcUrls.mainnet + -const mainnetOptimismRpcUrl = publicRpcUrls.mainnet + +const mainnetAlchemyRpcUrl = mainnet.rpcUrls.alchemy + +const mainnetInfuraRpcUrl = mainnet.rpcUrls.infura + +const mainnetOptimismRpcUrl = mainnet.rpcUrls.optimism + ``` + +- [#1344](https://github.com/wevm/wagmi/pull/1344) [`57a19374`](https://github.com/wevm/wagmi/commit/57a1937464a4ccf72719fc86c38d1734f6306652) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: Changed `waitForTransaction` behavior to throw an error if the transaction reverted. + +- [#1344](https://github.com/wevm/wagmi/pull/1344) [`57a19374`](https://github.com/wevm/wagmi/commit/57a1937464a4ccf72719fc86c38d1734f6306652) Thanks [@jxom](https://github.com/jxom)! - Updated errors to use `cause` instead of `internal` + +### Patch Changes + +- [#1344](https://github.com/wevm/wagmi/pull/1344) [`57a19374`](https://github.com/wevm/wagmi/commit/57a1937464a4ccf72719fc86c38d1734f6306652) Thanks [@jxom](https://github.com/jxom)! - `waitForTransaction` now respects repriced (sped up) transactions. + +- [#1344](https://github.com/wevm/wagmi/pull/1344) [`57a19374`](https://github.com/wevm/wagmi/commit/57a1937464a4ccf72719fc86c38d1734f6306652) Thanks [@jxom](https://github.com/jxom)! - Export `getClient` + +- [#1344](https://github.com/wevm/wagmi/pull/1344) [`57a19374`](https://github.com/wevm/wagmi/commit/57a1937464a4ccf72719fc86c38d1734f6306652) Thanks [@jxom](https://github.com/jxom)! - `waitForTransaction` now throws an error for cancelled or replaced transactions. + +## 0.7.9 + +### Patch Changes + +- [#1411](https://github.com/wevm/wagmi/pull/1411) [`659be184`](https://github.com/wevm/wagmi/commit/659be1840c613ce9f7aca9ac96694c4f60da4a66) Thanks [@tmm](https://github.com/tmm)! - Fixed issue where block invalidation was not properly disabled when setting `enabled: false`. + +## 0.7.8 + +### Patch Changes + +- [#1406](https://github.com/wevm/wagmi/pull/1406) [`4f18c450`](https://github.com/wevm/wagmi/commit/4f18c450a4d7952bfcfa6c533348ffbe55893d3c) Thanks [@tmm](https://github.com/tmm)! - Function for selecting the [EIP-1193](https://eips.ethereum.org/EIPS/eip-1193) Ethereum Provider to target. Defaults to `() => typeof window !== 'undefined' ? window.ethereum : undefined`. + + ```ts + import { InjectedConnector } from "@wagmi/core/connectors/injected"; + + const connector = new InjectedConnector({ + options: { + name: "My Injected Wallet", + getProvider: () => + typeof window !== "undefined" ? window.myInjectedWallet : undefined, + }, + }); + ``` + +## 0.7.7 + +### Patch Changes + +- [#1386](https://github.com/wevm/wagmi/pull/1386) [`206a2adb`](https://github.com/wevm/wagmi/commit/206a2adbb4ee5149a364543b34612050ccf78c21) Thanks [@jxom](https://github.com/jxom)! - Fixed an issue where `persister` would still use `window.localStorage` instead of the wagmi `storage`. + +- [#1376](https://github.com/wevm/wagmi/pull/1376) [`a70a9528`](https://github.com/wevm/wagmi/commit/a70a9528f93f4d7fea28b7652751dfef2dcacf9b) Thanks [@jxom](https://github.com/jxom)! - Fixed issue where `switchChain` on `WalletConnectConnector` would not resolve. + +- [#1386](https://github.com/wevm/wagmi/pull/1386) [`206a2adb`](https://github.com/wevm/wagmi/commit/206a2adbb4ee5149a364543b34612050ccf78c21) Thanks [@jxom](https://github.com/jxom)! - Added `serialize`/`deserialize` as config options to `createStorage`. + +- [#1392](https://github.com/wevm/wagmi/pull/1392) [`88afc849`](https://github.com/wevm/wagmi/commit/88afc84978afe9689ab7364633e4422ecd7699ea) Thanks [@tmm](https://github.com/tmm)! - Added check for active connector when connecting + +## 0.7.6 + +### Patch Changes + +- [#1384](https://github.com/wevm/wagmi/pull/1384) [`027e88d6`](https://github.com/wevm/wagmi/commit/027e88d6e5f8d028d46ee78aec8500701e0173d9) Thanks [@tmm](https://github.com/tmm)! - Fixed issue reconnecting after disconnect with `MetaMaskConnector` in MetaMask mobile browser. + +## 0.7.5 + +### Patch Changes + +- [`1169914a`](https://github.com/wevm/wagmi/commit/1169914a0f0ad2810ca1c536b1f1bc6c20f2c1be) Thanks [@jxom](https://github.com/jxom)! - Use `get_accounts` for `getSigner` in InjectedConnector + +## 0.7.4 + +### Patch Changes + +- [#1309](https://github.com/wevm/wagmi/pull/1309) [`1f4a4261`](https://github.com/wevm/wagmi/commit/1f4a4261247b1d3a90e3123157bc851a35d49b9c) Thanks [@tmm](https://github.com/tmm)! - Fixed internal type + +## 0.7.3 + +### Patch Changes + +- [#1294](https://github.com/wevm/wagmi/pull/1294) [`b2f88949`](https://github.com/wevm/wagmi/commit/b2f88949f32aabaf13f318472648cd51a8b7f2e7) Thanks [@tmm](https://github.com/tmm)! - Set `abi` return type value for `prepareContractWrite` as more permissive when not inferrable as `Abi`. + +## 0.7.2 + +### Patch Changes + +- [`e9f806b6`](https://github.com/wevm/wagmi/commit/e9f806b652ba62effb3ddac464815e447fc287f6) Thanks [@tmm](https://github.com/tmm)! - Bumped abitype and zustand versions. + +## 0.7.1 + +### Patch Changes + +- [#1272](https://github.com/wevm/wagmi/pull/1272) [`1f7fc41`](https://github.com/wevm/wagmi/commit/1f7fc419f7960bbdc51dfa85c2f33b89f1ecc1bf) Thanks [@tmm](https://github.com/tmm)! - Fixed ethers import path + +## 0.7.0 + +### Minor Changes + +- [#1202](https://github.com/wevm/wagmi/pull/1202) [`9bf56af`](https://github.com/wevm/wagmi/commit/9bf56af3c30bdb80abb1e785c002e00986fadfb2) Thanks [@tmm](https://github.com/tmm)! - **Breaking**: Removed the following deprecated chains: + + - `ropsten` + - `rinkeby` + - `kovan` + - `optimismKovan` + - `arbitrumRinkeby` + + If you feel you still need to include one of these testnets in your application, you will have to define it manually: + + ```diff + -import { rinkeby } from 'wagmi' + +import { Chain } from 'wagmi' + + +export const rinkeby: Chain = { + + id: 4, + + name: 'Rinkeby', + + network: 'rinkeby', + + nativeCurrency: { name: 'Rinkeby Ether', symbol: 'ETH', decimals: 18 }, + + rpcUrls: { + + alchemy: 'https://eth-rinkeby.alchemyapi.io/v2', + + default: 'https://rpc.ankr.com/eth_rinkeby', + + infura: 'https://rinkeby.infura.io/v3', + + public: 'https://rpc.ankr.com/eth_rinkeby', + + }, + + blockExplorers: { + + etherscan: 'https://rinkeby.etherscan.io', + + default: 'https://rinkeby.etherscan.io', + + }, + + ens: { + + address: '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e', + + }, + + multicall: { + + address: '0xca11bde05977b3631167028862be2a173976ca11', + + blockCreated: 10299530, + + }, + + testnet: true, + } + ``` + + You can reference these removed chains [here](https://github.com/wevm/wagmi/blob/389765f7d9af063ab0df07389a2bbfbc10a41060/packages/core/src/constants/chains.ts). + +- [#1202](https://github.com/wevm/wagmi/pull/1202) [`9bf56af`](https://github.com/wevm/wagmi/commit/9bf56af3c30bdb80abb1e785c002e00986fadfb2) Thanks [@tmm](https://github.com/tmm)! - **Breaking**: `addressOrName` renamed to `address` for `fetchBalance` and `fetchEnsAvatar`. + + ```diff + const result = await fetchBalance({ + - addressOrName: '0x…', + + address: '0x…', + }) + ``` + + If you were using an ENS name instead of an address, you can resolve the name to an address before passing it to the action. + + ```diff + + const { data: address } = await fetchEnsAddress({ name: 'example.eth' }) + const result = await fetchBalance({ + - addressOrName: 'example.eth', + + address, + }) + ``` + +- [#1202](https://github.com/wevm/wagmi/pull/1202) [`9bf56af`](https://github.com/wevm/wagmi/commit/9bf56af3c30bdb80abb1e785c002e00986fadfb2) Thanks [@tmm](https://github.com/tmm)! - **Breaking**: Made `apiKey` required on `infuraProvider` and `alchemyProvider`. + + ```diff + import { configureChains } from 'wagmi' + + const config = configureChains(defaultChains, [ + - alchemyProvider(), + + alchemyProvider({ apiKey: process.env.ALCHEMY_API_KEY }) + ]) + ``` + + You can find your Alchemy API key from the [Alchemy Dashboard](https://dashboard.alchemyapi.io/), or your Infura API key from the [Infura Dashboard](https://infura.io/login). + +- [#1202](https://github.com/wevm/wagmi/pull/1202) [`9bf56af`](https://github.com/wevm/wagmi/commit/9bf56af3c30bdb80abb1e785c002e00986fadfb2) Thanks [@tmm](https://github.com/tmm)! - Removed CommonJS support + +## 0.6.12 + +### Patch Changes + +- [#1250](https://github.com/wevm/wagmi/pull/1250) [`ce2e0f4`](https://github.com/wevm/wagmi/commit/ce2e0f4a46b8fd1c509ead552012ef4c072a525b) Thanks [@tmm](https://github.com/tmm)! - Added support for Trust Wallet browser extension. + +## 0.6.11 + +### Patch Changes + +- [#1234](https://github.com/wevm/wagmi/pull/1234) [`3ff9303`](https://github.com/wevm/wagmi/commit/3ff930349250f62137cca4ca3b382522882abf8a) Thanks [@tmm](https://github.com/tmm)! - Fixed issue with adding chain to wallet without block explorer URL. + +## 0.6.10 + +### Patch Changes + +- [#1232](https://github.com/wevm/wagmi/pull/1232) [`c0ca509`](https://github.com/wevm/wagmi/commit/c0ca509506dcf6d98b058df549dc761c9a5f3d1c) Thanks [@tmm](https://github.com/tmm)! - Added validation to check that chain is configured for connector when accessing `Signer`. + +## 0.6.9 + +### Patch Changes + +- [#1207](https://github.com/wevm/wagmi/pull/1207) [`c73d463`](https://github.com/wevm/wagmi/commit/c73d463d65c9dbfcfe709187e47323a769589741) Thanks [@lvshaoping007](https://github.com/lvshaoping007)! - Added Kucoin wallet support to `InjectedConnector` + +## 0.6.8 + +### Patch Changes + +- [#1132](https://github.com/wevm/wagmi/pull/1132) [`d41c0d6`](https://github.com/wevm/wagmi/commit/d41c0d650f8c0e54145758685b7604b8909d7ae0) Thanks [@toniocodo](https://github.com/toniocodo)! - Added ERC-4626 ABI + +- [#1201](https://github.com/wevm/wagmi/pull/1201) [`9a07efa`](https://github.com/wevm/wagmi/commit/9a07efaa397d3ba03f2edbe527c359f21e22139a) Thanks [@jxom](https://github.com/jxom)! - Fixed issue where non-checksum addresses did not resolve with an ENS name + +## 0.6.7 + +### Patch Changes + +- [#1174](https://github.com/wevm/wagmi/pull/1174) [`196a458`](https://github.com/wevm/wagmi/commit/196a458f64141e8a9f39c1b1e1af5937f692cb39) Thanks [@jxom](https://github.com/jxom)! - Fixed an issue where `client.chains` (active connector chains) would be populated when there is no active connector (disconnected user). + +- [#1176](https://github.com/wevm/wagmi/pull/1176) [`389765f`](https://github.com/wevm/wagmi/commit/389765f7d9af063ab0df07389a2bbfbc10a41060) Thanks [@jxom](https://github.com/jxom)! - Migrate away from Alchemy RPC URLs in the public RPC URL list + +## 0.6.6 + +### Patch Changes + +- [`81ce9e6`](https://github.com/wevm/wagmi/commit/81ce9e64d85f7d01370324c1a529988a0919894f) Thanks [@jxom](https://github.com/jxom)! - Add `isPortal` to injected MetaMask flags. + +- [`c2c0109`](https://github.com/wevm/wagmi/commit/c2c01096ef4cd0ffadbb49062969c208604c6194) Thanks [@jxom](https://github.com/jxom)! - Add etherscan block explorer to Optimism Goerli + +## 0.6.5 + +### Patch Changes + +- [#1162](https://github.com/wevm/wagmi/pull/1162) [`30335b3`](https://github.com/wevm/wagmi/commit/30335b3199fb425e398e9c492b50c68d5e2ade7e) Thanks [@tmm](https://github.com/tmm)! - Fixed issue where non-indexed event parameter types were set to `null`. + +- [#1162](https://github.com/wevm/wagmi/pull/1162) [`30335b3`](https://github.com/wevm/wagmi/commit/30335b3199fb425e398e9c492b50c68d5e2ade7e) Thanks [@tmm](https://github.com/tmm)! - Fixed issue where `useContractReads` and `useContractInfiniteReads` types were slowing down TypeScript compiler. + +## 0.6.4 + +### Patch Changes + +- [#1103](https://github.com/wevm/wagmi/pull/1103) [`651eda0`](https://github.com/wevm/wagmi/commit/651eda06384bd0955268427f898e9337b2dc5a31) Thanks [@tmm](https://github.com/tmm)! - Bumped `abitype` dependency. + +## 0.6.3 + +### Patch Changes + +- [#1086](https://github.com/wevm/wagmi/pull/1086) [`4e28d2a`](https://github.com/wevm/wagmi/commit/4e28d2ad4c2e6b3479b728563040b9529463cbcf) Thanks [@tmm](https://github.com/tmm)! - Exposed module types. + +## 0.6.2 + +### Patch Changes + +- [#1080](https://github.com/wevm/wagmi/pull/1080) [`3be5e8b`](https://github.com/wevm/wagmi/commit/3be5e8b01e58ed40cc9dab7ef9533c0197cb74d0) Thanks [@tmm](https://github.com/tmm)! - Added `abitype` to `dependencies` so types ship correctly. + +## 0.6.1 + +### Patch Changes + +- [#1074](https://github.com/wevm/wagmi/pull/1074) [`8db807f`](https://github.com/wevm/wagmi/commit/8db807f16149aa278c2a7db9ee5245431db12173) Thanks [@IljaDaderko](https://github.com/IljaDaderko)! - Exported `EventListener` type + +## 0.6.0 + +### Minor Changes + +- [#940](https://github.com/wevm/wagmi/pull/940) [`b6cb8f4`](https://github.com/wevm/wagmi/commit/b6cb8f4cd15eb13073bc7e9ecb4bfa2c261c0663) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: `watchSigner` now requires an arguments object (that accepts an optional `chainId`) as it's first parameter. + + ```diff + import { watchSigner } from `@wagmi/core` + + -watchSigner(signer => { + +watchSigner({}, signer => { + console.log('new signer!', signer) + }) + ``` + +- [#940](https://github.com/wevm/wagmi/pull/940) [`b6cb8f4`](https://github.com/wevm/wagmi/commit/b6cb8f4cd15eb13073bc7e9ecb4bfa2c261c0663) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: `prepareSendTransaction` now throws when a `chainId` is specified and the end-user is on a different chain id (the wrong network). + +- [#941](https://github.com/wevm/wagmi/pull/941) [`0c96009`](https://github.com/wevm/wagmi/commit/0c96009398647a515a57f72ef25c32724f7c978c) Thanks [@tmm](https://github.com/tmm)! - **Breaking**: `addressOrName` and `contractInterface` renamed to `address` and `abi` respectively for contract actions: `getContract`, `multicall`, `prepareWriteContract`, `readContract`, `readContracts`, `watchContractEvent`, `watchMulticall`, `watchReadContract`, `watchReadContracts`, `writeContract`. + + ```diff + import { readContract } from '@wagmi/core' + + const result = await readContract({ + - addressOrName: '0x…', + + address: '0x…', + - contractInterface: […] as const, + + abi: […] as const, + functionName: 'balanceOf', + args: ['0x…'], + }) + ``` + + If you were using an ENS name instead of an address, you can resolve the name to an address before passing it to the action. + + ```diff + - import { readContract } from '@wagmi/core' + + import { fetchEnsAddress, readContract } from '@wagmi/core' + + + const address = await fetchEnsAddress('example.eth') + const result = await readContract({ + - addressOrName: 'example.eth', + + address, + abi: […] as const, + functionName: 'balanceOf', + args: ['0x…'], + }) + ``` + +- [#940](https://github.com/wevm/wagmi/pull/940) [`b6cb8f4`](https://github.com/wevm/wagmi/commit/b6cb8f4cd15eb13073bc7e9ecb4bfa2c261c0663) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: `prepareWriteContract` now throws when a `chainId` is specified and the end-user is on a different chain id (the wrong network). + +- [#940](https://github.com/wevm/wagmi/pull/940) [`b6cb8f4`](https://github.com/wevm/wagmi/commit/b6cb8f4cd15eb13073bc7e9ecb4bfa2c261c0663) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: `prepareSendTransaction` now only accepts a `signer` instead of `signerOrProvider`. + + This is to reach parity with `prepareWriteContract`. + + If no `signer` is provided, wagmi will use the signer that is currently connected. If no user is connected, then `prepareWriteContract` will throw an error. + +- [#941](https://github.com/wevm/wagmi/pull/941) [`0c96009`](https://github.com/wevm/wagmi/commit/0c96009398647a515a57f72ef25c32724f7c978c) Thanks [@tmm](https://github.com/tmm)! - **Breaking**: `args` config option must now be an array for the following actions: `readContract`, `writeContract`, `prepareWriteContract`, `multicall`, `readContracts`, `watchMulticall`, and `watchReadContracts`. + + ```diff + import { readContract } from '@wagmi/core' + + const result = await readContract({ + address: '0x…', + abi: […], + functionName: 'balanceOf', + - args: '0x…', + + args: ['0x…'], + }) + ``` + +- [#941](https://github.com/wevm/wagmi/pull/941) [`0c96009`](https://github.com/wevm/wagmi/commit/0c96009398647a515a57f72ef25c32724f7c978c) Thanks [@tmm](https://github.com/tmm)! - **Breaking**: `watchContractEvent` now accepts a configuration object and callback instead of positional arguments. + + ```diff + import { watchContractEvent } from '@wagmi/core' + + - const unsubscribe = watchContractEvent( + - { + - address: '0x…', + - abi: […], + - }, + - 'Transfer', + - (from, to, tokenId) => { + - // ... + - }, + - { once: true }, + - ) + + const unsubscribe = watchContractEvent( + + { + + address: '0x…', + + abi: […], + + eventName: 'Transfer', + + once: true, + + }, + + (from, to, tokenId) => { + + // ... + + }, + + ) + ``` + +- [#941](https://github.com/wevm/wagmi/pull/941) [`0c96009`](https://github.com/wevm/wagmi/commit/0c96009398647a515a57f72ef25c32724f7c978c) Thanks [@tmm](https://github.com/tmm)! - **Breaking**: Updated TypeScript version to `typescript@>=4.7.4`. + + `@wagmi/core` can now infer types based on [ABI](https://docs.soliditylang.org/en/v0.8.15/abi-spec.html#json) and [EIP-712](https://eips.ethereum.org/EIPS/eip-712) Typed Data definitions, giving you full end-to-end type-safety from your contracts to your frontend and incredible developer experience (e.g. autocomplete contract function names and catch misspellings, type contract function arguments, etc.). + + For this to work, you must upgrade to `typescript@>=4.7.4`. Why is TypeScript v4.7.4 or greater necessary? TypeScript 4.7.4 introduced the ability to [extend constraints on inferred type variables](https://devblogs.microsoft.com/typescript/announcing-typescript-4-7/#extends-constraints-on-infer-type-variables), which is used extensively to help narrow types for ABIs. Good news! When upgrading TypeScript from 4.6 to 4.7 there are likely no [breaking changes](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-7.html#breaking-changes) for your set up. + +- [#941](https://github.com/wevm/wagmi/pull/941) [`0c96009`](https://github.com/wevm/wagmi/commit/0c96009398647a515a57f72ef25c32724f7c978c) Thanks [@tmm](https://github.com/tmm)! - **Breaking**: Updated TypeScript generics for contract interaction and typed data actions. + + Adding a [const assertion](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-4.html#const-assertions) to `abi` allows TypeScript to infer `functionName`, `args`, `overrides`, and return types for functions, and `eventName` and `listener` types for events. + + ```diff + import { readContract } from '@wagmi/core' + + const result = await readContract({ + address: '0x…', + - abi: […], + + abi: […] as const, + functionName: 'balanceOf', // will autocomplete and catch typos + args: ['0x…'], // inferred based on `functionName` + }) + result // inferred based on `functionName` + ``` + + This works for the following actions: `readContract`, `writeContract`, `prepareWriteContract`, `multicall`, `readContracts`, `watchMulticall`, `watchReadContracts`, and `watchContractEvent`. + + Adding a [const assertion](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-4.html#const-assertions) to `signTypedData`'s config option, `types`, allows TypeScript to infer `value`. + + ```diff + import { signTypedData } from '@wagmi/core' + + const result = await signTypedData({ + domain: { + name: 'Ether Mail', + version: '1', + chainId: 1, + verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC', + }, + types: { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], + - }, + + } as const, + value: { // `value` is inferred based on `types` + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, + }) + ``` + +### Patch Changes + +- [#1061](https://github.com/wevm/wagmi/pull/1061) [`a4ffe8b`](https://github.com/wevm/wagmi/commit/a4ffe8b25516d5504685ae94579da4cd8c409329) Thanks [@alecananian](https://github.com/alecananian)! - Added Arbitrum Goerli Arbiscan block explorer + +- [#940](https://github.com/wevm/wagmi/pull/940) [`b6cb8f4`](https://github.com/wevm/wagmi/commit/b6cb8f4cd15eb13073bc7e9ecb4bfa2c261c0663) Thanks [@jxom](https://github.com/jxom)! - The `fetchSigner` action now accepts an optional `chainId` to use for signer initialization as an argument. + + ```tsx + import { fetchSigner } from "@wagmi/core"; + import { optimism } from "@wagmi/core/chains"; + + // ... + + fetchSigner({ chainId: optimism.id }); + ``` + +- [#1048](https://github.com/wevm/wagmi/pull/1048) [`ed13074`](https://github.com/wevm/wagmi/commit/ed130747c0f28c1d9980a1328883e4000a60455e) Thanks [@Max-3-7](https://github.com/Max-3-7)! - Added support for Avalanche core wallet + +- [#1046](https://github.com/wevm/wagmi/pull/1046) [`ab9ecaa`](https://github.com/wevm/wagmi/commit/ab9ecaa74dfa4324279e167dd7e348319ef7d35d) Thanks [@jxom](https://github.com/jxom)! - make ethers block format validator compatible with Celo + +- [#1050](https://github.com/wevm/wagmi/pull/1050) [`73d4d47`](https://github.com/wevm/wagmi/commit/73d4d47bc679f4f9a1cf46010fe2bf858c9d0b5c) Thanks [@jxom](https://github.com/jxom)! - update dependencies + + - `zustand@4.1.1` + +## 0.5.8 + +### Patch Changes + +- [`8cb07462`](https://github.com/wevm/wagmi/commit/8cb07462acc3c5637398d11d2451f8b8e330d553) Thanks [@jxom](https://github.com/jxom)! - Added `chainId` as an argument to `watchBlockNumber`. + +* [`53c1a474`](https://github.com/wevm/wagmi/commit/53c1a4747d03b685e8cfbf55361fc2a56777fb06) Thanks [@tmm](https://github.com/tmm)! - Added missing `decimals` option to `Connector` `watchAsset` + +- [`4d74dd4f`](https://github.com/wevm/wagmi/commit/4d74dd4ff827ba5c43c3546a218f38cee45ea76a) Thanks [@jxom](https://github.com/jxom)! - Support ERC20 contracts that represent strings as bytes32 + +## 0.5.7 + +### Patch Changes + +- [`aa51bc4d`](https://github.com/wevm/wagmi/commit/aa51bc4dc5683bf0178597d2fdb8f2e9d82e7970) Thanks [@jxom](https://github.com/jxom)! - Fixed an issue in `CoinbaseWalletConnector` where the browser extension would unintendedly reset the network when the browser is refreshed. + +* [#955](https://github.com/wevm/wagmi/pull/955) [`e326cd80`](https://github.com/wevm/wagmi/commit/e326cd80fe65267db623eb6c80ccdd75572914cf) Thanks [@0xFlicker](https://github.com/0xFlicker)! - Added Infura RPC URL for Sepolia + +- [`cec14089`](https://github.com/wevm/wagmi/commit/cec14089500c86687226ab272b4c3fcb85ae3d69) Thanks [@jxom](https://github.com/jxom)! - Fixed an issue where `useProvider` & `getProvider` were not returning referentially equal providers. + +* [`cec14089`](https://github.com/wevm/wagmi/commit/cec14089500c86687226ab272b4c3fcb85ae3d69) Thanks [@jxom](https://github.com/jxom)! - Fixed an issue where the `watch` option was not respecting the neighboring `chainId` option in `useBlockNumber`. + +- [`cec14089`](https://github.com/wevm/wagmi/commit/cec14089500c86687226ab272b4c3fcb85ae3d69) Thanks [@jxom](https://github.com/jxom)! - Fixed an issue where block listeners (via `watch`) were firing excessively on L2 chains. + +## 0.5.6 + +### Patch Changes + +- [#936](https://github.com/wevm/wagmi/pull/936) [`3329d1f`](https://github.com/wevm/wagmi/commit/3329d1f5880431566e14ac1640f48d0975aec4c2) Thanks [@jxom](https://github.com/jxom)! - Added the ability to provide a custom logger to override how logs are broadcasted to the consumer in wagmi. + + A custom logger can be provided to the wagmi client via `logger`. + + ### API + + ```tsx + logger?: { + warn: typeof console.warn | null + } + ``` + + ### Examples + + **Passing in a custom logger** + + You can pass in a function to define your own custom logger. + + ```diff + + import { logWarn } from './logger'; + + const client = createClient({ + ... + + logger: { + + warn: message => logWarn(message) + + } + ... + }) + ``` + + **Disabling a logger** + + You can disable a logger by passing `null` as the value. + + ```diff + const client = createClient({ + ... + + logger: { + + warn: null + + } + ... + }) + ``` + +* [#889](https://github.com/wevm/wagmi/pull/889) [`27788ed`](https://github.com/wevm/wagmi/commit/27788ed989b5dc26849c7945fb91a92e56766018) Thanks [@jxom](https://github.com/jxom)! - Make multicall & readContracts more error robust + +## 0.5.5 + +### Patch Changes + +- [#912](https://github.com/wevm/wagmi/pull/912) [`e529e12`](https://github.com/wevm/wagmi/commit/e529e125c713ed3ef24a59c6bf226fe4deee7ac9) Thanks [@zouhangwithsweet](https://github.com/zouhangwithsweet)! - Added BitKeep to injected flags + +- [#912](https://github.com/wevm/wagmi/pull/910) Thanks [@mytangying](https://github.com/zouhangwithsweet)! - Added MathWallet to injected flags + +- [#904](https://github.com/wevm/wagmi/pull/904) [`c231058`](https://github.com/wevm/wagmi/commit/c23105850f335f8798031e14c7098b7dee8c2975) Thanks [@jxom](https://github.com/jxom)! - Minimized contract interface returned from `prepareWriteContract`. + +## 0.5.4 + +### Patch Changes + +- [#852](https://github.com/wevm/wagmi/pull/852) [`c3192d0`](https://github.com/wevm/wagmi/commit/c3192d0663aa332ae9edfd9dd49b333454013ab7) Thanks [@skeithc](https://github.com/skeithc)! - Added support for the Sepolia testnet + +## 0.5.3 + +### Patch Changes + +- [#835](https://github.com/wevm/wagmi/pull/835) [`1b85e54`](https://github.com/wevm/wagmi/commit/1b85e54ae654e2564cf5bc2dae6411fe0a25875c) Thanks [@jxom](https://github.com/jxom)! - Update `@coinbase/wallet-sdk` to `3.4.1` + +* [#834](https://github.com/wevm/wagmi/pull/834) [`9655879`](https://github.com/wevm/wagmi/commit/96558793b0319df47aefafa6b7b9c959068d491b) Thanks [@jxom](https://github.com/jxom)! - Update zustand to `4.0.0` + +## 0.5.2 + +### Patch Changes + +- [#823](https://github.com/wevm/wagmi/pull/823) [`10b8b78`](https://github.com/wevm/wagmi/commit/10b8b78605b7246b2c55b8d69f96663906e5cd20) Thanks [@tmm](https://github.com/tmm)! - Add Optimism Goerli to `chain` lookup. + +## 0.5.1 + +### Patch Changes + +- [#767](https://github.com/wevm/wagmi/pull/767) [`e9392f3`](https://github.com/wevm/wagmi/commit/e9392f396e48e928bd9d2522e3ad671c589f08cb) Thanks [@klyap](https://github.com/klyap)! - Add Optimism Goerli chain ahead of [Kovan deprecation](https://dev.optimism.io/kovan-to-goerli). + +* [#817](https://github.com/wevm/wagmi/pull/817) [`7e5cac7`](https://github.com/wevm/wagmi/commit/7e5cac75815dcd8aa563462342a4853fc5207735) Thanks [@alecananian](https://github.com/alecananian)! - Added custom name mapping for 1inch Wallet injected provider + +- [#806](https://github.com/wevm/wagmi/pull/806) [`0b34e56`](https://github.com/wevm/wagmi/commit/0b34e56db97e6dcdb71088e0149b2d55ebc604a5) Thanks [@vmichalik](https://github.com/vmichalik)! - Fix canonical testnet native asset symbols by changing them to ETH + +* [#778](https://github.com/wevm/wagmi/pull/778) [`0892908`](https://github.com/wevm/wagmi/commit/08929084eeeba1a3a55aa098fa9d92a243685ad5) Thanks [@0xcadams](https://github.com/0xcadams)! - Add Arbitrum Goerli chain. + +## 0.5.0 + +### Minor Changes + +- [#658](https://github.com/wevm/wagmi/pull/658) [`d70c115`](https://github.com/wevm/wagmi/commit/d70c115131f299fb61f87867b6ac4218e0bcf432) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: The configuration passed to the `sendTransaction` action now needs to be: + + - prepared with the `prepareSendTransaction` action **(new functionality)**, or + - recklessly unprepared **(previous functionality)** + + > Why? [Read here](https://wagmi.sh/docs/prepare-hooks) + + ### Prepared usage + + ```diff + import { prepareSendTransaction, sendTransaction } from '@wagmi/core' + + +const config = await prepareSendTransaction({ + + request: { + + to: 'moxey.eth', + + value: parseEther('1'), + + } + +}) + + const result = await sendTransaction({ + - request: { + - to: 'moxey.eth', + - value: parseEther('1') + - } + + ...config + }) + ``` + + ### Recklessly unprepared usage + + It is possible to use `sendTransaction` without preparing the configuration first by passing `mode: 'recklesslyUnprepared'`. + + ```diff + import { sendTransaction } from '@wagmi/core' + + const result = await sendTransaction({ + + mode: 'recklesslyUnprepared', + request: { + to: 'moxey.eth', + value: parseEther('1'), + } + }) + ``` + +* [#760](https://github.com/wevm/wagmi/pull/760) [`d8af6bf`](https://github.com/wevm/wagmi/commit/d8af6bf50885aec110ae4d64716642453aa27896) Thanks [@tmm](https://github.com/tmm)! - **Breaking:** `alchemyProvider` and `infuraProvider` now use a generic `apiKey` configuration option instead of `alchemyId` and `infuraId`. + + ```diff + import { alchemyProvider } from '@wagmi/core/providers/alchemy' + import { infuraProvider } from '@wagmi/core/providers/infura' + + alchemyProvider({ + - alchemyId: 'yourAlchemyApiKey', + + apiKey: 'yourAlchemyApiKey', + }) + + infuraProvider({ + - infuraId: 'yourInfuraApiKey', + + apiKey: 'yourInfuraApiKey', + }) + ``` + +- [#727](https://github.com/wevm/wagmi/pull/727) [`ac3b9b8`](https://github.com/wevm/wagmi/commit/ac3b9b87f80cb45b65d003f09d916d7d1427a62e) Thanks [@tmm](https://github.com/tmm)! - **Breaking**: Moved the `pollingInterval` config option from the chain provider config to `configureChains` config. + + ```diff + const { chains, provider } = configureChains( + [chain.mainnet, chain.polygon], + [ + - alchemyProvider({ apiKey, pollingInterval: 5000 }), + - publicProvider({ pollingInterval: 5000 }) + + alchemyProvider({ apiKey }), + + publicProvider() + ], + + { pollingInterval: 5000 } + ) + ``` + +* [#658](https://github.com/wevm/wagmi/pull/658) [`d70c115`](https://github.com/wevm/wagmi/commit/d70c115131f299fb61f87867b6ac4218e0bcf432) Thanks [@jxom](https://github.com/jxom)! - **Breaking:** The `sendTransaction` action now returns an object only consisting of `hash` & `wait`, and not the full [`TransactionResponse`](https://docs.ethers.io/v5/api/providers/types/#providers-TransactionResponse). + + If you require the full `TransactionResponse`, you can use `fetchTransaction`: + + ```diff + import { sendTransaction, fetchTransaction } from '@wagmi/core' + + const { + hash, + wait, + - ...transaction + } = sendTransaction(...) + + +const transaction = fetchTransaction({ hash }) + ``` + + > Why? The old implementation of `sendTransaction` created a long-running async task, causing [UX pitfalls](https://wagmi.sh/docs/prepare-hooks#ux-pitfalls-without-prepare-hooks) when invoked in a click handler. + +- [#658](https://github.com/wevm/wagmi/pull/658) [`d70c115`](https://github.com/wevm/wagmi/commit/d70c115131f299fb61f87867b6ac4218e0bcf432) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: If a `chainId` is passed to `writeContract` or `sendTransaction`, it will no longer attempt to switch chain before sending the transaction. Instead, it will throw an error if the user is on the wrong chain. + + > Why? + > + > - Eagerly prompting to switch chain in these actions created a long-running async task that that makes [iOS App Links](https://wagmi.sh/docs/prepare-hooks#ios-app-link-constraints) vulnerable. + > - Not all wallets support programmatic chain switching. + +### Patch Changes + +- [#658](https://github.com/wevm/wagmi/pull/658) [`d70c115`](https://github.com/wevm/wagmi/commit/d70c115131f299fb61f87867b6ac4218e0bcf432) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: The configuration passed to the `writeContract` action now needs to be: + + - prepared with the `prepareWriteContract` action **(new functionality)**, or + - recklessly unprepared **(previous functionality)** + + > Why? [Read here](https://wagmi.sh/docs/prepare-hooks) + + ### Prepared usage + + ```diff + import { prepareWriteContract, writeContract } from '@wagmi/core' + + const tokenId = 69 + + +const config = await prepareWriteContract({ + + addressOrName: '0x...', + + contractInterface: wagmiAbi, + + functionName: 'mint', + + args: [tokenId] + +}) + + const result = await writeContract({ + - addressOrName: '0x...', + - contractInterface: wagmiAbi, + - functionName: 'mint', + - args: [tokenId], + + ...config + }) + ``` + + ### Recklessly unprepared usage + + It is possible to use `writeContract` without preparing the configuration first by passing `mode: 'recklesslyUnprepared'`. + + ```diff + import { writeContract } from '@wagmi/core' + + const tokenId = 69 + + const result = await writeContract({ + + mode: 'recklesslyUnprepared', + addressOrName: '0x...', + contractInterface: wagmiAbi, + functionName: 'mint', + args: [tokenId], + }) + ``` + +* [#658](https://github.com/wevm/wagmi/pull/658) [`d70c115`](https://github.com/wevm/wagmi/commit/d70c115131f299fb61f87867b6ac4218e0bcf432) Thanks [@jxom](https://github.com/jxom)! - Added the `prepareSendTransaction` hook that prepares the parameters required for sending a transaction. + + It returns config to be passed through to `sendTransaction`. + + ```ts + import { prepareSendTransaction, sendTransaction } from "@wagmi/core"; + + const config = await prepareSendTransaction({ + request: { + to: "moxey.eth", + value: parseEther("1"), + }, + }); + const result = await sendTransaction(config); + ``` + +- [#658](https://github.com/wevm/wagmi/pull/658) [`d70c115`](https://github.com/wevm/wagmi/commit/d70c115131f299fb61f87867b6ac4218e0bcf432) Thanks [@jxom](https://github.com/jxom)! - Added the `prepareWriteContract` hook that prepares the parameters required for a contract write transaction. + + It returns config to be passed through to `writeContract`. + + Example: + + ```tsx + import { prepareWriteContract, writeContract } from "@wagmi/core"; + + const config = await prepareWriteContract({ + addressOrName: "0x...", + contractInterface: wagmiAbi, + functionName: "mint", + }); + const result = await writeContract(config); + ``` + +* [#739](https://github.com/wevm/wagmi/pull/739) [`c2295a5`](https://github.com/wevm/wagmi/commit/c2295a56cc86d02cc6602e2b4557b8ab9a091a3f) Thanks [@tmm](https://github.com/tmm)! - Fix balance formatting for tokens that do not have 18 decimals. + +- [#759](https://github.com/wevm/wagmi/pull/759) [`959953d`](https://github.com/wevm/wagmi/commit/959953d1f5b3e8189bac56de245c62333470d18e) Thanks [@tmm](https://github.com/tmm)! - Added `fetchTransaction` action: + + ```ts + import { fetchTransaction } from "@wagmi/core"; + + const transaction = await fetchTransaction({ + hash: "0x5c504ed432cb51138bcf09aa5e8a410dd4a1e204ef84bfed1be16dfba1b22060", + }); + ``` + +## 0.4.9 + +### Patch Changes + +- [#721](https://github.com/tmm/wagmi/pull/721) [`abea25f`](https://github.com/tmm/wagmi/commit/abea25fd15d81d1ecaec9d3fbd687042ab29b1e6) Thanks [@tmm](https://github.com/tmm)! - Stay connected to existing `client.connector` when `connect` action fails to connect to new connector. + +* [#721](https://github.com/tmm/wagmi/pull/721) [`abea25f`](https://github.com/tmm/wagmi/commit/abea25fd15d81d1ecaec9d3fbd687042ab29b1e6) Thanks [@tmm](https://github.com/tmm)! - Switch `fetchToken` action to multicall and add `name` output property. + +## 0.4.8 + +### Patch Changes + +- [#693](https://github.com/tmm/wagmi/pull/693) [`56e468c`](https://github.com/tmm/wagmi/commit/56e468c3617ec222527bb3c02eadec3ebeff923a) Thanks [@markdalgleish](https://github.com/markdalgleish)! - Fix import errors with Coinbase Wallet SDK in Vite + +## 0.4.7 + +### Patch Changes + +- [#677](https://github.com/tmm/wagmi/pull/677) [`35e4219`](https://github.com/tmm/wagmi/commit/35e42199af9dd346549c1718e144728f55b8d7dd) Thanks [@jxom](https://github.com/jxom)! - Move `parseContractResult` to `@wagmi/core` + +## 0.4.6 + +### Patch Changes + +- [#670](https://github.com/tmm/wagmi/pull/670) [`29a0d21`](https://github.com/tmm/wagmi/commit/29a0d21ee83995559f63542778dfa805f15e7441) Thanks [@tmm](https://github.com/tmm)! - Added ethers-compatible `deepEqual` function. + +## 0.4.5 + +### Patch Changes + +- [#654](https://github.com/tmm/wagmi/pull/654) [`e66530b`](https://github.com/tmm/wagmi/commit/e66530bf4881b3533c528f8c5a5f41be0eab0a64) Thanks [@jxom](https://github.com/jxom)! - fix `multicall` returning nullish data for all calls unexpectedly + +## 0.4.4 + +### Patch Changes + +- [#616](https://github.com/tmm/wagmi/pull/616) [`7a7a17a`](https://github.com/tmm/wagmi/commit/7a7a17a46d4c9e6465cc46a111b5fe8a56109f1b) Thanks [@tmm](https://github.com/tmm)! - Adds `UNSTABLE_shimOnConnectSelectAccount` flag. With this flag and "disconnected" with `shimDisconnect` enabled, the user is prompted to select a different MetaMask account (than the currently connected account) when trying to connect (e.g. `useConnect`/`connect` action). + +## 0.4.3 + +### Patch Changes + +- [#631](https://github.com/tmm/wagmi/pull/631) [`a780e32`](https://github.com/tmm/wagmi/commit/a780e32e91a0072c795fa0b5a6111302768e2a01) Thanks [@tmm](https://github.com/tmm)! - Fix WalletConnect stale session + +## 0.4.2 + +### Patch Changes + +- [#624](https://github.com/tmm/wagmi/pull/624) [`416fa7e`](https://github.com/tmm/wagmi/commit/416fa7ee1f8019ab86e33fb93783ffddecc02c49) Thanks [@jxom](https://github.com/jxom)! - Fix broken `WebSocketProvider` type defs + +## 0.4.1 + +### Patch Changes + +- [#622](https://github.com/tmm/wagmi/pull/622) [`d171581`](https://github.com/tmm/wagmi/commit/d171581464891dd870d97b6232205da0cb152d9b) Thanks [@tmm](https://github.com/tmm)! - Use `domain.chainId` to validate and switch chain before signing in `signTypedData`. + +* [#618](https://github.com/tmm/wagmi/pull/618) [`a5138e8`](https://github.com/tmm/wagmi/commit/a5138e82a00e4d9469ad78c97b2d34200d7f1fbe) Thanks [@tmm](https://github.com/tmm)! - Fix adding chains when using MetaMask mobile app, add `publicRpcUrls` constant, and default to public endpoint when adding chain. + +## 0.4.0 + +### Minor Changes + +- [`fc94210`](https://github.com/tmm/wagmi/commit/fc94210b67daa91aa164625dfe189d5b6c2f92d4) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: The `provider` config option is now required on `createClient`. It is recommended to pass the [`provider` given from `configureChains`](https://wagmi.sh/docs/providers/configuring-chains). + + ```diff + import { + createClient, + + defaultChains, + + configureChains + } from 'wagmi' + +import { publicProvider } from 'wagmi/providers/publicProvider' + + +const { provider } = configureChains(defaultChains, [ + + publicProvider + +]) + + const client = createClient({ + + provider + }) + ``` + + If you previously used an ethers.js Provider, you now need to provide your `chains` on the Provider instance: + + ```diff + import { + createClient, + + defaultChains + } from 'wagmi' + import ethers from 'ethers' + + const client = createClient({ + - provider: getDefaultProvider() + + provider: Object.assign(getDefaultProvider(), { chains: defaultChains }) + }) + ``` + +* [`4f8f3c0`](https://github.com/tmm/wagmi/commit/4f8f3c0d65383bd8bbdfc3f1033adfdb11d80ebb) Thanks [@nachoiacovino](https://github.com/nachoiacovino)! - Use ethereum-lists chains symbols + +- [`fc94210`](https://github.com/tmm/wagmi/commit/fc94210b67daa91aa164625dfe189d5b6c2f92d4) Thanks [@jxom](https://github.com/jxom)! - **Breaking:** Removed the `chainId` parameter from `connectors` function on `createClient`. + + ```diff + const client = createClient({ + - connectors({ chainId }) { + + connectors() { + ... + } + }) + ``` + + If you previously derived RPC URLs from the `chainId` on `connectors`, you can now remove that logic as `wagmi` now handles RPC URLs internally when used with `configureChains`. + + ```diff + import { + chain, + + configureChains, + createClient + } from 'wagmi'; + + +import { publicProvider } from 'wagmi/providers/public' + + import { CoinbaseWalletConnector } from 'wagmi/connectors/coinbaseWallet' + import { InjectedConnector } from 'wagmi/connectors/injected' + import { MetaMaskConnector } from 'wagmi/connectors/metaMask' + import { WalletConnectConnector } from 'wagmi/connectors/walletConnect' + + +const { chains } = configureChains( + + [chain.mainnet], + + [publicProvider()] + +); + + const client = createClient({ + - connectors({ chainId }) { + - const chain = chains.find((x) => x.id === chainId) ?? defaultChain + - const rpcUrl = chain.rpcUrls.alchemy + - ? `${chain.rpcUrls.alchemy}/${alchemyId}` + - : chain.rpcUrls.default + - return [ + + connectors: [ + new MetaMaskConnector({ chains }), + new CoinbaseWalletConnector({ + chains, + options: { + appName: 'wagmi', + - chainId: chain.id, + - jsonRpcUrl: rpcUrl, + }, + }), + new WalletConnectConnector({ + chains, + options: { + qrcode: true, + - rpc: { [chain.id]: rpcUrl }, + }, + }), + new InjectedConnector({ + chains, + options: { name: 'Injected' }, + }), + ] + - }, + }) + ``` + +* [#611](https://github.com/tmm/wagmi/pull/611) [`3089c34`](https://github.com/tmm/wagmi/commit/3089c34196d4034acabac031e0a2f7ee63ae30cc) Thanks [@tmm](https://github.com/tmm)! - **Breaking**: `Connector`s `getProvider` method no longer supports the `create` config parameter. Use the `chainId` config option instead. + +- [#596](https://github.com/tmm/wagmi/pull/596) [`a770af7`](https://github.com/tmm/wagmi/commit/a770af7d2cb214b6620d5341115f1e938e1e77ff) Thanks [@tmm](https://github.com/tmm)! - **Breaking**: `TypedDataDomain` and `TypedDataField` types were removed and incorporated into `SignTypedDataArgs`. + +* [`4f8f3c0`](https://github.com/tmm/wagmi/commit/4f8f3c0d65383bd8bbdfc3f1033adfdb11d80ebb) Thanks [@nachoiacovino](https://github.com/nachoiacovino)! - Update symbols to match ethereum-lists/chains + +- [`fc94210`](https://github.com/tmm/wagmi/commit/fc94210b67daa91aa164625dfe189d5b6c2f92d4) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: The `writeContract` function parameters have been consolidated into a singular config parameter. + + Before: + + ```tsx + writeContract( + { + addressOrName: "0xecb504d39723b0be0e3a9aa33d646642d1051ee1", + contractInterface: wagmigotchiABI, + }, + "feed", + ); + ``` + + After: + + ```tsx + readContract({ + addressOrName: "0xecb504d39723b0be0e3a9aa33d646642d1051ee1", + contractInterface: wagmigotchiABI, + functionName: "feed", + }); + ``` + +### Patch Changes + +- [`fc94210`](https://github.com/tmm/wagmi/commit/fc94210b67daa91aa164625dfe189d5b6c2f92d4) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: The `readContract` & `watchReadContract` function parameters have been consolidated into a singular config parameter. + + Before: + + ```tsx + readContract( + { + addressOrName: "0xecb504d39723b0be0e3a9aa33d646642d1051ee1", + contractInterface: wagmigotchiABI, + }, + "getHunger", + { args: [0] }, + ); + + watchReadContract( + { + addressOrName: "0xecb504d39723b0be0e3a9aa33d646642d1051ee1", + contractInterface: wagmigotchiABI, + }, + "getHunger", + { args: [0] }, + (result) => {}, + ); + ``` + + After: + + ```tsx + readContract({ + addressOrName: "0xecb504d39723b0be0e3a9aa33d646642d1051ee1", + contractInterface: wagmigotchiABI, + functionName: "getHunger", + args: [0], + }); + + watchReadContract( + { + addressOrName: "0xecb504d39723b0be0e3a9aa33d646642d1051ee1", + contractInterface: wagmigotchiABI, + functionName: "getHunger", + args: [0], + }, + (result) => {}, + ); + ``` + +* [#598](https://github.com/tmm/wagmi/pull/598) [`fef26bf`](https://github.com/tmm/wagmi/commit/fef26bf8aef76fc9621e3cd54d4e0ca8f69abb38) Thanks [@markdalgleish](https://github.com/markdalgleish)! - Update `@coinbase/wallet-sdk` peer dependency to `>=3.3.0` to fix errors when connecting with older versions of the Coinbase Wallet extension and mobile app. + +- [#611](https://github.com/tmm/wagmi/pull/611) [`3089c34`](https://github.com/tmm/wagmi/commit/3089c34196d4034acabac031e0a2f7ee63ae30cc) Thanks [@tmm](https://github.com/tmm)! - Added `chainId` config parameter for `writeContract` and `sendTransaction`. + + If `chainId` is provided, the connector will validate that `chainId` is the active chain before sending a transaction (and switch to `chainId` if necessary). + +* [#582](https://github.com/tmm/wagmi/pull/582) [`b03830a`](https://github.com/tmm/wagmi/commit/b03830a54465215c2526f9509543fe2c978bfe70) Thanks [@jxom](https://github.com/jxom)! - Fixed an issue where the wagmi client's `status` would not update from `"disconnected"` to `"connecting" -> "connected"` when the `connect` action is invoked. + +- [`fc94210`](https://github.com/tmm/wagmi/commit/fc94210b67daa91aa164625dfe189d5b6c2f92d4) Thanks [@jxom](https://github.com/jxom)! - Added a `multicall` & `watchMulticall` action that provides multicall support. + + Internally uses the [`multicall3` contract](https://github.com/mds1/multicall). + + [See example usage](https://github.com/tmm/wagmi/blob/194866032985fdd3f49bc46bf1b14181d7cb61d1/packages/core/src/actions/contracts/multicall.test.ts) + +* [`fc94210`](https://github.com/tmm/wagmi/commit/fc94210b67daa91aa164625dfe189d5b6c2f92d4) Thanks [@jxom](https://github.com/jxom)! - Added a `readContracts` & `watchReadContracts` action that provides the ability to batch up multiple ethers Contract read-only methods. + +## 0.3.8 + +### Patch Changes + +- [#570](https://github.com/tmm/wagmi/pull/570) [`0e3fe15`](https://github.com/tmm/wagmi/commit/0e3fe15445377f35d6f4142b49bf1c96bfeb62cd) Thanks [@tmm](https://github.com/tmm)! - adds chain for [Foundry](https://github.com/foundry-rs) + +## 0.3.7 + +### Patch Changes + +- [#550](https://github.com/tmm/wagmi/pull/550) [`2a5313e`](https://github.com/tmm/wagmi/commit/2a5313e8cbc9ba6335e8e4b85e43862c9b711bd3) Thanks [@tmm](https://github.com/tmm)! - fix `CoinbaseWalletConnector` possible type error + +* [#548](https://github.com/tmm/wagmi/pull/548) [`0c48719`](https://github.com/tmm/wagmi/commit/0c487199f2421f042abc1f1d139468ccbbc5646a) Thanks [@dohaki](https://github.com/dohaki)! - add ensAddress to Chain type + +- [#549](https://github.com/tmm/wagmi/pull/549) [`89b3a74`](https://github.com/tmm/wagmi/commit/89b3a74ead4234daacd0dcf8506659887ebf0553) Thanks [@tmm](https://github.com/tmm)! - Turns on [`noUncheckedIndexedAccess`](https://www.typescriptlang.org/tsconfig#noUncheckedIndexedAccess=) and [`strictNullChecks`](https://www.typescriptlang.org/tsconfig#strictNullChecks=) for better runtime safety. + +## 0.3.6 + +### Patch Changes + +- [#526](https://github.com/tmm/wagmi/pull/526) [`e95c5f9`](https://github.com/tmm/wagmi/commit/e95c5f91859e57d079b962a72d06b93dce004d2f) Thanks [@jxom](https://github.com/jxom)! - Added `shimChainChangedDisconnect` option to `InjectedConnector`. Defaults to `true` for `MetaMaskConnector`. + +* [#526](https://github.com/tmm/wagmi/pull/526) [`e95c5f9`](https://github.com/tmm/wagmi/commit/e95c5f91859e57d079b962a72d06b93dce004d2f) Thanks [@jxom](https://github.com/jxom)! - Added `lastUsedChainId` property to the wagmi `Client`. + +- [#526](https://github.com/tmm/wagmi/pull/526) [`e95c5f9`](https://github.com/tmm/wagmi/commit/e95c5f91859e57d079b962a72d06b93dce004d2f) Thanks [@jxom](https://github.com/jxom)! - Added `chainId` config option to the `connect` action. + + Example: + + ```tsx + import { connect } from "@wagmi/core"; + + await connect({ chainId: 69 }); + ``` + +## 0.3.5 + +### Patch Changes + +- [#543](https://github.com/tmm/wagmi/pull/543) [`4d489fd`](https://github.com/tmm/wagmi/commit/4d489fd630dd8c00440bdaf4d646de662c41ff52) Thanks [@tmm](https://github.com/tmm)! - fix fee data formatting for null values + +## 0.3.4 + +### Patch Changes + +- [`c4deb66`](https://github.com/tmm/wagmi/commit/c4deb6655a52e4cc4e5b3fd82202db11d6106848) Thanks [@jxom](https://github.com/jxom)! - infer `options.chainId` config from `chains` on WalletConnectConnector + +## 0.3.3 + +### Patch Changes + +- [#486](https://github.com/tmm/wagmi/pull/486) [`dbfe3dd`](https://github.com/tmm/wagmi/commit/dbfe3dd320d178d6854a8096101200c1508786bb) Thanks [@tmm](https://github.com/tmm)! - add chains entrypoint + +## 0.3.2 + +### Patch Changes + +- [`17212da`](https://github.com/tmm/wagmi/commit/17212da601640110d2835300e6433d1433db212e) Thanks [@jxom](https://github.com/jxom)! - Made the `defaultChains` type generic in `configureChains`. + +## 0.3.1 + +### Patch Changes + +- [#484](https://github.com/tmm/wagmi/pull/484) [`1b9a503`](https://github.com/tmm/wagmi/commit/1b9a5033d51c6655b4f6570c490da6e0e9a29da9) Thanks [@tmm](https://github.com/tmm)! - export React Context + +## 0.3.0 + +### Minor Changes + +- [#408](https://github.com/tmm/wagmi/pull/408) [`bfcc3a5`](https://github.com/tmm/wagmi/commit/bfcc3a51bbb1551753e3ccde6af134e9fd4fec9a) Thanks [@jxom](https://github.com/jxom)! - **Breaking:** The `connectors` option on `createClient` no longer reacts to chain switching. + + **Passing a function to `connectors` has been deprecated.** + + If you previously derived an RPC URL from the `chainId` in `connectors`, you will need to migrate to use the [`configureChains` API](https://wagmi.sh/docs/providers/configuring-chains). + + ### Before + + ```tsx + import { providers } from "ethers"; + import { chain, createClient, defaultChains } from "wagmi"; + import { CoinbaseWalletConnector } from "wagmi/connectors/coinbaseWallet"; + import { InjectedConnector } from "wagmi/connectors/injected"; + import { MetaMaskConnector } from "wagmi/connectors/metaMask"; + import { WalletConnectConnector } from "wagmi/connectors/walletConnect"; + + const alchemyId = process.env.ALCHEMY_ID; + + const chains = defaultChains; + const defaultChain = chain.mainnet; + + const client = createClient({ + autoConnect: true, + connectors({ chainId }) { + const chain = chains.find((x) => x.id === chainId) ?? defaultChain; + const rpcUrl = chain.rpcUrls.alchemy + ? `${chain.rpcUrls.alchemy}/${alchemyId}` + : chain.rpcUrls.default; + return [ + new MetaMaskConnector({ chains }), + new CoinbaseWalletConnector({ + chains, + options: { + appName: "wagmi", + chainId: chain.id, + jsonRpcUrl: rpcUrl, + }, + }), + new WalletConnectConnector({ + chains, + options: { + qrcode: true, + rpc: { [chain.id]: rpcUrl }, + }, + }), + new InjectedConnector({ + chains, + options: { + name: "Injected", + shimDisconnect: true, + }, + }), + ]; + }, + }); + ``` + + ### After + + ```tsx + import { chain, createClient, defaultChains } from "wagmi"; + + import { alchemyProvider } from "wagmi/providers/alchemy"; + import { publicProvider } from "wagmi/providers/public"; + + import { CoinbaseWalletConnector } from "wagmi/connectors/coinbaseWallet"; + import { InjectedConnector } from "wagmi/connectors/injected"; + import { MetaMaskConnector } from "wagmi/connectors/metaMask"; + import { WalletConnectConnector } from "wagmi/connectors/walletConnect"; + + const alchemyId = process.env.ALCHEMY_ID; + + const { chains } = configureChains(defaultChains, [ + alchemyProvider({ alchemyId }), + publicProvider(), + ]); + + const client = createClient({ + autoConnect: true, + connectors: [ + new MetaMaskConnector({ chains }), + new CoinbaseWalletConnector({ + chains, + options: { + appName: "wagmi", + }, + }), + new WalletConnectConnector({ + chains, + options: { + qrcode: true, + }, + }), + new InjectedConnector({ + chains, + options: { + name: "Injected", + shimDisconnect: true, + }, + }), + ], + }); + ``` + +* [#468](https://github.com/tmm/wagmi/pull/468) [`44a884b`](https://github.com/tmm/wagmi/commit/44a884b84171c418f57701e80ef8de972948ef0b) Thanks [@tmm](https://github.com/tmm)! - **Breaking:** Duplicate exports with different names and the same functionality were removed to simplify the public API. In addition, confusing exports were renamed to be more descriptive. + + - `createWagmiClient` alias was removed. Use `createClient` instead. + - `useWagmiClient` alias was removed. Use `useClient` instead. + - `WagmiClient` alias was removed. Use `Client` instead. + - `createWagmiStorage` alias was removed. Use `createStorage` instead. + - `Provider` was renamed and `WagmiProvider` alias was removed. Use `WagmiConfig` instead. + +- [#408](https://github.com/tmm/wagmi/pull/408) [`bfcc3a5`](https://github.com/tmm/wagmi/commit/bfcc3a51bbb1551753e3ccde6af134e9fd4fec9a) Thanks [@jxom](https://github.com/jxom)! - Add `configureChains` API. + + The `configureChains` function allows you to configure your chains with a selected provider (Alchemy, Infura, JSON RPC, Public RPC URLs). This means you don't have to worry about deriving your own RPC URLs for each chain, or instantiating a Ethereum Provider. + + `configureChains` accepts 3 parameters: an array of chains, and an array of providers, and a config object. + + [Learn more about configuring chains & providers.](https://wagmi.sh/docs/providers/configuring-chains) + + ### Before + + ```tsx + import { providers } from "ethers"; + import { chain, createClient, defaultChains } from "wagmi"; + import { CoinbaseWalletConnector } from "wagmi/connectors/coinbaseWallet"; + import { InjectedConnector } from "wagmi/connectors/injected"; + import { MetaMaskConnector } from "wagmi/connectors/metaMask"; + import { WalletConnectConnector } from "wagmi/connectors/walletConnect"; + + const alchemyId = process.env.ALCHEMY_ID; + + const chains = defaultChains; + const defaultChain = chain.mainnet; + + const client = createClient({ + autoConnect: true, + connectors({ chainId }) { + const chain = chains.find((x) => x.id === chainId) ?? defaultChain; + const rpcUrl = chain.rpcUrls.alchemy + ? `${chain.rpcUrls.alchemy}/${alchemyId}` + : chain.rpcUrls.default; + return [ + new MetaMaskConnector({ chains }), + new CoinbaseWalletConnector({ + chains, + options: { + appName: "wagmi", + chainId: chain.id, + jsonRpcUrl: rpcUrl, + }, + }), + new WalletConnectConnector({ + chains, + options: { + qrcode: true, + rpc: { [chain.id]: rpcUrl }, + }, + }), + new InjectedConnector({ + chains, + options: { + name: "Injected", + shimDisconnect: true, + }, + }), + ]; + }, + provider: ({ chainId }) => + new providers.AlchemyProvider(chainId, alchemyId), + }); + ``` + + ### After + + ```tsx + import { chain, createClient, defaultChains } from "wagmi"; + + import { alchemyProvider } from "wagmi/providers/alchemy"; + import { publicProvider } from "wagmi/providers/public"; + + import { CoinbaseWalletConnector } from "wagmi/connectors/coinbaseWallet"; + import { InjectedConnector } from "wagmi/connectors/injected"; + import { MetaMaskConnector } from "wagmi/connectors/metaMask"; + import { WalletConnectConnector } from "wagmi/connectors/walletConnect"; + + const alchemyId = process.env.ALCHEMY_ID; + + const { chains, provider, webSocketProvider } = configureChains( + defaultChains, + [alchemyProvider({ alchemyId }), publicProvider()], + ); + + const client = createClient({ + autoConnect: true, + connectors: [ + new MetaMaskConnector({ chains }), + new CoinbaseWalletConnector({ + chains, + options: { + appName: "wagmi", + }, + }), + new WalletConnectConnector({ + chains, + options: { + qrcode: true, + }, + }), + new InjectedConnector({ + chains, + options: { + name: "Injected", + shimDisconnect: true, + }, + }), + ], + provider, + webSocketProvider, + }); + ``` + +### Patch Changes + +- [#404](https://github.com/tmm/wagmi/pull/404) [`f81c156`](https://github.com/tmm/wagmi/commit/f81c15665e2e71534f84ada3fa705f2d78627472) Thanks [@holic](https://github.com/holic)! - Add `ProviderRpcError` and `RpcError` error classes. + + Certain wagmi-standardized errors may wrap `ProviderRpcError` or `RpcError`. For these cases, you can access the original provider rpc or rpc error value using the `internal` property. + +* [#459](https://github.com/tmm/wagmi/pull/459) [`72dcf7c`](https://github.com/tmm/wagmi/commit/72dcf7c09e814261b2e43a8fa364c57675c472de) Thanks [@tmm](https://github.com/tmm)! - update dependencies + +- [#473](https://github.com/tmm/wagmi/pull/473) [`a54f3e2`](https://github.com/tmm/wagmi/commit/a54f3e23ea385ed8aa4ad188128d7089ba20f83e) Thanks [@cesargdm](https://github.com/cesargdm)! - Add workaround for CoinbaseWalletSDK import on esbuild + +* [#447](https://github.com/tmm/wagmi/pull/447) [`b9ebf78`](https://github.com/tmm/wagmi/commit/b9ebf782e0900725bcb76483686b30f09d357ebd) Thanks [@tmm](https://github.com/tmm)! - Fix case where connector disconnected while app was closed and stale data was returned when autoconnecting. For example, [MetaMask was locked](https://github.com/tmm/wagmi/issues/444) when page was closed. + +## 0.2.5 + +### Patch Changes + +- [`4e03666`](https://github.com/tmm/wagmi/commit/4e03666428d42fc9186c617001b5eb356229677e) Thanks [@tmm](https://github.com/tmm)! - bump dependencies #429 + add imToken support for WC switch chains #432 + fix MetaMask and Brave Wallet collision #436 + +## 0.2.4 + +### Patch Changes + +- [#421](https://github.com/tmm/wagmi/pull/421) [`a232b3f`](https://github.com/tmm/wagmi/commit/a232b3ff5cc41e882c4d2a34c599a8cb670edd2b) Thanks [@tmm](https://github.com/tmm)! - fix erc721 abi + +## 0.2.3 + +### Patch Changes + +- [#412](https://github.com/tmm/wagmi/pull/412) [`80bef4f`](https://github.com/tmm/wagmi/commit/80bef4ff3f714b0b8f896f1b4b658acc7266299b) Thanks [@markdalgleish](https://github.com/markdalgleish)! - Import providers from `ethers` peer dependency rather than `@ethersproject/providers` to avoid multiple conflicting versions being installed + +## 0.2.2 + +### Patch Changes + +- [`018c2a1`](https://github.com/tmm/wagmi/commit/018c2a11b22ee513571cc7f83fd63f7eb169ee70) Thanks [@tmm](https://github.com/tmm)! - - warn and fallback to default client #380 + + - remove signerOrProvider option from read contract #390 + + - MetaMaskConnector #391 + +## 0.2.1 + +### Patch Changes + +- [`afc4607`](https://github.com/tmm/wagmi/commit/afc46071e91601ab8a2b465524da796cd60b6ad4) Thanks [@tmm](https://github.com/tmm)! - - Fix time scaling e9593df + - Use fully-specified path for use-sync-external-store import 7b235c1 + - Update serialize 236fc17 + +## 0.2.0 + +### Minor Changes + +- [#311](https://github.com/tmm/wagmi/pull/311) [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d) Thanks [@tmm](https://github.com/tmm)! - don't persist account data when `autoConnect` is falsy + +* [#311](https://github.com/tmm/wagmi/pull/311) [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d) Thanks [@tmm](https://github.com/tmm)! - - fix(@wagmi/core): persist connector chains to local storage + +- [#311](https://github.com/tmm/wagmi/pull/311) [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d) Thanks [@tmm](https://github.com/tmm)! - - Favour `message` event over `connecting` event to conform to EIP-1193 + - Export `useWaitForTransaction` + +* [#311](https://github.com/tmm/wagmi/pull/311) [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d) Thanks [@tmm](https://github.com/tmm)! - Initial 0.3.0 release + +- [#311](https://github.com/tmm/wagmi/pull/311) [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d) Thanks [@tmm](https://github.com/tmm)! - Add `cacheOnBlock` config for `useContractRead` + Update `react-query` to v4 + Fix `watchBlockNumber` listener leak + +* [#311](https://github.com/tmm/wagmi/pull/311) [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d) Thanks [@tmm](https://github.com/tmm)! - add `connecting` event to connectors + +- [#311](https://github.com/tmm/wagmi/pull/311) [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d) Thanks [@tmm](https://github.com/tmm)! - Fix issue where `getProvider` was not being awaited in `getSigner` + +* [#311](https://github.com/tmm/wagmi/pull/311) [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d) Thanks [@tmm](https://github.com/tmm)! - - remove storage persistence of `connector` + - add `chains` to client state + +### Patch Changes + +- [#311](https://github.com/tmm/wagmi/pull/311) [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d) Thanks [@tmm](https://github.com/tmm)! - add chainId to actions and hooks + +* [#311](https://github.com/tmm/wagmi/pull/311) [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d) Thanks [@tmm](https://github.com/tmm)! - showtime + +- [#311](https://github.com/tmm/wagmi/pull/311) [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d) Thanks [@tmm](https://github.com/tmm)! - improve type support for ethers providers + +* [#311](https://github.com/tmm/wagmi/pull/311) [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d) Thanks [@tmm](https://github.com/tmm)! - update zustand + +- [#311](https://github.com/tmm/wagmi/pull/311) [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d) Thanks [@tmm](https://github.com/tmm)! - update babel target + +* [#311](https://github.com/tmm/wagmi/pull/311) [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d) Thanks [@tmm](https://github.com/tmm)! - update block explorers and rpc urls structure + +- [#311](https://github.com/tmm/wagmi/pull/311) [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d) Thanks [@tmm](https://github.com/tmm)! - keep previous data when watching + +* [#311](https://github.com/tmm/wagmi/pull/311) [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d) Thanks [@tmm](https://github.com/tmm)! - republish + +- [#311](https://github.com/tmm/wagmi/pull/311) [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d) Thanks [@tmm](https://github.com/tmm)! - fix stale connectors when switching chains + +* [#311](https://github.com/tmm/wagmi/pull/311) [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d) Thanks [@tmm](https://github.com/tmm)! - last beta + +## 0.2.0-next.18 + +### Patch Changes + +- showtime + +## 0.2.0-next.17 + +### Patch Changes + +- update block explorers and rpc urls structure + +## 0.2.0-next.16 + +### Patch Changes + +- last beta + +## 0.2.0-next.15 + +### Patch Changes + +- update zustand + +## 0.2.0-next.14 + +### Minor Changes + +- Add `cacheOnBlock` config for `useContractRead` +- Update `react-query` to v4 +- Fix `watchBlockNumber` listener leak + +## 0.2.0-next.13 + +### Patch Changes + +- keep previous data when watching + +## 0.2.0-next.12 + +### Patch Changes + +- add chainId to actions and hooks + +## 0.2.0-next.11 + +### Patch Changes + +- fix stale connectors when switching chains + +## 0.2.0-next.10 + +### Patch Changes + +- republish + +## 0.2.0-next.9 + +### Patch Changes + +- improve type support for ethers providers + +## 0.2.0-next.8 + +### Patch Changes + +- update babel target + +## 0.2.0-next.7 + +### Minor Changes + +- - Favour `message` event over `connecting` event to conform to EIP-1193 + - Export `useWaitForTransaction` + +## 0.2.0-next.6 + +### Minor Changes + +- add `connecting` event to connectors + +## 0.2.0-next.5 + +### Minor Changes + +- don't persist account data when `autoConnect` is falsy + +## 0.2.0-next.4 + +### Minor Changes + +- remove storage persistence of `connector` +- add `chains` to client state + +## 0.2.0-next.3 + +### Minor Changes + +- Fix issue where `getProvider` was not being awaited in `getSigner` + +## 0.2.0-next.2 + +### Minor Changes + +- fix: persist connector chains to local storage + +## 0.2.0-next.1 + +### Minor Changes + +- Initial 0.3.0 release + +## 0.1.22 + +### Patch Changes + +- [`747d895`](https://github.com/tmm/wagmi/commit/747d895a54b562958afde34b1d34e81ab5039e2c) Thanks [@tmm](https://github.com/tmm)! - add warning to WalletLinkConnector + +## 0.1.21 + +### Patch Changes + +- [`c858c51`](https://github.com/tmm/wagmi/commit/c858c51b44d9039f1d0db5bcf016639f47d1931f) Thanks [@tmm](https://github.com/tmm)! - update coinbase connector + +## 0.1.20 + +### Patch Changes + +- [#326](https://github.com/tmm/wagmi/pull/326) [`36e6989`](https://github.com/tmm/wagmi/commit/36e69894f4c27aaad7fb6d678476c8bb870244bb) Thanks [@0xGabi](https://github.com/0xGabi)! - Add Gnosis Chain + +## 0.1.19 + +### Patch Changes + +- [`d467df6`](https://github.com/tmm/wagmi/commit/d467df6374210dbc4b016788b4beb4fded54cb4d) Thanks [@tmm](https://github.com/tmm)! - fix global type leaking + +## 0.1.18 + +### Patch Changes + +- [#294](https://github.com/tmm/wagmi/pull/294) [`1d253f3`](https://github.com/tmm/wagmi/commit/1d253f3a59b61d24c88d25c99decd84a6c734e5d) Thanks [@tmm](https://github.com/tmm)! - change babel target + +## 0.1.17 + +### Patch Changes + +- [#292](https://github.com/tmm/wagmi/pull/292) [`53c9be1`](https://github.com/tmm/wagmi/commit/53c9be17ee0c2ae6b8f34f2351b8858257b3f5f2) Thanks [@tmm](https://github.com/tmm)! - fix private fields + +## 0.1.16 + +### Patch Changes + +- [`79a2499`](https://github.com/tmm/wagmi/commit/79a249989029f818c32c0e84c0dd2c75e8aa990a) Thanks [@tmm](https://github.com/tmm)! - update build target to es2021 + +## 0.1.15 + +### Patch Changes + +- [`f9790b5`](https://github.com/tmm/wagmi/commit/f9790b55600df09c77bb8ca349c5a3457df1b07c) Thanks [@tmm](https://github.com/tmm)! - fix WalletConnect issue + +## 0.1.14 + +### Patch Changes + +- [#236](https://github.com/tmm/wagmi/pull/236) [`53bad61`](https://github.com/tmm/wagmi/commit/53bad615788764e31121678083c382c1bd042fe8) Thanks [@markdalgleish](https://github.com/markdalgleish)! - Updated `@walletconnect/ethereum-provider` to [v1.7.4](https://github.com/WalletConnect/walletconnect-monorepo/releases/tag/1.7.4) + +## 0.1.13 + +### Patch Changes + +- [`8e9412a`](https://github.com/tmm/wagmi/commit/8e9412af71958301ae2f9748febb936e79900aa0) Thanks [@tmm](https://github.com/tmm)! - bump walletlink + +## 0.1.12 + +### Patch Changes + +- [#210](https://github.com/tmm/wagmi/pull/210) [`684468a`](https://github.com/tmm/wagmi/commit/684468aee3e42a1ce2b4b599f3f17d1819213de8) Thanks [@tmm](https://github.com/tmm)! - update chains to match chainslist.org + +## 0.1.11 + +### Patch Changes + +- [#195](https://github.com/tmm/wagmi/pull/195) [`25b6083`](https://github.com/tmm/wagmi/commit/25b6083a662a0236794d1765343467691421c14b) Thanks [@tmm](https://github.com/tmm)! - rename wagmi-private to wagmi-core + +## 0.1.10 + +### Patch Changes + +- [#192](https://github.com/tmm/wagmi/pull/192) [`428cedb`](https://github.com/tmm/wagmi/commit/428cedb3dec4e3e4b9f4559c8e65932e05f94e05) Thanks [@tmm](https://github.com/tmm)! - rename core and testing packages + +## 0.1.9 + +### Patch Changes + +- [#190](https://github.com/tmm/wagmi/pull/190) [`7034bb8`](https://github.com/tmm/wagmi/commit/7034bb868412b9f481b206371280e84c2d52706d) Thanks [@tmm](https://github.com/tmm)! - add shim for metamask chain changed to prevent disconnect + +## 0.1.8 + +### Patch Changes + +- [#137](https://github.com/tmm/wagmi/pull/137) [`dceeb43`](https://github.com/tmm/wagmi/commit/dceeb430d9021fbf98366859cb1cd0149e80c55c) Thanks [@tmm](https://github.com/tmm)! - add siwe guide + +## 0.1.7 + +### Patch Changes + +- [#127](https://github.com/tmm/wagmi/pull/127) [`f05b031`](https://github.com/tmm/wagmi/commit/f05b0310f7f7e6447e9b6c81cedbb27dcf2f3649) Thanks [@tmm](https://github.com/tmm)! - update switch chain return type + +## 0.1.6 + +### Patch Changes + +- [`1412eed`](https://github.com/tmm/wagmi/commit/1412eed0d1494bb4f8c6845a0e890f79e4e68e03) Thanks [@tmm](https://github.com/tmm)! - add frame to injected + +## 0.1.5 + +### Patch Changes + +- [`e338c3b`](https://github.com/tmm/wagmi/commit/e338c3b6cc255742be6a67593aa5da6c17e90fbd) Thanks [@tmm](https://github.com/tmm)! - checksum connector address on change events + + add shim to injected connector for simulating disconnect + +## 0.1.4 + +### Patch Changes + +- [`0176c4e`](https://github.com/tmm/wagmi/commit/0176c4e83fb0c5f159c3c802a1da3d6deb2184ae) Thanks [@tmm](https://github.com/tmm)! - added switchChain to WalletConnect and WalletLink connectors + +## 0.1.3 + +### Patch Changes + +- [`071d7fb`](https://github.com/tmm/wagmi/commit/071d7fbca35ec4832700b5343661ceb2dae20598) Thanks [@tmm](https://github.com/tmm)! - add hardhat chain + +## 0.1.2 + +### Patch Changes + +- [`78bade9`](https://github.com/tmm/wagmi/commit/78bade9d0da97ab38a7e6594c34e3841ec1c8fe6) Thanks [@tmm](https://github.com/tmm)! - add type definitions + +## 0.1.1 + +### Patch Changes + +- [#56](https://github.com/tmm/wagmi/pull/56) [`2ebfd8e`](https://github.com/tmm/wagmi/commit/2ebfd8e85b560f25cd46cff04619c84643cab297) Thanks [@tmm](https://github.com/tmm)! - add chain support status + +## 0.1.0 + +### Minor Changes + +- [#52](https://github.com/tmm/wagmi/pull/52) [`da7a3a6`](https://github.com/tmm/wagmi/commit/da7a3a615def2443f65c041999100ce35e9774cc) Thanks [@tmm](https://github.com/tmm)! - Moves connectors to their own entrypoints to reduce bundle size. + + ```ts + // old - WalletLinkConnector unused, but still in final bundle + import { InjectedConnector, WalletConnectConnector } from "wagmi"; + + // new - WalletLinkConnector not in final bundle + import { InjectedConnector } from "wagmi/connectors/injected"; + import { WalletConnectConnector } from "wagmi/connectors/walletConnect"; + ``` + +## 0.0.17 + +### Patch Changes + +- [#25](https://github.com/tmm/wagmi/pull/25) [`9a7dab7`](https://github.com/tmm/wagmi/commit/9a7dab78b3518658bc7d85dc397990f0d28da175) Thanks [@tmm](https://github.com/tmm)! - update response types + +## 0.0.16 + +### Patch Changes + +- [`d1574cf`](https://github.com/tmm/wagmi/commit/d1574cf5f7a578ccd480889c2e375134145a4aba) Thanks [@tmm](https://github.com/tmm)! - add better type information for contract results + +## 0.0.15 + +### Patch Changes + +- [`3909624`](https://github.com/tmm/wagmi/commit/39096249c1fa9516beabb11735beb67c94032879) Thanks [@tmm](https://github.com/tmm)! - make contract read and write execute overrides param optional + +## 0.0.14 + +### Patch Changes + +- [`63312e2`](https://github.com/tmm/wagmi/commit/63312e2b06b8d835abc2908cba399d941ca79408) Thanks [@tmm](https://github.com/tmm)! - add once to contract event + +## 0.0.13 + +### Patch Changes + +- [`6f890b0`](https://github.com/tmm/wagmi/commit/6f890b0dabbdbea913ec91cb8bfc970c05ed0a93) Thanks [@tmm](https://github.com/tmm)! - update readme + +## 0.0.12 + +### Patch Changes + +- [#19](https://github.com/tmm/wagmi/pull/19) [`7bc1c47`](https://github.com/tmm/wagmi/commit/7bc1c47875e9ef24e9c79cfafc6b23e7a838b5bc) Thanks [@tmm](https://github.com/tmm)! - remove console log from walletlink connector + +## 0.0.11 + +### Patch Changes + +- [#17](https://github.com/tmm/wagmi/pull/17) [`571648b`](https://github.com/tmm/wagmi/commit/571648b754f7f538536bafc9387bd3104657ea49) Thanks [@tmm](https://github.com/tmm)! - standardize connector provider + +## 0.0.10 + +### Patch Changes + +- [#15](https://github.com/tmm/wagmi/pull/15) [`5f7675c`](https://github.com/tmm/wagmi/commit/5f7675c3ffd848522d4117c07c1f62b17dfc6616) Thanks [@tmm](https://github.com/tmm)! - read and write contract functions + +## 0.0.9 + +### Patch Changes + +- [#13](https://github.com/tmm/wagmi/pull/13) [`e5545f5`](https://github.com/tmm/wagmi/commit/e5545f5565cf0bbf5e62ec7ccab3051705b1d313) Thanks [@tmm](https://github.com/tmm)! - add testing package + +## 0.0.8 + +### Patch Changes + +- [`5332500`](https://github.com/tmm/wagmi/commit/5332500918ac240d29ffe4d2aed8566a8ac001e4) Thanks [@tmm](https://github.com/tmm)! - update signing + +## 0.0.7 + +### Patch Changes + +- [`0bff89a`](https://github.com/tmm/wagmi/commit/0bff89ab2ad28b2cb9b346d1ac870e859d9278bc) Thanks [@tmm](https://github.com/tmm)! - update injected connector + +## 0.0.6 + +### Patch Changes + +- [`37d39d1`](https://github.com/tmm/wagmi/commit/37d39d174ddfa122462bbe2d02141cd61eb9db4a) Thanks [@tmm](https://github.com/tmm)! - add message signing + +## 0.0.5 + +### Patch Changes + +- [`d7d94f0`](https://github.com/tmm/wagmi/commit/d7d94f06f7d30468e5e39d64db63124c6315cf82) Thanks [@tmm](https://github.com/tmm)! - fix injected connector name + +## 0.0.4 + +### Patch Changes + +- [`29fbe29`](https://github.com/tmm/wagmi/commit/29fbe2920046b9e87a34faa04500ccf3c4f83748) Thanks [@tmm](https://github.com/tmm)! - fix external deps + +## 0.0.3 + +### Patch Changes + +- [#6](https://github.com/tmm/wagmi/pull/6) [`8dc3a5d`](https://github.com/tmm/wagmi/commit/8dc3a5d5f418813b09663534fe585d9bcf94dbeb) Thanks [@tmm](https://github.com/tmm)! - clean up deps + +## 0.0.2 + +### Patch Changes + +- [#4](https://github.com/tmm/wagmi/pull/4) [`2fbd821`](https://github.com/tmm/wagmi/commit/2fbd8216379bd03c9cc5c06b10b75637e75cb7d8) Thanks [@tmm](https://github.com/tmm)! - init changesets diff --git a/wagmi-project/packages/core/README.md b/wagmi-project/packages/core/README.md new file mode 100644 index 000000000..b46e39c55 --- /dev/null +++ b/wagmi-project/packages/core/README.md @@ -0,0 +1,13 @@ +# @wagmi/core + +VanillaJS library for Ethereum + +## Installation + +```bash +pnpm add @wagmi/core viem +``` + +## Documentation + +For documentation and guides, visit [wagmi.sh](https://wagmi.sh). diff --git a/wagmi-project/packages/core/package.json b/wagmi-project/packages/core/package.json new file mode 100644 index 000000000..00589ee83 --- /dev/null +++ b/wagmi-project/packages/core/package.json @@ -0,0 +1,100 @@ +{ + "name": "@wagmi/core", + "description": "VanillaJS library for Ethereum", + "version": "2.17.2", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/wevm/wagmi.git", + "directory": "packages/core" + }, + "scripts": { + "build": "pnpm run clean && pnpm run build:esm+types", + "build:esm+types": "tsc --project tsconfig.build.json --outDir ./dist/esm --declaration --declarationMap --declarationDir ./dist/types", + "check:types": "tsc --noEmit", + "clean": "rm -rf dist tsconfig.tsbuildinfo actions chains codegen experimental internal query", + "test:build": "publint --strict && attw --pack --ignore-rules cjs-resolves-to-esm" + }, + "files": [ + "dist/**", + "!dist/**/*.tsbuildinfo", + "src/**/*.ts", + "!src/**/*.test.ts", + "!src/**/*.test-d.ts", + "/actions", + "/chains", + "/experimental", + "/internal", + "/query" + ], + "sideEffects": false, + "type": "module", + "main": "./dist/esm/exports/index.js", + "types": "./dist/types/exports/index.d.ts", + "typings": "./dist/types/exports/index.d.ts", + "exports": { + ".": { + "types": "./dist/types/exports/index.d.ts", + "default": "./dist/esm/exports/index.js" + }, + "./actions": { + "types": "./dist/types/exports/actions.d.ts", + "default": "./dist/esm/exports/actions.js" + }, + "./chains": { + "types": "./dist/types/exports/chains.d.ts", + "default": "./dist/esm/exports/chains.js" + }, + "./codegen": { + "types": "./dist/types/exports/codegen.d.ts", + "default": "./dist/esm/exports/codegen.js" + }, + "./experimental": { + "types": "./dist/types/exports/experimental.d.ts", + "default": "./dist/esm/exports/experimental.js" + }, + "./internal": { + "types": "./dist/types/exports/internal.d.ts", + "default": "./dist/esm/exports/internal.js" + }, + "./query": { + "types": "./dist/types/exports/query.d.ts", + "default": "./dist/esm/exports/query.js" + }, + "./package.json": "./package.json" + }, + "typesVersions": { + "*": { + "actions": ["./dist/types/exports/actions.d.ts"], + "chains": ["./dist/types/exports/chains.d.ts"], + "codegen": ["./dist/types/exports/codegen.d.ts"], + "experimental": ["./dist/types/exports/experimental.d.ts"], + "internal": ["./dist/types/exports/internal.d.ts"], + "query": ["./dist/types/exports/query.d.ts"] + } + }, + "peerDependencies": { + "@tanstack/query-core": ">=5.0.0", + "typescript": ">=5.0.4", + "viem": "2.x" + }, + "peerDependenciesMeta": { + "@tanstack/query-core": { + "optional": true + }, + "typescript": { + "optional": true + } + }, + "dependencies": { + "eventemitter3": "5.0.1", + "mipd": "0.0.7", + "zustand": "5.0.0" + }, + "devDependencies": { + "@tanstack/query-core": "catalog:" + }, + "contributors": ["awkweb.eth ", "jxom.eth "], + "funding": "https://github.com/sponsors/wevm", + "keywords": ["wagmi", "eth", "ethereum", "dapps", "wallet", "web3"] +} diff --git a/wagmi-project/packages/core/src/actions/call.test.ts b/wagmi-project/packages/core/src/actions/call.test.ts new file mode 100644 index 000000000..2ef01160d --- /dev/null +++ b/wagmi-project/packages/core/src/actions/call.test.ts @@ -0,0 +1,149 @@ +import { accounts, address, config } from '@wagmi/test' +import { parseEther, parseGwei } from 'viem' +import { expect, test } from 'vitest' + +import { call } from './call.js' + +const name4bytes = '0x06fdde03' +const mint4bytes = '0x1249c58b' +const mintWithParams4bytes = '0xa0712d68' +const fourTwenty = + '00000000000000000000000000000000000000000000000000000000000001a4' + +const account = accounts[0] + +test('default', async () => { + await expect( + call(config, { + account, + data: name4bytes, + to: address.wagmiMintExample, + }), + ).resolves.toMatchInlineSnapshot(` + { + "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000057761676d69000000000000000000000000000000000000000000000000000000", + } + `) +}) + +test('zero data', async () => { + await expect( + call(config, { + account, + data: mint4bytes, + to: address.wagmiMintExample, + }), + ).resolves.toMatchInlineSnapshot(` + { + "data": undefined, + } + `) +}) + +// TODO: Re-enable +test.skip('parameters: blockNumber', async () => { + await expect( + call(config, { + account, + data: name4bytes, + to: address.wagmiMintExample, + blockNumber: 16280770n, + }), + ).resolves.toMatchInlineSnapshot(` + { + "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000057761676d69000000000000000000000000000000000000000000000000000000", + } + `) +}) + +test('insufficient funds', async () => { + await expect( + call(config, { + account, + to: accounts[1], + value: parseEther('100000'), + }), + ).rejects.toThrowErrorMatchingInlineSnapshot(` + [CallExecutionError: The total cost (gas * gas fee + value) of executing this transaction exceeds the balance of the account. + + This error could arise when the account does not have enough funds to: + - pay for the total gas fee, + - pay for the value to send. + + The cost of the transaction is calculated as \`gas * gas fee + value\`, where: + - \`gas\` is the amount of gas needed for transaction to execute, + - \`gas fee\` is the gas fee, + - \`value\` is the amount of ether to send to the recipient. + + Raw Call Arguments: + from: 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 + to: 0x70997970c51812dc3a010c7d01b50e0d17dc79c8 + value: 100000 ETH + + Details: Insufficient funds for gas * price + value + Version: viem@2.29.2] + `) +}) + +test('maxFeePerGas less than maxPriorityFeePerGas', async () => { + await expect( + call(config, { + account, + data: name4bytes, + to: address.wagmiMintExample, + maxFeePerGas: parseGwei('20'), + maxPriorityFeePerGas: parseGwei('22'), + }), + ).rejects.toThrowErrorMatchingInlineSnapshot(` + [CallExecutionError: The provided tip (\`maxPriorityFeePerGas\` = 22 gwei) cannot be higher than the fee cap (\`maxFeePerGas\` = 20 gwei). + + Raw Call Arguments: + from: 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 + to: 0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2 + data: 0x06fdde03 + maxFeePerGas: 20 gwei + maxPriorityFeePerGas: 22 gwei + + Version: viem@2.29.2] + `) +}) + +test('contract revert (contract error)', async () => { + await expect( + call(config, { + account, + data: `${mintWithParams4bytes}${fourTwenty}`, + to: address.wagmiMintExample, + }), + ).rejects.toThrowErrorMatchingInlineSnapshot(` + [CallExecutionError: Execution reverted with reason: Token ID is taken. + + Raw Call Arguments: + from: 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 + to: 0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2 + data: 0xa0712d6800000000000000000000000000000000000000000000000000000000000001a4 + + Details: execution reverted: Token ID is taken + Version: viem@2.29.2] + `) +}) + +test('contract revert (insufficient params)', async () => { + await expect( + call(config, { + account, + data: mintWithParams4bytes, + to: address.wagmiMintExample, + }), + ).rejects.toThrowErrorMatchingInlineSnapshot(` + [CallExecutionError: Execution reverted for an unknown reason. + + Raw Call Arguments: + from: 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 + to: 0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2 + data: 0xa0712d68 + + Details: execution reverted + Version: viem@2.29.2] + `) +}) diff --git a/wagmi-project/packages/core/src/actions/call.ts b/wagmi-project/packages/core/src/actions/call.ts new file mode 100644 index 000000000..90e6c1ae2 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/call.ts @@ -0,0 +1,27 @@ +import type { + CallErrorType as viem_CallErrorType, + CallParameters as viem_CallParameters, + CallReturnType as viem_CallReturnType, +} from 'viem' +import { call as viem_call } from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { ChainIdParameter } from '../types/properties.js' +import { getAction } from '../utils/getAction.js' + +export type CallParameters = + viem_CallParameters & ChainIdParameter + +export type CallReturnType = viem_CallReturnType + +export type CallErrorType = viem_CallErrorType + +export async function call( + config: config, + parameters: CallParameters, +): Promise { + const { chainId, ...rest } = parameters + const client = config.getClient({ chainId }) + const action = getAction(client, viem_call, 'call') + return action(rest) +} diff --git a/wagmi-project/packages/core/src/actions/codegen/createReadContract.test-d.ts b/wagmi-project/packages/core/src/actions/codegen/createReadContract.test-d.ts new file mode 100644 index 000000000..f5c9dd302 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/codegen/createReadContract.test-d.ts @@ -0,0 +1,130 @@ +import { abi, config, mainnet, optimism } from '@wagmi/test' +import { assertType, expectTypeOf, test } from 'vitest' + +import { createReadContract } from './createReadContract.js' + +test('default', async () => { + const readErc20 = createReadContract({ + abi: abi.erc20, + address: '0x', + }) + + const result = await readErc20(config, { + functionName: 'balanceOf', + args: ['0x'], + chainId: 1, + }) + expectTypeOf(result).toEqualTypeOf() +}) + +test('multichain address', async () => { + const readErc20 = createReadContract({ + abi: abi.erc20, + address: { + [mainnet.id]: '0x', + [optimism.id]: '0x', + }, + }) + + const result = await readErc20(config, { + functionName: 'balanceOf', + args: ['0x'], + chainId: mainnet.id, + // ^? + }) + assertType(result) + + readErc20(config, { + functionName: 'balanceOf', + args: ['0x'], + // @ts-expect-error chain id must match address keys + chainId: 420, + }) + + readErc20(config, { + functionName: 'balanceOf', + args: ['0x'], + // @ts-expect-error address not allowed + address: '0x', + }) +}) + +test('overloads', async () => { + const readViewOverloads = createReadContract({ + abi: abi.viewOverloads, + address: '0x', + }) + + const result1 = await readViewOverloads(config, { + functionName: 'foo', + }) + assertType(result1) + + const result2 = await readViewOverloads(config, { + functionName: 'foo', + args: [], + }) + assertType(result2) + + const result3 = await readViewOverloads(config, { + functionName: 'foo', + args: ['0x'], + }) + // @ts-ignore – TODO: Fix https://github.com/wevm/viem/issues/1916 + assertType(result3) + + const result4 = await readViewOverloads(config, { + functionName: 'foo', + args: ['0x', '0x'], + }) + assertType<{ + foo: `0x${string}` + bar: `0x${string}` + // @ts-ignore – TODO: Fix https://github.com/wevm/viem/issues/1916 + }>(result4) +}) + +test('functionName', async () => { + const readErc20BalanceOf = createReadContract({ + abi: abi.erc20, + address: '0x', + functionName: 'balanceOf', + }) + + const result = await readErc20BalanceOf(config, { + args: ['0x'], + chainId: 1, + }) + expectTypeOf(result).toEqualTypeOf() +}) + +test('functionName with overloads', async () => { + const readViewOverloads = createReadContract({ + abi: abi.viewOverloads, + address: '0x', + functionName: 'foo', + }) + + const result1 = await readViewOverloads(config, {}) + assertType(result1) + + const result2 = await readViewOverloads(config, { + args: [], + }) + assertType(result2) + + const result3 = await readViewOverloads(config, { + args: ['0x'], + }) + // @ts-ignore – TODO: Fix https://github.com/wevm/viem/issues/1916 + assertType(result3) + + const result4 = await readViewOverloads(config, { + args: ['0x', '0x'], + }) + assertType<{ + foo: `0x${string}` + bar: `0x${string}` + // @ts-ignore – TODO: Fix https://github.com/wevm/viem/issues/1916 + }>(result4) +}) diff --git a/wagmi-project/packages/core/src/actions/codegen/createReadContract.test.ts b/wagmi-project/packages/core/src/actions/codegen/createReadContract.test.ts new file mode 100644 index 000000000..9de7ae718 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/codegen/createReadContract.test.ts @@ -0,0 +1,50 @@ +import { abi, address, chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { createReadContract } from './createReadContract.js' + +test('default', async () => { + const readWagmiMintExample = createReadContract({ + address: address.wagmiMintExample, + abi: abi.wagmiMintExample, + }) + + await expect( + readWagmiMintExample(config, { + functionName: 'balanceOf', + args: ['0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC'], + }), + ).resolves.toMatchInlineSnapshot('4n') +}) + +test('multichain', async () => { + const readWagmiMintExample = createReadContract({ + address: { + [chain.mainnet.id]: address.wagmiMintExample, + [chain.mainnet2.id]: address.wagmiMintExample, + }, + abi: abi.wagmiMintExample, + }) + + await expect( + readWagmiMintExample(config, { + functionName: 'balanceOf', + args: ['0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC'], + chainId: chain.mainnet2.id, + }), + ).resolves.toMatchInlineSnapshot('4n') +}) + +test('functionName', async () => { + const readWagmiMintExampleBalanceOf = createReadContract({ + address: address.wagmiMintExample, + abi: abi.wagmiMintExample, + functionName: 'balanceOf', + }) + + await expect( + readWagmiMintExampleBalanceOf(config, { + args: ['0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC'], + }), + ).resolves.toMatchInlineSnapshot('4n') +}) diff --git a/wagmi-project/packages/core/src/actions/codegen/createReadContract.ts b/wagmi-project/packages/core/src/actions/codegen/createReadContract.ts new file mode 100644 index 000000000..f7dbfbed4 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/codegen/createReadContract.ts @@ -0,0 +1,100 @@ +import type { + Abi, + Address, + ContractFunctionArgs, + ContractFunctionName, +} from 'viem' + +import type { Config } from '../../createConfig.js' +import type { UnionCompute, UnionStrictOmit } from '../../types/utils.js' +import { getAccount } from '../getAccount.js' +import { getChainId } from '../getChainId.js' +import { + type ReadContractParameters, + type ReadContractReturnType, + readContract, +} from '../readContract.js' + +type stateMutability = 'pure' | 'view' + +export type CreateReadContractParameters< + abi extends Abi | readonly unknown[], + address extends Address | Record | undefined = undefined, + functionName extends + | ContractFunctionName + | undefined = undefined, +> = { + abi: abi | Abi | readonly unknown[] + address?: address | Address | Record | undefined + functionName?: + | functionName + | ContractFunctionName + | undefined +} + +export type CreateReadContractReturnType< + abi extends Abi | readonly unknown[], + address extends Address | Record | undefined, + functionName extends ContractFunctionName | undefined, + /// + omittedProperties extends 'abi' | 'address' | 'chainId' | 'functionName' = + | 'abi' + | (address extends undefined ? never : 'address') + | (address extends Record ? 'chainId' : never) + | (functionName extends undefined ? never : 'functionName'), +> = < + config extends Config, + name extends functionName extends ContractFunctionName + ? functionName + : ContractFunctionName, + args extends ContractFunctionArgs, +>( + config: config, + parameters: UnionCompute< + UnionStrictOmit< + ReadContractParameters, + omittedProperties + > + > & + (address extends Record + ? { chainId?: keyof address | undefined } + : unknown), +) => Promise> + +export function createReadContract< + const abi extends Abi | readonly unknown[], + const address extends + | Address + | Record + | undefined = undefined, + functionName extends + | ContractFunctionName + | undefined = undefined, +>( + c: CreateReadContractParameters, +): CreateReadContractReturnType { + if (c.address !== undefined && typeof c.address === 'object') + return (config, parameters) => { + const configChainId = getChainId(config) + const account = getAccount(config) + const chainId = + (parameters as { chainId?: number })?.chainId ?? + account.chainId ?? + configChainId + return readContract(config, { + ...(parameters as any), + ...(c.functionName ? { functionName: c.functionName } : {}), + address: c.address?.[chainId], + abi: c.abi, + }) + } + + return (config, parameters) => { + return readContract(config, { + ...(parameters as any), + ...(c.address ? { address: c.address } : {}), + ...(c.functionName ? { functionName: c.functionName } : {}), + abi: c.abi, + }) + } +} diff --git a/wagmi-project/packages/core/src/actions/codegen/createSimulateContract.test-d.ts b/wagmi-project/packages/core/src/actions/codegen/createSimulateContract.test-d.ts new file mode 100644 index 000000000..91e599897 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/codegen/createSimulateContract.test-d.ts @@ -0,0 +1,211 @@ +import { abi, config, mainnet, optimism } from '@wagmi/test' +import { http, type Address } from 'viem' +import { celo } from 'viem/chains' +import { assertType, expectTypeOf, test } from 'vitest' + +import { createConfig } from '../../createConfig.js' +import { createSimulateContract } from './createSimulateContract.js' + +test('default', async () => { + const simulateErc20 = createSimulateContract({ + abi: abi.erc20, + address: '0x', + }) + + const result = await simulateErc20(config, { + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + chainId: 1, + }) + + expectTypeOf(result).toMatchTypeOf<{ + result: boolean + request: { + chainId: 1 + abi: readonly [ + { + readonly name: 'transferFrom' + readonly type: 'function' + readonly stateMutability: 'nonpayable' + readonly inputs: readonly [ + { readonly type: 'address'; readonly name: 'sender' }, + { readonly type: 'address'; readonly name: 'recipient' }, + { readonly type: 'uint256'; readonly name: 'amount' }, + ] + readonly outputs: readonly [{ type: 'bool' }] + }, + ] + functionName: 'transferFrom' + args: readonly [Address, Address, bigint] + } + }>() +}) + +test('multichain address', async () => { + const simulateErc20 = createSimulateContract({ + abi: abi.erc20, + address: { + [mainnet.id]: '0x', + [optimism.id]: '0x', + }, + }) + + const result = await simulateErc20(config, { + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + chainId: optimism.id, + }) + expectTypeOf(result.result).toEqualTypeOf() + + simulateErc20(config, { + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + // @ts-expect-error chain id must match address keys + chainId: 420, + }) + + simulateErc20(config, { + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + // @ts-expect-error address not allowed + address: '0x', + }) +}) + +test('overloads', async () => { + const simulateWriteOverloads = createSimulateContract({ + abi: abi.writeOverloads, + address: '0x', + }) + + const result1 = await simulateWriteOverloads(config, { + functionName: 'foo', + }) + assertType(result1.result) + + const result2 = await simulateWriteOverloads(config, { + functionName: 'foo', + args: [], + }) + assertType(result2.result) + + const result3 = await simulateWriteOverloads(config, { + functionName: 'foo', + args: ['0x'], + }) + // @ts-ignore – TODO: Fix https://github.com/wevm/viem/issues/1916 + assertType(result3.result) + + const result4 = await simulateWriteOverloads(config, { + functionName: 'foo', + args: ['0x', '0x'], + }) + assertType< + | { + foo: `0x${string}` + bar: `0x${string}` + } + | undefined + // @ts-ignore – TODO: Fix https://github.com/wevm/viem/issues/1916 + >(result4.result) +}) + +test('functionName', async () => { + const simulateErc20 = createSimulateContract({ + abi: abi.erc20, + address: '0x', + functionName: 'transferFrom', + }) + + const result = await simulateErc20(config, { + args: ['0x', '0x', 123n], + chainId: 1, + }) + + expectTypeOf(result).toMatchTypeOf<{ + result: boolean + request: { + chainId: 1 + abi: readonly [ + { + readonly name: 'transferFrom' + readonly type: 'function' + readonly stateMutability: 'nonpayable' + readonly inputs: readonly [ + { readonly type: 'address'; readonly name: 'sender' }, + { readonly type: 'address'; readonly name: 'recipient' }, + { readonly type: 'uint256'; readonly name: 'amount' }, + ] + readonly outputs: readonly [{ type: 'bool' }] + }, + ] + functionName: 'transferFrom' + args: readonly [Address, Address, bigint] + } + }>() +}) + +test('functionName with overloads', async () => { + const simulateWriteOverloads = createSimulateContract({ + abi: abi.writeOverloads, + address: '0x', + functionName: 'foo', + }) + + const result1 = await simulateWriteOverloads(config, {}) + assertType(result1.result) + + const result2 = await simulateWriteOverloads(config, { + args: [], + }) + assertType(result2.result) + + const result3 = await simulateWriteOverloads(config, { + args: ['0x'], + }) + // @ts-ignore – TODO: Fix https://github.com/wevm/viem/issues/1916 + assertType(result3.result) + + const result4 = await simulateWriteOverloads(config, { + args: ['0x', '0x'], + }) + assertType< + | { + foo: `0x${string}` + bar: `0x${string}` + } + | undefined + // @ts-ignore – TODO: Fix https://github.com/wevm/viem/issues/1916 + >(result4.result) +}) + +test('chain formatters', async () => { + const simulateErc20 = createSimulateContract({ + abi: abi.erc20, + address: '0x', + }) + + const config = createConfig({ + chains: [celo, mainnet], + transports: { [celo.id]: http(), [mainnet.id]: http() }, + }) + + const response = await simulateErc20(config, { + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + }) + if (response.chainId === celo.id) { + expectTypeOf(response.request.feeCurrency).toEqualTypeOf< + `0x${string}` | undefined + >() + } + + const response2 = await simulateErc20(config, { + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + chainId: celo.id, + }) + expectTypeOf(response2.request.feeCurrency).toEqualTypeOf< + `0x${string}` | undefined + >() +}) diff --git a/wagmi-project/packages/core/src/actions/codegen/createSimulateContract.test.ts b/wagmi-project/packages/core/src/actions/codegen/createSimulateContract.test.ts new file mode 100644 index 000000000..bd37d1377 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/codegen/createSimulateContract.test.ts @@ -0,0 +1,137 @@ +import { abi, address, chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { connect } from '../connect.js' +import { disconnect } from '../disconnect.js' +import { createSimulateContract } from './createSimulateContract.js' + +const connector = config.connectors[0]! + +test('default', async () => { + await connect(config, { connector }) + + const simulateWagmiMintExample = createSimulateContract({ + address: address.wagmiMintExample, + abi: abi.wagmiMintExample, + }) + + await expect( + simulateWagmiMintExample(config, { + functionName: 'mint', + }), + ).resolves.toMatchInlineSnapshot(` + { + "chainId": 1, + "request": { + "abi": [ + { + "inputs": [], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + ], + "account": { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "type": "json-rpc", + }, + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "args": undefined, + "chainId": undefined, + "dataSuffix": undefined, + "functionName": "mint", + }, + "result": undefined, + } + `) + + await disconnect(config, { connector }) +}) + +test('multichain', async () => { + await connect(config, { connector }) + + const simulateWagmiMintExample = createSimulateContract({ + address: { + [chain.mainnet.id]: address.wagmiMintExample, + [chain.mainnet2.id]: address.wagmiMintExample, + }, + abi: abi.wagmiMintExample, + }) + + await expect( + simulateWagmiMintExample(config, { + functionName: 'mint', + chainId: chain.mainnet2.id, + }), + ).resolves.toMatchInlineSnapshot(` + { + "chainId": 456, + "request": { + "abi": [ + { + "inputs": [], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + ], + "account": { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "type": "json-rpc", + }, + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "args": undefined, + "chainId": 456, + "dataSuffix": undefined, + "functionName": "mint", + }, + "result": undefined, + } + `) + + await disconnect(config, { connector }) +}) + +test('functionName', async () => { + await connect(config, { connector }) + + const simulateWagmiMintExample = createSimulateContract({ + address: address.wagmiMintExample, + abi: abi.wagmiMintExample, + functionName: 'mint', + }) + + await expect( + simulateWagmiMintExample(config, {}), + ).resolves.toMatchInlineSnapshot(` + { + "chainId": 1, + "request": { + "abi": [ + { + "inputs": [], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + ], + "account": { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "type": "json-rpc", + }, + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "args": undefined, + "chainId": undefined, + "dataSuffix": undefined, + "functionName": "mint", + }, + "result": undefined, + } + `) + + await disconnect(config, { connector }) +}) diff --git a/wagmi-project/packages/core/src/actions/codegen/createSimulateContract.ts b/wagmi-project/packages/core/src/actions/codegen/createSimulateContract.ts new file mode 100644 index 000000000..016384e24 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/codegen/createSimulateContract.ts @@ -0,0 +1,122 @@ +import type { + Abi, + Account, + Address, + Chain, + ContractFunctionArgs, + ContractFunctionName, + SimulateContractParameters as viem_SimulateContractParameters, +} from 'viem' + +import type { Config } from '../../createConfig.js' +import type { SelectChains } from '../../types/chain.js' +import type { + ChainIdParameter, + ConnectorParameter, +} from '../../types/properties.js' +import type { UnionCompute, UnionStrictOmit } from '../../types/utils.js' +import { getAccount } from '../getAccount.js' +import { getChainId } from '../getChainId.js' +import { + type SimulateContractReturnType, + simulateContract, +} from '../simulateContract.js' + +type stateMutability = 'nonpayable' | 'payable' + +export type CreateSimulateContractParameters< + abi extends Abi | readonly unknown[], + address extends Address | Record | undefined = undefined, + functionName extends + | ContractFunctionName + | undefined = undefined, +> = { + abi: abi | Abi | readonly unknown[] + address?: address | Address | Record | undefined + functionName?: + | functionName + | ContractFunctionName + | undefined +} + +export type CreateSimulateContractReturnType< + abi extends Abi | readonly unknown[], + address extends Address | Record | undefined, + functionName extends ContractFunctionName | undefined, +> = < + config extends Config, + name extends functionName extends ContractFunctionName + ? functionName + : ContractFunctionName, + args extends ContractFunctionArgs, + chainId extends config['chains'][number]['id'] | undefined = undefined, + /// + chains extends readonly Chain[] = SelectChains, +>( + config: config, + parameters: { + [key in keyof chains]: UnionCompute< + UnionStrictOmit< + viem_SimulateContractParameters< + abi, + name, + args, + chains[key], + chains[key], + Account | Address + >, + | 'abi' + | 'chain' + | (address extends undefined ? never : 'address') + | (functionName extends undefined ? never : 'functionName') + > + > & + ChainIdParameter & + ConnectorParameter & { + chainId?: address extends Record + ? + | keyof address + | (chainId extends keyof address ? chainId : never) + | undefined + : chainId | number | undefined + } + }[number], +) => Promise> + +export function createSimulateContract< + const abi extends Abi | readonly unknown[], + const address extends + | Address + | Record + | undefined = undefined, + functionName extends + | ContractFunctionName + | undefined = undefined, +>( + c: CreateSimulateContractParameters, +): CreateSimulateContractReturnType { + if (c.address !== undefined && typeof c.address === 'object') + return (config, parameters) => { + const configChainId = getChainId(config) + const account = getAccount(config) + const chainId = + (parameters as { chainId?: number })?.chainId ?? + account.chainId ?? + configChainId + return simulateContract(config, { + ...(parameters as any), + ...(c.functionName ? { functionName: c.functionName } : {}), + address: c.address?.[chainId], + abi: c.abi, + }) + } + + return (config, parameters) => { + return simulateContract(config, { + ...(parameters as any), + ...(c.address ? { address: c.address } : {}), + ...(c.functionName ? { functionName: c.functionName } : {}), + abi: c.abi, + }) + } +} diff --git a/wagmi-project/packages/core/src/actions/codegen/createWatchContractEvent.test-d.ts b/wagmi-project/packages/core/src/actions/codegen/createWatchContractEvent.test-d.ts new file mode 100644 index 000000000..6c0485f39 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/codegen/createWatchContractEvent.test-d.ts @@ -0,0 +1,123 @@ +import { abi, config, mainnet, optimism } from '@wagmi/test' +import { http, webSocket } from 'viem' +import { expectTypeOf, test } from 'vitest' + +import { createConfig } from '../../createConfig.js' +import { createWatchContractEvent } from './createWatchContractEvent.js' + +test('default', () => { + const watchErc20Event = createWatchContractEvent({ + abi: abi.erc20, + }) + + watchErc20Event(config, { + eventName: 'Transfer', + chainId: 1, + onLogs(logs) { + expectTypeOf(logs[0]!.eventName).toEqualTypeOf<'Transfer'>() + expectTypeOf(logs[0]!.args).toEqualTypeOf<{ + from?: `0x${string}` | undefined + to?: `0x${string}` | undefined + value?: bigint | undefined + }>() + }, + }) +}) + +test('multichain address', () => { + const watchErc20Event = createWatchContractEvent({ + abi: abi.erc20, + address: { + [mainnet.id]: '0x', + [optimism.id]: '0x', + }, + }) + + watchErc20Event(config, { + eventName: 'Transfer', + chainId: mainnet.id, + // ^? + onLogs() {}, + }) + + watchErc20Event(config, { + eventName: 'Transfer', + // @ts-expect-error chain id must match address keys + chainId: 420, + onLogs() {}, + }) + + watchErc20Event(config, { + eventName: 'Transfer', + // @ts-expect-error chain id must match address keys + address: '0x', + onLogs() {}, + }) +}) + +test('differing transports', () => { + const watchErc20Event = createWatchContractEvent({ + abi: abi.erc20, + }) + + const config = createConfig({ + chains: [mainnet, optimism], + transports: { + [mainnet.id]: http(), + [optimism.id]: webSocket(), + }, + }) + + watchErc20Event(config, { + poll: false, + address: '0x', + onLogs() {}, + }) + + watchErc20Event(config, { + chainId: mainnet.id, + poll: true, + address: '0x', + onLogs() {}, + }) + watchErc20Event(config, { + config, + chainId: mainnet.id, + // @ts-expect-error poll required since http transport + poll: false, + address: '0x', + onLogs() {}, + }) + + watchErc20Event(config, { + chainId: optimism.id, + poll: true, + address: '0x', + onLogs() {}, + }) + watchErc20Event(config, { + chainId: optimism.id, + poll: false, + address: '0x', + onLogs() {}, + }) +}) + +test('eventName', () => { + const watchErc20Event = createWatchContractEvent({ + abi: abi.erc20, + eventName: 'Transfer', + }) + + watchErc20Event(config, { + chainId: 1, + onLogs(logs) { + expectTypeOf(logs[0]!.eventName).toEqualTypeOf<'Transfer'>() + expectTypeOf(logs[0]!.args).toEqualTypeOf<{ + from?: `0x${string}` | undefined + to?: `0x${string}` | undefined + value?: bigint | undefined + }>() + }, + }) +}) diff --git a/wagmi-project/packages/core/src/actions/codegen/createWatchContractEvent.test.ts b/wagmi-project/packages/core/src/actions/codegen/createWatchContractEvent.test.ts new file mode 100644 index 000000000..19ba09b2a --- /dev/null +++ b/wagmi-project/packages/core/src/actions/codegen/createWatchContractEvent.test.ts @@ -0,0 +1,41 @@ +import { abi, address, chain, config } from '@wagmi/test' +import type { WatchEventOnLogsParameter } from 'viem' +import { test } from 'vitest' + +import { createWatchContractEvent } from './createWatchContractEvent.js' + +test('default', async () => { + const watchErc20Event = createWatchContractEvent({ + address: address.usdc, + abi: abi.wagmiMintExample, + }) + + let logs: WatchEventOnLogsParameter = [] + const unwatch = watchErc20Event(config, { + eventName: 'Transfer', + onLogs(next) { + logs = logs.concat(next) + }, + }) + unwatch() +}) + +test('multichain', async () => { + const watchErc20Event = createWatchContractEvent({ + address: { + [chain.mainnet.id]: address.usdc, + [chain.mainnet2.id]: address.usdc, + }, + abi: abi.wagmiMintExample, + }) + + let logs: WatchEventOnLogsParameter = [] + const unwatch = watchErc20Event(config, { + eventName: 'Transfer', + chainId: chain.mainnet2.id, + onLogs(next) { + logs = logs.concat(next) + }, + }) + unwatch() +}) diff --git a/wagmi-project/packages/core/src/actions/codegen/createWatchContractEvent.ts b/wagmi-project/packages/core/src/actions/codegen/createWatchContractEvent.ts new file mode 100644 index 000000000..2817efc70 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/codegen/createWatchContractEvent.ts @@ -0,0 +1,88 @@ +import type { Abi, Address, ContractEventName } from 'viem' + +import type { Config } from '../../createConfig.js' +import type { UnionCompute, UnionStrictOmit } from '../../types/utils.js' +import { getAccount } from '../getAccount.js' +import { getChainId } from '../getChainId.js' +import { + type WatchContractEventParameters, + type WatchContractEventReturnType, + watchContractEvent, +} from '../watchContractEvent.js' + +export type CreateWatchContractEventParameters< + abi extends Abi | readonly unknown[], + address extends Address | Record | undefined = undefined, + eventName extends ContractEventName | undefined = undefined, +> = { + abi: abi | Abi | readonly unknown[] + address?: address | Address | Record | undefined + eventName?: eventName | ContractEventName | undefined +} + +export type CreateWatchContractEventReturnType< + abi extends Abi | readonly unknown[], + address extends Address | Record | undefined, + eventName extends ContractEventName | undefined, + /// + omittedProperties extends 'abi' | 'address' | 'chainId' | 'eventName' = + | 'abi' + | (address extends undefined ? never : 'address') + | (address extends Record ? 'chainId' : never) + | (eventName extends undefined ? never : 'eventName'), +> = < + config extends Config, + name extends eventName extends ContractEventName + ? eventName + : ContractEventName, + strict extends boolean | undefined = undefined, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +>( + config: config, + parameters: UnionCompute< + UnionStrictOmit< + WatchContractEventParameters, + omittedProperties + > + > & + (address extends Record + ? { chainId?: keyof address | undefined } + : unknown), +) => WatchContractEventReturnType + +export function createWatchContractEvent< + const abi extends Abi | readonly unknown[], + const address extends + | Address + | Record + | undefined = undefined, + eventName extends ContractEventName | undefined = undefined, +>( + c: CreateWatchContractEventParameters, +): CreateWatchContractEventReturnType { + if (c.address !== undefined && typeof c.address === 'object') + return (config, parameters) => { + const configChainId = getChainId(config) + const account = getAccount(config) + const chainId = + (parameters as { chainId?: number })?.chainId ?? + account.chainId ?? + configChainId + return watchContractEvent(config, { + ...(parameters as any), + ...(c.eventName ? { eventName: c.eventName } : {}), + address: c.address?.[chainId], + abi: c.abi, + }) + } + + return (config, parameters) => { + return watchContractEvent(config, { + ...(parameters as any), + ...(c.address ? { address: c.address } : {}), + ...(c.eventName ? { eventName: c.eventName } : {}), + abi: c.abi, + }) + } +} diff --git a/wagmi-project/packages/core/src/actions/codegen/createWriteContract.test-d.ts b/wagmi-project/packages/core/src/actions/codegen/createWriteContract.test-d.ts new file mode 100644 index 000000000..9c69ede5b --- /dev/null +++ b/wagmi-project/packages/core/src/actions/codegen/createWriteContract.test-d.ts @@ -0,0 +1,129 @@ +import { abi, config, mainnet, optimism } from '@wagmi/test' +import { test } from 'vitest' + +import { simulateContract } from '../simulateContract.js' +import { createWriteContract } from './createWriteContract.js' + +test('default', () => { + const writeErc20 = createWriteContract({ + abi: abi.erc20, + address: '0x', + }) + + writeErc20(config, { + functionName: 'transfer', + args: ['0x', 123n], + }) +}) + +test('multichain address', () => { + const writeErc20 = createWriteContract({ + abi: abi.erc20, + address: { + [mainnet.id]: '0x', + [optimism.id]: '0x', + }, + }) + + writeErc20(config, { + functionName: 'transfer', + args: ['0x', 123n], + chainId: mainnet.id, + // ^? + }) + + writeErc20(config, { + functionName: 'transfer', + args: ['0x', 123n], + // @ts-expect-error chain id must match address keys + chainId: 420, + }) + + writeErc20(config, { + // @ts-expect-error address not allowed + address: '0x', + functionName: 'transfer', + args: ['0x', 123n], + }) +}) + +test('overloads', () => { + const writeOverloads = createWriteContract({ + abi: abi.writeOverloads, + address: { + [mainnet.id]: '0x', + [optimism.id]: '0x', + }, + }) + + writeOverloads(config, { + functionName: 'foo', + args: [], + }) + + writeOverloads(config, { + functionName: 'foo', + args: ['0x'], + }) + + writeOverloads(config, { + functionName: 'foo', + args: ['0x', '0x'], + }) +}) + +test('useSimulateContract', async () => { + const writeErc20 = createWriteContract({ + abi: abi.erc20, + address: { + [mainnet.id]: '0x', + [optimism.id]: '0x', + }, + }) + + const { request } = await simulateContract(config, { + account: '0x', + address: '0x', + abi: abi.erc20, + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + chainId: 1, + }) + + writeErc20(config, request) +}) + +test('functionName', () => { + const writeErc20 = createWriteContract({ + abi: abi.erc20, + address: '0x', + functionName: 'transfer', + }) + + writeErc20(config, { + args: ['0x', 123n], + }) +}) + +test('functionName with overloads', () => { + const writeOverloads = createWriteContract({ + abi: abi.writeOverloads, + address: { + [mainnet.id]: '0x', + [optimism.id]: '0x', + }, + functionName: 'foo', + }) + + writeOverloads(config, { + args: [], + }) + + writeOverloads(config, { + args: ['0x'], + }) + + writeOverloads(config, { + args: ['0x', '0x'], + }) +}) diff --git a/wagmi-project/packages/core/src/actions/codegen/createWriteContract.test.ts b/wagmi-project/packages/core/src/actions/codegen/createWriteContract.test.ts new file mode 100644 index 000000000..04511d13a --- /dev/null +++ b/wagmi-project/packages/core/src/actions/codegen/createWriteContract.test.ts @@ -0,0 +1,11 @@ +import { abi } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { createWriteContract } from './createWriteContract.js' + +test('default', () => { + const writeErc20 = createWriteContract({ + abi: abi.erc20, + }) + expect(writeErc20).toBeDefined() +}) diff --git a/wagmi-project/packages/core/src/actions/codegen/createWriteContract.ts b/wagmi-project/packages/core/src/actions/codegen/createWriteContract.ts new file mode 100644 index 000000000..6c1d891a3 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/codegen/createWriteContract.ts @@ -0,0 +1,145 @@ +import type { + Abi, + Account, + Address, + Chain, + ContractFunctionArgs, + ContractFunctionName, + WriteContractParameters as viem_WriteContractParameters, +} from 'viem' + +import type { Config } from '../../createConfig.js' +import type { SelectChains } from '../../types/chain.js' +import type { + ChainIdParameter, + ConnectorParameter, +} from '../../types/properties.js' +import type { + Compute, + UnionCompute, + UnionStrictOmit, +} from '../../types/utils.js' +import { getAccount } from '../getAccount.js' +import { getChainId } from '../getChainId.js' +import { + type WriteContractReturnType, + writeContract, +} from '../writeContract.js' + +type stateMutability = 'nonpayable' | 'payable' + +export type CreateWriteContractParameters< + abi extends Abi | readonly unknown[], + address extends Address | Record | undefined = undefined, + functionName extends + | ContractFunctionName + | undefined = undefined, +> = { + abi: abi | Abi | readonly unknown[] + address?: address | Address | Record | undefined + functionName?: + | functionName + | ContractFunctionName + | undefined +} + +export type CreateWriteContractReturnType< + abi extends Abi | readonly unknown[], + address extends Address | Record | undefined, + functionName extends ContractFunctionName | undefined, +> = < + config extends Config, + name extends functionName extends ContractFunctionName + ? functionName + : ContractFunctionName, + args extends ContractFunctionArgs, + chainId extends config['chains'][number]['id'], + /// + allFunctionNames = ContractFunctionName, + chains extends readonly Chain[] = SelectChains, + omittedProperties extends 'abi' | 'address' | 'functionName' = + | 'abi' + | (address extends undefined ? never : 'address') + | (functionName extends undefined ? never : 'functionName'), +>( + config: config, + parameters: UnionCompute< + { + [key in keyof chains]: UnionStrictOmit< + viem_WriteContractParameters< + abi, + name, + args, + chains[key], + Account, + chains[key], + allFunctionNames + >, + omittedProperties | 'chain' + > + }[number] & + (address extends Record + ? { + chainId?: + | keyof address + | (chainId extends keyof address ? chainId : never) + | undefined + } + : Compute>) & + ConnectorParameter & { + /** @deprecated */ + __mode?: 'prepared' + } + >, +) => Promise + +export function createWriteContract< + const abi extends Abi | readonly unknown[], + const address extends + | Address + | Record + | undefined = undefined, + functionName extends + | ContractFunctionName + | undefined = undefined, +>( + c: CreateWriteContractParameters, +): CreateWriteContractReturnType { + if (c.address !== undefined && typeof c.address === 'object') + return (config, parameters) => { + const configChainId = getChainId(config) + const account = getAccount(config) + + let chainId: number | undefined + if (parameters.chainId) chainId = parameters.chainId + else if ( + (parameters as unknown as { account: Address | Account | undefined }) + .account && + (parameters as unknown as { account: Address | Account | undefined }) + .account === account.address + ) + chainId = account.chainId + else if ( + (parameters as unknown as { account: Address | Account | undefined }) + .account === undefined + ) + chainId = account.chainId + else chainId = configChainId + + return writeContract(config, { + ...(parameters as any), + ...(c.functionName ? { functionName: c.functionName } : {}), + address: chainId ? c.address?.[chainId] : undefined, + abi: c.abi, + }) + } + + return (config, parameters) => { + return writeContract(config, { + ...(parameters as any), + ...(c.address ? { address: c.address } : {}), + ...(c.functionName ? { functionName: c.functionName } : {}), + abi: c.abi, + }) + } +} diff --git a/wagmi-project/packages/core/src/actions/connect.test-d.ts b/wagmi-project/packages/core/src/actions/connect.test-d.ts new file mode 100644 index 000000000..ad790b120 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/connect.test-d.ts @@ -0,0 +1,48 @@ +import { accounts } from '@wagmi/test' +import { http } from 'viem' +import { mainnet } from 'viem/chains' +import { expectTypeOf, test } from 'vitest' + +import type { CreateConnectorFn } from '../connectors/createConnector.js' +import { mock } from '../connectors/mock.js' +import { type Connector, createConfig } from '../createConfig.js' +import { connect } from './connect.js' + +const config = createConfig({ + chains: [mainnet], + transports: { [mainnet.id]: http() }, +}) + +test('parameters: connector (ConnectorFn)', () => { + const connectorFn = mock({ accounts }) + + connect(config, { + connector: connectorFn, + foo: 'bar', + }) + expectTypeOf< + typeof connectorFn extends CreateConnectorFn ? true : false + >().toEqualTypeOf() + + type Result = NonNullable< + Parameters>[1] + > + expectTypeOf().toEqualTypeOf() +}) + +test('parameters: connector (Connector)', () => { + const connector = config._internal.connectors.setup(mock({ accounts })) + + connect(config, { + connector, + foo: 'bar', + }) + expectTypeOf< + typeof connector extends Connector ? true : false + >().toEqualTypeOf() + + type Result = NonNullable< + Parameters>[1] + > + expectTypeOf().toEqualTypeOf() +}) diff --git a/wagmi-project/packages/core/src/actions/connect.test.ts b/wagmi-project/packages/core/src/actions/connect.test.ts new file mode 100644 index 000000000..eece8c3a4 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/connect.test.ts @@ -0,0 +1,71 @@ +import { accounts, chain, config } from '@wagmi/test' +import { beforeEach, expect, test } from 'vitest' + +import { mock } from '../connectors/mock.js' +import { connect } from './connect.js' +import { disconnect } from './disconnect.js' + +const connector = config._internal.connectors.setup(mock({ accounts })) + +beforeEach(async () => { + if (config.state.current === connector.uid) + await disconnect(config, { connector }) +}) + +test('default', async () => { + await expect(connect(config, { connector })).resolves.toMatchObject( + expect.objectContaining({ + accounts: expect.any(Array), + chainId: expect.any(Number), + }), + ) +}) + +test('parameters: chainId', async () => { + const chainId = chain.mainnet2.id + await expect(connect(config, { connector, chainId })).resolves.toMatchObject( + expect.objectContaining({ + accounts: expect.any(Array), + chainId, + }), + ) +}) + +test('parameters: connector', async () => { + const connector_ = config._internal.connectors.setup(mock({ accounts })) + await expect( + connect(config, { connector: connector_ }), + ).resolves.toMatchObject( + expect.objectContaining({ + accounts: expect.any(Array), + chainId: expect.any(Number), + }), + ) + await disconnect(config, { connector: connector_ }) +}) + +test('behavior: user rejected request', async () => { + const connector_ = config._internal.connectors.setup( + mock({ + accounts, + features: { connectError: true }, + }), + ) + await expect( + connect(config, { connector: connector_ }), + ).rejects.toMatchInlineSnapshot(` + [UserRejectedRequestError: User rejected the request. + + Details: Failed to connect. + Version: viem@2.29.2] + `) +}) + +test('behavior: already connected', async () => { + await connect(config, { connector }) + await expect(connect(config, { connector })).rejects.toMatchInlineSnapshot(` + [ConnectorAlreadyConnectedError: Connector already connected. + + Version: @wagmi/core@x.y.z] + `) +}) diff --git a/wagmi-project/packages/core/src/actions/connect.ts b/wagmi-project/packages/core/src/actions/connect.ts new file mode 100644 index 000000000..f69809e50 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/connect.ts @@ -0,0 +1,110 @@ +import type { + Address, + ResourceUnavailableRpcErrorType, + UserRejectedRequestErrorType, +} from 'viem' + +import type { CreateConnectorFn } from '../connectors/createConnector.js' +import type { Config, Connector } from '../createConfig.js' +import type { BaseErrorType, ErrorType } from '../errors/base.js' +import { + ConnectorAlreadyConnectedError, + type ConnectorAlreadyConnectedErrorType, +} from '../errors/config.js' +import type { ChainIdParameter } from '../types/properties.js' +import type { Compute } from '../types/utils.js' + +export type ConnectParameters< + config extends Config = Config, + connector extends Connector | CreateConnectorFn = + | Connector + | CreateConnectorFn, + /// + parameters extends unknown | undefined = + | (connector extends CreateConnectorFn + ? Omit< + NonNullable['connect']>[0]>, + 'isReconnecting' + > + : never) + | (connector extends Connector + ? Omit< + NonNullable[0]>, + 'isReconnecting' + > + : never), +> = Compute< + ChainIdParameter & { + connector: connector | CreateConnectorFn + } +> & + parameters + +export type ConnectReturnType = { + accounts: readonly [Address, ...Address[]] + chainId: + | config['chains'][number]['id'] + | (number extends config['chains'][number]['id'] ? number : number & {}) +} + +export type ConnectErrorType = + | ConnectorAlreadyConnectedErrorType + // connector.connect() + | UserRejectedRequestErrorType + | ResourceUnavailableRpcErrorType + // base + | BaseErrorType + | ErrorType + +/** https://wagmi.sh/core/api/actions/connect */ +export async function connect< + config extends Config, + connector extends Connector | CreateConnectorFn, +>( + config: config, + parameters: ConnectParameters, +): Promise> { + // "Register" connector if not already created + let connector: Connector + if (typeof parameters.connector === 'function') { + connector = config._internal.connectors.setup(parameters.connector) + } else connector = parameters.connector + + // Check if connector is already connected + if (connector.uid === config.state.current) + throw new ConnectorAlreadyConnectedError() + + try { + config.setState((x) => ({ ...x, status: 'connecting' })) + connector.emitter.emit('message', { type: 'connecting' }) + + const { connector: _, ...rest } = parameters + const data = await connector.connect(rest) + const accounts = data.accounts as readonly [Address, ...Address[]] + + connector.emitter.off('connect', config._internal.events.connect) + connector.emitter.on('change', config._internal.events.change) + connector.emitter.on('disconnect', config._internal.events.disconnect) + + await config.storage?.setItem('recentConnectorId', connector.id) + config.setState((x) => ({ + ...x, + connections: new Map(x.connections).set(connector.uid, { + accounts, + chainId: data.chainId, + connector: connector, + }), + current: connector.uid, + status: 'connected', + })) + + return { accounts, chainId: data.chainId } + } catch (error) { + config.setState((x) => ({ + ...x, + // Keep existing connector connected in case of error + status: x.current ? 'connected' : 'disconnected', + })) + throw error + } +} diff --git a/wagmi-project/packages/core/src/actions/deployContract.test-d.ts b/wagmi-project/packages/core/src/actions/deployContract.test-d.ts new file mode 100644 index 000000000..b7a6a897d --- /dev/null +++ b/wagmi-project/packages/core/src/actions/deployContract.test-d.ts @@ -0,0 +1,71 @@ +import { abi, bytecode, config } from '@wagmi/test' +import { http } from 'viem' +import { celo, mainnet } from 'viem/chains' +import { expectTypeOf, test } from 'vitest' + +import { createConfig } from '../createConfig.js' +import { + type DeployContractParameters, + deployContract, +} from './deployContract.js' + +test('default', async () => { + await deployContract(config, { + abi: abi.bayc, + bytecode: bytecode.bayc, + args: ['Bored Ape Wagmi Club', 'BAYC', 69420n, 0n], + chainId: mainnet.id, + }) +}) + +test('chain formatters', () => { + const config = createConfig({ + chains: [mainnet, celo], + transports: { [celo.id]: http(), [mainnet.id]: http() }, + }) + + type Result = DeployContractParameters + expectTypeOf().toMatchTypeOf<{ + chainId?: typeof celo.id | typeof mainnet.id | undefined + feeCurrency?: `0x${string}` | undefined + }>() + deployContract(config, { + abi: abi.bayc, + bytecode: bytecode.bayc, + args: ['Bored Ape Wagmi Club', 'BAYC', 69420n, 0n], + feeCurrency: '0x', + }) + + type Result2 = DeployContractParameters< + typeof abi.bayc, + typeof config, + typeof celo.id + > + expectTypeOf().toMatchTypeOf<{ + feeCurrency?: `0x${string}` | undefined + }>() + deployContract(config, { + chainId: celo.id, + abi: abi.bayc, + bytecode: bytecode.bayc, + args: ['Bored Ape Wagmi Club', 'BAYC', 69420n, 0n], + feeCurrency: '0x', + }) + + type Result3 = DeployContractParameters< + typeof abi.bayc, + typeof config, + typeof mainnet.id + > + expectTypeOf().not.toMatchTypeOf<{ + feeCurrency?: `0x${string}` | undefined + }>() + deployContract(config, { + chainId: mainnet.id, + abi: abi.bayc, + bytecode: bytecode.bayc, + args: ['Bored Ape Wagmi Club', 'BAYC', 69420n, 0n], + // @ts-expect-error + feeCurrency: '0x', + }) +}) diff --git a/wagmi-project/packages/core/src/actions/deployContract.test.ts b/wagmi-project/packages/core/src/actions/deployContract.test.ts new file mode 100644 index 000000000..bebf42342 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/deployContract.test.ts @@ -0,0 +1,67 @@ +import { + abi, + bytecode, + config, + testClient, + transactionHashRegex, +} from '@wagmi/test' +import { parseEther } from 'viem' +import { expect, test } from 'vitest' + +import { connect } from './connect.js' +import { deployContract } from './deployContract.js' +import { disconnect } from './disconnect.js' + +const connector = config.connectors[0]! + +test('default', async () => { + await connect(config, { connector }) + await expect( + deployContract(config, { + abi: abi.bayc, + bytecode: bytecode.bayc, + args: ['Bored Ape Wagmi Club', 'BAYC', 69420n, 0n], + }), + ).resolves.toMatch(transactionHashRegex) + await disconnect(config, { connector }) +}) + +test('behavior: no funds', async () => { + const data = await connect(config, { connector }) + const connectedAddress = data.accounts[0] + + await testClient.mainnet.setBalance({ + address: connectedAddress, + value: parseEther('0'), + }) + + await expect( + deployContract(config, { + chainId: testClient.mainnet.chain.id, + abi: abi.bayc, + bytecode: bytecode.bayc, + args: ['Bored Ape Wagmi Club', 'BAYC', 69420n, 0n], + }), + ).rejects.toThrowErrorMatchingInlineSnapshot(` + [TransactionExecutionError: The total cost (gas * gas fee + value) of executing this transaction exceeds the balance of the account. + + This error could arise when the account does not have enough funds to: + - pay for the total gas fee, + - pay for the value to send. + + The cost of the transaction is calculated as \`gas * gas fee + value\`, where: + - \`gas\` is the amount of gas needed for transaction to execute, + - \`gas fee\` is the gas fee, + - \`value\` is the amount of ether to send to the recipient. + + Request Arguments: + chain: undefined (id: 1) + from: 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 + data: 0x608060405260405180602001604052806000815250600b90805190602001906200002b92919062000484565b506000600f60006101000a81548160ff0219169083151502179055503480156200005457600080fd5b50604051620046d0380380620046d0833981810160405260808110156200007a57600080fd5b81019080805160405193929190846401000000008211156200009b57600080fd5b83820191506020820185811115620000b257600080fd5b8251866001820283011164010000000082111715620000d057600080fd5b8083526020830192505050908051906020019080838360005b8381101562000106578082015181840152602081019050620000e9565b50505050905090810190601f168015620001345780820380516001836020036101000a031916815260200191505b50604052602001805160405193929190846401000000008211156200015857600080fd5b838201915060208201858111156200016f57600080fd5b82518660018202830111640100000000821117156200018d57600080fd5b8083526020830192505050908051906020019080838360005b83811015620001c3578082015181840152602081019050620001a6565b50505050905090810190601f168015620001f15780820380516001836020036101000a031916815260200191505b5060405260200180519060200190929190805190602001909291905050508383620002296301ffc9a760e01b6200037360201b60201c565b81600690805190602001906200024192919062000484565b5080600790805190602001906200025a92919062000484565b50620002736380ac58cd60e01b6200037360201b60201c565b6200028b635b5e139f60e01b6200037360201b60201c565b620002a363780e9d6360e01b6200037360201b60201c565b50506000620002b76200047c60201b60201c565b905080600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35081600e81905550620bdd808101601081905550505050506200052a565b63ffffffff60e01b817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141562000410576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601c8152602001807f4552433136353a20696e76616c696420696e746572666163652069640000000081525060200191505060405180910390fd5b6001600080837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b600033905090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10620004c757805160ff1916838001178555620004f8565b82800160010185558215620004f8579182015b82811115620004f7578251825591602001919060010190620004da565b5b5090506200050791906200050b565b5090565b5b80821115620005265760008160009055506001016200050c565b5090565b614196806200053a6000396000f3fe60806040526004361061021a5760003560e01c80636c0360eb11610123578063b0f67427116100ab578063e36d64981161006f578063e36d649814610ddf578063e985e9c514610e0a578063e986655014610e91578063eb8d244414610ea8578063f2fde38b14610ed55761021a565b8063b0f6742714610bac578063b88d4fde14610bc3578063bb8a16bd14610cd5578063c87b56dd14610d00578063cb774d4714610db45761021a565b80637d17fcbe116100f25780637d17fcbe14610a395780638da5cb5b14610a5057806395d89b4114610a91578063a22cb46514610b21578063a723533e14610b7e5761021a565b80636c0360eb1461090257806370a0823114610992578063715018a6146109f75780637a3f451e14610a0e5761021a565b80632f745c59116101a65780634f6ccce7116101755780634f6ccce7146106cb57806355f804b31461071a578063571dff3b146107e2578063607e20e31461080d5780636352211e1461089d5761021a565b80632f745c59146105b357806334918dfd146106225780633ccfd60b1461063957806342842e0e146106505761021a565b8063095ea7b3116101ed578063095ea7b3146103bf578063109695231461041a57806318160ddd146104e257806318e20a381461050d57806323b872dd146105385761021a565b8063018a2c371461021f57806301ffc9a71461025a57806306fdde03146102ca578063081812fc1461035a575b600080fd5b34801561022b57600080fd5b506102586004803603602081101561024257600080fd5b8101908080359060200190929190505050610f26565b005b34801561026657600080fd5b506102b26004803603602081101561027d57600080fd5b8101908080357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19169060200190929190505050610fdf565b60405180821515815260200191505060405180910390f35b3480156102d657600080fd5b506102df611046565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561031f578082015181840152602081019050610304565b50505050905090810190601f16801561034c5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561036657600080fd5b506103936004803603602081101561037d57600080fd5b81019080803590602001909291905050506110e8565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156103cb57600080fd5b50610418600480360360408110156103e257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611183565b005b34801561042657600080fd5b506104e06004803603602081101561043d57600080fd5b810190808035906020019064010000000081111561045a57600080fd5b82018360208201111561046c57600080fd5b8035906020019184600183028401116401000000008311171561048e57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192905050506112c7565b005b3480156104ee57600080fd5b506104f7611390565b6040518082815260200191505060405180910390f35b34801561051957600080fd5b506105226113a1565b6040518082815260200191505060405180910390f35b34801561054457600080fd5b506105b16004803603606081101561055b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506113a7565b005b3480156105bf57600080fd5b5061060c600480360360408110156105d657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061141d565b6040518082815260200191505060405180910390f35b34801561062e57600080fd5b50610637611478565b005b34801561064557600080fd5b5061064e611553565b005b34801561065c57600080fd5b506106c96004803603606081101561067357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611651565b005b3480156106d757600080fd5b50610704600480360360208110156106ee57600080fd5b8101908080359060200190929190505050611671565b6040518082815260200191505060405180910390f35b34801561072657600080fd5b506107e06004803603602081101561073d57600080fd5b810190808035906020019064010000000081111561075a57600080fd5b82018360208201111561076c57600080fd5b8035906020019184600183028401116401000000008311171561078e57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050611694565b005b3480156107ee57600080fd5b506107f761174f565b6040518082815260200191505060405180910390f35b34801561081957600080fd5b50610822611754565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610862578082015181840152602081019050610847565b50505050905090810190601f16801561088f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156108a957600080fd5b506108d6600480360360208110156108c057600080fd5b81019080803590602001909291905050506117f2565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561090e57600080fd5b50610917611829565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561095757808201518184015260208101905061093c565b50505050905090810190601f1680156109845780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561099e57600080fd5b506109e1600480360360208110156109b557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506118cb565b6040518082815260200191505060405180910390f35b348015610a0357600080fd5b50610a0c6119a0565b005b348015610a1a57600080fd5b50610a23611b10565b6040518082815260200191505060405180910390f35b348015610a4557600080fd5b50610a4e611b1c565b005b348015610a5c57600080fd5b50610a65611c4c565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b348015610a9d57600080fd5b50610aa6611c76565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610ae6578082015181840152602081019050610acb565b50505050905090810190601f168015610b135780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b348015610b2d57600080fd5b50610b7c60048036036040811015610b4457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803515159060200190929190505050611d18565b005b610baa60048036036020811015610b9457600080fd5b8101908080359060200190929190505050611ece565b005b348015610bb857600080fd5b50610bc1612127565b005b348015610bcf57600080fd5b50610cd360048036036080811015610be657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190640100000000811115610c4d57600080fd5b820183602082011115610c5f57600080fd5b80359060200191846001830284011164010000000083111715610c8157600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929050505061220b565b005b348015610ce157600080fd5b50610cea612283565b6040518082815260200191505060405180910390f35b348015610d0c57600080fd5b50610d3960048036036020811015610d2357600080fd5b8101908080359060200190929190505050612289565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610d79578082015181840152602081019050610d5e565b50505050905090810190601f168015610da65780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b348015610dc057600080fd5b50610dc961255a565b6040518082815260200191505060405180910390f35b348015610deb57600080fd5b50610df4612560565b6040518082815260200191505060405180910390f35b348015610e1657600080fd5b50610e7960048036036040811015610e2d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612566565b60405180821515815260200191505060405180910390f35b348015610e9d57600080fd5b50610ea66125fa565b005b348015610eb457600080fd5b50610ebd612764565b60405180821515815260200191505060405180910390f35b348015610ee157600080fd5b50610f2460048036036020811015610ef857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612777565b005b610f2e61296c565b73ffffffffffffffffffffffffffffffffffffffff16610f4c611c4c565b73ffffffffffffffffffffffffffffffffffffffff1614610fd5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b8060108190555050565b6000806000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060009054906101000a900460ff169050919050565b606060068054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156110de5780601f106110b3576101008083540402835291602001916110de565b820191906000526020600020905b8154815290600101906020018083116110c157829003601f168201915b5050505050905090565b60006110f382612974565b611148576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c81526020018061408b602c913960400191505060405180910390fd5b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600061118e826117f2565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415611215576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602181526020018061410f6021913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1661123461296c565b73ffffffffffffffffffffffffffffffffffffffff16148061126357506112628161125d61296c565b612566565b5b6112b8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526038815260200180613f956038913960400191505060405180910390fd5b6112c28383612991565b505050565b6112cf61296c565b73ffffffffffffffffffffffffffffffffffffffff166112ed611c4c565b73ffffffffffffffffffffffffffffffffffffffff1614611376576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b80600b908051906020019061138c929190613de6565b5050565b600061139c6002612a4a565b905090565b60105481565b6113b86113b261296c565b82612a5f565b61140d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260318152602001806141306031913960400191505060405180910390fd5b611418838383612b53565b505050565b600061147082600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020612d9690919063ffffffff16565b905092915050565b61148061296c565b73ffffffffffffffffffffffffffffffffffffffff1661149e611c4c565b73ffffffffffffffffffffffffffffffffffffffff1614611527576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600f60009054906101000a900460ff1615600f60006101000a81548160ff021916908315150217905550565b61155b61296c565b73ffffffffffffffffffffffffffffffffffffffff16611579611c4c565b73ffffffffffffffffffffffffffffffffffffffff1614611602576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b60004790503373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f1935050505015801561164d573d6000803e3d6000fd5b5050565b61166c8383836040518060200160405280600081525061220b565b505050565b600080611688836002612db090919063ffffffff16565b50905080915050919050565b61169c61296c565b73ffffffffffffffffffffffffffffffffffffffff166116ba611c4c565b73ffffffffffffffffffffffffffffffffffffffff1614611743576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b61174c81612ddc565b50565b601481565b600b8054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156117ea5780601f106117bf576101008083540402835291602001916117ea565b820191906000526020600020905b8154815290600101906020018083116117cd57829003601f168201915b505050505081565b600061182282604051806060016040528060298152602001613ff7602991396002612df69092919063ffffffff16565b9050919050565b606060098054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156118c15780601f10611896576101008083540402835291602001916118c1565b820191906000526020600020905b8154815290600101906020018083116118a457829003601f168201915b5050505050905090565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611952576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180613fcd602a913960400191505060405180910390fd5b611999600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020612e15565b9050919050565b6119a861296c565b73ffffffffffffffffffffffffffffffffffffffff166119c6611c4c565b73ffffffffffffffffffffffffffffffffffffffff1614611a4f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a36000600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b67011c37937e08000081565b611b2461296c565b73ffffffffffffffffffffffffffffffffffffffff16611b42611c4c565b73ffffffffffffffffffffffffffffffffffffffff1614611bcb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b6000600d5414611c43576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f5374617274696e6720696e64657820697320616c72656164792073657400000081525060200191505060405180910390fd5b43600c81905550565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060078054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015611d0e5780601f10611ce357610100808354040283529160200191611d0e565b820191906000526020600020905b815481529060010190602001808311611cf157829003601f168201915b5050505050905090565b611d2061296c565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611dc1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f4552433732313a20617070726f766520746f2063616c6c65720000000000000081525060200191505060405180910390fd5b8060056000611dce61296c565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16611e7b61296c565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405180821515815260200191505060405180910390a35050565b600f60009054906101000a900460ff16611f50576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f53616c65206d7573742062652061637469766520746f206d696e74204170650081525060200191505060405180910390fd5b6014811115611faa576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180613f746021913960400191505060405180910390fd5b600e54611fc782611fb9611390565b612e2a90919063ffffffff16565b111561201e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260288152602001806140426028913960400191505060405180910390fd5b3461203a8267011c37937e080000612eb290919063ffffffff16565b11156120ae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f45746865722076616c75652073656e74206973206e6f7420636f72726563740081525060200191505060405180910390fd5b60005b818110156120ef5760006120c3611390565b9050600e546120d0611390565b10156120e1576120e03382612f38565b5b5080806001019150506120b1565b506000600c541480156121175750600e54612108611390565b148061211657506010544210155b5b156121245743600c819055505b50565b61212f61296c565b73ffffffffffffffffffffffffffffffffffffffff1661214d611c4c565b73ffffffffffffffffffffffffffffffffffffffff16146121d6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b60006121e0611390565b905060005b601e811015612207576121fa33828401612f38565b80806001019150506121e5565b5050565b61221c61221661296c565b83612a5f565b612271576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260318152602001806141306031913960400191505060405180910390fd5b61227d84848484612f56565b50505050565b600e5481565b606061229482612974565b6122e9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602f8152602001806140e0602f913960400191505060405180910390fd5b6060600860008481526020019081526020016000208054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156123925780601f1061236757610100808354040283529160200191612392565b820191906000526020600020905b81548152906001019060200180831161237557829003601f168201915b5050505050905060606123a3611829565b90506000815114156123b9578192505050612555565b60008251111561248a5780826040516020018083805190602001908083835b602083106123fb57805182526020820191506020810190506020830392506123d8565b6001836020036101000a03801982511681845116808217855250505050505090500182805190602001908083835b6020831061244c5780518252602082019150602081019050602083039250612429565b6001836020036101000a0380198251168184511680821785525050505050509050019250505060405160208183030381529060405292505050612555565b8061249485612fc8565b6040516020018083805190602001908083835b602083106124ca57805182526020820191506020810190506020830392506124a7565b6001836020036101000a03801982511681845116808217855250505050505090500182805190602001908083835b6020831061251b57805182526020820191506020810190506020830392506124f8565b6001836020036101000a03801982511681845116808217855250505050505090500192505050604051602081830303815290604052925050505b919050565b600d5481565b600c5481565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6000600d5414612672576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f5374617274696e6720696e64657820697320616c72656164792073657400000081525060200191505060405180910390fd5b6000600c5414156126eb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f5374617274696e6720696e64657820626c6f636b206d7573742062652073657481525060200191505060405180910390fd5b600e54600c544060001c816126fc57fe5b06600d8190555060ff61271a600c544361310f90919063ffffffff16565b111561273a57600e54600143034060001c8161273257fe5b06600d819055505b6000600d5414156127625761275b6001600d54612e2a90919063ffffffff16565b600d819055505b565b600f60009054906101000a900460ff1681565b61277f61296c565b73ffffffffffffffffffffffffffffffffffffffff1661279d611c4c565b73ffffffffffffffffffffffffffffffffffffffff1614612826576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156128ac576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180613ed86026913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a380600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600033905090565b600061298a82600261319290919063ffffffff16565b9050919050565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16612a04836117f2565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000612a58826000016131ac565b9050919050565b6000612a6a82612974565b612abf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180613f48602c913960400191505060405180910390fd5b6000612aca836117f2565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480612b3957508373ffffffffffffffffffffffffffffffffffffffff16612b21846110e8565b73ffffffffffffffffffffffffffffffffffffffff16145b80612b4a5750612b498185612566565b5b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff16612b73826117f2565b73ffffffffffffffffffffffffffffffffffffffff1614612bdf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260298152602001806140b76029913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612c65576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526024815260200180613efe6024913960400191505060405180910390fd5b612c708383836131bd565b612c7b600082612991565b612ccc81600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206131c290919063ffffffff16565b50612d1e81600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206131dc90919063ffffffff16565b50612d35818360026131f69092919063ffffffff16565b50808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b6000612da5836000018361322b565b60001c905092915050565b600080600080612dc386600001866132ae565b915091508160001c8160001c9350935050509250929050565b8060099080519060200190612df2929190613de6565b5050565b6000612e09846000018460001b84613347565b60001c90509392505050565b6000612e238260000161343d565b9050919050565b600080828401905083811015612ea8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b600080831415612ec55760009050612f32565b6000828402905082848281612ed657fe5b0414612f2d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602181526020018061406a6021913960400191505060405180910390fd5b809150505b92915050565b612f5282826040518060200160405280600081525061344e565b5050565b612f61848484612b53565b612f6d848484846134bf565b612fc2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526032815260200180613ea66032913960400191505060405180910390fd5b50505050565b60606000821415613010576040518060400160405280600181526020017f3000000000000000000000000000000000000000000000000000000000000000815250905061310a565b600082905060005b6000821461303a578080600101915050600a828161303257fe5b049150613018565b60608167ffffffffffffffff8111801561305357600080fd5b506040519080825280601f01601f1916602001820160405280156130865781602001600182028036833780820191505090505b50905060006001830390508593505b6000841461310257600a84816130a757fe5b0660300160f81b828280600190039350815181106130c157fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a84816130fa57fe5b049350613095565b819450505050505b919050565b600082821115613187576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525060200191505060405180910390fd5b818303905092915050565b60006131a4836000018360001b6136d8565b905092915050565b600081600001805490509050919050565b505050565b60006131d4836000018360001b6136fb565b905092915050565b60006131ee836000018360001b6137e3565b905092915050565b6000613222846000018460001b8473ffffffffffffffffffffffffffffffffffffffff1660001b613853565b90509392505050565b60008183600001805490501161328c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180613e846022913960400191505060405180910390fd5b82600001828154811061329b57fe5b9060005260206000200154905092915050565b60008082846000018054905011613310576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806140206022913960400191505060405180910390fd5b600084600001848154811061332157fe5b906000526020600020906002020190508060000154816001015492509250509250929050565b6000808460010160008581526020019081526020016000205490506000811415839061340e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b838110156133d35780820151818401526020810190506133b8565b50505050905090810190601f1680156134005780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5084600001600182038154811061342157fe5b9060005260206000209060020201600101549150509392505050565b600081600001805490509050919050565b613458838361392f565b61346560008484846134bf565b6134ba576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526032815260200180613ea66032913960400191505060405180910390fd5b505050565b60006134e08473ffffffffffffffffffffffffffffffffffffffff16613b23565b6134ed57600190506136d0565b606061365763150b7a0260e01b61350261296c565b888787604051602401808573ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff16815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561358657808201518184015260208101905061356b565b50505050905090810190601f1680156135b35780820380516001836020036101000a031916815260200191505b5095505050505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051806060016040528060328152602001613ea6603291398773ffffffffffffffffffffffffffffffffffffffff16613b369092919063ffffffff16565b9050600081806020019051602081101561367057600080fd5b8101908080519060200190929190505050905063150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614925050505b949350505050565b600080836001016000848152602001908152602001600020541415905092915050565b600080836001016000848152602001908152602001600020549050600081146137d7576000600182039050600060018660000180549050039050600086600001828154811061374657fe5b906000526020600020015490508087600001848154811061376357fe5b906000526020600020018190555060018301876001016000838152602001908152602001600020819055508660000180548061379b57fe5b600190038181906000526020600020016000905590558660010160008781526020019081526020016000206000905560019450505050506137dd565b60009150505b92915050565b60006137ef8383613b4e565b61384857826000018290806001815401808255809150506001900390600052602060002001600090919091909150558260000180549050836001016000848152602001908152602001600020819055506001905061384d565b600090505b92915050565b60008084600101600085815260200190815260200160002054905060008114156138fa57846000016040518060400160405280868152602001858152509080600181540180825580915050600190039060005260206000209060020201600090919091909150600082015181600001556020820151816001015550508460000180549050856001016000868152602001908152602001600020819055506001915050613928565b8285600001600183038154811061390d57fe5b90600052602060002090600202016001018190555060009150505b9392505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156139d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4552433732313a206d696e7420746f20746865207a65726f206164647265737381525060200191505060405180910390fd5b6139db81612974565b15613a4e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601c8152602001807f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000081525060200191505060405180910390fd5b613a5a600083836131bd565b613aab81600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206131dc90919063ffffffff16565b50613ac2818360026131f69092919063ffffffff16565b50808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050565b600080823b905060008111915050919050565b6060613b458484600085613b71565b90509392505050565b600080836001016000848152602001908152602001600020541415905092915050565b606082471015613bcc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180613f226026913960400191505060405180910390fd5b613bd585613b23565b613c47576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000081525060200191505060405180910390fd5b600060608673ffffffffffffffffffffffffffffffffffffffff1685876040518082805190602001908083835b60208310613c975780518252602082019150602081019050602083039250613c74565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114613cf9576040519150601f19603f3d011682016040523d82523d6000602084013e613cfe565b606091505b5091509150613d0e828286613d1a565b92505050949350505050565b60608315613d2a57829050613ddf565b600083511115613d3d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613da4578082015181840152602081019050613d89565b50505050905090810190601f168015613dd15780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b9392505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10613e2757805160ff1916838001178555613e55565b82800160010185558215613e55579182015b82811115613e54578251825591602001919060010190613e39565b5b509050613e629190613e66565b5090565b5b80821115613e7f576000816000905550600101613e67565b509056fe456e756d657261626c655365743a20696e646578206f7574206f6620626f756e64734552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e7465724f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573734552433732313a207472616e7366657220746f20746865207a65726f2061646472657373416464726573733a20696e73756666696369656e742062616c616e636520666f722063616c6c4552433732313a206f70657261746f7220717565727920666f72206e6f6e6578697374656e7420746f6b656e43616e206f6e6c79206d696e7420323020746f6b656e7320617420612074696d654552433732313a20617070726f76652063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f76656420666f7220616c6c4552433732313a2062616c616e636520717565727920666f7220746865207a65726f20616464726573734552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656e456e756d657261626c654d61703a20696e646578206f7574206f6620626f756e6473507572636861736520776f756c6420657863656564206d617820737570706c79206f662041706573536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774552433732313a20617070726f76656420717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732313a207472616e73666572206f6620746f6b656e2074686174206973206e6f74206f776e4552433732314d657461646174613a2055524920717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732313a20617070726f76616c20746f2063757272656e74206f776e65724552433732313a207472616e736665722063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f766564a2646970667358221220b0e64d1fa6c4dbeb9c6f54607d7e1996943fe27624a80652f57b53fda084621b64736f6c63430007000033000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000002710000000000000000000000000000000000000000000000000000000006080e6d70000000000000000000000000000000000000000000000000000000000000011426f7265644170655961636874436c756200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044241594300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000010f2c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014426f72656420417065205761676d6920436c756200000000000000000000000000000000000000000000000000000000000000000000000000000000000000044241594300000000000000000000000000000000000000000000000000000000 + + Details: Insufficient funds for gas * price + value + Version: viem@2.29.2] + `) + + await disconnect(config, { connector }) +}) diff --git a/wagmi-project/packages/core/src/actions/deployContract.ts b/wagmi-project/packages/core/src/actions/deployContract.ts new file mode 100644 index 000000000..a688dd7cf --- /dev/null +++ b/wagmi-project/packages/core/src/actions/deployContract.ts @@ -0,0 +1,87 @@ +import type { Abi, Account, Chain, Client, ContractConstructorArgs } from 'viem' +import { + type DeployContractErrorType as viem_DeployContractErrorType, + type DeployContractParameters as viem_DeployContractParameters, + type DeployContractReturnType as viem_DeployContractReturnType, + deployContract as viem_deployContract, +} from 'viem/actions' +import type { Config } from '../createConfig.js' +import type { BaseErrorType, ErrorType } from '../errors/base.js' +import type { SelectChains } from '../types/chain.js' +import type { + ChainIdParameter, + ConnectorParameter, +} from '../types/properties.js' +import type { Compute } from '../types/utils.js' +import { getAction } from '../utils/getAction.js' +import { + type GetConnectorClientErrorType, + getConnectorClient, +} from './getConnectorClient.js' + +export type DeployContractParameters< + abi extends Abi | readonly unknown[] = Abi, + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + /// + allArgs = ContractConstructorArgs, + chains extends readonly Chain[] = SelectChains, +> = { + [key in keyof chains]: Compute< + Omit< + viem_DeployContractParameters< + abi, + chains[key], + Account, + chains[key], + allArgs + >, + 'chain' + > & + ChainIdParameter & + ConnectorParameter + > +}[number] + +export type DeployContractReturnType = viem_DeployContractReturnType + +export type DeployContractErrorType = + // getConnectorClient() + | GetConnectorClientErrorType + // base + | BaseErrorType + | ErrorType + // viem + | viem_DeployContractErrorType + +/** https://wagmi.sh/core/api/actions/deployContract */ +export async function deployContract< + config extends Config, + const abi extends Abi | readonly unknown[], + chainId extends config['chains'][number]['id'], +>( + config: config, + parameters: DeployContractParameters, +): Promise { + const { account, chainId, connector, ...rest } = parameters + + let client: Client + if (typeof account === 'object' && account?.type === 'local') + client = config.getClient({ chainId }) + else + client = await getConnectorClient(config, { + account: account ?? undefined, + chainId, + connector, + }) + + const action = getAction(client, viem_deployContract, 'deployContract') + const hash = await action({ + ...(rest as any), + ...(account ? { account } : {}), + chain: chainId ? { id: chainId } : null, + }) + + return hash +} diff --git a/wagmi-project/packages/core/src/actions/disconnect.test.ts b/wagmi-project/packages/core/src/actions/disconnect.test.ts new file mode 100644 index 000000000..03d63db7d --- /dev/null +++ b/wagmi-project/packages/core/src/actions/disconnect.test.ts @@ -0,0 +1,33 @@ +import { accounts, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { mock } from '../connectors/mock.js' +import { connect } from './connect.js' +import { disconnect } from './disconnect.js' + +const connector = config._internal.connectors.setup(mock({ accounts })) + +test('default', async () => { + await connect(config, { connector }) + expect(config.state.status).toEqual('connected') + await disconnect(config) + expect(config.state.status).toEqual('disconnected') +}) + +test('parameters: connector', async () => { + await connect(config, { connector }) + expect(config.state.status).toEqual('connected') + await disconnect(config, { connector }) + expect(config.state.status).toEqual('disconnected') +}) + +test('behavior: uses next connector on disconnect', async () => { + const connector_ = config._internal.connectors.setup(mock({ accounts })) + await connect(config, { connector: connector_ }) + await connect(config, { connector }) + + expect(config.state.status).toEqual('connected') + await disconnect(config, { connector }) + expect(config.state.status).toEqual('connected') + await disconnect(config, { connector: connector_ }) +}) diff --git a/wagmi-project/packages/core/src/actions/disconnect.ts b/wagmi-project/packages/core/src/actions/disconnect.ts new file mode 100644 index 000000000..6efb4c790 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/disconnect.ts @@ -0,0 +1,71 @@ +import type { Config, Connection, Connector } from '../createConfig.js' +import type { BaseErrorType, ErrorType } from '../errors/base.js' +import type { + ConnectorNotConnectedErrorType, + ConnectorNotFoundErrorType, +} from '../errors/config.js' +import type { ConnectorParameter } from '../types/properties.js' + +export type DisconnectParameters = ConnectorParameter + +export type DisconnectReturnType = void + +export type DisconnectErrorType = + | ConnectorNotFoundErrorType + | ConnectorNotConnectedErrorType + // base + | BaseErrorType + | ErrorType + +/** https://wagmi.sh/core/api/actions/disconnect */ +export async function disconnect( + config: Config, + parameters: DisconnectParameters = {}, +): Promise { + let connector: Connector | undefined + if (parameters.connector) connector = parameters.connector + else { + const { connections, current } = config.state + const connection = connections.get(current!) + connector = connection?.connector + } + + const connections = config.state.connections + + if (connector) { + await connector.disconnect() + connector.emitter.off('change', config._internal.events.change) + connector.emitter.off('disconnect', config._internal.events.disconnect) + connector.emitter.on('connect', config._internal.events.connect) + + connections.delete(connector.uid) + } + + config.setState((x) => { + // if no connections exist, move to disconnected state + if (connections.size === 0) + return { + ...x, + connections: new Map(), + current: null, + status: 'disconnected', + } + + // switch over to another connection + const nextConnection = connections.values().next().value as Connection + return { + ...x, + connections: new Map(connections), + current: nextConnection.connector.uid, + } + }) + + // Set recent connector if exists + { + const current = config.state.current + if (!current) return + const connector = config.state.connections.get(current)?.connector + if (!connector) return + await config.storage?.setItem('recentConnectorId', connector.id) + } +} diff --git a/wagmi-project/packages/core/src/actions/estimateFeesPerGas.test-d.ts b/wagmi-project/packages/core/src/actions/estimateFeesPerGas.test-d.ts new file mode 100644 index 000000000..dada2ea31 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/estimateFeesPerGas.test-d.ts @@ -0,0 +1,41 @@ +import { config } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' +import { estimateFeesPerGas } from './estimateFeesPerGas.js' + +test('types', async () => { + const default_ = await estimateFeesPerGas(config) + expectTypeOf(default_).toMatchTypeOf<{ + gasPrice?: undefined + maxFeePerGas: bigint + maxPriorityFeePerGas: bigint + formatted: { + gasPrice?: undefined + maxFeePerGas: string + maxPriorityFeePerGas: string + } + }>() + + const legacy = await estimateFeesPerGas(config, { type: 'legacy' }) + expectTypeOf(legacy).toMatchTypeOf<{ + gasPrice: bigint + maxFeePerGas?: undefined + maxPriorityFeePerGas?: undefined + formatted: { + gasPrice: string + maxFeePerGas?: undefined + maxPriorityFeePerGas?: undefined + } + }>() + + const eip1559 = await estimateFeesPerGas(config, { type: 'eip1559' }) + expectTypeOf(eip1559).toMatchTypeOf<{ + gasPrice?: undefined + maxFeePerGas: bigint + maxPriorityFeePerGas: bigint + formatted: { + gasPrice?: undefined + maxFeePerGas: string + maxPriorityFeePerGas: string + } + }>() +}) diff --git a/wagmi-project/packages/core/src/actions/estimateFeesPerGas.test.ts b/wagmi-project/packages/core/src/actions/estimateFeesPerGas.test.ts new file mode 100644 index 000000000..4c5d668b8 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/estimateFeesPerGas.test.ts @@ -0,0 +1,16 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { estimateFeesPerGas } from './estimateFeesPerGas.js' + +test('default', async () => { + const result = await estimateFeesPerGas(config) + expect(Object.keys(result)).toMatchInlineSnapshot(` + [ + "formatted", + "gasPrice", + "maxFeePerGas", + "maxPriorityFeePerGas", + ] + `) +}) diff --git a/wagmi-project/packages/core/src/actions/estimateFeesPerGas.ts b/wagmi-project/packages/core/src/actions/estimateFeesPerGas.ts new file mode 100644 index 000000000..66915f010 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/estimateFeesPerGas.ts @@ -0,0 +1,87 @@ +import { + type Chain, + type FeeValuesEIP1559, + type FeeValuesLegacy, + type FeeValuesType, + formatUnits, +} from 'viem' +import { + type EstimateFeesPerGasErrorType as viem_EstimateFeesPerGasErrorType, + type EstimateFeesPerGasParameters as viem_EstimateFeesPerGasParameters, + type EstimateFeesPerGasReturnType as viem_EstimateFeesPerGasReturnType, + estimateFeesPerGas as viem_estimateFeesPerGas, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { ChainIdParameter } from '../types/properties.js' +import type { Unit } from '../types/unit.js' +import type { Compute } from '../types/utils.js' +import type { UnionCompute, UnionLooseOmit } from '../types/utils.js' +import { getAction } from '../utils/getAction.js' +import { getUnit } from '../utils/getUnit.js' + +export type EstimateFeesPerGasParameters< + type extends FeeValuesType = FeeValuesType, + config extends Config = Config, +> = UnionCompute< + UnionLooseOmit< + viem_EstimateFeesPerGasParameters, + 'chain' + > & + ChainIdParameter & { + /** @deprecated */ + formatUnits?: Unit | undefined + } +> + +export type EstimateFeesPerGasReturnType< + type extends FeeValuesType = FeeValuesType, +> = Compute< + viem_EstimateFeesPerGasReturnType & { + /** @deprecated */ + formatted: UnionCompute< + | (type extends 'legacy' ? FeeValuesLegacy : never) + | (type extends 'eip1559' ? FeeValuesEIP1559 : never) + > + } +> + +export type EstimateFeesPerGasErrorType = viem_EstimateFeesPerGasErrorType + +export async function estimateFeesPerGas< + config extends Config, + type extends FeeValuesType = 'eip1559', +>( + config: config, + parameters: EstimateFeesPerGasParameters = {}, +): Promise> { + const { chainId, formatUnits: units = 'gwei', ...rest } = parameters + + const client = config.getClient({ chainId }) + const action = getAction( + client, + viem_estimateFeesPerGas, + 'estimateFeesPerGas', + ) + + const { gasPrice, maxFeePerGas, maxPriorityFeePerGas } = await action({ + ...rest, + chain: client.chain, + }) + + const unit = getUnit(units) + const formatted = { + gasPrice: gasPrice ? formatUnits(gasPrice, unit) : undefined, + maxFeePerGas: maxFeePerGas ? formatUnits(maxFeePerGas, unit) : undefined, + maxPriorityFeePerGas: maxPriorityFeePerGas + ? formatUnits(maxPriorityFeePerGas, unit) + : undefined, + } + + return { + formatted, + gasPrice, + maxFeePerGas, + maxPriorityFeePerGas, + } as EstimateFeesPerGasReturnType +} diff --git a/wagmi-project/packages/core/src/actions/estimateGas.test-d.ts b/wagmi-project/packages/core/src/actions/estimateGas.test-d.ts new file mode 100644 index 000000000..5fc66c0ec --- /dev/null +++ b/wagmi-project/packages/core/src/actions/estimateGas.test-d.ts @@ -0,0 +1,47 @@ +import { http, parseEther } from 'viem' +import { celo, mainnet } from 'viem/chains' +import { expectTypeOf, test } from 'vitest' + +import { createConfig } from '../createConfig.js' +import { type EstimateGasParameters, estimateGas } from './estimateGas.js' + +test('chain formatters', () => { + const config = createConfig({ + chains: [mainnet, celo], + transports: { [celo.id]: http(), [mainnet.id]: http() }, + }) + + type Result = EstimateGasParameters + expectTypeOf().toMatchTypeOf<{ + chainId?: typeof celo.id | typeof mainnet.id | undefined + feeCurrency?: `0x${string}` | undefined + }>() + estimateGas(config, { + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), + feeCurrency: '0x', + }) + + type Result2 = EstimateGasParameters + expectTypeOf().toMatchTypeOf<{ + feeCurrency?: `0x${string}` | undefined + }>() + estimateGas(config, { + chainId: celo.id, + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), + feeCurrency: '0x', + }) + + type Result3 = EstimateGasParameters + expectTypeOf().not.toMatchTypeOf<{ + feeCurrency?: `0x${string}` | undefined + }>() + estimateGas(config, { + chainId: mainnet.id, + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), + // @ts-expect-error + feeCurrency: '0x', + }) +}) diff --git a/wagmi-project/packages/core/src/actions/estimateGas.test.ts b/wagmi-project/packages/core/src/actions/estimateGas.test.ts new file mode 100644 index 000000000..f0154c55f --- /dev/null +++ b/wagmi-project/packages/core/src/actions/estimateGas.test.ts @@ -0,0 +1,47 @@ +import { accounts, config } from '@wagmi/test' +import { parseEther } from 'viem' +import { expect, test } from 'vitest' + +import { mock } from '../connectors/mock.js' +import { connect } from './connect.js' +import { disconnect } from './disconnect.js' +import { estimateGas } from './estimateGas.js' + +const connector = config._internal.connectors.setup(mock({ accounts })) + +test('parameters: account', async () => { + await expect( + estimateGas(config, { + account: accounts[0], + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), + }), + ).resolves.toMatchInlineSnapshot('21000n') +}) + +test('parameters: connector', async () => { + await connect(config, { connector }) + + await expect( + estimateGas(config, { + connector, + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), + }), + ).resolves.toMatchInlineSnapshot('21000n') + + await disconnect(config, { connector }) +}) + +test('behavior: no account and not connected', async () => { + await expect( + estimateGas(config, { + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), + }), + ).rejects.toThrowErrorMatchingInlineSnapshot(` + [ConnectorNotConnectedError: Connector not connected. + + Version: @wagmi/core@x.y.z] + `) +}) diff --git a/wagmi-project/packages/core/src/actions/estimateGas.ts b/wagmi-project/packages/core/src/actions/estimateGas.ts new file mode 100644 index 000000000..c049fa42f --- /dev/null +++ b/wagmi-project/packages/core/src/actions/estimateGas.ts @@ -0,0 +1,73 @@ +import type { Account, Address, Chain } from 'viem' +import { + type EstimateGasErrorType as viem_EstimateGasErrorType, + type EstimateGasParameters as viem_EstimateGasParameters, + type EstimateGasReturnType as viem_EstimateGasReturnType, + estimateGas as viem_estimateGas, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { BaseErrorType, ErrorType } from '../errors/base.js' +import type { SelectChains } from '../types/chain.js' +import type { + ChainIdParameter, + ConnectorParameter, +} from '../types/properties.js' +import type { UnionCompute, UnionLooseOmit } from '../types/utils.js' +import { getAction } from '../utils/getAction.js' +import { + type GetConnectorClientErrorType, + getConnectorClient, +} from './getConnectorClient.js' + +export type EstimateGasParameters< + config extends Config = Config, + chainId extends + | config['chains'][number]['id'] + | undefined = config['chains'][number]['id'], + /// + chains extends readonly Chain[] = SelectChains, +> = { + [key in keyof chains]: UnionCompute< + UnionLooseOmit, 'chain'> & + ChainIdParameter & + ConnectorParameter + > +}[number] + +export type EstimateGasReturnType = viem_EstimateGasReturnType + +export type EstimateGasErrorType = + // getConnectorClient() + | GetConnectorClientErrorType + // base + | BaseErrorType + | ErrorType + // viem + | viem_EstimateGasErrorType + +/** https://wagmi.sh/core/api/actions/estimateGas */ +export async function estimateGas< + config extends Config, + chainId extends config['chains'][number]['id'] | undefined = undefined, +>( + config: config, + parameters: EstimateGasParameters, +): Promise { + const { chainId, connector, ...rest } = parameters + + let account: Address | Account + if (parameters.account) account = parameters.account + else { + const connectorClient = await getConnectorClient(config, { + account: parameters.account, + chainId, + connector, + }) + account = connectorClient.account + } + + const client = config.getClient({ chainId }) + const action = getAction(client, viem_estimateGas, 'estimateGas') + return action({ ...(rest as viem_EstimateGasParameters), account }) +} diff --git a/wagmi-project/packages/core/src/actions/estimateMaxPriorityFeePerGas.test.ts b/wagmi-project/packages/core/src/actions/estimateMaxPriorityFeePerGas.test.ts new file mode 100644 index 000000000..deb969ebe --- /dev/null +++ b/wagmi-project/packages/core/src/actions/estimateMaxPriorityFeePerGas.test.ts @@ -0,0 +1,16 @@ +import { chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { estimateMaxPriorityFeePerGas } from './estimateMaxPriorityFeePerGas.js' + +test('default', async () => { + await expect(estimateMaxPriorityFeePerGas(config)).resolves.toBeDefined() +}) + +test('parameters: chainId', async () => { + await expect( + estimateMaxPriorityFeePerGas(config, { + chainId: chain.mainnet2.id, + }), + ).resolves.toBeDefined() +}) diff --git a/wagmi-project/packages/core/src/actions/estimateMaxPriorityFeePerGas.ts b/wagmi-project/packages/core/src/actions/estimateMaxPriorityFeePerGas.ts new file mode 100644 index 000000000..06378d84f --- /dev/null +++ b/wagmi-project/packages/core/src/actions/estimateMaxPriorityFeePerGas.ts @@ -0,0 +1,49 @@ +import type { Chain } from 'viem' +import { + type EstimateMaxPriorityFeePerGasErrorType as viem_EstimateMaxPriorityFeePerGasErrorType, + type EstimateMaxPriorityFeePerGasParameters as viem_EstimateMaxPriorityFeePerGasParameters, + type EstimateMaxPriorityFeePerGasReturnType as viem_EstimateMaxPriorityFeePerGasReturnType, + estimateMaxPriorityFeePerGas as viem_estimateMaxPriorityFeePerGas, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { ChainIdParameter } from '../types/properties.js' +import type { Compute, UnionLooseOmit } from '../types/utils.js' +import { getAction } from '../utils/getAction.js' + +export type EstimateMaxPriorityFeePerGasParameters< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +> = Compute< + UnionLooseOmit< + viem_EstimateMaxPriorityFeePerGasParameters & + ChainIdParameter, + 'chain' + > +> + +export type EstimateMaxPriorityFeePerGasReturnType = + viem_EstimateMaxPriorityFeePerGasReturnType + +export type EstimateMaxPriorityFeePerGasErrorType = + viem_EstimateMaxPriorityFeePerGasErrorType + +/** https://wagmi.sh/core/api/actions/estimateMaxPriorityFeePerGas */ +export async function estimateMaxPriorityFeePerGas< + config extends Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +>( + config: config, + parameters: EstimateMaxPriorityFeePerGasParameters = {}, +): Promise { + const { chainId } = parameters + const client = config.getClient({ chainId }) + const action = getAction( + client, + viem_estimateMaxPriorityFeePerGas, + 'estimateMaxPriorityFeePerGas', + ) + return action({ chain: client.chain }) +} diff --git a/wagmi-project/packages/core/src/actions/getAccount.test-d.ts b/wagmi-project/packages/core/src/actions/getAccount.test-d.ts new file mode 100644 index 000000000..728468039 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getAccount.test-d.ts @@ -0,0 +1,69 @@ +import { config } from '@wagmi/test' +import type { Address } from 'viem' +import { expectTypeOf, test } from 'vitest' + +import type { Connector } from '../createConfig.js' +import { getAccount } from './getAccount.js' + +test('states', () => { + const result = getAccount(config) + + switch (result.status) { + case 'reconnecting': { + expectTypeOf(result).toMatchTypeOf<{ + address: Address | undefined + chain: (typeof config)['chains'][number] | undefined + chainId: number | undefined + connector: Connector | undefined + isConnected: boolean + isConnecting: false + isDisconnected: false + isReconnecting: true + status: 'reconnecting' + }>() + break + } + case 'connecting': { + expectTypeOf(result).toMatchTypeOf<{ + address: Address | undefined + chain: (typeof config)['chains'][number] | undefined + chainId: number | undefined + connector: Connector | undefined + isConnected: false + isReconnecting: false + isConnecting: true + isDisconnected: false + status: 'connecting' + }>() + break + } + case 'connected': { + expectTypeOf(result).toMatchTypeOf<{ + address: Address + chain: (typeof config)['chains'][number] | undefined + chainId: number + connector: Connector + isConnected: true + isConnecting: false + isDisconnected: false + isReconnecting: false + status: 'connected' + }>() + break + } + case 'disconnected': { + expectTypeOf(result).toMatchTypeOf<{ + address: undefined + chain: undefined + chainId: undefined + connector: undefined + isConnected: false + isReconnecting: false + isConnecting: false + isDisconnected: true + status: 'disconnected' + }>() + break + } + } +}) diff --git a/wagmi-project/packages/core/src/actions/getAccount.test.ts b/wagmi-project/packages/core/src/actions/getAccount.test.ts new file mode 100644 index 000000000..a53835787 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getAccount.test.ts @@ -0,0 +1,37 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { connect } from './connect.js' +import { disconnect } from './disconnect.js' +import { getAccount } from './getAccount.js' + +test('default', () => { + expect(getAccount(config)).toMatchInlineSnapshot(` + { + "address": undefined, + "addresses": undefined, + "chain": undefined, + "chainId": undefined, + "connector": undefined, + "isConnected": false, + "isConnecting": false, + "isDisconnected": true, + "isReconnecting": false, + "status": "disconnected", + } + `) +}) + +test('behavior: connected', async () => { + let result = getAccount(config) + expect(result.status).toEqual('disconnected') + + await connect(config, { connector: config.connectors[0]! }) + result = getAccount(config) + expect(result.address).toBeDefined() + expect(result.status).toEqual('connected') + + await disconnect(config) + result = getAccount(config) + expect(result.status).toEqual('disconnected') +}) diff --git a/wagmi-project/packages/core/src/actions/getAccount.ts b/wagmi-project/packages/core/src/actions/getAccount.ts new file mode 100644 index 000000000..af5daea02 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getAccount.ts @@ -0,0 +1,126 @@ +import type { Address, Chain } from 'viem' + +import type { Config, Connector } from '../createConfig.js' + +export type GetAccountReturnType< + config extends Config = Config, + /// + chain = Config extends config ? Chain : config['chains'][number], +> = + | { + address: Address + addresses: readonly [Address, ...Address[]] + chain: chain | undefined + chainId: number + connector: Connector + isConnected: true + isConnecting: false + isDisconnected: false + isReconnecting: false + status: 'connected' + } + | { + address: Address | undefined + addresses: readonly Address[] | undefined + chain: chain | undefined + chainId: number | undefined + connector: Connector | undefined + isConnected: boolean + isConnecting: false + isDisconnected: false + isReconnecting: true + status: 'reconnecting' + } + | { + address: Address | undefined + addresses: readonly Address[] | undefined + chain: chain | undefined + chainId: number | undefined + connector: Connector | undefined + isConnected: false + isReconnecting: false + isConnecting: true + isDisconnected: false + status: 'connecting' + } + | { + address: undefined + addresses: undefined + chain: undefined + chainId: undefined + connector: undefined + isConnected: false + isReconnecting: false + isConnecting: false + isDisconnected: true + status: 'disconnected' + } + +/** https://wagmi.sh/core/api/actions/getAccount */ +export function getAccount( + config: config, +): GetAccountReturnType { + const uid = config.state.current! + const connection = config.state.connections.get(uid) + const addresses = connection?.accounts + const address = addresses?.[0] + const chain = config.chains.find( + (chain) => chain.id === connection?.chainId, + ) as GetAccountReturnType['chain'] + const status = config.state.status + + switch (status) { + case 'connected': + return { + address: address!, + addresses: addresses!, + chain, + chainId: connection?.chainId!, + connector: connection?.connector!, + isConnected: true, + isConnecting: false, + isDisconnected: false, + isReconnecting: false, + status, + } + case 'reconnecting': + return { + address, + addresses, + chain, + chainId: connection?.chainId, + connector: connection?.connector, + isConnected: !!address, + isConnecting: false, + isDisconnected: false, + isReconnecting: true, + status, + } + case 'connecting': + return { + address, + addresses, + chain, + chainId: connection?.chainId, + connector: connection?.connector, + isConnected: false, + isConnecting: true, + isDisconnected: false, + isReconnecting: false, + status, + } + case 'disconnected': + return { + address: undefined, + addresses: undefined, + chain: undefined, + chainId: undefined, + connector: undefined, + isConnected: false, + isConnecting: false, + isDisconnected: true, + isReconnecting: false, + status, + } + } +} diff --git a/wagmi-project/packages/core/src/actions/getBalance.test.ts b/wagmi-project/packages/core/src/actions/getBalance.test.ts new file mode 100644 index 000000000..954c09c2e --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getBalance.test.ts @@ -0,0 +1,102 @@ +import { accounts, chain, config, testClient } from '@wagmi/test' +import { parseEther } from 'viem' +import { beforeEach, expect, test } from 'vitest' + +import { getBalance } from './getBalance.js' + +const address = accounts[0] + +beforeEach(async () => { + await testClient.mainnet.setBalance({ + address, + value: parseEther('10000'), + }) + await testClient.mainnet.mine({ blocks: 1 }) + await testClient.mainnet2.setBalance({ + address, + value: parseEther('420'), + }) + await testClient.mainnet2.mine({ blocks: 1 }) +}) + +test('default', async () => { + await expect(getBalance(config, { address })).resolves.toMatchInlineSnapshot(` + { + "decimals": 18, + "formatted": "10000", + "symbol": "ETH", + "value": 10000000000000000000000n, + } + `) + + await testClient.mainnet.setBalance({ + address, + value: parseEther('6969.12222215666'), + }) + await expect(getBalance(config, { address })).resolves.toMatchInlineSnapshot(` + { + "decimals": 18, + "formatted": "6969.12222215666", + "symbol": "ETH", + "value": 6969122222156660000000n, + } + `) +}) + +test('parameters: chainId', async () => { + await expect( + getBalance(config, { address, chainId: chain.mainnet2.id }), + ).resolves.toMatchInlineSnapshot(` + { + "decimals": 18, + "formatted": "420", + "symbol": "WAG", + "value": 420000000000000000000n, + } + `) +}) + +test('parameters: token', async () => { + await expect( + getBalance(config, { + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', + token: '0x6B175474E89094C44Da98b954EedeAC495271d0F', + }), + ).resolves.toMatchInlineSnapshot(` + { + "decimals": 18, + "formatted": "0.559062564299199392", + "symbol": "DAI", + "value": 559062564299199392n, + } + `) +}) + +test('parameters: token (bytes32 symbol)', async () => { + await expect( + getBalance(config, { + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', + token: '0x9f8f72aa9304c8b593d555f12ef6589cc3a579a2', + }), + ).resolves.toMatchInlineSnapshot(` + { + "decimals": 18, + "formatted": "0", + "symbol": "MKR", + "value": 0n, + } + `) +}) + +test('parameters: unit', async () => { + await expect( + getBalance(config, { address, unit: 'wei' }), + ).resolves.toMatchInlineSnapshot(` + { + "decimals": 18, + "formatted": "10000000000000000000000", + "symbol": "ETH", + "value": 10000000000000000000000n, + } + `) +}) diff --git a/wagmi-project/packages/core/src/actions/getBalance.ts b/wagmi-project/packages/core/src/actions/getBalance.ts new file mode 100644 index 000000000..1aae5667b --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getBalance.ts @@ -0,0 +1,149 @@ +import { type Address, type Hex, formatUnits, hexToString, trim } from 'viem' +import { + type GetBalanceErrorType as viem_GetBalanceErrorType, + type GetBalanceParameters as viem_GetBalanceParameters, + getBalance as viem_getBalance, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { ChainIdParameter } from '../types/properties.js' +import type { Unit } from '../types/unit.js' +import type { Compute } from '../types/utils.js' +import { getAction } from '../utils/getAction.js' +import { getUnit } from '../utils/getUnit.js' +import { type ReadContractsErrorType, readContracts } from './readContracts.js' + +export type GetBalanceParameters = Compute< + ChainIdParameter & + viem_GetBalanceParameters & { + /** @deprecated */ + token?: Address | undefined + /** @deprecated */ + unit?: Unit | undefined + } +> + +export type GetBalanceReturnType = { + decimals: number + /** @deprecated */ + formatted: string + symbol: string + value: bigint +} + +export type GetBalanceErrorType = viem_GetBalanceErrorType + +/** https://wagmi.sh/core/api/actions/getBalance */ +export async function getBalance( + config: config, + parameters: GetBalanceParameters, +): Promise { + const { + address, + blockNumber, + blockTag, + chainId, + token: tokenAddress, + unit = 'ether', + } = parameters + + if (tokenAddress) { + try { + return await getTokenBalance(config, { + balanceAddress: address, + chainId, + symbolType: 'string', + tokenAddress, + }) + } catch (error) { + // In the chance that there is an error upon decoding the contract result, + // it could be likely that the contract data is represented as bytes32 instead + // of a string. + if ( + (error as ReadContractsErrorType).name === + 'ContractFunctionExecutionError' + ) { + const balance = await getTokenBalance(config, { + balanceAddress: address, + chainId, + symbolType: 'bytes32', + tokenAddress, + }) + const symbol = hexToString( + trim(balance.symbol as Hex, { dir: 'right' }), + ) + return { ...balance, symbol } + } + throw error + } + } + + const client = config.getClient({ chainId }) + const action = getAction(client, viem_getBalance, 'getBalance') + const value = await action( + blockNumber ? { address, blockNumber } : { address, blockTag }, + ) + const chain = config.chains.find((x) => x.id === chainId) ?? client.chain! + return { + decimals: chain.nativeCurrency.decimals, + formatted: formatUnits(value, getUnit(unit)), + symbol: chain.nativeCurrency.symbol, + value, + } +} + +type GetTokenBalanceParameters = { + balanceAddress: Address + chainId?: number | undefined + symbolType: 'bytes32' | 'string' + tokenAddress: Address + unit?: Unit | undefined +} + +async function getTokenBalance( + config: Config, + parameters: GetTokenBalanceParameters, +) { + const { balanceAddress, chainId, symbolType, tokenAddress, unit } = parameters + const contract = { + abi: [ + { + type: 'function', + name: 'balanceOf', + stateMutability: 'view', + inputs: [{ type: 'address' }], + outputs: [{ type: 'uint256' }], + }, + { + type: 'function', + name: 'decimals', + stateMutability: 'view', + inputs: [], + outputs: [{ type: 'uint8' }], + }, + { + type: 'function', + name: 'symbol', + stateMutability: 'view', + inputs: [], + outputs: [{ type: symbolType }], + }, + ], + address: tokenAddress, + } as const + const [value, decimals, symbol] = await readContracts(config, { + allowFailure: false, + contracts: [ + { + ...contract, + functionName: 'balanceOf', + args: [balanceAddress], + chainId, + }, + { ...contract, functionName: 'decimals', chainId }, + { ...contract, functionName: 'symbol', chainId }, + ] as const, + }) + const formatted = formatUnits(value ?? '0', getUnit(unit ?? decimals)) + return { decimals, formatted, symbol, value } +} diff --git a/wagmi-project/packages/core/src/actions/getBlock.test-d.ts b/wagmi-project/packages/core/src/actions/getBlock.test-d.ts new file mode 100644 index 000000000..2344c5026 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getBlock.test-d.ts @@ -0,0 +1,35 @@ +import { http, type Hex } from 'viem' +import { celo, mainnet } from 'viem/chains' +import { expectTypeOf, test } from 'vitest' + +import { createConfig } from '../createConfig.js' +import { getBlock } from './getBlock.js' + +test('chain formatters', async () => { + const config = createConfig({ + chains: [celo, mainnet], + transports: { [celo.id]: http(), [mainnet.id]: http() }, + }) + const result = await getBlock(config) + if (result.chainId === celo.id) { + expectTypeOf(result.difficulty).toEqualTypeOf() + expectTypeOf(result.gasLimit).toEqualTypeOf() + expectTypeOf(result.mixHash).toEqualTypeOf() + expectTypeOf(result.nonce).toEqualTypeOf<`0x${string}`>() + expectTypeOf(result.uncles).toEqualTypeOf() + } +}) + +test('chainId', async () => { + const config = createConfig({ + chains: [celo, mainnet], + transports: { [celo.id]: http(), [mainnet.id]: http() }, + }) + const result = await getBlock(config, { + chainId: celo.id, + }) + expectTypeOf(result.difficulty).toEqualTypeOf() + expectTypeOf(result.gasLimit).toEqualTypeOf() + expectTypeOf(result.mixHash).toEqualTypeOf() + expectTypeOf(result.nonce).toEqualTypeOf<`0x${string}`>() +}) diff --git a/wagmi-project/packages/core/src/actions/getBlock.test.ts b/wagmi-project/packages/core/src/actions/getBlock.test.ts new file mode 100644 index 000000000..b1e92ba36 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getBlock.test.ts @@ -0,0 +1,153 @@ +import { config, mainnet } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getBlock } from './getBlock.js' + +test('default', async () => { + await expect(getBlock(config)).resolves.toBeDefined() +}) + +test('args: blockNumber', async () => { + const { transactions, ...block } = await getBlock(config, { + blockNumber: mainnet.fork.blockNumber, + }) + expect(transactions).toMatchObject( + expect.arrayContaining([expect.any(String)]), + ) + expect(block).toMatchInlineSnapshot(` + { + "baseFeePerGas": 24076814055n, + "blobGasUsed": undefined, + "chainId": 1, + "difficulty": 0n, + "excessBlobGas": undefined, + "extraData": "0x546974616e2028746974616e6275696c6465722e78797a29", + "gasLimit": 30000000n, + "gasUsed": 26325393n, + "hash": "0xcfa5df46abf1521f68ae72a7f7c4661949f4fb08a3d1296fe8082f6580a414e0", + "logsBloom": "0x2df3b5a24d2d57e7d73f96dbfea3577b1d5fbaacfcb9b5fb86db74d2e4ffd1e48bba050c33edada84fe477213937158c1e95d3da9f457f6f36e3ff0afdffcb667c5ee5f9e3ddffa9db1af6bbf15fcbbca5139717d5eedab4daa63cd8bb7dfa3e976b1e7023e2dc4586cef3caa0b73d6ff2ba3afb989c9f58f6b67bb4ed596c5aeb78cef51f69ad3675df70ffbd2aa6576d7c9e3debd00cccec3b69fc617b8568bfe588f7e126ef591f34ddd0d8b68c28b7ed45b46af3a7bb75c0e2fe4bec54fb772c87ae6f7efcdfb13139b758cfda4d98dffe426fef6d1c2e55f36b5bb1f0a2aef7bcbdf83d31ea646cf6ef3fe9d8b9af2ad4197f7ea2de462bd029fdef7e6f", + "miner": "0x4838b106fce9647bdf1e7877bf73ce8b0bad5f97", + "mixHash": "0x92ac9cd6e57bacd7c7d3e9b087c3907b1c085e284eec2dce7379a847cb4c9940", + "nonce": "0x0000000000000000", + "number": 19258213n, + "parentHash": "0x40cb7885ad596d0397d664a4dc9ef5c2011c09e9a62b386f838f5f5362582ebb", + "receiptsRoot": "0x910a69ba396ab4f59c2c77aa413e941fc4da97a021b8d8bbf12c125bfc42d9d3", + "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "size": 158252n, + "stateRoot": "0x6e27207d219b0251dbc2fde71f3cde8e33703261f032056453c27275500dddbc", + "timestamp": 1708302299n, + "totalDifficulty": null, + "transactionsRoot": "0x897dba26a3a940b62f86da6e5fec5f71312ad7c871a4031db79dee67442c9d1e", + "uncles": [], + "withdrawals": [ + { + "address": "0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f", + "amount": "0x112da72", + "index": "0x21ec946", + "validatorIndex": "0x5cd8e", + }, + { + "address": "0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f", + "amount": "0x1119345", + "index": "0x21ec947", + "validatorIndex": "0x5cd8f", + }, + { + "address": "0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f", + "amount": "0x110e2ca", + "index": "0x21ec948", + "validatorIndex": "0x5cd90", + }, + { + "address": "0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f", + "amount": "0x1119245", + "index": "0x21ec949", + "validatorIndex": "0x5cd91", + }, + { + "address": "0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f", + "amount": "0x1115a03", + "index": "0x21ec94a", + "validatorIndex": "0x5cd92", + }, + { + "address": "0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f", + "amount": "0x111cf3f", + "index": "0x21ec94b", + "validatorIndex": "0x5cd93", + }, + { + "address": "0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f", + "amount": "0x1106006", + "index": "0x21ec94c", + "validatorIndex": "0x5cd94", + }, + { + "address": "0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f", + "amount": "0x1115bb3", + "index": "0x21ec94d", + "validatorIndex": "0x5cd95", + }, + { + "address": "0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f", + "amount": "0x111e0d9", + "index": "0x21ec94e", + "validatorIndex": "0x5cd96", + }, + { + "address": "0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f", + "amount": "0x110829f", + "index": "0x21ec94f", + "validatorIndex": "0x5cd97", + }, + { + "address": "0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f", + "amount": "0x11029ab", + "index": "0x21ec950", + "validatorIndex": "0x5cd98", + }, + { + "address": "0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f", + "amount": "0x11140a6", + "index": "0x21ec951", + "validatorIndex": "0x5cd99", + }, + { + "address": "0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f", + "amount": "0x111396c", + "index": "0x21ec952", + "validatorIndex": "0x5cd9a", + }, + { + "address": "0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f", + "amount": "0x110de16", + "index": "0x21ec953", + "validatorIndex": "0x5cd9b", + }, + { + "address": "0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f", + "amount": "0x1121062", + "index": "0x21ec954", + "validatorIndex": "0x5cd9c", + }, + { + "address": "0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f", + "amount": "0x11188bc", + "index": "0x21ec955", + "validatorIndex": "0x5cd9d", + }, + ], + "withdrawalsRoot": "0x26638497bd55075025ac2362d92bd789ac1232fd50c4b3866565280318027950", + } + `) +}) + +test('args: includeTransactions', async () => { + const { transactions } = await getBlock(config, { + includeTransactions: true, + blockNumber: mainnet.fork.blockNumber, + }) + expect(transactions).toMatchObject( + expect.arrayContaining([expect.any(Object)]), + ) +}) diff --git a/wagmi-project/packages/core/src/actions/getBlock.ts b/wagmi-project/packages/core/src/actions/getBlock.ts new file mode 100644 index 000000000..babb52cd4 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getBlock.ts @@ -0,0 +1,74 @@ +import type { BlockTag, Chain } from 'viem' +import { + type GetBlockErrorType as viem_GetBlockErrorType, + type GetBlockParameters as viem_GetBlockParameters, + type GetBlockReturnType as viem_GetBlockReturnType, + getBlock as viem_getBlock, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { SelectChains } from '../types/chain.js' +import type { ChainIdParameter } from '../types/properties.js' +import type { Compute, IsNarrowable } from '../types/utils.js' +import { getAction } from '../utils/getAction.js' + +export type GetBlockParameters< + includeTransactions extends boolean = false, + blockTag extends BlockTag = 'latest', + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +> = Compute< + viem_GetBlockParameters & + ChainIdParameter +> + +export type GetBlockReturnType< + includeTransactions extends boolean = false, + blockTag extends BlockTag = 'latest', + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + /// + chains extends readonly Chain[] = SelectChains, +> = Compute< + { + [key in keyof chains]: viem_GetBlockReturnType< + IsNarrowable extends true ? chains[key] : undefined, + includeTransactions, + blockTag + > & { chainId: chains[key]['id'] } + }[number] +> + +export type GetBlockErrorType = viem_GetBlockErrorType + +/** https://wagmi.sh/core/actions/getBlock */ +export async function getBlock< + config extends Config, + chainId extends config['chains'][number]['id'], + includeTransactions extends boolean = false, + blockTag extends BlockTag = 'latest', +>( + config: config, + parameters: GetBlockParameters< + includeTransactions, + blockTag, + config, + chainId + > = {}, +): Promise> { + const { chainId, ...rest } = parameters + const client = config.getClient({ chainId }) + const action = getAction(client, viem_getBlock, 'getBlock') + const block = await action(rest) + return { + ...(block as unknown as GetBlockReturnType< + includeTransactions, + blockTag, + config, + chainId + >), + chainId: client.chain.id, + } +} diff --git a/wagmi-project/packages/core/src/actions/getBlockNumber.test.ts b/wagmi-project/packages/core/src/actions/getBlockNumber.test.ts new file mode 100644 index 000000000..7e18744e1 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getBlockNumber.test.ts @@ -0,0 +1,8 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getBlockNumber } from './getBlockNumber.js' + +test('default', async () => { + await expect(getBlockNumber(config)).resolves.toBeDefined() +}) diff --git a/wagmi-project/packages/core/src/actions/getBlockNumber.ts b/wagmi-project/packages/core/src/actions/getBlockNumber.ts new file mode 100644 index 000000000..ecad7c0f6 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getBlockNumber.ts @@ -0,0 +1,36 @@ +import { + type GetBlockNumberErrorType as viem_GetBlockNumberErrorType, + type GetBlockNumberParameters as viem_GetBlockNumberParameters, + type GetBlockNumberReturnType as viem_GetBlockNumberReturnType, + getBlockNumber as viem_getBlockNumber, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { ChainIdParameter } from '../types/properties.js' +import type { Compute } from '../types/utils.js' +import { getAction } from '../utils/getAction.js' + +export type GetBlockNumberParameters< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +> = Compute> + +export type GetBlockNumberReturnType = viem_GetBlockNumberReturnType + +export type GetBlockNumberErrorType = viem_GetBlockNumberErrorType + +/** https://wagmi.sh/core/api/actions/getBlockNumber */ +export function getBlockNumber< + config extends Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +>( + config: config, + parameters: GetBlockNumberParameters = {}, +): Promise { + const { chainId, ...rest } = parameters + const client = config.getClient({ chainId }) + const action = getAction(client, viem_getBlockNumber, 'getBlockNumber') + return action(rest) +} diff --git a/wagmi-project/packages/core/src/actions/getBlockTransactionCount.test.ts b/wagmi-project/packages/core/src/actions/getBlockTransactionCount.test.ts new file mode 100644 index 000000000..d8a593aa0 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getBlockTransactionCount.test.ts @@ -0,0 +1,61 @@ +import { chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getBlockTransactionCount } from './getBlockTransactionCount.js' + +test('default', async () => { + await expect(getBlockTransactionCount(config)).resolves.toBeTypeOf('number') +}) + +test('parameters: chainId', async () => { + await expect( + getBlockTransactionCount(config, { chainId: chain.mainnet2.id }), + ).resolves.toBeTypeOf('number') +}) + +test('parameters: blockNumber', async () => { + await expect( + getBlockTransactionCount(config, { blockNumber: 13677382n }), + ).resolves.toBeTypeOf('number') +}) + +test('parameters: blockHash', async () => { + await expect( + getBlockTransactionCount(config, { + blockHash: + '0x6201f37a245850d1f11e4be3ac45bc51bd9d43ee4a127192cad550f351cfa575', + }), + ).resolves.toBeTypeOf('number') +}) + +test('parameters: blockTag', async () => { + await expect( + getBlockTransactionCount(config, { + blockTag: 'earliest', + }), + ).resolves.toBeTypeOf('number') + + await expect( + getBlockTransactionCount(config, { + blockTag: 'finalized', + }), + ).resolves.toBeTypeOf('number') + + await expect( + getBlockTransactionCount(config, { + blockTag: 'latest', + }), + ).resolves.toBeTypeOf('number') + + await expect( + getBlockTransactionCount(config, { + blockTag: 'pending', + }), + ).resolves.toBeTypeOf('number') + + await expect( + getBlockTransactionCount(config, { + blockTag: 'safe', + }), + ).resolves.toBeTypeOf('number') +}) diff --git a/wagmi-project/packages/core/src/actions/getBlockTransactionCount.ts b/wagmi-project/packages/core/src/actions/getBlockTransactionCount.ts new file mode 100644 index 000000000..e30aca976 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getBlockTransactionCount.ts @@ -0,0 +1,44 @@ +import { + type GetBlockTransactionCountErrorType as viem_GetBlockTransactionCountErrorType, + type GetBlockTransactionCountParameters as viem_GetBlockTransactionCountParameters, + type GetBlockTransactionCountReturnType as viem_GetBlockTransactionCountReturnType, + getBlockTransactionCount as viem_getBlockTransactionCount, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { ChainIdParameter } from '../types/properties.js' +import type { UnionCompute } from '../types/utils.js' +import { getAction } from '../utils/getAction.js' + +export type GetBlockTransactionCountParameters< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +> = UnionCompute< + viem_GetBlockTransactionCountParameters & ChainIdParameter +> + +export type GetBlockTransactionCountReturnType = + viem_GetBlockTransactionCountReturnType + +export type GetBlockTransactionCountErrorType = + viem_GetBlockTransactionCountErrorType + +/** https://wagmi.sh/core/api/actions/getBlockTransactionCount */ +export function getBlockTransactionCount< + config extends Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +>( + config: config, + parameters: GetBlockTransactionCountParameters = {}, +): Promise { + const { chainId, ...rest } = parameters + const client = config.getClient({ chainId }) + const action = getAction( + client, + viem_getBlockTransactionCount, + 'getBlockTransactionCount', + ) + return action(rest) +} diff --git a/wagmi-project/packages/core/src/actions/getBytecode.test.ts b/wagmi-project/packages/core/src/actions/getBytecode.test.ts new file mode 100644 index 000000000..1d5b6bdff --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getBytecode.test.ts @@ -0,0 +1,45 @@ +import { address, chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getBytecode } from './getBytecode.js' + +test('default', async () => { + await expect( + getBytecode(config, { + address: '0x0000000000000000000000000000000000000000', + }), + ).resolves.toBe(undefined) + + await expect( + getBytecode(config, { + address: address.wagmiMintExample, + }), + ).resolves.toMatch(/^0x.*/) +}) + +test('parameters: blockNumber', async () => { + await expect( + getBytecode(config, { + address: address.wagmiMintExample, + blockNumber: 15564163n, + }), + ).resolves.toBe(undefined) +}) + +test('parameters: blockTag', async () => { + await expect( + getBytecode(config, { + address: address.wagmiMintExample, + blockTag: 'earliest', + }), + ).resolves.toBe(undefined) +}) + +test('parameters: chainId', async () => { + await expect( + getBytecode(config, { + address: address.wagmiMintExample, + chainId: chain.optimism.id, + }), + ).resolves.toBe(undefined) +}) diff --git a/wagmi-project/packages/core/src/actions/getBytecode.ts b/wagmi-project/packages/core/src/actions/getBytecode.ts new file mode 100644 index 000000000..2ece822a8 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getBytecode.ts @@ -0,0 +1,30 @@ +import { + type GetBytecodeErrorType as viem_GetBytecodeErrorType, + type GetBytecodeParameters as viem_GetBytecodeParameters, + type GetBytecodeReturnType as viem_GetBytecodeReturnType, + getBytecode as viem_getBytecode, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { ChainIdParameter } from '../types/properties.js' +import type { Compute } from '../types/utils.js' +import { getAction } from '../utils/getAction.js' + +export type GetBytecodeParameters = Compute< + viem_GetBytecodeParameters & ChainIdParameter +> + +export type GetBytecodeReturnType = viem_GetBytecodeReturnType + +export type GetBytecodeErrorType = viem_GetBytecodeErrorType + +/** https://wagmi.sh/core/api/actions/getBytecode */ +export async function getBytecode( + config: config, + parameters: GetBytecodeParameters, +): Promise { + const { chainId, ...rest } = parameters + const client = config.getClient({ chainId }) + const action = getAction(client, viem_getBytecode, 'getBytecode') + return action(rest) +} diff --git a/wagmi-project/packages/core/src/actions/getCallsStatus.test.ts b/wagmi-project/packages/core/src/actions/getCallsStatus.test.ts new file mode 100644 index 000000000..72978a3c7 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getCallsStatus.test.ts @@ -0,0 +1,70 @@ +import { accounts, config, testClient } from '@wagmi/test' +import { parseEther } from 'viem' +import { expect, test } from 'vitest' + +import { connect } from './connect.js' +import { disconnect } from './disconnect.js' +import { getCallsStatus } from './getCallsStatus.js' +import { sendCalls } from './sendCalls.js' + +const connector = config.connectors[0]! + +test('default', async () => { + await connect(config, { connector }) + const { id } = await sendCalls(config, { + calls: [ + { + data: '0xdeadbeef', + to: accounts[1], + value: parseEther('1'), + }, + { + to: accounts[2], + value: parseEther('2'), + }, + { + to: accounts[3], + value: parseEther('3'), + }, + ], + }) + await testClient.mainnet.mine({ blocks: 1 }) + const { receipts, status } = await getCallsStatus(config, { + id, + }) + + expect(status).toBe('success') + expect( + receipts?.map((x) => ({ ...x, blockHash: undefined })), + ).toMatchInlineSnapshot( + ` + [ + { + "blockHash": undefined, + "blockNumber": 19258214n, + "gasUsed": 21064n, + "logs": [], + "status": "success", + "transactionHash": "0x13c53b2d4d9da424835525349cd66e553330f323d6fb19458b801ae1f7989a41", + }, + { + "blockHash": undefined, + "blockNumber": 19258214n, + "gasUsed": 21000n, + "logs": [], + "status": "success", + "transactionHash": "0xd8397b3e82b061c26a0c2093f1ceca0c3662a512614f7d6370349e89d0eea007", + }, + { + "blockHash": undefined, + "blockNumber": 19258214n, + "gasUsed": 21000n, + "logs": [], + "status": "success", + "transactionHash": "0x4d26e346593d9ea265bb164b115e89aa92df43b0b8778ac75d4ad28e2a22b101", + }, + ] + `, + ) + await disconnect(config, { connector }) +}) diff --git a/wagmi-project/packages/core/src/actions/getCallsStatus.ts b/wagmi-project/packages/core/src/actions/getCallsStatus.ts new file mode 100644 index 000000000..85f7a592c --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getCallsStatus.ts @@ -0,0 +1,27 @@ +import { + type GetCallsStatusErrorType as viem_GetCallsStatusErrorType, + type GetCallsStatusParameters as viem_GetCallsStatusParameters, + type GetCallsStatusReturnType as viem_GetCallsStatusReturnType, + getCallsStatus as viem_getCallsStatus, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { ConnectorParameter } from '../types/properties.js' +import { getConnectorClient } from './getConnectorClient.js' + +export type GetCallsStatusParameters = viem_GetCallsStatusParameters & + ConnectorParameter + +export type GetCallsStatusReturnType = viem_GetCallsStatusReturnType + +export type GetCallsStatusErrorType = viem_GetCallsStatusErrorType + +/** https://wagmi.sh/core/api/actions/getCallsStatus */ +export async function getCallsStatus( + config: config, + parameters: GetCallsStatusParameters, +): Promise { + const { connector, id } = parameters + const client = await getConnectorClient(config, { connector }) + return viem_getCallsStatus(client, { id }) +} diff --git a/wagmi-project/packages/core/src/actions/getCapabilities.test.ts b/wagmi-project/packages/core/src/actions/getCapabilities.test.ts new file mode 100644 index 000000000..e7c02ec44 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getCapabilities.test.ts @@ -0,0 +1,64 @@ +import { accounts, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { connect } from './connect.js' +import { disconnect } from './disconnect.js' +import { getCapabilities } from './getCapabilities.js' + +const connector = config.connectors[0]! + +test('default', async () => { + await connect(config, { connector }) + const capabilities = await getCapabilities(config) + expect(capabilities).toMatchInlineSnapshot(` + { + "8453": { + "paymasterService": { + "supported": true, + }, + "sessionKeys": { + "supported": true, + }, + }, + "84532": { + "paymasterService": { + "supported": true, + }, + }, + } + `) + await disconnect(config, { connector }) +}) + +test('args: account', async () => { + await connect(config, { connector }) + const capabilities = await getCapabilities(config, { + account: accounts[1], + }) + expect(capabilities).toMatchInlineSnapshot(` + { + "8453": { + "paymasterService": { + "supported": false, + }, + "sessionKeys": { + "supported": true, + }, + }, + "84532": { + "paymasterService": { + "supported": false, + }, + }, + } + `) + await disconnect(config, { connector }) +}) + +test('behavior: not connected', async () => { + await expect(getCapabilities(config)).rejects.toMatchInlineSnapshot(` + [ConnectorNotConnectedError: Connector not connected. + + Version: @wagmi/core@x.y.z] + `) +}) diff --git a/wagmi-project/packages/core/src/actions/getCapabilities.ts b/wagmi-project/packages/core/src/actions/getCapabilities.ts new file mode 100644 index 000000000..ab8ea82bf --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getCapabilities.ts @@ -0,0 +1,39 @@ +import type { Account } from 'viem' +import { + type GetCapabilitiesErrorType as viem_GetCapabilitiesErrorType, + type GetCapabilitiesParameters as viem_GetCapabilitiesParameters, + type GetCapabilitiesReturnType as viem_GetCapabilitiesReturnType, + getCapabilities as viem_getCapabilities, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { ConnectorParameter } from '../types/properties.js' +import { getConnectorClient } from './getConnectorClient.js' + +export type GetCapabilitiesParameters< + config extends Config = Config, + chainId extends config['chains'][number]['id'] | undefined = undefined, +> = viem_GetCapabilitiesParameters & ConnectorParameter + +export type GetCapabilitiesReturnType< + config extends Config = Config, + chainId extends config['chains'][number]['id'] | undefined = undefined, +> = viem_GetCapabilitiesReturnType + +export type GetCapabilitiesErrorType = viem_GetCapabilitiesErrorType + +/** https://wagmi.sh/core/api/actions/getCapabilities */ +export async function getCapabilities< + config extends Config, + chainId extends config['chains'][number]['id'] | undefined = undefined, +>( + config: config, + parameters: GetCapabilitiesParameters = {}, +): Promise> { + const { account, chainId, connector } = parameters + const client = await getConnectorClient(config, { account, connector }) + return viem_getCapabilities(client as any, { + account: account as Account, + chainId, + }) +} diff --git a/wagmi-project/packages/core/src/actions/getChainId.test.ts b/wagmi-project/packages/core/src/actions/getChainId.test.ts new file mode 100644 index 000000000..3dcedcf08 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getChainId.test.ts @@ -0,0 +1,10 @@ +import { chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getChainId } from './getChainId.js' + +test('default', async () => { + expect(getChainId(config)).toEqual(chain.mainnet.id) + config.setState((x) => ({ ...x, chainId: chain.mainnet2.id })) + expect(getChainId(config)).toEqual(chain.mainnet2.id) +}) diff --git a/wagmi-project/packages/core/src/actions/getChainId.ts b/wagmi-project/packages/core/src/actions/getChainId.ts new file mode 100644 index 000000000..208602e05 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getChainId.ts @@ -0,0 +1,11 @@ +import type { Config } from '../createConfig.js' + +export type GetChainIdReturnType = + config['chains'][number]['id'] + +/** https://wagmi.sh/core/api/actions/getChainId */ +export function getChainId( + config: config, +): GetChainIdReturnType { + return config.state.chainId +} diff --git a/wagmi-project/packages/core/src/actions/getChains.test-d.ts b/wagmi-project/packages/core/src/actions/getChains.test-d.ts new file mode 100644 index 000000000..cd5f04c9c --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getChains.test-d.ts @@ -0,0 +1,12 @@ +import { type chain, config } from '@wagmi/test' +import type { Chain } from 'viem' +import { expectTypeOf, test } from 'vitest' + +import { getChains } from './getChains.js' + +test('default', async () => { + const chains = getChains(config) + expectTypeOf(chains[0]).toEqualTypeOf() + expectTypeOf(chains[2]).toEqualTypeOf() + expectTypeOf(chains[3]).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/core/src/actions/getChains.test.ts b/wagmi-project/packages/core/src/actions/getChains.test.ts new file mode 100644 index 000000000..fbaeae764 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getChains.test.ts @@ -0,0 +1,14 @@ +import { chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getChains } from './getChains.js' + +test('default', async () => { + expect(getChains(config)).toEqual([ + chain.mainnet, + chain.mainnet2, + chain.optimism, + ]) + config._internal.chains.setState([chain.mainnet, chain.mainnet2]) + expect(getChains(config)).toEqual([chain.mainnet, chain.mainnet2]) +}) diff --git a/wagmi-project/packages/core/src/actions/getChains.ts b/wagmi-project/packages/core/src/actions/getChains.ts new file mode 100644 index 000000000..a91e6e89b --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getChains.ts @@ -0,0 +1,21 @@ +import type { Chain } from 'viem' +import type { Config } from '../createConfig.js' +import { deepEqual } from '../utils/deepEqual.js' + +export type GetChainsReturnType = readonly [ + ...config['chains'], + ...Chain[], +] + +let previousChains: readonly Chain[] = [] + +/** https://wagmi.sh/core/api/actions/getChains */ +export function getChains( + config: config, +): GetChainsReturnType { + const chains = config.chains + if (deepEqual(previousChains, chains)) + return previousChains as GetChainsReturnType + previousChains = chains + return chains as unknown as GetChainsReturnType +} diff --git a/wagmi-project/packages/core/src/actions/getClient.test-d.ts b/wagmi-project/packages/core/src/actions/getClient.test-d.ts new file mode 100644 index 000000000..f64cbae2c --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getClient.test-d.ts @@ -0,0 +1,27 @@ +import { chain, config } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' + +import { getClient } from './getClient.js' + +test('default', () => { + const client = getClient(config) + expectTypeOf(client.chain).toEqualTypeOf<(typeof config)['chains'][number]>() + expectTypeOf(client.transport.type).toEqualTypeOf<'http'>() +}) + +test('parameters: chainId', () => { + const client = getClient(config, { + chainId: chain.mainnet.id, + }) + expectTypeOf(client.chain).toEqualTypeOf() + expectTypeOf(client.chain).not.toEqualTypeOf() + expectTypeOf(client.transport.type).toEqualTypeOf<'http'>() +}) + +test('behavior: unconfigured chain', () => { + const client = getClient(config, { + // @ts-expect-error + chainId: 123456, + }) + expectTypeOf(client).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/core/src/actions/getClient.test.ts b/wagmi-project/packages/core/src/actions/getClient.test.ts new file mode 100644 index 000000000..9eb0fa574 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getClient.test.ts @@ -0,0 +1,17 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getClient } from './getClient.js' + +test('default', () => { + expect(getClient(config)).toBeDefined() +}) + +test('behavior: unconfigured chain', () => { + expect( + getClient(config, { + // @ts-expect-error + chainId: 123456, + }), + ).toBeUndefined() +}) diff --git a/wagmi-project/packages/core/src/actions/getClient.ts b/wagmi-project/packages/core/src/actions/getClient.ts new file mode 100644 index 000000000..82f1c6c17 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getClient.ts @@ -0,0 +1,52 @@ +import type { Client } from 'viem' + +import type { Config } from '../createConfig.js' +import type { ChainIdParameter } from '../types/properties.js' +import type { Compute, IsNarrowable } from '../types/utils.js' + +export type GetClientParameters< + config extends Config = Config, + chainId extends + | config['chains'][number]['id'] + | number + | undefined = config['chains'][number]['id'], +> = ChainIdParameter + +export type GetClientReturnType< + config extends Config = Config, + chainId extends + | config['chains'][number]['id'] + | undefined = config['chains'][number]['id'], + /// + resolvedChainId extends + | config['chains'][number]['id'] + | undefined = IsNarrowable< + config['chains'][number]['id'], + number + > extends true + ? IsNarrowable extends true + ? chainId + : config['chains'][number]['id'] + : config['chains'][number]['id'] | undefined, +> = resolvedChainId extends config['chains'][number]['id'] + ? Compute< + Client< + config['_internal']['transports'][resolvedChainId], + Extract + > + > + : undefined + +export function getClient< + config extends Config, + chainId extends config['chains'][number]['id'] | number | undefined, +>( + config: config, + parameters: GetClientParameters = {}, +): GetClientReturnType { + let client = undefined + try { + client = config.getClient(parameters) + } catch {} + return client as GetClientReturnType +} diff --git a/wagmi-project/packages/core/src/actions/getConnections.test.ts b/wagmi-project/packages/core/src/actions/getConnections.test.ts new file mode 100644 index 000000000..22e6748cf --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getConnections.test.ts @@ -0,0 +1,15 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { connect } from './connect.js' +import { disconnect } from './disconnect.js' +import { getConnections } from './getConnections.js' + +test('default', async () => { + const connector = config.connectors[0]! + expect(getConnections(config)).toEqual([]) + await connect(config, { connector }) + expect(getConnections(config).length).toEqual(1) + await disconnect(config, { connector }) + expect(getConnections(config)).toEqual([]) +}) diff --git a/wagmi-project/packages/core/src/actions/getConnections.ts b/wagmi-project/packages/core/src/actions/getConnections.ts new file mode 100644 index 000000000..72cdbc27d --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getConnections.ts @@ -0,0 +1,16 @@ +import type { Config, Connection } from '../createConfig.js' +import type { Compute } from '../types/utils.js' +import { deepEqual } from '../utils/deepEqual.js' + +export type GetConnectionsReturnType = Compute[] + +let previousConnections: Connection[] = [] + +/** https://wagmi.sh/core/api/actions/getConnections */ +export function getConnections(config: Config): GetConnectionsReturnType { + const connections = [...config.state.connections.values()] + if (config.state.status === 'reconnecting') return previousConnections + if (deepEqual(previousConnections, connections)) return previousConnections + previousConnections = connections + return connections +} diff --git a/wagmi-project/packages/core/src/actions/getConnectorClient.test-d.ts b/wagmi-project/packages/core/src/actions/getConnectorClient.test-d.ts new file mode 100644 index 000000000..c4d980a7d --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getConnectorClient.test-d.ts @@ -0,0 +1,19 @@ +import { chain, config } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' + +import { getConnectorClient } from './getConnectorClient.js' + +test('default', async () => { + const client = await getConnectorClient(config) + expectTypeOf(client.chain).toEqualTypeOf<(typeof config)['chains'][number]>() + expectTypeOf(client.transport.type).toEqualTypeOf<'http'>() +}) + +test('parameters: chainId', async () => { + const client = await getConnectorClient(config, { + chainId: chain.mainnet.id, + }) + expectTypeOf(client.chain).toEqualTypeOf() + expectTypeOf(client.chain).not.toEqualTypeOf() + expectTypeOf(client.transport.type).toEqualTypeOf<'http'>() +}) diff --git a/wagmi-project/packages/core/src/actions/getConnectorClient.test.ts b/wagmi-project/packages/core/src/actions/getConnectorClient.test.ts new file mode 100644 index 000000000..a9d60f514 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getConnectorClient.test.ts @@ -0,0 +1,106 @@ +import { address, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import type { Connector } from '../createConfig.js' +import { connect } from './connect.js' +import { disconnect } from './disconnect.js' +import { getConnectorClient } from './getConnectorClient.js' + +const connector = config.connectors[0]! + +test('default', async () => { + await connect(config, { connector }) + await expect(getConnectorClient(config)).resolves.toBeDefined() + await disconnect(config, { connector }) +}) + +test('parameters: connector', async () => { + const connector2 = config.connectors[1]! + await connect(config, { connector }) + await connect(config, { connector: connector2 }) + await expect(getConnectorClient(config, { connector })).resolves.toBeDefined() + await disconnect(config, { connector }) + await disconnect(config, { connector: connector2 }) +}) + +test.todo('custom connector client') + +test('behavior: account address is checksummed', async () => { + await connect(config, { connector }) + const account = '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266' + const client = await getConnectorClient(config, { account }) + expect(client.account.address).toMatchInlineSnapshot( + '"0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"', + ) + expect(client.account.address).not.toBe(account) + await disconnect(config, { connector }) +}) + +test('behavior: not connected', async () => { + await expect( + getConnectorClient(config), + ).rejects.toThrowErrorMatchingInlineSnapshot(` + [ConnectorNotConnectedError: Connector not connected. + + Version: @wagmi/core@x.y.z] + `) +}) + +test('behavior: connector is on different chain', async () => { + await connect(config, { chainId: 1, connector }) + config.setState((state) => { + const uid = state.current! + const connection = state.connections.get(uid)! + return { + ...state, + connections: new Map(state.connections).set(uid, { + ...connection, + chainId: 456, + }), + } + }) + await expect( + getConnectorClient(config, { account: address.usdcHolder }), + ).rejects.toThrowErrorMatchingInlineSnapshot(` + [ConnectorChainMismatchError: The current chain of the connector (id: 1) does not match the connection's chain (id: 456). + + Current Chain ID: 1 + Expected Chain ID: 456 + + Version: @wagmi/core@x.y.z] + `) + await disconnect(config, { connector }) +}) + +test('behavior: account does not exist on connector', async () => { + await connect(config, { connector }) + await expect( + getConnectorClient(config, { account: address.usdcHolder }), + ).rejects.toThrowErrorMatchingInlineSnapshot(` + [ConnectorAccountNotFoundError: Account "0x5414d89a8bF7E99d732BC52f3e6A3Ef461c0C078" not found for connector "Mock Connector". + + Version: @wagmi/core@x.y.z] + `) + await disconnect(config, { connector }) +}) + +test('behavior: reconnecting', async () => { + config.setState((state) => ({ ...state, status: 'reconnecting' })) + const { id, name, type, uid } = connector + await expect( + getConnectorClient(config, { + connector: { + id, + name, + type, + uid, + } as unknown as Connector, + }), + ).rejects.toThrowErrorMatchingInlineSnapshot(` + [ConnectorUnavailableReconnectingError: Connector "Mock Connector" unavailable while reconnecting. + + Details: During the reconnection step, the only connector methods guaranteed to be available are: \`id\`, \`name\`, \`type\`, \`uid\`. All other methods are not guaranteed to be available until reconnection completes and connectors are fully restored. This error commonly occurs for connectors that asynchronously inject after reconnection has already started. + Version: @wagmi/core@x.y.z] + `) + config.setState((state) => ({ ...state, status: 'disconnected' })) +}) diff --git a/wagmi-project/packages/core/src/actions/getConnectorClient.ts b/wagmi-project/packages/core/src/actions/getConnectorClient.ts new file mode 100644 index 000000000..534ba76bc --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getConnectorClient.ts @@ -0,0 +1,147 @@ +import { + type Account, + type Address, + type BaseErrorType, + type Client, + createClient, + custom, +} from 'viem' +import { getAddress, parseAccount } from 'viem/utils' + +import type { Config, Connection } from '../createConfig.js' +import type { ErrorType } from '../errors/base.js' +import { + ConnectorAccountNotFoundError, + type ConnectorAccountNotFoundErrorType, + ConnectorChainMismatchError, + type ConnectorChainMismatchErrorType, + ConnectorNotConnectedError, + type ConnectorNotConnectedErrorType, + ConnectorUnavailableReconnectingError, + type ConnectorUnavailableReconnectingErrorType, +} from '../errors/config.js' +import type { + ChainIdParameter, + ConnectorParameter, +} from '../types/properties.js' +import type { Compute } from '../types/utils.js' + +export type GetConnectorClientParameters< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +> = Compute< + ChainIdParameter & + ConnectorParameter & { + /** + * Account to use for the client. + * + * - `Account | Address`: An Account MUST exist on the connector. + * - `null`: Account MAY NOT exist on the connector. This is useful for + * actions that can infer the account from the connector (e.g. sending a + * call without a connected account – the user will be prompted to select + * an account within the wallet). + */ + account?: Address | Account | null | undefined + } +> + +export type GetConnectorClientReturnType< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +> = Compute< + Client< + config['_internal']['transports'][chainId], + Extract, + Account + > +> + +export type GetConnectorClientErrorType = + | ConnectorAccountNotFoundErrorType + | ConnectorChainMismatchErrorType + | ConnectorNotConnectedErrorType + | ConnectorUnavailableReconnectingErrorType + // base + | BaseErrorType + | ErrorType + +/** https://wagmi.sh/core/api/actions/getConnectorClient */ +export async function getConnectorClient< + config extends Config, + chainId extends config['chains'][number]['id'], +>( + config: config, + parameters: GetConnectorClientParameters = {}, +): Promise> { + // Get connection + let connection: Connection | undefined + if (parameters.connector) { + const { connector } = parameters + if ( + config.state.status === 'reconnecting' && + !connector.getAccounts && + !connector.getChainId + ) + throw new ConnectorUnavailableReconnectingError({ connector }) + + const [accounts, chainId] = await Promise.all([ + connector.getAccounts().catch((e) => { + if (parameters.account === null) return [] + throw e + }), + connector.getChainId(), + ]) + connection = { + accounts: accounts as readonly [Address, ...Address[]], + chainId, + connector, + } + } else connection = config.state.connections.get(config.state.current!) + if (!connection) throw new ConnectorNotConnectedError() + + const chainId = parameters.chainId ?? connection.chainId + + // Check connector using same chainId as connection + const connectorChainId = await connection.connector.getChainId() + if (connectorChainId !== connection.chainId) + throw new ConnectorChainMismatchError({ + connectionChainId: connection.chainId, + connectorChainId, + }) + + // If connector has custom `getClient` implementation + type Return = GetConnectorClientReturnType + const connector = connection.connector + if (connector.getClient) + return connector.getClient({ chainId }) as unknown as Return + + // Default using `custom` transport + const account = parseAccount(parameters.account ?? connection.accounts[0]!) + if (account) account.address = getAddress(account.address) // TODO: Checksum address as part of `parseAccount`? + + // If account was provided, check that it exists on the connector + if ( + parameters.account && + !connection.accounts.some( + (x) => x.toLowerCase() === account.address.toLowerCase(), + ) + ) + throw new ConnectorAccountNotFoundError({ + address: account.address, + connector, + }) + + const chain = config.chains.find((chain) => chain.id === chainId) + const provider = (await connection.connector.getProvider({ chainId })) as { + request(...args: any): Promise + } + + return createClient({ + account, + chain, + name: 'Connector Client', + transport: (opts) => custom(provider)({ ...opts, retryCount: 0 }), + }) as Return +} diff --git a/wagmi-project/packages/core/src/actions/getConnectors.test.ts b/wagmi-project/packages/core/src/actions/getConnectors.test.ts new file mode 100644 index 000000000..d15f5fbb0 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getConnectors.test.ts @@ -0,0 +1,8 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getConnectors } from './getConnectors.js' + +test('default', () => { + expect(getConnectors(config)).toEqual(config.connectors) +}) diff --git a/wagmi-project/packages/core/src/actions/getConnectors.ts b/wagmi-project/packages/core/src/actions/getConnectors.ts new file mode 100644 index 000000000..439362d3f --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getConnectors.ts @@ -0,0 +1,17 @@ +import type { Config, Connector } from '../createConfig.js' +import { deepEqual } from '../utils/deepEqual.js' + +export type GetConnectorsReturnType = + config['connectors'] + +let previousConnectors: readonly Connector[] = [] + +/** https://wagmi.sh/core/api/actions/getConnectors */ +export function getConnectors( + config: config, +): GetConnectorsReturnType { + const connectors = config.connectors + if (deepEqual(previousConnectors, connectors)) return previousConnectors + previousConnectors = connectors + return connectors +} diff --git a/wagmi-project/packages/core/src/actions/getEnsAddress.test.ts b/wagmi-project/packages/core/src/actions/getEnsAddress.test.ts new file mode 100644 index 000000000..d120c82ef --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getEnsAddress.test.ts @@ -0,0 +1,12 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getEnsAddress } from './getEnsAddress.js' + +test('default', async () => { + await expect( + getEnsAddress(config, { name: 'wevm.eth' }), + ).resolves.toMatchInlineSnapshot( + '"0xd2135CfB216b74109775236E36d4b433F1DF507B"', + ) +}) diff --git a/wagmi-project/packages/core/src/actions/getEnsAddress.ts b/wagmi-project/packages/core/src/actions/getEnsAddress.ts new file mode 100644 index 000000000..5f882999b --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getEnsAddress.ts @@ -0,0 +1,30 @@ +import { + type GetEnsAddressErrorType as viem_GetEnsAddressErrorType, + type GetEnsAddressParameters as viem_GetEnsAddressParameters, + type GetEnsAddressReturnType as viem_GetEnsAddressReturnType, + getEnsAddress as viem_getEnsAddress, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { ChainIdParameter } from '../types/properties.js' +import type { Compute } from '../types/utils.js' +import { getAction } from '../utils/getAction.js' + +export type GetEnsAddressParameters = Compute< + viem_GetEnsAddressParameters & ChainIdParameter +> + +export type GetEnsAddressReturnType = viem_GetEnsAddressReturnType + +export type GetEnsAddressErrorType = viem_GetEnsAddressErrorType + +/** https://wagmi.sh/core/api/actions/getEnsAddress */ +export function getEnsAddress( + config: config, + parameters: GetEnsAddressParameters, +): Promise { + const { chainId, ...rest } = parameters + const client = config.getClient({ chainId }) + const action = getAction(client, viem_getEnsAddress, 'getEnsAddress') + return action(rest) +} diff --git a/wagmi-project/packages/core/src/actions/getEnsAvatar.test.ts b/wagmi-project/packages/core/src/actions/getEnsAvatar.test.ts new file mode 100644 index 000000000..ed1e83048 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getEnsAvatar.test.ts @@ -0,0 +1,12 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getEnsAvatar } from './getEnsAvatar.js' + +test('default', async () => { + await expect( + getEnsAvatar(config, { + name: 'wevm.eth', + }), + ).resolves.toMatchInlineSnapshot('"https://euc.li/wevm.eth"') +}) diff --git a/wagmi-project/packages/core/src/actions/getEnsAvatar.ts b/wagmi-project/packages/core/src/actions/getEnsAvatar.ts new file mode 100644 index 000000000..e6c3855d1 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getEnsAvatar.ts @@ -0,0 +1,30 @@ +import { + type GetEnsAvatarErrorType as viem_GetEnsAvatarErrorType, + type GetEnsAvatarParameters as viem_GetEnsAvatarParameters, + type GetEnsAvatarReturnType as viem_GetEnsAvatarReturnType, + getEnsAvatar as viem_getEnsAvatar, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { ChainIdParameter } from '../types/properties.js' +import type { Compute } from '../types/utils.js' +import { getAction } from '../utils/getAction.js' + +export type GetEnsAvatarParameters = Compute< + viem_GetEnsAvatarParameters & ChainIdParameter +> + +export type GetEnsAvatarReturnType = viem_GetEnsAvatarReturnType + +export type GetEnsAvatarErrorType = viem_GetEnsAvatarErrorType + +/** https://wagmi.sh/core/api/actions/getEnsAvatar */ +export function getEnsAvatar( + config: config, + parameters: GetEnsAvatarParameters, +): Promise { + const { chainId, ...rest } = parameters + const client = config.getClient({ chainId }) + const action = getAction(client, viem_getEnsAvatar, 'getEnsAvatar') + return action(rest) +} diff --git a/wagmi-project/packages/core/src/actions/getEnsName.test.ts b/wagmi-project/packages/core/src/actions/getEnsName.test.ts new file mode 100644 index 000000000..38d1bae97 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getEnsName.test.ts @@ -0,0 +1,12 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getEnsName } from './getEnsName.js' + +test('default', async () => { + await expect( + getEnsName(config, { + address: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + }), + ).resolves.toMatchInlineSnapshot('"wevm.eth"') +}) diff --git a/wagmi-project/packages/core/src/actions/getEnsName.ts b/wagmi-project/packages/core/src/actions/getEnsName.ts new file mode 100644 index 000000000..e6ab338db --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getEnsName.ts @@ -0,0 +1,30 @@ +import { + type GetEnsNameErrorType as viem_GetEnsNameErrorType, + type GetEnsNameParameters as viem_GetEnsNameParameters, + type GetEnsNameReturnType as viem_GetEnsNameReturnType, + getEnsName as viem_getEnsName, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { ChainIdParameter } from '../types/properties.js' +import type { Compute } from '../types/utils.js' +import { getAction } from '../utils/getAction.js' + +export type GetEnsNameParameters = Compute< + viem_GetEnsNameParameters & ChainIdParameter +> + +export type GetEnsNameReturnType = viem_GetEnsNameReturnType + +export type GetEnsNameErrorType = viem_GetEnsNameErrorType + +/** https://wagmi.sh/core/api/actions/getEnsName */ +export function getEnsName( + config: config, + parameters: GetEnsNameParameters, +): Promise { + const { chainId, ...rest } = parameters + const client = config.getClient({ chainId }) + const action = getAction(client, viem_getEnsName, 'getEnsName') + return action(rest) +} diff --git a/wagmi-project/packages/core/src/actions/getEnsResolver.test.ts b/wagmi-project/packages/core/src/actions/getEnsResolver.test.ts new file mode 100644 index 000000000..4bc30be55 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getEnsResolver.test.ts @@ -0,0 +1,14 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getEnsResolver } from './getEnsResolver.js' + +test('default', async () => { + await expect( + getEnsResolver(config, { + name: 'wevm.eth', + }), + ).resolves.toMatchInlineSnapshot( + '"0x4976fb03C32e5B8cfe2b6cCB31c09Ba78EBaBa41"', + ) +}) diff --git a/wagmi-project/packages/core/src/actions/getEnsResolver.ts b/wagmi-project/packages/core/src/actions/getEnsResolver.ts new file mode 100644 index 000000000..ab59b7d76 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getEnsResolver.ts @@ -0,0 +1,30 @@ +import { + type GetEnsResolverErrorType as viem_GetEnsResolverErrorType, + type GetEnsResolverParameters as viem_GetEnsResolverParameters, + type GetEnsResolverReturnType as viem_GetEnsResolverReturnType, + getEnsResolver as viem_getEnsResolver, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { ChainIdParameter } from '../types/properties.js' +import type { Compute } from '../types/utils.js' +import { getAction } from '../utils/getAction.js' + +export type GetEnsResolverParameters = Compute< + viem_GetEnsResolverParameters & ChainIdParameter +> + +export type GetEnsResolverReturnType = viem_GetEnsResolverReturnType + +export type GetEnsResolverErrorType = viem_GetEnsResolverErrorType + +/** https://wagmi.sh/core/api/actions/getEnsResolver */ +export function getEnsResolver( + config: config, + parameters: GetEnsResolverParameters, +): Promise { + const { chainId, ...rest } = parameters + const client = config.getClient({ chainId }) + const action = getAction(client, viem_getEnsResolver, 'getEnsResolver') + return action(rest) +} diff --git a/wagmi-project/packages/core/src/actions/getEnsText.test.ts b/wagmi-project/packages/core/src/actions/getEnsText.test.ts new file mode 100644 index 000000000..63801747d --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getEnsText.test.ts @@ -0,0 +1,13 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getEnsText } from './getEnsText.js' + +test('default', async () => { + await expect( + getEnsText(config, { + name: 'wevm.eth', + key: 'com.twitter', + }), + ).resolves.toMatchInlineSnapshot('"wevm_dev"') +}) diff --git a/wagmi-project/packages/core/src/actions/getEnsText.ts b/wagmi-project/packages/core/src/actions/getEnsText.ts new file mode 100644 index 000000000..d786f72b7 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getEnsText.ts @@ -0,0 +1,30 @@ +import { + type GetEnsTextErrorType as viem_GetEnsTextErrorType, + type GetEnsTextParameters as viem_GetEnsTextParameters, + type GetEnsTextReturnType as viem_GetEnsTextReturnType, + getEnsText as viem_getEnsText, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { ChainIdParameter } from '../types/properties.js' +import type { Compute } from '../types/utils.js' +import { getAction } from '../utils/getAction.js' + +export type GetEnsTextParameters = Compute< + viem_GetEnsTextParameters & ChainIdParameter +> + +export type GetEnsTextReturnType = viem_GetEnsTextReturnType + +export type GetEnsTextErrorType = viem_GetEnsTextErrorType + +/** https://wagmi.sh/core/api/actions/getEnsText */ +export function getEnsText( + config: config, + parameters: GetEnsTextParameters, +): Promise { + const { chainId, ...rest } = parameters + const client = config.getClient({ chainId }) + const action = getAction(client, viem_getEnsText, 'getEnsText') + return action(rest) +} diff --git a/wagmi-project/packages/core/src/actions/getFeeHistory.test.ts b/wagmi-project/packages/core/src/actions/getFeeHistory.test.ts new file mode 100644 index 000000000..263038155 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getFeeHistory.test.ts @@ -0,0 +1,63 @@ +import { chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getFeeHistory } from './getFeeHistory.js' + +test('default', async () => { + await expect( + getFeeHistory(config, { + blockCount: 4, + rewardPercentiles: [25, 75], + }), + ).resolves.toMatchObject({ + baseFeePerGas: expect.arrayContaining([expect.any(BigInt)]), + gasUsedRatio: expect.arrayContaining([expect.any(Number)]), + oldestBlock: expect.any(BigInt), + reward: expect.any(Array), + }) +}) + +test('parameters: chainId', async () => { + await expect( + getFeeHistory(config, { + blockCount: 4, + rewardPercentiles: [25, 75], + chainId: chain.mainnet2.id, + }), + ).resolves.toMatchObject({ + baseFeePerGas: expect.arrayContaining([expect.any(BigInt)]), + gasUsedRatio: expect.arrayContaining([expect.any(Number)]), + oldestBlock: expect.any(BigInt), + reward: expect.any(Array), + }) +}) + +test('parameters: blockNumber', async () => { + await expect( + getFeeHistory(config, { + blockCount: 4, + rewardPercentiles: [25, 75], + blockNumber: 18677379n, + }), + ).resolves.toMatchObject({ + baseFeePerGas: expect.arrayContaining([expect.any(BigInt)]), + gasUsedRatio: expect.arrayContaining([expect.any(Number)]), + oldestBlock: expect.any(BigInt), + reward: expect.any(Array), + }) +}) + +test('parameters: blockTag', async () => { + await expect( + getFeeHistory(config, { + blockCount: 4, + rewardPercentiles: [25, 75], + blockTag: 'safe', + }), + ).resolves.toMatchObject({ + baseFeePerGas: expect.arrayContaining([expect.any(BigInt)]), + gasUsedRatio: expect.arrayContaining([expect.any(Number)]), + oldestBlock: expect.any(BigInt), + reward: expect.any(Array), + }) +}) diff --git a/wagmi-project/packages/core/src/actions/getFeeHistory.ts b/wagmi-project/packages/core/src/actions/getFeeHistory.ts new file mode 100644 index 000000000..958821413 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getFeeHistory.ts @@ -0,0 +1,36 @@ +import { + type GetFeeHistoryErrorType as viem_GetFeeHistoryErrorType, + type GetFeeHistoryParameters as viem_GetFeeHistoryParameters, + type GetFeeHistoryReturnType as viem_GetFeeHistoryReturnType, + getFeeHistory as viem_getFeeHistory, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { ChainIdParameter } from '../types/properties.js' +import type { Compute } from '../types/utils.js' +import { getAction } from '../utils/getAction.js' + +export type GetFeeHistoryParameters< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +> = Compute> + +export type GetFeeHistoryReturnType = viem_GetFeeHistoryReturnType + +export type GetFeeHistoryErrorType = viem_GetFeeHistoryErrorType + +/** https://wagmi.sh/core/api/actions/getFeeHistory */ +export function getFeeHistory< + config extends Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +>( + config: config, + parameters: GetFeeHistoryParameters, +): Promise { + const { chainId, ...rest } = parameters + const client = config.getClient({ chainId }) + const action = getAction(client, viem_getFeeHistory, 'getFeeHistory') + return action(rest) +} diff --git a/wagmi-project/packages/core/src/actions/getGasPrice.test.ts b/wagmi-project/packages/core/src/actions/getGasPrice.test.ts new file mode 100644 index 000000000..64b7ba6fd --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getGasPrice.test.ts @@ -0,0 +1,21 @@ +import { chain, config, testClient } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getGasPrice } from './getGasPrice.js' + +test('default', async () => { + await testClient.mainnet.setNextBlockBaseFeePerGas({ + baseFeePerGas: 2_000_000_000n, + }) + await expect(getGasPrice(config)).resolves.toBe(3000000000n) +}) + +test('parameters: chainId', async () => { + await testClient.mainnet2.setNextBlockBaseFeePerGas({ + baseFeePerGas: 1_000_000_000n, + }) + await testClient.mainnet2.mine({ blocks: 1 }) + await expect( + getGasPrice(config, { chainId: chain.mainnet2.id }), + ).resolves.toBe(1875000000n) +}) diff --git a/wagmi-project/packages/core/src/actions/getGasPrice.ts b/wagmi-project/packages/core/src/actions/getGasPrice.ts new file mode 100644 index 000000000..c6482c44a --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getGasPrice.ts @@ -0,0 +1,35 @@ +import { + type GetGasPriceErrorType as viem_GetGasPriceErrorType, + type GetGasPriceReturnType as viem_GetGasPriceReturnType, + getGasPrice as viem_getGasPrice, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { ChainIdParameter } from '../types/properties.js' +import type { Compute } from '../types/utils.js' +import { getAction } from '../utils/getAction.js' + +export type GetGasPriceParameters< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +> = Compute> + +export type GetGasPriceReturnType = viem_GetGasPriceReturnType + +export type GetGasPriceErrorType = viem_GetGasPriceErrorType + +/** https://wagmi.sh/core/api/actions/getGasPrice */ +export function getGasPrice< + config extends Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +>( + config: config, + parameters: GetGasPriceParameters = {}, +): Promise { + const { chainId } = parameters + const client = config.getClient({ chainId }) + const action = getAction(client, viem_getGasPrice, 'getGasPrice') + return action({}) +} diff --git a/wagmi-project/packages/core/src/actions/getProof.test.ts b/wagmi-project/packages/core/src/actions/getProof.test.ts new file mode 100644 index 000000000..5ff0af282 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getProof.test.ts @@ -0,0 +1,16 @@ +import { chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getProof } from './getProof.js' + +test('default', async () => { + await expect( + getProof(config, { + chainId: chain.optimism.id, + address: '0x4200000000000000000000000000000000000016', + storageKeys: [ + '0x4a932049252365b3eedbc5190e18949f2ec11f39d3bef2d259764799a1b27d99', + ], + }), + ).resolves.toBeDefined() +}) diff --git a/wagmi-project/packages/core/src/actions/getProof.ts b/wagmi-project/packages/core/src/actions/getProof.ts new file mode 100644 index 000000000..ee9ec218d --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getProof.ts @@ -0,0 +1,30 @@ +import { + type GetProofErrorType as viem_GetProofErrorType, + type GetProofParameters as viem_GetProofParameters, + type GetProofReturnType as viem_GetProofReturnType, + getProof as viem_getProof, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { ChainIdParameter } from '../types/properties.js' +import type { Compute } from '../types/utils.js' +import { getAction } from '../utils/getAction.js' + +export type GetProofParameters = Compute< + viem_GetProofParameters & ChainIdParameter +> + +export type GetProofReturnType = viem_GetProofReturnType + +export type GetProofErrorType = viem_GetProofErrorType + +/** https://wagmi.sh/core/api/actions/getProof */ +export async function getProof( + config: config, + parameters: GetProofParameters, +): Promise { + const { chainId, ...rest } = parameters + const client = config.getClient({ chainId }) + const action = getAction(client, viem_getProof, 'getProof') + return action(rest) +} diff --git a/wagmi-project/packages/core/src/actions/getPublicClient.test-d.ts b/wagmi-project/packages/core/src/actions/getPublicClient.test-d.ts new file mode 100644 index 000000000..711f11a29 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getPublicClient.test-d.ts @@ -0,0 +1,27 @@ +import { chain, config } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' + +import { getPublicClient } from './getPublicClient.js' + +test('default', () => { + const client = getPublicClient(config) + expectTypeOf(client.chain).toEqualTypeOf<(typeof config)['chains'][number]>() + expectTypeOf(client.transport.type).toEqualTypeOf<'http'>() +}) + +test('parameters: chainId', () => { + const client = getPublicClient(config, { + chainId: chain.mainnet.id, + }) + expectTypeOf(client.chain).toEqualTypeOf() + expectTypeOf(client.chain).not.toEqualTypeOf() + expectTypeOf(client.transport.type).toEqualTypeOf<'http'>() +}) + +test('behavior: unconfigured chain', () => { + const client = getPublicClient(config, { + // @ts-expect-error + chainId: 123456, + }) + expectTypeOf(client).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/core/src/actions/getPublicClient.test.ts b/wagmi-project/packages/core/src/actions/getPublicClient.test.ts new file mode 100644 index 000000000..c77d0bfb9 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getPublicClient.test.ts @@ -0,0 +1,17 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getPublicClient } from './getPublicClient.js' + +test('default', () => { + expect(getPublicClient(config)).toBeDefined() +}) + +test('behavior: unconfigured chain', () => { + expect( + getPublicClient(config, { + // @ts-expect-error + chainId: 123456, + }), + ).toBeUndefined() +}) diff --git a/wagmi-project/packages/core/src/actions/getPublicClient.ts b/wagmi-project/packages/core/src/actions/getPublicClient.ts new file mode 100644 index 000000000..1fbd53ed3 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getPublicClient.ts @@ -0,0 +1,52 @@ +import { type Client, type PublicClient, publicActions } from 'viem' + +import type { Config } from '../createConfig.js' +import type { ChainIdParameter } from '../types/properties.js' +import type { Compute, IsNarrowable } from '../types/utils.js' +import { getClient } from './getClient.js' + +export type GetPublicClientParameters< + config extends Config = Config, + chainId extends + | config['chains'][number]['id'] + | undefined = config['chains'][number]['id'], +> = ChainIdParameter + +export type GetPublicClientReturnType< + config extends Config = Config, + chainId extends + | config['chains'][number]['id'] + | undefined = config['chains'][number]['id'], + /// + resolvedChainId extends + | config['chains'][number]['id'] + | undefined = IsNarrowable< + config['chains'][number]['id'], + number + > extends true + ? IsNarrowable extends true + ? chainId + : config['chains'][number]['id'] + : config['chains'][number]['id'] | undefined, +> = resolvedChainId extends config['chains'][number]['id'] + ? Compute< + PublicClient< + config['_internal']['transports'][resolvedChainId], + Extract + > + > + : undefined + +export function getPublicClient< + config extends Config, + chainId extends config['chains'][number]['id'] | number | undefined, +>( + config: config, + parameters: GetPublicClientParameters = {}, +): GetPublicClientReturnType { + const client = getClient(config, parameters) + return (client as Client)?.extend(publicActions) as GetPublicClientReturnType< + config, + chainId + > +} diff --git a/wagmi-project/packages/core/src/actions/getStorageAt.test.ts b/wagmi-project/packages/core/src/actions/getStorageAt.test.ts new file mode 100644 index 000000000..bc612fe91 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getStorageAt.test.ts @@ -0,0 +1,59 @@ +import { address, chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getStorageAt } from './getStorageAt.js' + +test('default', async () => { + await expect( + getStorageAt(config, { + address: address.wagmiMintExample, + slot: '0x0', + }), + ).resolves.toBe( + '0x7761676d6900000000000000000000000000000000000000000000000000000a', + ) + await expect( + getStorageAt(config, { + address: address.wagmiMintExample, + slot: '0x1', + }), + ).resolves.toBe( + '0x5741474d4900000000000000000000000000000000000000000000000000000a', + ) +}) + +test('parameters: blockNumber', async () => { + await expect( + getStorageAt(config, { + address: address.wagmiMintExample, + blockNumber: 16280770n, + slot: '0x0', + }), + ).resolves.toBe( + '0x7761676d6900000000000000000000000000000000000000000000000000000a', + ) +}) + +test('parameters: blockTag', async () => { + await expect( + getStorageAt(config, { + address: address.wagmiMintExample, + blockTag: 'safe', + slot: '0x0', + }), + ).resolves.toBe( + '0x7761676d6900000000000000000000000000000000000000000000000000000a', + ) +}) + +test('parameters: chainId', async () => { + await expect( + getStorageAt(config, { + address: address.wagmiMintExample, + chainId: chain.optimism.id, + slot: '0x0', + }), + ).resolves.toBe( + '0x0000000000000000000000000000000000000000000000000000000000000000', + ) +}) diff --git a/wagmi-project/packages/core/src/actions/getStorageAt.ts b/wagmi-project/packages/core/src/actions/getStorageAt.ts new file mode 100644 index 000000000..a07ec081b --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getStorageAt.ts @@ -0,0 +1,30 @@ +import { + type GetStorageAtErrorType as viem_GetStorageAtErrorType, + type GetStorageAtParameters as viem_GetStorageAtParameters, + type GetStorageAtReturnType as viem_GetStorageAtReturnType, + getStorageAt as viem_getStorageAt, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { ChainIdParameter } from '../types/properties.js' +import type { Compute } from '../types/utils.js' +import { getAction } from '../utils/getAction.js' + +export type GetStorageAtParameters = Compute< + viem_GetStorageAtParameters & ChainIdParameter +> + +export type GetStorageAtReturnType = viem_GetStorageAtReturnType + +export type GetStorageAtErrorType = viem_GetStorageAtErrorType + +/** https://wagmi.sh/core/api/actions/getStorageAt */ +export async function getStorageAt( + config: config, + parameters: GetStorageAtParameters, +): Promise { + const { chainId, ...rest } = parameters + const client = config.getClient({ chainId }) + const action = getAction(client, viem_getStorageAt, 'getStorageAt') + return action(rest) +} diff --git a/wagmi-project/packages/core/src/actions/getToken.test.ts b/wagmi-project/packages/core/src/actions/getToken.test.ts new file mode 100644 index 000000000..ed8903f3d --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getToken.test.ts @@ -0,0 +1,84 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getToken } from './getToken.js' + +test('default', async () => { + await expect( + getToken(config, { + address: '0x1f9840a85d5af5bf1d1762f925bdaddc4201f984', + }), + ).resolves.toMatchInlineSnapshot(` + { + "address": "0x1f9840a85d5af5bf1d1762f925bdaddc4201f984", + "decimals": 18, + "name": "Uniswap", + "symbol": "UNI", + "totalSupply": { + "formatted": "1000000000", + "value": 1000000000000000000000000000n, + }, + } + `) +}) + +test('parameters: formatUnits', async () => { + await expect( + getToken(config, { + address: '0x1f9840a85d5af5bf1d1762f925bdaddc4201f984', + formatUnits: 'gwei', + }), + ).resolves.toMatchInlineSnapshot(` + { + "address": "0x1f9840a85d5af5bf1d1762f925bdaddc4201f984", + "decimals": 18, + "name": "Uniswap", + "symbol": "UNI", + "totalSupply": { + "formatted": "1000000000000000000", + "value": 1000000000000000000000000000n, + }, + } + `) +}) + +test('behavior: bytes32 token', async () => { + await expect( + getToken(config, { + address: '0x9f8f72aa9304c8b593d555f12ef6589cc3a579a2', + }), + ).resolves.toMatchInlineSnapshot(` + { + "address": "0x9f8f72aa9304c8b593d555f12ef6589cc3a579a2", + "decimals": 18, + "name": "Maker", + "symbol": "MKR", + "totalSupply": { + "formatted": "977631.036950888222010062", + "value": 977631036950888222010062n, + }, + } + `) +}) + +test('behavior: bogus token', async () => { + await expect( + getToken(config, { + address: '0xa0cf798816d4b9b9866b5330eea46a18382f251e', + }), + ).rejects.toThrowErrorMatchingInlineSnapshot(` + [ContractFunctionExecutionError: The contract function "decimals" returned no data ("0x"). + + This could be due to any of the following: + - The contract does not have the function "decimals", + - The parameters passed to the contract function may be invalid, or + - The address is not a contract. + + Contract Call: + address: 0xa0cf798816d4b9b9866b5330eea46a18382f251e + function: decimals() + + Docs: https://viem.sh/docs/contract/multicall + Version: viem@2.29.2] + `) +}) diff --git a/wagmi-project/packages/core/src/actions/getToken.ts b/wagmi-project/packages/core/src/actions/getToken.ts new file mode 100644 index 000000000..480a74282 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getToken.ts @@ -0,0 +1,141 @@ +import type { Address, Hex } from 'viem' +import { + ContractFunctionExecutionError, + formatUnits, + hexToString, + trim, +} from 'viem' + +import type { Config } from '../createConfig.js' +import type { ChainIdParameter } from '../types/properties.js' +import type { Unit } from '../types/unit.js' +import type { Compute } from '../types/utils.js' +import { getUnit } from '../utils/getUnit.js' +import { type ReadContractsErrorType, readContracts } from './readContracts.js' + +export type GetTokenParameters = Compute< + ChainIdParameter & { + address: Address + formatUnits?: Unit | undefined + } +> + +export type GetTokenReturnType = { + address: Address + decimals: number + name: string | undefined + symbol: string | undefined + totalSupply: { + formatted: string + value: bigint + } +} + +export type GetTokenErrorType = ReadContractsErrorType + +/** @deprecated */ +export async function getToken( + config: config, + parameters: GetTokenParameters, +): Promise { + const { address, chainId, formatUnits: unit = 18 } = parameters + + function getAbi(type: type) { + return [ + { + type: 'function', + name: 'decimals', + stateMutability: 'view', + inputs: [], + outputs: [{ type: 'uint8' }], + }, + { + type: 'function', + name: 'name', + stateMutability: 'view', + inputs: [], + outputs: [{ type }], + }, + { + type: 'function', + name: 'symbol', + stateMutability: 'view', + inputs: [], + outputs: [{ type }], + }, + { + type: 'function', + name: 'totalSupply', + stateMutability: 'view', + inputs: [], + outputs: [{ type: 'uint256' }], + }, + ] as const + } + + try { + const abi = getAbi('string') + const contractConfig = { address, abi, chainId } as const + const [decimals, name, symbol, totalSupply] = await readContracts(config, { + allowFailure: true, + contracts: [ + { ...contractConfig, functionName: 'decimals' }, + { ...contractConfig, functionName: 'name' }, + { ...contractConfig, functionName: 'symbol' }, + { ...contractConfig, functionName: 'totalSupply' }, + ] as const, + }) + + // throw if `name` or `symbol` failed + if (name.error instanceof ContractFunctionExecutionError) throw name.error + if (symbol.error instanceof ContractFunctionExecutionError) + throw symbol.error + + // `decimals` and `totalSupply` are required + if (decimals.error) throw decimals.error + if (totalSupply.error) throw totalSupply.error + + return { + address, + decimals: decimals.result, + name: name.result, + symbol: symbol.result, + totalSupply: { + formatted: formatUnits(totalSupply.result!, getUnit(unit)), + value: totalSupply.result, + }, + } + } catch (error) { + // In the chance that there is an error upon decoding the contract result, + // it could be likely that the contract data is represented as bytes32 instead + // of a string. + if (error instanceof ContractFunctionExecutionError) { + const abi = getAbi('bytes32') + const contractConfig = { address, abi, chainId } as const + const [decimals, name, symbol, totalSupply] = await readContracts( + config, + { + allowFailure: false, + contracts: [ + { ...contractConfig, functionName: 'decimals' }, + { ...contractConfig, functionName: 'name' }, + { ...contractConfig, functionName: 'symbol' }, + { ...contractConfig, functionName: 'totalSupply' }, + ] as const, + }, + ) + return { + address, + decimals, + name: hexToString(trim(name as Hex, { dir: 'right' })), + symbol: hexToString(trim(symbol as Hex, { dir: 'right' })), + totalSupply: { + formatted: formatUnits(totalSupply, getUnit(unit)), + value: totalSupply, + }, + } + } + + throw error + } +} diff --git a/wagmi-project/packages/core/src/actions/getTransaction.test-d.ts b/wagmi-project/packages/core/src/actions/getTransaction.test-d.ts new file mode 100644 index 000000000..9476b781c --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getTransaction.test-d.ts @@ -0,0 +1,29 @@ +import { http } from 'viem' +import { celo, mainnet } from 'viem/chains' +import { expectTypeOf, test } from 'vitest' + +import { createConfig } from '../createConfig.js' +import { getTransaction } from './getTransaction.js' + +test('chain formatters', async () => { + const config = createConfig({ + chains: [celo, mainnet], + transports: { [celo.id]: http(), [mainnet.id]: http() }, + }) + const result = await getTransaction(config, { hash: '0x123' }) + if (result.chainId === celo.id) { + expectTypeOf(result.feeCurrency).toEqualTypeOf<`0x${string}` | null>() + } +}) + +test('chainId', async () => { + const config = createConfig({ + chains: [celo, mainnet], + transports: { [celo.id]: http(), [mainnet.id]: http() }, + }) + const result = await getTransaction(config, { + hash: '0x123', + chainId: celo.id, + }) + expectTypeOf(result.feeCurrency).toEqualTypeOf<`0x${string}` | null>() +}) diff --git a/wagmi-project/packages/core/src/actions/getTransaction.test.ts b/wagmi-project/packages/core/src/actions/getTransaction.test.ts new file mode 100644 index 000000000..3615e6a0d --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getTransaction.test.ts @@ -0,0 +1,36 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getTransaction } from './getTransaction.js' + +test('default', async () => { + await expect( + getTransaction(config, { + hash: '0xa559259bd2d0e8372421e222ff3545f705b5da60005bd787a23c2e68d6d7fefd', + }), + ).resolves.toMatchInlineSnapshot(` + { + "accessList": [], + "blockHash": "0x61c4e868008b465addd7c0a5da03db28bb9911597c58e239a85dd14dd43fd56a", + "blockNumber": 17488642n, + "chainId": 1, + "from": "0xd2135cfb216b74109775236e36d4b433f1df507b", + "gas": 53671n, + "gasPrice": 15806335296n, + "hash": "0xa559259bd2d0e8372421e222ff3545f705b5da60005bd787a23c2e68d6d7fefd", + "input": "0xa9059cbb0000000000000000000000006acbe090725d8b1cd59fe5f3e0c9c3685ebb77af00000000000000000000000000000000000000000000000000000002540be400", + "maxFeePerGas": 19000000000n, + "maxPriorityFeePerGas": 1000000000n, + "nonce": 29, + "r": "0x60a19c4a708571d2a7c661dc5494542fa2c6ddd8e7dc218e4c4795b6ba7969f5", + "s": "0x7ef2778cc21f5c12861208d0c030e77193a234273e32a1dd5066d7d677aa1ef2", + "to": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", + "transactionIndex": 58, + "type": "eip1559", + "typeHex": "0x2", + "v": 1n, + "value": 0n, + "yParity": 1, + } + `) +}) diff --git a/wagmi-project/packages/core/src/actions/getTransaction.ts b/wagmi-project/packages/core/src/actions/getTransaction.ts new file mode 100644 index 000000000..014828281 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getTransaction.ts @@ -0,0 +1,51 @@ +import type { Chain } from 'viem' +import { + type GetTransactionErrorType as viem_GetTransactionErrorType, + type GetTransactionParameters as viem_GetTransactionParameters, + type GetTransactionReturnType as viem_GetTransactionReturnType, + getTransaction as viem_getTransaction, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { SelectChains } from '../types/chain.js' +import type { ChainIdParameter } from '../types/properties.js' +import type { Compute, IsNarrowable } from '../types/utils.js' +import { getAction } from '../utils/getAction.js' + +export type GetTransactionParameters< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +> = Compute> + +export type GetTransactionReturnType< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + /// + chains extends readonly Chain[] = SelectChains, +> = Compute< + { + [key in keyof chains]: viem_GetTransactionReturnType< + IsNarrowable extends true ? chains[key] : undefined + > & { chainId: chains[key]['id'] } + }[number] +> + +export type GetTransactionErrorType = viem_GetTransactionErrorType + +/** https://wagmi.sh/core/api/actions/getTransaction */ +export function getTransaction< + config extends Config, + chainId extends config['chains'][number]['id'], +>( + config: config, + parameters: GetTransactionParameters, +): Promise> { + const { chainId, ...rest } = parameters + const client = config.getClient({ chainId }) + const action = getAction(client, viem_getTransaction, 'getTransaction') + return action(rest) as unknown as Promise< + GetTransactionReturnType + > +} diff --git a/wagmi-project/packages/core/src/actions/getTransactionConfirmations.test-d.ts b/wagmi-project/packages/core/src/actions/getTransactionConfirmations.test-d.ts new file mode 100644 index 000000000..fd9168dfa --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getTransactionConfirmations.test-d.ts @@ -0,0 +1,85 @@ +import { config } from '@wagmi/test' +import { mainnet, zkSync } from 'viem/chains' +import { test } from 'vitest' + +import { http } from 'viem' +import { createConfig } from '../createConfig.js' +import { getTransactionConfirmations } from './getTransactionConfirmations.js' + +test('default', async () => { + getTransactionConfirmations(config, { + transactionReceipt: { + blockHash: '0x', + blockNumber: 1n, + contractAddress: '0x', + cumulativeGasUsed: 1n, + effectiveGasPrice: 1n, + from: '0x', + gasUsed: 1n, + l1Fee: 1n, + logs: [], + logsBloom: '0x', + status: 'success', + to: '0x', + transactionHash: '0x', + transactionIndex: 1, + type: 'eip1559', + }, + }) +}) + +test('chain formatters', async () => { + const config = createConfig({ + chains: [mainnet, zkSync], + transports: { [mainnet.id]: http(), [zkSync.id]: http() }, + }) + + const transactionReceipt = { + blockHash: '0x', + blockNumber: 1n, + contractAddress: '0x', + cumulativeGasUsed: 1n, + effectiveGasPrice: 1n, + from: '0x', + gasUsed: 1n, + logsBloom: '0x', + status: 'success', + to: '0x', + transactionHash: '0x', + transactionIndex: 1, + type: 'eip1559', + } as const + + getTransactionConfirmations(config, { + transactionReceipt: { + ...transactionReceipt, + l1BatchNumber: 1n, + l1BatchTxIndex: 1n, + logs: [], + l2ToL1Logs: [], + }, + }) + + getTransactionConfirmations(config, { + chainId: zkSync.id, + transactionReceipt: { + ...transactionReceipt, + l1BatchNumber: 1n, + l1BatchTxIndex: 1n, + logs: [], + l2ToL1Logs: [], + }, + }) + + getTransactionConfirmations(config, { + chainId: mainnet.id, + transactionReceipt: { + ...transactionReceipt, + // @ts-expect-error + l1BatchNumber: 1n, + l1BatchTxIndex: 1n, + logs: [], + l2ToL1Logs: [], + }, + }) +}) diff --git a/wagmi-project/packages/core/src/actions/getTransactionConfirmations.test.ts b/wagmi-project/packages/core/src/actions/getTransactionConfirmations.test.ts new file mode 100644 index 000000000..a2f47d6a4 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getTransactionConfirmations.test.ts @@ -0,0 +1,25 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getTransactionConfirmations } from './getTransactionConfirmations.js' +import { getTransactionReceipt } from './getTransactionReceipt.js' + +test('default', async () => { + await expect( + getTransactionConfirmations(config, { + hash: '0xa559259bd2d0e8372421e222ff3545f705b5da60005bd787a23c2e68d6d7fefd', + }), + ).resolves.toBeTypeOf('bigint') +}) + +test('parameters: transactionReceipt', async () => { + const transactionReceipt = await getTransactionReceipt(config, { + hash: '0xa559259bd2d0e8372421e222ff3545f705b5da60005bd787a23c2e68d6d7fefd', + }) + + await expect( + getTransactionConfirmations(config, { + transactionReceipt, + }), + ).resolves.toBeTypeOf('bigint') +}) diff --git a/wagmi-project/packages/core/src/actions/getTransactionConfirmations.ts b/wagmi-project/packages/core/src/actions/getTransactionConfirmations.ts new file mode 100644 index 000000000..8baa88cf1 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getTransactionConfirmations.ts @@ -0,0 +1,52 @@ +import type { Chain } from 'viem' +import { + type GetTransactionConfirmationsErrorType as viem_GetTransactionConfirmationsErrorType, + type GetTransactionConfirmationsParameters as viem_GetTransactionConfirmationsParameters, + type GetTransactionConfirmationsReturnType as viem_GetTransactionConfirmationsReturnType, + getTransactionConfirmations as viem_getTransactionConfirmations, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { SelectChains } from '../types/chain.js' +import type { ChainIdParameter } from '../types/properties.js' +import { getAction } from '../utils/getAction.js' + +export type GetTransactionConfirmationsParameters< + config extends Config = Config, + chainId extends + | config['chains'][number]['id'] + | undefined = config['chains'][number]['id'], + /// + chains extends readonly Chain[] = SelectChains, +> = { + [key in keyof chains]: viem_GetTransactionConfirmationsParameters< + chains[key] + > & + ChainIdParameter +}[number] + +export type GetTransactionConfirmationsReturnType = + viem_GetTransactionConfirmationsReturnType + +export type GetTransactionConfirmationsErrorType = + viem_GetTransactionConfirmationsErrorType + +/** https://wagmi.sh/core/api/actions/getTransactionConfirmations */ +export function getTransactionConfirmations< + config extends Config, + chainId extends + | config['chains'][number]['id'] + | undefined = config['chains'][number]['id'], +>( + config: config, + parameters: GetTransactionConfirmationsParameters, +): Promise { + const { chainId, ...rest } = parameters + const client = config.getClient({ chainId }) + const action = getAction( + client, + viem_getTransactionConfirmations, + 'getTransactionConfirmations', + ) + return action(rest as viem_GetTransactionConfirmationsParameters) +} diff --git a/wagmi-project/packages/core/src/actions/getTransactionCount.test.ts b/wagmi-project/packages/core/src/actions/getTransactionCount.test.ts new file mode 100644 index 000000000..95f0e6dde --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getTransactionCount.test.ts @@ -0,0 +1,50 @@ +import { accounts, chain, config, testClient } from '@wagmi/test' +import { expect, test } from 'vitest' + +import type { BlockTag } from 'viem' +import { getTransactionCount } from './getTransactionCount.js' + +const address = accounts[0] + +test('default', async () => { + await expect(getTransactionCount(config, { address })).resolves.toBeTypeOf( + 'number', + ) +}) + +test('parameters: chainId', async () => { + await testClient.mainnet2.setNonce({ + address, + nonce: 6969, + }) + await testClient.mainnet2.mine({ blocks: 1 }) + await expect( + getTransactionCount(config, { address, chainId: chain.mainnet2.id }), + ).resolves.toBeTypeOf('number') +}) + +test('parameters: blockNumber', async () => { + await expect( + getTransactionCount(config, { address, blockNumber: 13677382n }), + ).resolves.toBeTypeOf('number') +}) + +test.each([ + { blockTag: 'earliest' }, + { blockTag: 'finalized' }, + { blockTag: 'latest' }, + { blockTag: 'pending' }, + { blockTag: 'safe' }, +] as { blockTag: BlockTag; expected: number }[])( + 'parameters: blockTag $blockTag', + async ({ blockTag }) => { + await testClient.mainnet.restart() + + await expect( + getTransactionCount(config, { + address, + blockTag, + }), + ).resolves.toBeTypeOf('number') + }, +) diff --git a/wagmi-project/packages/core/src/actions/getTransactionCount.ts b/wagmi-project/packages/core/src/actions/getTransactionCount.ts new file mode 100644 index 000000000..6872e6ede --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getTransactionCount.ts @@ -0,0 +1,34 @@ +import { + type GetTransactionCountErrorType as viem_GetTransactionCountErrorType, + type GetTransactionCountParameters as viem_GetTransactionCountParameters, + type GetTransactionCountReturnType as viem_GetTransactionCountReturnType, + getTransactionCount as viem_getTransactionCount, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { ChainIdParameter } from '../types/properties.js' +import type { Compute } from '../types/utils.js' +import { getAction } from '../utils/getAction.js' + +export type GetTransactionCountParameters = + Compute & viem_GetTransactionCountParameters> + +export type GetTransactionCountReturnType = viem_GetTransactionCountReturnType + +export type GetTransactionCountErrorType = viem_GetTransactionCountErrorType + +/** https://wagmi.sh/core/api/actions/getTransactionCount */ +export async function getTransactionCount( + config: config, + parameters: GetTransactionCountParameters, +): Promise { + const { address, blockNumber, blockTag, chainId } = parameters + + const client = config.getClient({ chainId }) + const action = getAction( + client, + viem_getTransactionCount, + 'getTransactionCount', + ) + return action(blockNumber ? { address, blockNumber } : { address, blockTag }) +} diff --git a/wagmi-project/packages/core/src/actions/getTransactionReceipt.test-d.ts b/wagmi-project/packages/core/src/actions/getTransactionReceipt.test-d.ts new file mode 100644 index 000000000..e9850eacc --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getTransactionReceipt.test-d.ts @@ -0,0 +1,36 @@ +import { http } from 'viem' +import { mainnet, zkSync } from 'viem/chains' +import type { ZkSyncL2ToL1Log, ZkSyncLog } from 'viem/zksync' +import { expectTypeOf, test } from 'vitest' + +import { createConfig } from '../createConfig.js' +import { getTransactionReceipt } from './getTransactionReceipt.js' + +test('chain formatters', async () => { + const config = createConfig({ + chains: [mainnet, zkSync], + transports: { [mainnet.id]: http(), [zkSync.id]: http() }, + }) + const result = await getTransactionReceipt(config, { hash: '0x123' }) + if (result.chainId === zkSync.id) { + expectTypeOf(result.l1BatchNumber).toEqualTypeOf() + expectTypeOf(result.l1BatchTxIndex).toEqualTypeOf() + expectTypeOf(result.logs).toEqualTypeOf() + expectTypeOf(result.l2ToL1Logs).toEqualTypeOf() + } +}) + +test('chainId', async () => { + const config = createConfig({ + chains: [zkSync], + transports: { [zkSync.id]: http() }, + }) + const result = await getTransactionReceipt(config, { + hash: '0x123', + chainId: zkSync.id, + }) + expectTypeOf(result.l1BatchNumber).toEqualTypeOf() + expectTypeOf(result.l1BatchTxIndex).toEqualTypeOf() + expectTypeOf(result.logs).toEqualTypeOf() + expectTypeOf(result.l2ToL1Logs).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/core/src/actions/getTransactionReceipt.test.ts b/wagmi-project/packages/core/src/actions/getTransactionReceipt.test.ts new file mode 100644 index 000000000..82fee0b11 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getTransactionReceipt.test.ts @@ -0,0 +1,35 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getTransaction } from './getTransaction.js' +import { getTransactionReceipt } from './getTransactionReceipt.js' + +test('default', async () => { + const transaction = await getTransaction(config, { + blockNumber: 16280769n, + index: 0, + }) + + await expect( + getTransactionReceipt(config, { + hash: transaction.hash, + }), + ).resolves.toMatchInlineSnapshot(` + { + "blockHash": "0xb932f77cf770d1d1c8f861153eec1e990f5d56b6ffdb4ac06aef3cca51ef37d4", + "blockNumber": 16280769n, + "contractAddress": null, + "cumulativeGasUsed": 21000n, + "effectiveGasPrice": 33427926161n, + "from": "0x043022ef9fca1066024d19d681e2ccf44ff90de3", + "gasUsed": 21000n, + "logs": [], + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "status": "success", + "to": "0x318a5fb4f1604fc46375a1db9a9018b6e423b345", + "transactionHash": "0xbf7d27700d053765c9638d3b9d39eb3c56bfc48377583e8be483d61f9f18a871", + "transactionIndex": 0, + "type": "legacy", + } + `) +}) diff --git a/wagmi-project/packages/core/src/actions/getTransactionReceipt.ts b/wagmi-project/packages/core/src/actions/getTransactionReceipt.ts new file mode 100644 index 000000000..8c06e36ba --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getTransactionReceipt.ts @@ -0,0 +1,57 @@ +import type { Chain } from 'viem' +import { + type GetTransactionReceiptErrorType as viem_GetTransactionReceiptErrorType, + type GetTransactionReceiptParameters as viem_GetTransactionReceiptParameters, + type GetTransactionReceiptReturnType as viem_GetTransactionReceiptReturnType, + getTransactionReceipt as viem_getTransactionReceipt, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { SelectChains } from '../types/chain.js' +import type { ChainIdParameter } from '../types/properties.js' +import type { Compute, IsNarrowable } from '../types/utils.js' +import { getAction } from '../utils/getAction.js' + +export type GetTransactionReceiptParameters< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +> = Compute< + viem_GetTransactionReceiptParameters & ChainIdParameter +> + +export type GetTransactionReceiptReturnType< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + /// + chains extends readonly Chain[] = SelectChains, +> = Compute< + { + [key in keyof chains]: viem_GetTransactionReceiptReturnType< + IsNarrowable extends true ? chains[key] : undefined + > & { chainId: chains[key]['id'] } + }[number] +> + +export type GetTransactionReceiptErrorType = viem_GetTransactionReceiptErrorType + +/** https://wagmi.sh/core/api/actions/getTransactionReceipt */ +export async function getTransactionReceipt< + config extends Config, + chainId extends config['chains'][number]['id'], +>( + config: config, + parameters: GetTransactionReceiptParameters, +): Promise> { + const { chainId, ...rest } = parameters + const client = config.getClient({ chainId }) + const action = getAction( + client, + viem_getTransactionReceipt, + 'getTransactionReceipt', + ) + return action(rest) as unknown as Promise< + GetTransactionReceiptReturnType + > +} diff --git a/wagmi-project/packages/core/src/actions/getWalletClient.test-d.ts b/wagmi-project/packages/core/src/actions/getWalletClient.test-d.ts new file mode 100644 index 000000000..d1d87f5e9 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getWalletClient.test-d.ts @@ -0,0 +1,22 @@ +import { chain, config } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' + +import type { Account } from 'viem' +import { getWalletClient } from './getWalletClient.js' + +test('default', async () => { + const client = await getWalletClient(config) + expectTypeOf(client.chain).toEqualTypeOf<(typeof config)['chains'][number]>() + expectTypeOf(client.transport.type).toEqualTypeOf<'http'>() + expectTypeOf(client.account).toEqualTypeOf() +}) + +test('parameters: chainId', async () => { + const client = await getWalletClient(config, { + chainId: chain.mainnet.id, + }) + expectTypeOf(client.chain).toEqualTypeOf() + expectTypeOf(client.chain).not.toEqualTypeOf() + expectTypeOf(client.transport.type).toEqualTypeOf<'http'>() + expectTypeOf(client.account).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/core/src/actions/getWalletClient.test.ts b/wagmi-project/packages/core/src/actions/getWalletClient.test.ts new file mode 100644 index 000000000..2350f81b3 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getWalletClient.test.ts @@ -0,0 +1,24 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { connect } from './connect.js' +import { disconnect } from './disconnect.js' +import { getWalletClient } from './getWalletClient.js' + +const connector = config.connectors[0]! + +test('default', async () => { + await connect(config, { connector }) + await expect(getWalletClient(config)).resolves.toBeDefined() + await disconnect(config, { connector }) +}) + +test('behavior: not connected', async () => { + await expect( + getWalletClient(config), + ).rejects.toThrowErrorMatchingInlineSnapshot(` + [ConnectorNotConnectedError: Connector not connected. + + Version: @wagmi/core@x.y.z] + `) +}) diff --git a/wagmi-project/packages/core/src/actions/getWalletClient.ts b/wagmi-project/packages/core/src/actions/getWalletClient.ts new file mode 100644 index 000000000..bf4966870 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getWalletClient.ts @@ -0,0 +1,50 @@ +import { type Account, type WalletClient, walletActions } from 'viem' + +import type { Config } from '../createConfig.js' +import type { BaseErrorType, ErrorType } from '../errors/base.js' +import type { Compute } from '../types/utils.js' +import { + type GetConnectorClientErrorType, + type GetConnectorClientParameters, + getConnectorClient, +} from './getConnectorClient.js' + +export type GetWalletClientParameters< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +> = GetConnectorClientParameters + +export type GetWalletClientReturnType< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +> = Compute< + WalletClient< + config['_internal']['transports'][chainId], + Extract, + Account + > +> + +export type GetWalletClientErrorType = + // getConnectorClient() + | GetConnectorClientErrorType + // base + | BaseErrorType + | ErrorType + +export async function getWalletClient< + config extends Config, + chainId extends config['chains'][number]['id'], +>( + config: config, + parameters: GetWalletClientParameters = {}, +): Promise> { + const client = await getConnectorClient(config, parameters) + // @ts-ignore + return client.extend(walletActions) as unknown as GetWalletClientReturnType< + config, + chainId + > +} diff --git a/wagmi-project/packages/core/src/actions/multicall.test-d.ts b/wagmi-project/packages/core/src/actions/multicall.test-d.ts new file mode 100644 index 000000000..bb70db998 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/multicall.test-d.ts @@ -0,0 +1,106 @@ +import { abi, config } from '@wagmi/test' +import type { Address } from 'viem' +import { expectTypeOf, test } from 'vitest' + +import { multicall } from './multicall.js' + +test('default', async () => { + const result = await multicall(config, { + chainId: 1, + contracts: [ + { + address: '0x', + abi: abi.erc20, + functionName: 'balanceOf', + args: ['0x'], + }, + { + address: '0x', + abi: abi.wagmiMintExample, + functionName: 'tokenURI', + args: [123n], + }, + ], + }) + expectTypeOf(result).toEqualTypeOf< + [ + ( + | { error: Error; result?: undefined; status: 'failure' } + | { error?: undefined; result: bigint; status: 'success' } + ), + ( + | { error: Error; result?: undefined; status: 'failure' } + | { error?: undefined; result: string; status: 'success' } + ), + ] + >() +}) + +test('allowFailure', async () => { + const result = await multicall(config, { + allowFailure: false, + contracts: [ + { + address: '0x', + abi: abi.erc20, + functionName: 'balanceOf', + args: ['0x'], + }, + { + address: '0x', + abi: abi.wagmiMintExample, + functionName: 'tokenURI', + args: [123n], + }, + ], + }) + expectTypeOf(result).toEqualTypeOf<[bigint, string]>() +}) + +test('MulticallParameters', async () => { + type Result = Parameters< + typeof multicall< + typeof config, + [ + { + address: '0x' + abi: typeof abi.viewOverloads + functionName: 'foo' + }, + ] + > + >[1]['contracts'][0] + expectTypeOf().toEqualTypeOf<'foo' | 'bar'>() + expectTypeOf().toEqualTypeOf< + readonly [] | readonly [Address] | readonly [Address, Address] | undefined + >() +}) + +test('overloads', async () => { + const res = await multicall(config, { + allowFailure: false, + contracts: [ + { + address: '0x', + abi: abi.viewOverloads, + functionName: 'foo', + }, + { + address: '0x', + abi: abi.viewOverloads, + functionName: 'foo', + args: ['0x'], + }, + { + address: '0x', + abi: abi.viewOverloads, + functionName: 'foo', + args: ['0x', '0x'], + }, + ], + }) + + expectTypeOf(res).toEqualTypeOf< + [number, string, { foo: Address; bar: Address }] + >() +}) diff --git a/wagmi-project/packages/core/src/actions/multicall.test.ts b/wagmi-project/packages/core/src/actions/multicall.test.ts new file mode 100644 index 000000000..cf2d7c0dd --- /dev/null +++ b/wagmi-project/packages/core/src/actions/multicall.test.ts @@ -0,0 +1,46 @@ +import { abi, address, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { multicall } from './multicall.js' + +test('default', async () => { + await expect( + multicall(config, { + contracts: [ + { + address: address.wagmiMintExample, + abi: abi.wagmiMintExample, + functionName: 'balanceOf', + args: ['0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC'], + }, + ], + }), + ).resolves.toMatchInlineSnapshot(` + [ + { + "result": 4n, + "status": "success", + }, + ] + `) +}) + +test('allowFailure', async () => { + await expect( + multicall(config, { + allowFailure: false, + contracts: [ + { + address: address.wagmiMintExample, + abi: abi.wagmiMintExample, + functionName: 'balanceOf', + args: ['0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC'], + }, + ], + }), + ).resolves.toMatchInlineSnapshot(` + [ + 4n, + ] + `) +}) diff --git a/wagmi-project/packages/core/src/actions/multicall.ts b/wagmi-project/packages/core/src/actions/multicall.ts new file mode 100644 index 000000000..528bb0118 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/multicall.ts @@ -0,0 +1,42 @@ +import type { + ContractFunctionParameters, + MulticallErrorType as viem_MulticallErrorType, + MulticallParameters as viem_MulticallParameters, + MulticallReturnType as viem_MulticallReturnType, +} from 'viem' +import { multicall as viem_multicall } from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { ChainIdParameter } from '../types/properties.js' +import { getAction } from '../utils/getAction.js' + +export type MulticallParameters< + contracts extends readonly unknown[] = readonly ContractFunctionParameters[], + allowFailure extends boolean = true, + config extends Config = Config, +> = viem_MulticallParameters & ChainIdParameter + +export type MulticallReturnType< + contracts extends readonly unknown[] = readonly ContractFunctionParameters[], + allowFailure extends boolean = true, +> = viem_MulticallReturnType + +export type MulticallErrorType = viem_MulticallErrorType + +export async function multicall< + config extends Config, + const contracts extends readonly ContractFunctionParameters[], + allowFailure extends boolean = true, +>( + config: config, + parameters: MulticallParameters, +): Promise> { + const { allowFailure = true, chainId, contracts, ...rest } = parameters + const client = config.getClient({ chainId }) + const action = getAction(client, viem_multicall, 'multicall') + return action({ + allowFailure, + contracts, + ...rest, + }) as Promise> +} diff --git a/wagmi-project/packages/core/src/actions/prepareTransactionRequest.test-d.ts b/wagmi-project/packages/core/src/actions/prepareTransactionRequest.test-d.ts new file mode 100644 index 000000000..a8a009115 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/prepareTransactionRequest.test-d.ts @@ -0,0 +1,80 @@ +import { accounts, config } from '@wagmi/test' +import { http, parseEther } from 'viem' +import { celo, mainnet } from 'viem/chains' +import { expectTypeOf, test } from 'vitest' + +import { createConfig } from '../createConfig.js' +import { + type PrepareTransactionRequestParameters, + prepareTransactionRequest, +} from './prepareTransactionRequest.js' + +const targetAccount = accounts[1] + +test('default', async () => { + const response = await prepareTransactionRequest(config, { + chainId: 1, + to: '0x', + value: parseEther('1'), + }) + const { nonce: _nonce, ...request } = response + request.to + request.chainId + + expectTypeOf(response).toMatchTypeOf<{ + chainId: 1 + }>() +}) + +test('chain formatters', async () => { + const config = createConfig({ + chains: [celo, mainnet], + transports: { [celo.id]: http(), [mainnet.id]: http() }, + }) + + type Result = PrepareTransactionRequestParameters + expectTypeOf().toMatchTypeOf<{ + chainId?: typeof celo.id | typeof mainnet.id | undefined + feeCurrency?: `0x${string}` | undefined + }>() + const request = await prepareTransactionRequest(config, { + to: targetAccount, + value: parseEther('0.01'), + feeCurrency: '0x', + }) + if (request.chainId === celo.id) { + expectTypeOf(request.chainId).toEqualTypeOf(celo.id) + expectTypeOf(request.feeCurrency).toEqualTypeOf<`0x${string}` | undefined>() + } + + type Result2 = PrepareTransactionRequestParameters< + typeof config, + typeof celo.id + > + expectTypeOf().toMatchTypeOf<{ + feeCurrency?: `0x${string}` | undefined + }>() + const request2 = await prepareTransactionRequest(config, { + chainId: celo.id, + to: targetAccount, + value: parseEther('0.01'), + feeCurrency: '0x', + }) + expectTypeOf(request2.chainId).toEqualTypeOf(celo.id) + expectTypeOf(request2.feeCurrency).toEqualTypeOf<`0x${string}` | undefined>() + + type Result3 = PrepareTransactionRequestParameters< + typeof config, + typeof mainnet.id + > + expectTypeOf().not.toMatchTypeOf<{ + feeCurrency?: `0x${string}` | undefined + }>() + prepareTransactionRequest(config, { + chainId: mainnet.id, + to: targetAccount, + value: parseEther('0.01'), + // @ts-expect-error + feeCurrency: '0x', + }) +}) diff --git a/wagmi-project/packages/core/src/actions/prepareTransactionRequest.test.ts b/wagmi-project/packages/core/src/actions/prepareTransactionRequest.test.ts new file mode 100644 index 000000000..271037af8 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/prepareTransactionRequest.test.ts @@ -0,0 +1,108 @@ +import { accounts, config, privateKey } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { parseEther } from 'viem' +import { privateKeyToAccount } from 'viem/accounts' +import { connect } from './connect.js' +import { disconnect } from './disconnect.js' +import { prepareTransactionRequest } from './prepareTransactionRequest.js' + +const connector = config.connectors[0]! + +test('default', async () => { + await connect(config, { connector }) + + const request = await prepareTransactionRequest(config, { + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + value: parseEther('1'), + }) + + const { + gas: _gas, + maxFeePerGas: _mfpg, + maxPriorityFeePerGas: _mpfpg, + nonce: _nonce, + ...rest + } = request + expect(rest).toMatchInlineSnapshot(` + { + "account": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "chainId": 1, + "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "to": "0x70997970c51812dc3a010c7d01b50e0d17dc79c8", + "type": "eip1559", + "value": 1000000000000000000n, + } + `) + + await disconnect(config, { connector }) +}) + +test('parameters: account', async () => { + await connect(config, { connector }) + + const request = await prepareTransactionRequest(config, { + account: accounts[0], + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + value: parseEther('1'), + }) + + const { + gas: _gas, + maxFeePerGas: _mfpg, + maxPriorityFeePerGas: _mpfpg, + nonce: _nonce, + ...rest + } = request + expect(rest).toMatchInlineSnapshot(` + { + "account": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "chainId": 1, + "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "to": "0x70997970c51812dc3a010c7d01b50e0d17dc79c8", + "type": "eip1559", + "value": 1000000000000000000n, + } + `) + + await disconnect(config, { connector }) +}) + +test('behavior: local account', async () => { + const account = privateKeyToAccount(privateKey) + + const request = await prepareTransactionRequest(config, { + account, + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + value: parseEther('1'), + }) + + const { + gas: _gas, + maxFeePerGas: _mfpg, + maxPriorityFeePerGas: _mpfpg, + nonce: _nonce, + ...rest + } = request + expect(rest).toMatchInlineSnapshot(` + { + "account": { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "nonceManager": undefined, + "publicKey": "0x048318535b54105d4a7aae60c08fc45f9687181b4fdfc625bd1a753fa7397fed753547f11ca8696646f2f3acb08e31016afac23e630c5d11f59f61fef57b0d2aa5", + "sign": [Function], + "signAuthorization": [Function], + "signMessage": [Function], + "signTransaction": [Function], + "signTypedData": [Function], + "source": "privateKey", + "type": "local", + }, + "chainId": 1, + "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "to": "0x70997970c51812dc3a010c7d01b50e0d17dc79c8", + "type": "eip1559", + "value": 1000000000000000000n, + } + `) +}) diff --git a/wagmi-project/packages/core/src/actions/prepareTransactionRequest.ts b/wagmi-project/packages/core/src/actions/prepareTransactionRequest.ts new file mode 100644 index 000000000..36ed81f77 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/prepareTransactionRequest.ts @@ -0,0 +1,125 @@ +import type { + Account, + Address, + Chain, + PrepareTransactionRequestErrorType as viem_PrepareTransactionRequestErrorType, + PrepareTransactionRequestParameters as viem_PrepareTransactionRequestParameters, + PrepareTransactionRequestRequest as viem_PrepareTransactionRequestRequest, + PrepareTransactionRequestReturnType as viem_PrepareTransactionRequestReturnType, +} from 'viem' +import { prepareTransactionRequest as viem_prepareTransactionRequest } from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { SelectChains } from '../types/chain.js' +import type { ChainIdParameter } from '../types/properties.js' +import type { + Compute, + IsNarrowable, + UnionCompute, + UnionStrictOmit, +} from '../types/utils.js' +import { getAction } from '../utils/getAction.js' +import { getAccount } from './getAccount.js' + +export type PrepareTransactionRequestParameters< + config extends Config = Config, + chainId extends + | config['chains'][number]['id'] + | undefined = config['chains'][number]['id'], + request extends viem_PrepareTransactionRequestRequest< + SelectChains[0], + SelectChains[0] + > = viem_PrepareTransactionRequestRequest< + SelectChains[0], + SelectChains[0] + >, + /// + chains extends readonly Chain[] = SelectChains, +> = { + [key in keyof chains]: UnionCompute< + UnionStrictOmit< + viem_PrepareTransactionRequestParameters< + chains[key], + Account, + chains[key], + Account | Address, + request extends viem_PrepareTransactionRequestRequest< + chains[key], + chains[key] + > + ? request + : never + >, + 'chain' + > & + ChainIdParameter & { + to: Address + } + > +}[number] + +export type PrepareTransactionRequestReturnType< + config extends Config = Config, + chainId extends + | config['chains'][number]['id'] + | undefined = config['chains'][number]['id'], + request extends viem_PrepareTransactionRequestRequest< + SelectChains[0], + SelectChains[0] + > = viem_PrepareTransactionRequestRequest< + SelectChains[0], + SelectChains[0] + >, + /// + chains extends readonly Chain[] = SelectChains, +> = { + [key in keyof chains]: Compute< + viem_PrepareTransactionRequestReturnType< + IsNarrowable extends true ? chains[key] : undefined, + Account, + chains[key], + Account, + request extends viem_PrepareTransactionRequestRequest< + IsNarrowable extends true ? chains[key] : undefined, + chains[key] + > + ? request + : never + > + > & { + chainId: chains[key]['id'] + } +}[number] + +export type PrepareTransactionRequestErrorType = + viem_PrepareTransactionRequestErrorType + +/** https://wagmi.sh/core/api/actions/prepareTransactionRequest */ +export async function prepareTransactionRequest< + config extends Config, + chainId extends config['chains'][number]['id'] | undefined, + const request extends viem_PrepareTransactionRequestRequest< + SelectChains['0'], + SelectChains['0'] + >, +>( + config: config, + parameters: PrepareTransactionRequestParameters, +): Promise> { + const { account: account_, chainId, ...rest } = parameters + + const account = account_ ?? getAccount(config).address + const client = config.getClient({ chainId }) + + const action = getAction( + client, + viem_prepareTransactionRequest, + 'prepareTransactionRequest', + ) + return action({ + ...rest, + ...(account ? { account } : {}), + } as unknown as viem_PrepareTransactionRequestParameters) as unknown as Promise< + PrepareTransactionRequestReturnType + > +} diff --git a/wagmi-project/packages/core/src/actions/readContract.test-d.ts b/wagmi-project/packages/core/src/actions/readContract.test-d.ts new file mode 100644 index 000000000..a667ec03e --- /dev/null +++ b/wagmi-project/packages/core/src/actions/readContract.test-d.ts @@ -0,0 +1,74 @@ +import { abi, config } from '@wagmi/test' +import { assertType, expectTypeOf, test } from 'vitest' + +import { readContract } from './readContract.js' + +test('default', async () => { + const result = await readContract(config, { + address: '0x', + abi: abi.erc20, + functionName: 'balanceOf', + args: ['0x'], + }) + expectTypeOf(result).toEqualTypeOf() +}) + +test('overloads', async () => { + const result1 = await readContract(config, { + address: '0x', + abi: abi.viewOverloads, + functionName: 'foo', + }) + assertType(result1) + + const result2 = await readContract(config, { + address: '0x', + abi: abi.viewOverloads, + functionName: 'foo', + args: [], + }) + assertType(result2) + + const result3 = await readContract(config, { + address: '0x', + abi: abi.viewOverloads, + functionName: 'foo', + args: ['0x'], + }) + // @ts-ignore – TODO: Fix https://github.com/wevm/viem/issues/1916 + assertType(result3) + + const result4 = await readContract(config, { + address: '0x', + abi: abi.viewOverloads, + functionName: 'foo', + args: ['0x', '0x'], + }) + assertType<{ + foo: `0x${string}` + bar: `0x${string}` + // @ts-ignore – TODO: Fix https://github.com/wevm/viem/issues/1916 + }>(result4) +}) + +test('deployless read (bytecode)', async () => { + const result = await readContract(config, { + code: '0x', + abi: abi.erc20, + functionName: 'balanceOf', + args: ['0x'], + }) + expectTypeOf(result).toEqualTypeOf() +}) + +test('deployless read (factory)', async () => { + const result = await readContract(config, { + address: '0x', + abi: abi.erc20, + functionName: 'balanceOf', + args: ['0x'], + factory: '0x', + factoryData: '0x', + }) + expectTypeOf(result).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/core/src/actions/readContract.test.ts b/wagmi-project/packages/core/src/actions/readContract.test.ts new file mode 100644 index 000000000..37f0db7e0 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/readContract.test.ts @@ -0,0 +1,37 @@ +import { abi, address, bytecode, chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { readContract } from './readContract.js' + +test('default', async () => { + await expect( + readContract(config, { + address: address.wagmiMintExample, + abi: abi.wagmiMintExample, + functionName: 'balanceOf', + args: ['0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC'], + }), + ).resolves.toMatchInlineSnapshot('4n') +}) + +test('parameters: chainId', async () => { + await expect( + readContract(config, { + address: address.wagmiMintExample, + abi: abi.wagmiMintExample, + functionName: 'balanceOf', + args: ['0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC'], + chainId: chain.mainnet2.id, + }), + ).resolves.toMatchInlineSnapshot('4n') +}) + +test('parameters: deployless read (bytecode)', async () => { + await expect( + readContract(config, { + abi: abi.wagmiMintExample, + functionName: 'name', + code: bytecode.wagmiMintExample, + }), + ).resolves.toMatchInlineSnapshot(`"wagmi"`) +}) diff --git a/wagmi-project/packages/core/src/actions/readContract.ts b/wagmi-project/packages/core/src/actions/readContract.ts new file mode 100644 index 000000000..e01e74e9f --- /dev/null +++ b/wagmi-project/packages/core/src/actions/readContract.ts @@ -0,0 +1,58 @@ +import type { Abi } from 'viem' +import type { ContractFunctionArgs, ContractFunctionName } from 'viem' +import { + type ReadContractErrorType as viem_ReadContractErrorType, + type ReadContractParameters as viem_ReadContractParameters, + type ReadContractReturnType as viem_ReadContractReturnType, + readContract as viem_readContract, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { ChainIdParameter } from '../types/properties.js' +import { getAction } from '../utils/getAction.js' + +export type ReadContractParameters< + abi extends Abi | readonly unknown[] = Abi, + functionName extends ContractFunctionName< + abi, + 'pure' | 'view' + > = ContractFunctionName, + args extends ContractFunctionArgs< + abi, + 'pure' | 'view', + functionName + > = ContractFunctionArgs, + config extends Config = Config, +> = viem_ReadContractParameters & + ChainIdParameter + +export type ReadContractReturnType< + abi extends Abi | readonly unknown[] = Abi, + functionName extends ContractFunctionName< + abi, + 'pure' | 'view' + > = ContractFunctionName, + args extends ContractFunctionArgs< + abi, + 'pure' | 'view', + functionName + > = ContractFunctionArgs, +> = viem_ReadContractReturnType + +export type ReadContractErrorType = viem_ReadContractErrorType + +/** https://wagmi.sh/core/api/actions/readContract */ +export function readContract< + config extends Config, + const abi extends Abi | readonly unknown[], + functionName extends ContractFunctionName, + args extends ContractFunctionArgs, +>( + config: config, + parameters: ReadContractParameters, +): Promise> { + const { chainId, ...rest } = parameters + const client = config.getClient({ chainId }) + const action = getAction(client, viem_readContract, 'readContract') + return action(rest as any) +} diff --git a/wagmi-project/packages/core/src/actions/readContracts.test-d.ts b/wagmi-project/packages/core/src/actions/readContracts.test-d.ts new file mode 100644 index 000000000..a68b2acab --- /dev/null +++ b/wagmi-project/packages/core/src/actions/readContracts.test-d.ts @@ -0,0 +1,118 @@ +import { abi, config } from '@wagmi/test' +import { assertType, expectTypeOf, test } from 'vitest' + +import { readContracts } from './readContracts.js' + +test('default', async () => { + const result = await readContracts(config, { + contracts: [ + { + address: '0x', + abi: abi.erc20, + functionName: 'balanceOf', + args: ['0x'], + chainId: 1, + }, + { + address: '0x', + abi: abi.wagmiMintExample, + functionName: 'tokenURI', + args: [123n], + }, + ], + }) + expectTypeOf(result).toEqualTypeOf< + [ + ( + | { error: Error; result?: undefined; status: 'failure' } + | { error?: undefined; result: bigint; status: 'success' } + ), + ( + | { error: Error; result?: undefined; status: 'failure' } + | { error?: undefined; result: string; status: 'success' } + ), + ] + >() +}) + +test('allowFailure', async () => { + const result = await readContracts(config, { + allowFailure: false, + contracts: [ + { + address: '0x', + abi: abi.erc20, + functionName: 'balanceOf', + args: ['0x'], + }, + { + address: '0x', + abi: abi.wagmiMintExample, + functionName: 'tokenURI', + args: [123n], + }, + ], + }) + expectTypeOf(result).toEqualTypeOf<[bigint, string]>() +}) + +test('overloads', async () => { + const result1 = await readContracts(config, { + allowFailure: false, + contracts: [ + { + address: '0x', + abi: abi.viewOverloads, + functionName: 'foo', + }, + ], + }) + assertType<[number] | undefined>(result1) + + const result2 = await readContracts(config, { + allowFailure: false, + contracts: [ + { + address: '0x', + abi: abi.viewOverloads, + functionName: 'foo', + args: [], + }, + ], + }) + assertType<[number] | undefined>(result2) + + const result3 = await readContracts(config, { + allowFailure: false, + contracts: [ + { + address: '0x', + abi: abi.viewOverloads, + functionName: 'foo', + args: ['0x'], + }, + ], + }) + assertType<[string] | undefined>(result3) + + const result4 = await readContracts(config, { + allowFailure: false, + contracts: [ + { + address: '0x', + abi: abi.viewOverloads, + functionName: 'foo', + args: ['0x', '0x'], + }, + ], + }) + assertType< + | [ + { + foo: `0x${string}` + bar: `0x${string}` + }, + ] + | undefined + >(result4) +}) diff --git a/wagmi-project/packages/core/src/actions/readContracts.test.ts b/wagmi-project/packages/core/src/actions/readContracts.test.ts new file mode 100644 index 000000000..4bc33f60d --- /dev/null +++ b/wagmi-project/packages/core/src/actions/readContracts.test.ts @@ -0,0 +1,678 @@ +import { abi, address, chain } from '@wagmi/test' +import { http, type MulticallResponse } from 'viem' +import { expect, expectTypeOf, test, vi } from 'vitest' + +import { createConfig } from '../createConfig.js' +import * as multicall from './multicall.js' +import * as readContract from './readContract.js' +import { readContracts } from './readContracts.js' + +const contracts = [ + { + abi: abi.wagmigotchi, + address: address.wagmigotchi, + functionName: 'love', + args: ['0x27a69ffba1e939ddcfecc8c7e0f967b872bac65c'], + }, + { + abi: abi.wagmigotchi, + address: address.wagmigotchi, + functionName: 'love', + args: ['0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC'], + }, + { + abi: abi.wagmigotchi, + address: address.wagmigotchi, + functionName: 'getAlive', + }, + { + abi: abi.mloot, + address: address.mloot, + functionName: 'tokenOfOwnerByIndex', + args: ['0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', 0n], + }, +] + +const { mainnet, mainnet2, optimism } = chain + +const config = createConfig({ + chains: [ + { ...mainnet, contracts: { multicall3: undefined } }, + { ...mainnet2, contracts: { multicall3: undefined } }, + ], + transports: { + [mainnet.id]: http(), + [mainnet2.id]: http(), + }, +}) + +test('default', async () => { + const spy = vi.spyOn(multicall, 'multicall') + const config = createConfig({ + chains: [mainnet, mainnet2], + transports: { + [mainnet.id]: http(), + [mainnet2.id]: http(), + }, + }) + const results = await readContracts(config, { contracts }) + + expect(spy).toHaveBeenCalledWith(config, { + allowFailure: true, + contracts, + chainId: mainnet.id, + }) + expect(results).toMatchInlineSnapshot(` + [ + { + "result": 2n, + "status": "success", + }, + { + "result": 1n, + "status": "success", + }, + { + "result": false, + "status": "success", + }, + { + "result": 370395n, + "status": "success", + }, + ] + `) +}) + +test.skip('falls back to readContract if multicall is not available', async () => { + const spy = vi.spyOn(readContract, 'readContract') + const config = createConfig({ + chains: [mainnet, { ...mainnet2, contracts: { multicall3: undefined } }], + transports: { + [mainnet.id]: http(), + [mainnet2.id]: http(), + }, + }) + const chainId = mainnet2.id + const contracts = [ + { + abi: abi.wagmigotchi, + address: address.wagmigotchi, + chainId: mainnet2.id, + functionName: 'love', + args: ['0x27a69ffba1e939ddcfecc8c7e0f967b872bac65c'], + }, + { + abi: abi.wagmigotchi, + address: address.wagmigotchi, + chainId: mainnet2.id, + functionName: 'love', + args: ['0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC'], + }, + { + abi: abi.wagmigotchi, + address: address.wagmigotchi, + chainId: mainnet2.id, + functionName: 'getAlive', + }, + { + abi: abi.mloot, + address: address.mloot, + chainId: mainnet2.id, + functionName: 'tokenOfOwnerByIndex', + args: ['0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', 0n], + }, + ] as const + const results = await readContracts(config, { contracts }) + expectTypeOf(results).toEqualTypeOf< + [ + MulticallResponse, + MulticallResponse, + MulticallResponse, + MulticallResponse, + ] + >() + + for (const contract of contracts) { + expect(spy).toBeCalledWith(config, { ...contract, chainId }) + } + expect(results).toMatchInlineSnapshot(` + [ + { + "result": 2n, + "status": "success", + }, + { + "result": 1n, + "status": "success", + }, + { + "result": false, + "status": "success", + }, + { + "result": 370395n, + "status": "success", + }, + ] + `) +}) + +test.skip('multichain', async () => { + const config = createConfig({ + chains: [mainnet, mainnet2, optimism], + transports: { + [mainnet.id]: http(), + [mainnet2.id]: http(), + [optimism.id]: http(), + }, + }) + + const spy = vi.spyOn(multicall, 'multicall') + const mainnetContracts = [ + { + abi: abi.wagmigotchi, + address: address.wagmigotchi, + chainId: mainnet.id, + functionName: 'love', + args: ['0x27a69ffba1e939ddcfecc8c7e0f967b872bac65c'], + }, + { + abi: abi.wagmigotchi, + address: address.wagmigotchi, + chainId: mainnet.id, + functionName: 'love', + args: ['0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC'], + }, + { + abi: abi.wagmigotchi, + address: address.wagmigotchi, + chainId: mainnet.id, + functionName: 'love', + args: ['0xd2135CfB216b74109775236E36d4b433F1DF507B'], + }, + ] as const + const mainnet2Contracts = [ + { + abi: abi.wagmigotchi, + address: address.wagmigotchi, + chainId: mainnet2.id, + functionName: 'getAlive', + }, + { + abi: abi.mloot, + address: address.mloot, + chainId: mainnet2.id, + functionName: 'tokenOfOwnerByIndex', + args: ['0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', 0n], + }, + ] as const + const optimismContracts = [ + { + abi: abi.erc20, + address: address.optimism.usdc, + chainId: optimism.id, + functionName: 'symbol', + }, + { + abi: abi.erc20, + address: address.optimism.usdc, + chainId: optimism.id, + functionName: 'balanceOf', + args: ['0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC'], + }, + ] as const + const results = await readContracts(config, { + contracts: [ + mainnetContracts[0]!, + optimismContracts[0]!, + mainnetContracts[1]!, + mainnet2Contracts[0]!, + optimismContracts[1]!, + mainnet2Contracts[1]!, + mainnetContracts[2]!, + ], + }) + expectTypeOf(results).toEqualTypeOf< + [ + MulticallResponse, + MulticallResponse, + MulticallResponse, + MulticallResponse, + MulticallResponse, + MulticallResponse, + MulticallResponse, + ] + >() + + expect(spy).toHaveBeenCalledWith(config, { + allowFailure: true, + contracts: mainnetContracts, + chainId: mainnet.id, + overrides: undefined, + }) + expect(spy).toHaveBeenCalledWith(config, { + allowFailure: true, + contracts: mainnet2Contracts, + chainId: mainnet2.id, + overrides: undefined, + }) + expect(results).toMatchInlineSnapshot(` + [ + { + "result": 2n, + "status": "success", + }, + { + "result": "USDC", + "status": "success", + }, + { + "result": 1n, + "status": "success", + }, + { + "result": false, + "status": "success", + }, + { + "result": 10959340n, + "status": "success", + }, + { + "result": 370395n, + "status": "success", + }, + { + "result": 0n, + "status": "success", + }, + ] + `) +}) + +test('multi-chain: falls back to readContract if multicall is not available', async () => { + const config = createConfig({ + chains: [mainnet, { ...optimism, contracts: { multicall3: undefined } }], + transports: { + [mainnet.id]: http(), + [optimism.id]: http(), + }, + }) + + const spy = vi.spyOn(readContract, 'readContract') + const mainnetContracts = [ + { + abi: abi.wagmigotchi, + address: address.wagmigotchi, + chainId: mainnet.id, + functionName: 'love', + args: ['0x27a69ffba1e939ddcfecc8c7e0f967b872bac65c'], + }, + { + abi: abi.wagmigotchi, + address: address.wagmigotchi, + chainId: mainnet.id, + functionName: 'love', + args: ['0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC'], + }, + ] as const + const optimismContracts = [ + { + abi: abi.erc20, + address: address.optimism.usdc, + chainId: optimism.id, + functionName: 'symbol', + }, + { + abi: abi.erc20, + address: address.optimism.usdc, + chainId: optimism.id, + functionName: 'balanceOf', + args: ['0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC'], + }, + ] as const + const results = await readContracts(config, { + contracts: [...mainnetContracts, ...optimismContracts], + }) + expectTypeOf(results).toEqualTypeOf< + [ + MulticallResponse, + MulticallResponse, + MulticallResponse, + MulticallResponse, + ] + >() + + for (const contract of mainnetContracts) { + expect(spy).toBeCalledWith(config, { ...contract, chainId: mainnet.id }) + } + for (const contract of optimismContracts) { + expect(spy).toBeCalledWith(config, { ...contract, chainId: optimism.id }) + } + expect(results).toMatchInlineSnapshot(` + [ + { + "result": 2n, + "status": "success", + }, + { + "result": 1n, + "status": "success", + }, + { + "result": "USDC", + "status": "success", + }, + { + "result": 10959340n, + "status": "success", + }, + ] + `) +}) + +test('throws if allowFailure=false & a contract method fails', async () => { + await expect( + readContracts(config, { + allowFailure: false, + contracts: [ + ...contracts, + { + abi: abi.mloot, + address: address.mloot, + functionName: 'tokenOfOwnerByIndex', + args: ['0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', 69420n], + }, + ], + }), + ).rejects.toThrowErrorMatchingInlineSnapshot( + ` + [ContractFunctionExecutionError: The contract function "tokenOfOwnerByIndex" reverted with the following reason: + ERC721Enumerable: owner index out of bounds + + Contract Call: + address: 0x1dfe7ca09e99d10835bf73044a23b73fc20623df + function: tokenOfOwnerByIndex(address owner, uint256 index) + args: (0xA0Cf798816D4b9b9866b5330EEa46a18382f251e, 69420) + + Docs: https://viem.sh/docs/contract/readContract + Version: viem@2.29.2] + `, + ) +}) + +test('allowFailure=true & a contract method fails', async () => { + expect( + await readContracts(config, { + allowFailure: true, + contracts: [ + ...contracts, + { + abi: abi.mloot, + address: address.mloot, + functionName: 'tokenOfOwnerByIndex', + args: ['0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', 69420n], + }, + { + abi: abi.mloot, + address: address.mloot, + functionName: 'tokenOfOwnerByIndex', + args: ['0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', 69421n], + }, + ], + }), + ).toMatchInlineSnapshot(` + [ + { + "result": 2n, + "status": "success", + }, + { + "result": 1n, + "status": "success", + }, + { + "result": false, + "status": "success", + }, + { + "result": 370395n, + "status": "success", + }, + { + "error": [ContractFunctionExecutionError: The contract function "tokenOfOwnerByIndex" reverted with the following reason: + ERC721Enumerable: owner index out of bounds + + Contract Call: + address: 0x1dfe7ca09e99d10835bf73044a23b73fc20623df + function: tokenOfOwnerByIndex(address owner, uint256 index) + args: (0xA0Cf798816D4b9b9866b5330EEa46a18382f251e, 69420) + + Docs: https://viem.sh/docs/contract/readContract + Version: viem@2.29.2], + "result": undefined, + "status": "failure", + }, + { + "error": [ContractFunctionExecutionError: The contract function "tokenOfOwnerByIndex" reverted with the following reason: + ERC721Enumerable: owner index out of bounds + + Contract Call: + address: 0x1dfe7ca09e99d10835bf73044a23b73fc20623df + function: tokenOfOwnerByIndex(address owner, uint256 index) + args: (0xA0Cf798816D4b9b9866b5330EEa46a18382f251e, 69421) + + Docs: https://viem.sh/docs/contract/readContract + Version: viem@2.29.2], + "result": undefined, + "status": "failure", + }, + ] + `) +}) + +test('throws if allowFailure=false & encoding contract function data fails', async () => { + await expect( + readContracts(config, { + allowFailure: false, + contracts: [ + ...contracts, + { + abi: abi.mloot, + functionName: 'ownerOf', + // address is not the mloot contract + address: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC', + args: [10e30], + }, + ], + }), + ).rejects.toThrowErrorMatchingInlineSnapshot( + ` + [ContractFunctionExecutionError: The contract function "ownerOf" returned no data ("0x"). + + This could be due to any of the following: + - The contract does not have the function "ownerOf", + - The parameters passed to the contract function may be invalid, or + - The address is not a contract. + + Contract Call: + address: 0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC + function: ownerOf(uint256 tokenId) + args: (1e+31) + + Docs: https://viem.sh/docs/contract/readContract + Version: viem@2.29.2] + `, + ) +}) + +test('allowFailure=true & encoding contract function data fails', async () => { + expect( + await readContracts(config, { + allowFailure: true, + contracts: [ + ...contracts, + { + abi: abi.mloot, + functionName: 'ownerOf', + // address is not the mloot contract + address: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC', + args: [10e30], + }, + { + abi: abi.mloot, + functionName: 'ownerOf', + // address is not the mloot contract + address: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC', + args: [10e30], + }, + ], + }), + ).toMatchInlineSnapshot(` + [ + { + "result": 2n, + "status": "success", + }, + { + "result": 1n, + "status": "success", + }, + { + "result": false, + "status": "success", + }, + { + "result": 370395n, + "status": "success", + }, + { + "error": [ContractFunctionExecutionError: The contract function "ownerOf" returned no data ("0x"). + + This could be due to any of the following: + - The contract does not have the function "ownerOf", + - The parameters passed to the contract function may be invalid, or + - The address is not a contract. + + Contract Call: + address: 0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC + function: ownerOf(uint256 tokenId) + args: (1e+31) + + Docs: https://viem.sh/docs/contract/readContract + Version: viem@2.29.2], + "result": undefined, + "status": "failure", + }, + { + "error": [ContractFunctionExecutionError: The contract function "ownerOf" returned no data ("0x"). + + This could be due to any of the following: + - The contract does not have the function "ownerOf", + - The parameters passed to the contract function may be invalid, or + - The address is not a contract. + + Contract Call: + address: 0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC + function: ownerOf(uint256 tokenId) + args: (1e+31) + + Docs: https://viem.sh/docs/contract/readContract + Version: viem@2.29.2], + "result": undefined, + "status": "failure", + }, + ] + `) +}) + +test('should throw if allowFailure=false & a contract has no response', async () => { + await expect( + readContracts(config, { + allowFailure: false, + contracts: [ + ...contracts, + { + abi: abi.wagmigotchi, + functionName: 'love', + // address is not the wagmigotchi contract + address: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC', + args: ['0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC'], + }, + ], + }), + ).rejects.toThrowErrorMatchingInlineSnapshot( + ` + [ContractFunctionExecutionError: The contract function "love" returned no data ("0x"). + + This could be due to any of the following: + - The contract does not have the function "love", + - The parameters passed to the contract function may be invalid, or + - The address is not a contract. + + Contract Call: + address: 0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC + function: love(address) + args: (0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC) + + Docs: https://viem.sh/docs/contract/readContract + Version: viem@2.29.2] + `, + ) +}) + +test('allowFailure=true & a contract has no response', async () => { + expect( + await readContracts(config, { + allowFailure: true, + contracts: [ + ...contracts, + { + abi: abi.wagmigotchi, + functionName: 'love', + // address is not the wagmigotchi contract + address: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC', + args: ['0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC'], + }, + ], + }), + ).toMatchInlineSnapshot(` + [ + { + "result": 2n, + "status": "success", + }, + { + "result": 1n, + "status": "success", + }, + { + "result": false, + "status": "success", + }, + { + "result": 370395n, + "status": "success", + }, + { + "error": [ContractFunctionExecutionError: The contract function "love" returned no data ("0x"). + + This could be due to any of the following: + - The contract does not have the function "love", + - The parameters passed to the contract function may be invalid, or + - The address is not a contract. + + Contract Call: + address: 0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC + function: love(address) + args: (0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC) + + Docs: https://viem.sh/docs/contract/readContract + Version: viem@2.29.2], + "result": undefined, + "status": "failure", + }, + ] + `) +}) diff --git a/wagmi-project/packages/core/src/actions/readContracts.ts b/wagmi-project/packages/core/src/actions/readContracts.ts new file mode 100644 index 000000000..45f2a0cef --- /dev/null +++ b/wagmi-project/packages/core/src/actions/readContracts.ts @@ -0,0 +1,96 @@ +import type { + ContractFunctionParameters, + MulticallParameters as viem_MulticallParameters, + MulticallReturnType as viem_MulticallReturnType, +} from 'viem' +import { ContractFunctionExecutionError } from 'viem' + +import type { Config } from '../createConfig.js' +import type { ChainIdParameter } from '../types/properties.js' +import { type MulticallErrorType, multicall } from './multicall.js' +import { type ReadContractErrorType, readContract } from './readContract.js' + +export type ReadContractsParameters< + contracts extends readonly unknown[] = readonly ContractFunctionParameters[], + allowFailure extends boolean = true, + config extends Config = Config, +> = viem_MulticallParameters< + contracts, + allowFailure, + { properties: ChainIdParameter } +> + +export type ReadContractsReturnType< + contracts extends readonly unknown[] = readonly ContractFunctionParameters[], + allowFailure extends boolean = true, +> = viem_MulticallReturnType + +export type ReadContractsErrorType = MulticallErrorType | ReadContractErrorType + +export async function readContracts< + config extends Config, + const contracts extends readonly ContractFunctionParameters[], + allowFailure extends boolean = true, +>( + config: config, + parameters: ReadContractsParameters, +): Promise> { + const { allowFailure = true, blockNumber, blockTag, ...rest } = parameters + const contracts = parameters.contracts as (ContractFunctionParameters & { + chainId?: number | undefined + })[] + + try { + const contractsByChainId: { + [chainId: number]: { + contract: ContractFunctionParameters + index: number + }[] + } = {} + for (const [index, contract] of contracts.entries()) { + const chainId = contract.chainId ?? config.state.chainId + if (!contractsByChainId[chainId]) contractsByChainId[chainId] = [] + contractsByChainId[chainId]?.push({ contract, index }) + } + const promises = () => + Object.entries(contractsByChainId).map(([chainId, contracts]) => + multicall(config, { + ...rest, + allowFailure, + blockNumber, + blockTag, + chainId: Number.parseInt(chainId), + contracts: contracts.map(({ contract }) => contract), + }), + ) + + const multicallResults = (await Promise.all(promises())).flat() + // Reorder the contract results back to the order they were + // provided in. + const resultIndexes = Object.values(contractsByChainId).flatMap( + (contracts) => contracts.map(({ index }) => index), + ) + return multicallResults.reduce((results, result, index) => { + if (results) (results as unknown[])[resultIndexes[index]!] = result + return results + }, [] as unknown[]) as ReadContractsReturnType + } catch (error) { + if (error instanceof ContractFunctionExecutionError) throw error + + const promises = () => + contracts.map((contract) => + readContract(config, { ...contract, blockNumber, blockTag }), + ) + if (allowFailure) + return (await Promise.allSettled(promises())).map((result) => { + if (result.status === 'fulfilled') + return { result: result.value, status: 'success' } + return { error: result.reason, result: undefined, status: 'failure' } + }) as ReadContractsReturnType + + return (await Promise.all(promises())) as ReadContractsReturnType< + contracts, + allowFailure + > + } +} diff --git a/wagmi-project/packages/core/src/actions/reconnect.test.ts b/wagmi-project/packages/core/src/actions/reconnect.test.ts new file mode 100644 index 000000000..910d16e30 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/reconnect.test.ts @@ -0,0 +1,119 @@ +import { accounts, config, mainnet } from '@wagmi/test' +import { http } from 'viem' +import { afterEach, expect, test, vi } from 'vitest' + +import { mock } from '../connectors/mock.js' +import { createConfig } from '../createConfig.js' +import { createStorage } from '../createStorage.js' +import { connect } from './connect.js' +import { disconnect } from './disconnect.js' +import { reconnect } from './reconnect.js' + +const connector = config._internal.connectors.setup( + mock({ + accounts, + features: { reconnect: true }, + }), +) + +afterEach(async () => { + if (config.state.current === connector.uid) + await disconnect(config, { connector }) + else if (config.state.current) await disconnect(config) +}) + +test('default', async () => { + await expect( + reconnect(config, { connectors: [connector] }), + ).resolves.toStrictEqual([]) + expect(config.state.status).toEqual('disconnected') +}) + +test('parameters: connectors (Connector)', async () => { + await connect(config, { connector }) + await expect( + reconnect(config, { connectors: [connector] }), + ).resolves.toMatchObject( + expect.arrayContaining([ + expect.objectContaining({ + accounts: expect.any(Array), + chainId: expect.any(Number), + }), + ]), + ) + expect(config.state.status).toEqual('connected') +}) + +test('parameters: connectors (CreateConnectorFn)', async () => { + const connector = mock({ + accounts, + features: { reconnect: true }, + }) + await connect(config, { connector }) + await expect( + reconnect(config, { connectors: [connector] }), + ).resolves.toMatchObject( + expect.arrayContaining([ + expect.objectContaining({ + accounts: expect.any(Array), + chainId: expect.any(Number), + }), + ]), + ) + expect(config.state.status).toEqual('connected') +}) + +test("behavior: doesn't reconnect if already reconnecting", async () => { + const previousStatus = config.state.status + config.setState((x) => ({ ...x, status: 'reconnecting' })) + await expect( + reconnect(config, { connectors: [connector] }), + ).resolves.toStrictEqual([]) + config.setState((x) => ({ ...x, status: previousStatus })) +}) + +test('behavior: recovers from invalid state', async () => { + const state = { + 'wagmi.store': JSON.stringify({ + state: { + status: 'connected', // <-- invalid - `status` should not be kept in storage + chainId: 1, + current: '983b8aca245', + }, + version: Number.NaN, // mocked version is `'x.y.z'`, which will get interpreted as `NaN` + }), + } as Record + Object.defineProperty(window, 'localStorage', { + value: { + getItem: vi.fn((key) => state[key] ?? null), + removeItem: vi.fn((key) => state.delete?.[key]), + setItem: vi.fn((key, value) => { + state[key] = value + }), + }, + writable: true, + }) + + const storage = createStorage<{ store: object }>({ + storage: window.localStorage, + }) + + const config = createConfig({ + chains: [mainnet], + storage, + transports: { + [mainnet.id]: http(), + }, + }) + + await reconnect(config, { connectors: [connector] }) + + expect(config.state).toMatchInlineSnapshot(` + { + "chainId": 1, + "connections": Map {}, + "current": null, + "status": "disconnected", + } + `) +}) diff --git a/wagmi-project/packages/core/src/actions/reconnect.ts b/wagmi-project/packages/core/src/actions/reconnect.ts new file mode 100644 index 000000000..2234c934d --- /dev/null +++ b/wagmi-project/packages/core/src/actions/reconnect.ts @@ -0,0 +1,127 @@ +import type { Address } from 'viem' + +import type { CreateConnectorFn } from '../connectors/createConnector.js' +import type { Config, Connection, Connector } from '../createConfig.js' +import type { ErrorType } from '../errors/base.js' +import type { Compute } from '../types/utils.js' + +export type ReconnectParameters = { + /** Connectors to attempt reconnect with */ + connectors?: readonly (CreateConnectorFn | Connector)[] | undefined +} + +export type ReconnectReturnType = Compute[] + +export type ReconnectErrorType = ErrorType + +let isReconnecting = false + +/** https://wagmi.sh/core/api/actions/reconnect */ +export async function reconnect( + config: Config, + parameters: ReconnectParameters = {}, +): Promise { + // If already reconnecting, do nothing + if (isReconnecting) return [] + isReconnecting = true + + config.setState((x) => ({ + ...x, + status: x.current ? 'reconnecting' : 'connecting', + })) + + const connectors: Connector[] = [] + if (parameters.connectors?.length) { + for (const connector_ of parameters.connectors) { + let connector: Connector + // "Register" connector if not already created + if (typeof connector_ === 'function') + connector = config._internal.connectors.setup(connector_) + else connector = connector_ + connectors.push(connector) + } + } else connectors.push(...config.connectors) + + // Try recently-used connectors first + let recentConnectorId: string | null | undefined + try { + recentConnectorId = await config.storage?.getItem('recentConnectorId') + } catch {} + const scores: Record = {} + for (const [, connection] of config.state.connections) { + scores[connection.connector.id] = 1 + } + if (recentConnectorId) scores[recentConnectorId] = 0 + const sorted = + Object.keys(scores).length > 0 + ? // .toSorted() + [...connectors].sort( + (a, b) => (scores[a.id] ?? 10) - (scores[b.id] ?? 10), + ) + : connectors + + // Iterate through each connector and try to connect + let connected = false + const connections: Connection[] = [] + const providers: unknown[] = [] + for (const connector of sorted) { + const provider = await connector.getProvider().catch(() => undefined) + if (!provider) continue + + // If we already have an instance of this connector's provider, + // then we have already checked it (ie. injected connectors can + // share the same `window.ethereum` instance, so we don't want to + // connect to it again). + if (providers.some((x) => x === provider)) continue + + const isAuthorized = await connector.isAuthorized() + if (!isAuthorized) continue + + const data = await connector + .connect({ isReconnecting: true }) + .catch(() => null) + if (!data) continue + + connector.emitter.off('connect', config._internal.events.connect) + connector.emitter.on('change', config._internal.events.change) + connector.emitter.on('disconnect', config._internal.events.disconnect) + + config.setState((x) => { + const connections = new Map(connected ? x.connections : new Map()).set( + connector.uid, + { accounts: data.accounts, chainId: data.chainId, connector }, + ) + return { + ...x, + current: connected ? x.current : connector.uid, + connections, + } + }) + connections.push({ + accounts: data.accounts as readonly [Address, ...Address[]], + chainId: data.chainId, + connector, + }) + providers.push(provider) + connected = true + } + + // Prevent overwriting connected status from race condition + if ( + config.state.status === 'reconnecting' || + config.state.status === 'connecting' + ) { + // If connecting didn't succeed, set to disconnected + if (!connected) + config.setState((x) => ({ + ...x, + connections: new Map(), + current: null, + status: 'disconnected', + })) + else config.setState((x) => ({ ...x, status: 'connected' })) + } + + isReconnecting = false + return connections +} diff --git a/wagmi-project/packages/core/src/actions/sendCalls.test.ts b/wagmi-project/packages/core/src/actions/sendCalls.test.ts new file mode 100644 index 000000000..cb25e2b0b --- /dev/null +++ b/wagmi-project/packages/core/src/actions/sendCalls.test.ts @@ -0,0 +1,121 @@ +import { accounts, config } from '@wagmi/test' +import { parseEther } from 'viem' +import { expect, test } from 'vitest' + +import { connect } from './connect.js' +import { disconnect } from './disconnect.js' +import { sendCalls } from './sendCalls.js' + +const connector = config.connectors[0]! + +test('default', async () => { + await connect(config, { connector }) + await expect( + sendCalls(config, { + calls: [ + { + data: '0xdeadbeef', + to: accounts[1], + value: parseEther('1'), + }, + { + to: accounts[2], + value: parseEther('2'), + }, + { + to: accounts[3], + value: parseEther('3'), + }, + ], + }), + ).resolves.toMatchInlineSnapshot( + ` + { + "id": "0x5dedb5a4ff8968db37459b52b83cbdc92b01c9c709c9cff26e345ef5cf27f92e", + } + `, + ) + await disconnect(config, { connector }) +}) + +test('behavior: not connected', async () => { + await expect( + sendCalls(config, { + calls: [ + { + to: accounts[1], + value: parseEther('1'), + }, + { + to: accounts[2], + value: parseEther('2'), + }, + { + to: accounts[3], + value: parseEther('3'), + }, + ], + }), + ).rejects.toThrowErrorMatchingInlineSnapshot(` + [ConnectorNotConnectedError: Connector not connected. + + Version: @wagmi/core@x.y.z] + `) +}) + +test('behavior: nullish account (account filled by wallet)', async () => { + await expect( + sendCalls(config, { + account: null, + connector, + calls: [ + { + to: accounts[1], + value: parseEther('1'), + }, + { + to: accounts[2], + value: parseEther('2'), + }, + { + to: accounts[3], + value: parseEther('3'), + }, + ], + }), + ).resolves.toMatchInlineSnapshot( + ` + { + "id": "0x035b56a56a5b2fea10e194bae4c846b415de48a8288c7eb704ba7880edcc29a0", + } + `, + ) +}) + +test('behavior: account does not exist on connector', async () => { + await connect(config, { connector }) + await expect( + sendCalls(config, { + account: '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + calls: [ + { + to: accounts[1], + value: parseEther('1'), + }, + { + to: accounts[2], + value: parseEther('2'), + }, + { + to: accounts[3], + value: parseEther('3'), + }, + ], + }), + ).rejects.toThrowErrorMatchingInlineSnapshot(` + [ConnectorAccountNotFoundError: Account "0xA0Cf798816D4b9b9866b5330EEa46a18382f251e" not found for connector "Mock Connector". + + Version: @wagmi/core@x.y.z] + `) + await disconnect(config, { connector }) +}) diff --git a/wagmi-project/packages/core/src/actions/sendCalls.ts b/wagmi-project/packages/core/src/actions/sendCalls.ts new file mode 100644 index 000000000..6139455d6 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/sendCalls.ts @@ -0,0 +1,74 @@ +import type { Account, Chain } from 'viem' +import { + type SendCallsErrorType as viem_SendCallsErrorType, + type SendCallsParameters as viem_SendCallsParameters, + type SendCallsReturnType as viem_SendCallsReturnType, + sendCalls as viem_sendCalls, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { BaseErrorType, ErrorType } from '../errors/base.js' +import type { SelectChains } from '../types/chain.js' +import type { + ChainIdParameter, + ConnectorParameter, +} from '../types/properties.js' +import type { Compute } from '../types/utils.js' +import { + type GetConnectorClientErrorType, + getConnectorClient, +} from './getConnectorClient.js' + +export type SendCallsParameters< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + calls extends readonly unknown[] = readonly unknown[], + /// + chains extends readonly Chain[] = SelectChains, +> = { + [key in keyof chains]: Compute< + Omit< + viem_SendCallsParameters, + 'chain' + > & + ChainIdParameter & + ConnectorParameter + > +}[number] + +export type SendCallsReturnType = viem_SendCallsReturnType + +export type SendCallsErrorType = + // getConnectorClient() + | GetConnectorClientErrorType + // base + | BaseErrorType + | ErrorType + // viem + | viem_SendCallsErrorType + +/** https://wagmi.sh/core/api/actions/sendCalls */ +export async function sendCalls< + const calls extends readonly unknown[], + config extends Config, + chainId extends config['chains'][number]['id'], +>( + config: config, + parameters: SendCallsParameters, +): Promise { + const { account, chainId, connector, calls, ...rest } = parameters + + const client = await getConnectorClient(config, { + account, + chainId, + connector, + }) + + return viem_sendCalls(client, { + ...(rest as any), + ...(typeof account !== 'undefined' ? { account } : {}), + calls, + chain: chainId ? { id: chainId } : undefined, + }) +} diff --git a/wagmi-project/packages/core/src/actions/sendTransaction.test-d.ts b/wagmi-project/packages/core/src/actions/sendTransaction.test-d.ts new file mode 100644 index 000000000..54ce62a94 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/sendTransaction.test-d.ts @@ -0,0 +1,50 @@ +import { http, parseEther } from 'viem' +import { celo, mainnet } from 'viem/chains' +import { expectTypeOf, test } from 'vitest' + +import { createConfig } from '../createConfig.js' +import { + type SendTransactionParameters, + sendTransaction, +} from './sendTransaction.js' + +test('chain formatters', () => { + const config = createConfig({ + chains: [mainnet, celo], + transports: { [celo.id]: http(), [mainnet.id]: http() }, + }) + + type Result = SendTransactionParameters + expectTypeOf().toMatchTypeOf<{ + chainId?: typeof celo.id | typeof mainnet.id | undefined + feeCurrency?: `0x${string}` | undefined + }>() + sendTransaction(config, { + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), + feeCurrency: '0x', + }) + + type Result2 = SendTransactionParameters + expectTypeOf().toMatchTypeOf<{ + feeCurrency?: `0x${string}` | undefined + }>() + sendTransaction(config, { + chainId: celo.id, + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), + feeCurrency: '0x', + }) + + type Result3 = SendTransactionParameters + expectTypeOf().not.toMatchTypeOf<{ + feeCurrency?: `0x${string}` | undefined + }>() + sendTransaction(config, { + chainId: mainnet.id, + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), + // @ts-expect-error + feeCurrency: '0x', + }) +}) diff --git a/wagmi-project/packages/core/src/actions/sendTransaction.test.ts b/wagmi-project/packages/core/src/actions/sendTransaction.test.ts new file mode 100644 index 000000000..e263d9667 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/sendTransaction.test.ts @@ -0,0 +1,105 @@ +import { config, privateKey, transactionHashRegex } from '@wagmi/test' +import { parseEther } from 'viem' +import { beforeEach, expect, test } from 'vitest' + +import { privateKeyToAccount } from 'viem/accounts' +import { connect } from './connect.js' +import { disconnect } from './disconnect.js' +import { sendTransaction } from './sendTransaction.js' + +const connector = config.connectors[0]! + +beforeEach(async () => { + if (config.state.current === connector.uid) + await disconnect(config, { connector }) +}) + +test('default', async () => { + const result = await connect(config, { connector }) + config.state.connections.set(connector.uid, { + ...result, + // Switch up the current account because the default one is running out of funds somewhere + accounts: result.accounts.slice(1) as unknown as typeof result.accounts, + connector, + }) + await expect( + sendTransaction(config, { + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.0001'), + }), + ).resolves.toMatch(transactionHashRegex) + await disconnect(config, { connector }) +}) + +test('behavior: connector not connected', async () => { + await connect(config, { connector }) + await expect( + sendTransaction(config, { + connector: config.connectors[1], + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.0001'), + }), + ).rejects.toThrowErrorMatchingInlineSnapshot(` + [ConnectorNotConnectedError: Connector not connected. + + Version: @wagmi/core@x.y.z] + `) + await disconnect(config, { connector }) +}) + +test('behavior: account does not exist on connector', async () => { + await connect(config, { connector }) + await expect( + sendTransaction(config, { + account: '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.0001'), + }), + ).rejects.toThrowErrorMatchingInlineSnapshot(` + [ConnectorAccountNotFoundError: Account "0xA0Cf798816D4b9b9866b5330EEa46a18382f251e" not found for connector "Mock Connector". + + Version: @wagmi/core@x.y.z] + `) + await disconnect(config, { connector }) +}) + +test('behavior: value exceeds balance', async () => { + await connect(config, { connector }) + await expect( + sendTransaction(config, { + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('99999'), + }), + ).rejects.toThrowErrorMatchingInlineSnapshot(` + [TransactionExecutionError: The total cost (gas * gas fee + value) of executing this transaction exceeds the balance of the account. + + This error could arise when the account does not have enough funds to: + - pay for the total gas fee, + - pay for the value to send. + + The cost of the transaction is calculated as \`gas * gas fee + value\`, where: + - \`gas\` is the amount of gas needed for transaction to execute, + - \`gas fee\` is the gas fee, + - \`value\` is the amount of ether to send to the recipient. + + Request Arguments: + from: 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 + to: 0xd2135CfB216b74109775236E36d4b433F1DF507B + value: 99999 ETH + + Details: Insufficient funds for gas * price + value + Version: viem@2.29.2] + `) + await disconnect(config, { connector }) +}) + +test('behavior: local account', async () => { + const account = privateKeyToAccount(privateKey) + await expect( + sendTransaction(config, { + account, + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.000001'), + }), + ).resolves.toMatch(transactionHashRegex) +}) diff --git a/wagmi-project/packages/core/src/actions/sendTransaction.ts b/wagmi-project/packages/core/src/actions/sendTransaction.ts new file mode 100644 index 000000000..76bc3a420 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/sendTransaction.ts @@ -0,0 +1,86 @@ +import type { + Account, + Chain, + Client, + TransactionRequest, + SendTransactionErrorType as viem_SendTransactionErrorType, + SendTransactionParameters as viem_SendTransactionParameters, + SendTransactionReturnType as viem_SendTransactionReturnType, +} from 'viem' +import { sendTransaction as viem_sendTransaction } from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { BaseErrorType, ErrorType } from '../errors/base.js' +import type { SelectChains } from '../types/chain.js' +import type { + ChainIdParameter, + ConnectorParameter, +} from '../types/properties.js' +import type { Compute } from '../types/utils.js' +import { getAction } from '../utils/getAction.js' +import { + type GetConnectorClientErrorType, + getConnectorClient, +} from './getConnectorClient.js' + +export type SendTransactionParameters< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + /// + chains extends readonly Chain[] = SelectChains, +> = { + [key in keyof chains]: Compute< + Omit< + viem_SendTransactionParameters, + 'chain' | 'gas' + > & + ChainIdParameter & + ConnectorParameter + > +}[number] & { + /** Gas provided for transaction execution. */ + gas?: TransactionRequest['gas'] | null +} + +export type SendTransactionReturnType = viem_SendTransactionReturnType + +export type SendTransactionErrorType = + // getConnectorClient() + | GetConnectorClientErrorType + // base + | BaseErrorType + | ErrorType + // viem + | viem_SendTransactionErrorType + +/** https://wagmi.sh/core/api/actions/sendTransaction */ +export async function sendTransaction< + config extends Config, + chainId extends config['chains'][number]['id'], +>( + config: config, + parameters: SendTransactionParameters, +): Promise { + const { account, chainId, connector, ...rest } = parameters + + let client: Client + if (typeof account === 'object' && account?.type === 'local') + client = config.getClient({ chainId }) + else + client = await getConnectorClient(config, { + account: account ?? undefined, + chainId, + connector, + }) + + const action = getAction(client, viem_sendTransaction, 'sendTransaction') + const hash = await action({ + ...(rest as any), + ...(account ? { account } : {}), + chain: chainId ? { id: chainId } : null, + gas: rest.gas ?? undefined, + }) + + return hash +} diff --git a/wagmi-project/packages/core/src/actions/showCallsStatus.test.ts b/wagmi-project/packages/core/src/actions/showCallsStatus.test.ts new file mode 100644 index 000000000..582224238 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/showCallsStatus.test.ts @@ -0,0 +1,36 @@ +import { accounts, config, testClient } from '@wagmi/test' +import { parseEther } from 'viem' +import { test } from 'vitest' + +import { connect } from './connect.js' +import { disconnect } from './disconnect.js' +import { sendCalls } from './sendCalls.js' +import { showCallsStatus } from './showCallsStatus.js' + +const connector = config.connectors[0]! + +test('default', async () => { + await connect(config, { connector }) + const { id } = await sendCalls(config, { + calls: [ + { + data: '0xdeadbeef', + to: accounts[1], + value: parseEther('1'), + }, + { + to: accounts[2], + value: parseEther('2'), + }, + { + to: accounts[3], + value: parseEther('3'), + }, + ], + }) + await testClient.mainnet.mine({ blocks: 1 }) + await showCallsStatus(config, { + id, + }) + await disconnect(config, { connector }) +}) diff --git a/wagmi-project/packages/core/src/actions/showCallsStatus.ts b/wagmi-project/packages/core/src/actions/showCallsStatus.ts new file mode 100644 index 000000000..e3c6ae067 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/showCallsStatus.ts @@ -0,0 +1,27 @@ +import { + type ShowCallsStatusErrorType as viem_ShowCallsStatusErrorType, + type ShowCallsStatusParameters as viem_ShowCallsStatusParameters, + type ShowCallsStatusReturnType as viem_ShowCallsStatusReturnType, + showCallsStatus as viem_showCallsStatus, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { ConnectorParameter } from '../types/properties.js' +import { getConnectorClient } from './getConnectorClient.js' + +export type ShowCallsStatusParameters = viem_ShowCallsStatusParameters & + ConnectorParameter + +export type ShowCallsStatusReturnType = viem_ShowCallsStatusReturnType + +export type ShowCallsStatusErrorType = viem_ShowCallsStatusErrorType + +/** https://wagmi.sh/core/api/actions/showCallsStatus */ +export async function showCallsStatus( + config: config, + parameters: ShowCallsStatusParameters, +): Promise { + const { connector, id } = parameters + const client = await getConnectorClient(config, { connector }) + return viem_showCallsStatus(client, { id }) +} diff --git a/wagmi-project/packages/core/src/actions/signMessage.test.ts b/wagmi-project/packages/core/src/actions/signMessage.test.ts new file mode 100644 index 000000000..5b87c7d65 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/signMessage.test.ts @@ -0,0 +1,67 @@ +import { accounts, config, privateKey } from '@wagmi/test' +import { recoverMessageAddress } from 'viem' +import { privateKeyToAccount } from 'viem/accounts' +import { expect, test } from 'vitest' + +import { mock } from '../connectors/mock.js' +import { connect } from './connect.js' +import { disconnect } from './disconnect.js' +import { getAccount } from './getAccount.js' +import { signMessage } from './signMessage.js' + +const connector = config.connectors[0]! + +test('default', async () => { + await connect(config, { connector }) + const signature = await signMessage(config, { message: 'foo bar baz' }) + await expect( + recoverMessageAddress({ + message: 'foo bar baz', + signature, + }), + ).resolves.toEqual(getAccount(config).address) + await disconnect(config, { connector }) +}) + +test('behavior: local account', async () => { + const account = privateKeyToAccount(privateKey) + const signature = await signMessage(config, { + account, + message: 'foo bar baz', + }) + await expect( + recoverMessageAddress({ + message: 'foo bar baz', + signature, + }), + ).resolves.toEqual(account.address) +}) + +test('behavior: user rejected request', async () => { + const connector_ = config._internal.connectors.setup( + mock({ + accounts, + features: { signMessageError: true }, + }), + ) + await connect(config, { connector: connector_ }) + await expect( + signMessage(config, { message: 'foo bar baz' }), + ).rejects.toMatchInlineSnapshot(` + [UserRejectedRequestError: User rejected the request. + + Details: Failed to sign message. + Version: viem@2.29.2] + `) + await disconnect(config, { connector: connector_ }) +}) + +test('behavior: not connected', async () => { + await expect( + signMessage(config, { message: 'foo bar baz' }), + ).rejects.toMatchInlineSnapshot(` + [ConnectorNotConnectedError: Connector not connected. + + Version: @wagmi/core@x.y.z] + `) +}) diff --git a/wagmi-project/packages/core/src/actions/signMessage.ts b/wagmi-project/packages/core/src/actions/signMessage.ts new file mode 100644 index 000000000..67f0c293a --- /dev/null +++ b/wagmi-project/packages/core/src/actions/signMessage.ts @@ -0,0 +1,51 @@ +import type { Account, Client } from 'viem' +import { + type SignMessageErrorType as viem_SignMessageErrorType, + type SignMessageParameters as viem_SignMessageParameters, + type SignMessageReturnType as viem_SignMessageReturnType, + signMessage as viem_signMessage, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { BaseErrorType, ErrorType } from '../errors/base.js' +import type { ConnectorParameter } from '../types/properties.js' +import type { Compute } from '../types/utils.js' +import { getAction } from '../utils/getAction.js' +import { + type GetConnectorClientErrorType, + getConnectorClient, +} from './getConnectorClient.js' + +export type SignMessageParameters = Compute< + viem_SignMessageParameters & ConnectorParameter +> + +export type SignMessageReturnType = viem_SignMessageReturnType + +export type SignMessageErrorType = + // getConnectorClient() + | GetConnectorClientErrorType + // base + | BaseErrorType + | ErrorType + // viem + | viem_SignMessageErrorType + +/** https://wagmi.sh/core/api/actions/signMessage */ +export async function signMessage( + config: Config, + parameters: SignMessageParameters, +): Promise { + const { account, connector, ...rest } = parameters + + let client: Client + if (typeof account === 'object' && account.type === 'local') + client = config.getClient() + else client = await getConnectorClient(config, { account, connector }) + + const action = getAction(client, viem_signMessage, 'signMessage') + return action({ + ...rest, + ...(account ? { account } : {}), + } as viem_SignMessageParameters) +} diff --git a/wagmi-project/packages/core/src/actions/signTypedData.test-d.ts b/wagmi-project/packages/core/src/actions/signTypedData.test-d.ts new file mode 100644 index 000000000..a502d26e9 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/signTypedData.test-d.ts @@ -0,0 +1,31 @@ +import { config, typedData } from '@wagmi/test' +import { test } from 'vitest' + +import { signTypedData } from './signTypedData.js' + +test('default', async () => { + signTypedData(config, { + types: typedData.basic.types, + primaryType: 'Mail', + message: typedData.basic.message, + }) +}) + +test('domain', async () => { + signTypedData(config, { + primaryType: 'EIP712Domain', + domain: {}, + }) +}) + +test('custom domain', async () => { + signTypedData(config, { + types: { + EIP712Domain: [{ type: 'uint256', name: 'chainId' }], + }, + primaryType: 'EIP712Domain', + domain: { + chainId: 123n, + }, + }) +}) diff --git a/wagmi-project/packages/core/src/actions/signTypedData.test.ts b/wagmi-project/packages/core/src/actions/signTypedData.test.ts new file mode 100644 index 000000000..b72ecab8c --- /dev/null +++ b/wagmi-project/packages/core/src/actions/signTypedData.test.ts @@ -0,0 +1,85 @@ +import { accounts, config, privateKey, typedData } from '@wagmi/test' +import { recoverTypedDataAddress } from 'viem' +import { expect, test } from 'vitest' + +import { privateKeyToAccount } from 'viem/accounts' +import { mock } from '../connectors/mock.js' +import { connect } from './connect.js' +import { disconnect } from './disconnect.js' +import { getAccount } from './getAccount.js' +import { signTypedData } from './signTypedData.js' + +const connector = config.connectors[0]! + +test('default', async () => { + await connect(config, { connector }) + const signature = await signTypedData(config, { + types: typedData.basic.types, + primaryType: 'Mail', + message: typedData.basic.message, + }) + await expect( + recoverTypedDataAddress({ + types: typedData.basic.types, + primaryType: 'Mail', + message: typedData.basic.message, + signature, + }), + ).resolves.toBe(getAccount(config).address) + await disconnect(config, { connector }) +}) + +test('behavior: user rejected request', async () => { + const connector_ = config._internal.connectors.setup( + mock({ + accounts, + features: { signTypedDataError: true }, + }), + ) + await connect(config, { connector: connector_ }) + await expect( + signTypedData(config, { + types: typedData.basic.types, + primaryType: 'Mail', + message: typedData.basic.message, + }), + ).rejects.toMatchInlineSnapshot(` + [UserRejectedRequestError: User rejected the request. + + Details: Failed to sign typed data. + Version: viem@2.29.2] + `) + await disconnect(config, { connector: connector_ }) +}) + +test('behavior: not connected', async () => { + await expect( + signTypedData(config, { + types: typedData.basic.types, + primaryType: 'Mail', + message: typedData.basic.message, + }), + ).rejects.toMatchInlineSnapshot(` + [ConnectorNotConnectedError: Connector not connected. + + Version: @wagmi/core@x.y.z] + `) +}) + +test('behavior: local account', async () => { + const account = privateKeyToAccount(privateKey) + const signature = await signTypedData(config, { + account, + types: typedData.basic.types, + primaryType: 'Mail', + message: typedData.basic.message, + }) + await expect( + recoverTypedDataAddress({ + types: typedData.basic.types, + primaryType: 'Mail', + message: typedData.basic.message, + signature, + }), + ).resolves.toBe(account.address) +}) diff --git a/wagmi-project/packages/core/src/actions/signTypedData.ts b/wagmi-project/packages/core/src/actions/signTypedData.ts new file mode 100644 index 000000000..22cea1266 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/signTypedData.ts @@ -0,0 +1,60 @@ +import type { Account, Client, TypedData } from 'viem' +import { + type SignMessageErrorType as viem_SignMessageErrorType, + type SignTypedDataParameters as viem_SignTypedDataParameters, + type SignTypedDataReturnType as viem_SignTypedDataReturnType, + signTypedData as viem_signTypedData, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { BaseErrorType, ErrorType } from '../errors/base.js' +import type { ConnectorParameter } from '../types/properties.js' +import type { UnionCompute } from '../types/utils.js' +import { getAction } from '../utils/getAction.js' +import { + type GetConnectorClientErrorType, + getConnectorClient, +} from './getConnectorClient.js' + +export type SignTypedDataParameters< + typedData extends TypedData | Record = TypedData, + primaryType extends keyof typedData | 'EIP712Domain' = keyof typedData, + /// + primaryTypes = typedData extends TypedData ? keyof typedData : string, +> = UnionCompute< + viem_SignTypedDataParameters & + ConnectorParameter +> + +export type SignTypedDataReturnType = viem_SignTypedDataReturnType + +export type SignTypedDataErrorType = + // getConnectorClient() + | GetConnectorClientErrorType + // base + | BaseErrorType + | ErrorType + // viem + | viem_SignMessageErrorType + +/** https://wagmi.sh/core/api/actions/signTypedData */ +export async function signTypedData< + const typedData extends TypedData | Record, + primaryType extends keyof typedData | 'EIP712Domain', +>( + config: Config, + parameters: SignTypedDataParameters, +): Promise { + const { account, connector, ...rest } = parameters + + let client: Client + if (typeof account === 'object' && account.type === 'local') + client = config.getClient() + else client = await getConnectorClient(config, { account, connector }) + + const action = getAction(client, viem_signTypedData, 'signTypedData') + return action({ + ...rest, + ...(account ? { account } : {}), + } as unknown as viem_SignTypedDataParameters) +} diff --git a/wagmi-project/packages/core/src/actions/simulateContract.test-d.ts b/wagmi-project/packages/core/src/actions/simulateContract.test-d.ts new file mode 100644 index 000000000..3f893ff8f --- /dev/null +++ b/wagmi-project/packages/core/src/actions/simulateContract.test-d.ts @@ -0,0 +1,160 @@ +import { abi, config } from '@wagmi/test' +import { http, type Address } from 'viem' +import { celo, mainnet } from 'viem/chains' +import { expectTypeOf, test } from 'vitest' + +import { createConfig } from '../createConfig.js' +import { + type SimulateContractParameters, + type SimulateContractReturnType, + simulateContract, +} from './simulateContract.js' + +test('default', async () => { + const response = await simulateContract(config, { + address: '0x', + abi: abi.erc20, + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + chainId: 1, + }) + + expectTypeOf(response).toMatchTypeOf<{ + result: boolean + request: { + chainId: 1 + abi: readonly [ + { + readonly name: 'transferFrom' + readonly type: 'function' + readonly stateMutability: 'nonpayable' + readonly inputs: readonly [ + { readonly type: 'address'; readonly name: 'sender' }, + { readonly type: 'address'; readonly name: 'recipient' }, + { readonly type: 'uint256'; readonly name: 'amount' }, + ] + readonly outputs: readonly [{ type: 'bool' }] + }, + ] + functionName: 'transferFrom' + args: readonly [Address, Address, bigint] + } + }>() +}) + +test('chain formatters', async () => { + const config = createConfig({ + chains: [celo, mainnet], + transports: { [celo.id]: http(), [mainnet.id]: http() }, + }) + + type Result = SimulateContractParameters< + typeof abi.erc20, + 'transferFrom', + [Address, Address, bigint], + typeof config + > + expectTypeOf().toMatchTypeOf<{ + chainId?: typeof celo.id | typeof mainnet.id | undefined + feeCurrency?: `0x${string}` | undefined + }>() + const response = await simulateContract(config, { + account: '0x', + address: '0x', + abi: abi.erc20, + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + feeCurrency: '0x', + }) + + if (response.chainId === celo.id) { + expectTypeOf(response.chainId).toEqualTypeOf(celo.id) + expectTypeOf(response.request.feeCurrency).toEqualTypeOf< + `0x${string}` | undefined + >() + } + + type Result2 = SimulateContractParameters< + typeof abi.erc20, + 'transferFrom', + [Address, Address, bigint], + typeof config, + typeof celo.id + > + expectTypeOf().toMatchTypeOf<{ + functionName: 'approve' | 'transfer' | 'transferFrom' + args: readonly [Address, Address, bigint] + feeCurrency?: `0x${string}` | undefined + }>() + const response2 = await simulateContract(config, { + chainId: celo.id, + account: '0x', + address: '0x', + abi: abi.erc20, + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + feeCurrency: '0x', + }) + expectTypeOf(response2.chainId).toEqualTypeOf(celo.id) + expectTypeOf(response2.request.feeCurrency).toEqualTypeOf< + `0x${string}` | undefined + >() + + type Result3 = SimulateContractParameters< + typeof abi.erc20, + 'transferFrom', + [Address, Address, bigint], + typeof config, + typeof mainnet.id + > + expectTypeOf().toMatchTypeOf<{ + functionName: 'approve' | 'transfer' | 'transferFrom' + args: readonly [Address, Address, bigint] + }>() + expectTypeOf().not.toMatchTypeOf<{ + feeCurrency?: `0x${string}` | undefined + }>() + simulateContract(config, { + chainId: mainnet.id, + account: '0x', + address: '0x', + abi: abi.erc20, + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + // @ts-expect-error + feeCurrency: '0x', + }) +}) + +test('SimulateContractParameters', () => { + type Result = SimulateContractParameters< + typeof abi.erc20, + 'transferFrom', + [Address, Address, bigint], + typeof config, + (typeof config)['chains'][number]['id'] + > + expectTypeOf().toMatchTypeOf<{ + chainId?: (typeof config)['chains'][number]['id'] | undefined + functionName: 'approve' | 'transfer' | 'transferFrom' + args: readonly [Address, Address, bigint] + }>() +}) + +test('SimulateContractReturnType', () => { + type Result = SimulateContractReturnType< + typeof abi.erc20, + 'transferFrom', + [Address, Address, bigint], + typeof config, + (typeof config)['chains'][number]['id'] + > + expectTypeOf().toMatchTypeOf<{ + result: boolean + request: { + functionName: 'transferFrom' + args: readonly [Address, Address, bigint] + chainId: (typeof config)['chains'][number]['id'] + } + }>() +}) diff --git a/wagmi-project/packages/core/src/actions/simulateContract.test.ts b/wagmi-project/packages/core/src/actions/simulateContract.test.ts new file mode 100644 index 000000000..a52cbd556 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/simulateContract.test.ts @@ -0,0 +1,84 @@ +import { abi, accounts, address, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { connect } from './connect.js' +import { disconnect } from './disconnect.js' +import { simulateContract } from './simulateContract.js' + +const connector = config.connectors[0]! + +test('parameters: account', async () => { + await expect( + simulateContract(config, { + account: accounts[0], + address: address.wagmiMintExample, + abi: abi.wagmiMintExample, + functionName: 'mint', + }), + ).resolves.toMatchInlineSnapshot(` + { + "chainId": 1, + "request": { + "abi": [ + { + "inputs": [], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + ], + "account": { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "type": "json-rpc", + }, + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "args": undefined, + "chainId": undefined, + "dataSuffix": undefined, + "functionName": "mint", + }, + "result": undefined, + } + `) +}) + +test('parameters: connector', async () => { + await connect(config, { connector }) + + await expect( + simulateContract(config, { + address: address.wagmiMintExample, + abi: abi.wagmiMintExample, + functionName: 'mint', + connector, + }), + ).resolves.toMatchInlineSnapshot(` + { + "chainId": 1, + "request": { + "abi": [ + { + "inputs": [], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + ], + "account": { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "type": "json-rpc", + }, + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "args": undefined, + "chainId": undefined, + "dataSuffix": undefined, + "functionName": "mint", + }, + "result": undefined, + } + `) + + await disconnect(config, { connector }) +}) diff --git a/wagmi-project/packages/core/src/actions/simulateContract.ts b/wagmi-project/packages/core/src/actions/simulateContract.ts new file mode 100644 index 000000000..e5fe5655f --- /dev/null +++ b/wagmi-project/packages/core/src/actions/simulateContract.ts @@ -0,0 +1,166 @@ +import type { + Abi, + Account, + Address, + Chain, + ContractFunctionArgs, + ContractFunctionName, +} from 'viem' +import { + type SimulateContractErrorType as viem_SimulateContractErrorType, + type SimulateContractParameters as viem_SimulateContractParameters, + type SimulateContractReturnType as viem_SimulateContractReturnType, + simulateContract as viem_simulateContract, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { BaseErrorType, ErrorType } from '../errors/base.js' +import type { SelectChains } from '../types/chain.js' +import type { + ChainIdParameter, + ConnectorParameter, +} from '../types/properties.js' +import type { + Compute, + PartialBy, + UnionCompute, + UnionStrictOmit, +} from '../types/utils.js' +import { getAction } from '../utils/getAction.js' +import { + type GetConnectorClientErrorType, + getConnectorClient, +} from './getConnectorClient.js' + +export type SimulateContractParameters< + abi extends Abi | readonly unknown[] = Abi, + functionName extends ContractFunctionName< + abi, + 'nonpayable' | 'payable' + > = ContractFunctionName, + args extends ContractFunctionArgs< + abi, + 'nonpayable' | 'payable', + functionName + > = ContractFunctionArgs, + config extends Config = Config, + chainId extends + | config['chains'][number]['id'] + | undefined = config['chains'][number]['id'], + /// + chains extends readonly Chain[] = SelectChains, +> = { + [key in keyof chains]: UnionCompute< + UnionStrictOmit< + viem_SimulateContractParameters< + abi, + functionName, + args, + chains[key], + chains[key], + Account | Address + >, + 'chain' + > + > & + ChainIdParameter & + ConnectorParameter +}[number] + +export type SimulateContractReturnType< + abi extends Abi | readonly unknown[] = Abi, + functionName extends ContractFunctionName< + abi, + 'nonpayable' | 'payable' + > = ContractFunctionName, + args extends ContractFunctionArgs< + abi, + 'nonpayable' | 'payable', + functionName + > = ContractFunctionArgs, + config extends Config = Config, + chainId extends + | config['chains'][number]['id'] + | undefined = config['chains'][number]['id'], + /// + chains extends readonly Chain[] = SelectChains, +> = { + [key in keyof chains]: viem_SimulateContractReturnType< + abi, + functionName, + args, + chains[key], + Account, + chains[key] + > & { + chainId: chains[key]['id'] + request: Compute< + PartialBy< + { chainId: chainId; chain: chains[key] }, + chainId extends config['chains'][number]['id'] ? never : 'chainId' + > + > + } +}[number] + +export type SimulateContractErrorType = + // getConnectorClient() + | GetConnectorClientErrorType + // base + | BaseErrorType + | ErrorType + // viem + | viem_SimulateContractErrorType + +/** https://wagmi.sh/core/api/actions/simulateContract */ +export async function simulateContract< + config extends Config, + const abi extends Abi | readonly unknown[], + functionName extends ContractFunctionName, + args extends ContractFunctionArgs< + abi, + 'nonpayable' | 'payable', + functionName + >, + chainId extends config['chains'][number]['id'] | undefined = undefined, +>( + config: config, + parameters: SimulateContractParameters< + abi, + functionName, + args, + config, + chainId + >, +): Promise< + SimulateContractReturnType +> { + const { abi, chainId, connector, ...rest } = + parameters as SimulateContractParameters + + let account: Address | Account + if (parameters.account) account = parameters.account + else { + const connectorClient = await getConnectorClient(config, { + chainId, + connector, + }) + account = connectorClient.account + } + + const client = config.getClient({ chainId }) + const action = getAction(client, viem_simulateContract, 'simulateContract') + const { result, request } = await action({ ...rest, abi, account }) + + return { + chainId: client.chain.id, + result, + request: { ...request, chainId }, + } as unknown as SimulateContractReturnType< + abi, + functionName, + args, + config, + chainId + > +} diff --git a/wagmi-project/packages/core/src/actions/switchAccount.test.ts b/wagmi-project/packages/core/src/actions/switchAccount.test.ts new file mode 100644 index 000000000..97d0e84b3 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/switchAccount.test.ts @@ -0,0 +1,32 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { connect } from './connect.js' +import { disconnect } from './disconnect.js' +import { getAccount } from './getAccount.js' +import { switchAccount } from './switchAccount.js' + +const connector1 = config.connectors[0]! +const connector2 = config.connectors[1]! + +test('default', async () => { + await connect(config, { connector: connector2 }) + await connect(config, { connector: connector1 }) + + const address1 = getAccount(config).address + + await switchAccount(config, { connector: connector2 }) + + const address2 = getAccount(config).address + expect(address2).toBeDefined() + expect(address1).not.toBe(address2) + + await switchAccount(config, { connector: connector1 }) + + const address3 = getAccount(config).address + expect(address3).toBeDefined() + expect(address1).toBe(address3) + + await disconnect(config, { connector: connector1 }) + await disconnect(config, { connector: connector2 }) +}) diff --git a/wagmi-project/packages/core/src/actions/switchAccount.ts b/wagmi-project/packages/core/src/actions/switchAccount.ts new file mode 100644 index 000000000..ec577a57c --- /dev/null +++ b/wagmi-project/packages/core/src/actions/switchAccount.ts @@ -0,0 +1,45 @@ +import type { Address } from 'viem' + +import type { Config, Connector } from '../createConfig.js' +import type { BaseError, ErrorType } from '../errors/base.js' +import { + ConnectorNotConnectedError, + type ConnectorNotConnectedErrorType, +} from '../errors/config.js' + +export type SwitchAccountParameters = { + connector: Connector +} + +export type SwitchAccountReturnType = { + accounts: readonly [Address, ...Address[]] + chainId: + | config['chains'][number]['id'] + | (number extends config['chains'][number]['id'] ? number : number & {}) +} + +export type SwitchAccountErrorType = + | ConnectorNotConnectedErrorType + | BaseError + | ErrorType + +/** https://wagmi.sh/core/api/actions/switchAccount */ +export async function switchAccount( + config: config, + parameters: SwitchAccountParameters, +): Promise> { + const { connector } = parameters + + const connection = config.state.connections.get(connector.uid) + if (!connection) throw new ConnectorNotConnectedError() + + await config.storage?.setItem('recentConnectorId', connector.id) + config.setState((x) => ({ + ...x, + current: connector.uid, + })) + return { + accounts: connection.accounts, + chainId: connection.chainId, + } +} diff --git a/wagmi-project/packages/core/src/actions/switchChain.test.ts b/wagmi-project/packages/core/src/actions/switchChain.test.ts new file mode 100644 index 000000000..466d77824 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/switchChain.test.ts @@ -0,0 +1,73 @@ +import { accounts, chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { mock } from '../connectors/mock.js' +import { connect } from './connect.js' +import { disconnect } from './disconnect.js' +import { getAccount } from './getAccount.js' +import { switchChain } from './switchChain.js' + +const connector = config.connectors[0]! + +test('default', async () => { + await connect(config, { connector }) + + const chainId1 = getAccount(config).chainId + + await switchChain(config, { chainId: chain.mainnet2.id }) + + const chainId2 = getAccount(config).chainId + expect(chainId2).toBeDefined() + expect(chainId1).not.toBe(chainId2) + + await switchChain(config, { chainId: chain.mainnet.id }) + + const chainId3 = getAccount(config).chainId + expect(chainId3).toBeDefined() + expect(chainId1).toBe(chainId3) + + await disconnect(config, { connector }) +}) + +test('behavior: user rejected request', async () => { + const connector_ = config._internal.connectors.setup( + mock({ + accounts, + features: { switchChainError: true }, + }), + ) + await connect(config, { connector: connector_ }) + await expect( + switchChain(config, { chainId: chain.mainnet.id }), + ).rejects.toMatchInlineSnapshot(` + [UserRejectedRequestError: User rejected the request. + + Details: Failed to switch chain. + Version: viem@2.29.2] + `) + await disconnect(config, { connector: connector_ }) +}) + +test('behavior: not supported', async () => { + const { switchChain: _, ...connector_ } = config._internal.connectors.setup( + mock({ accounts }), + ) + await connect(config, { connector: connector_ }) + await expect( + switchChain(config, { chainId: chain.mainnet.id }), + ).rejects.toMatchInlineSnapshot(` + [SwitchChainNotSupportedError: "Mock Connector" does not support programmatic chain switching. + + Version: @wagmi/core@x.y.z] + `) + await disconnect(config, { connector: connector_ }) +}) + +test('behavior: not connected', async () => { + const chainId = config.state.chainId + expect(config.state.chainId).toMatchInlineSnapshot('1') + await switchChain(config, { chainId: chain.mainnet2.id }) + expect(config.state.chainId).toMatchInlineSnapshot('456') + await switchChain(config, { chainId }) + expect(config.state.chainId).toMatchInlineSnapshot('1') +}) diff --git a/wagmi-project/packages/core/src/actions/switchChain.ts b/wagmi-project/packages/core/src/actions/switchChain.ts new file mode 100644 index 000000000..59f337d14 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/switchChain.ts @@ -0,0 +1,83 @@ +import type { + AddEthereumChainParameter, + UserRejectedRequestErrorType, + SwitchChainErrorType as viem_SwitchChainErrorType, +} from 'viem' + +import type { Config } from '../createConfig.js' +import type { BaseErrorType, ErrorType } from '../errors/base.js' +import { + ChainNotConfiguredError, + type ChainNotConfiguredErrorType, +} from '../errors/config.js' +import { + type ProviderNotFoundErrorType, + SwitchChainNotSupportedError, + type SwitchChainNotSupportedErrorType, +} from '../errors/connector.js' +import type { ConnectorParameter } from '../types/properties.js' +import type { Compute, ExactPartial } from '../types/utils.js' + +export type SwitchChainParameters< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +> = Compute< + ConnectorParameter & { + chainId: chainId | config['chains'][number]['id'] + addEthereumChainParameter?: + | Compute>> + | undefined + } +> + +export type SwitchChainReturnType< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +> = Extract< + config['chains'][number], + { id: Config extends config ? number : chainId } +> + +export type SwitchChainErrorType = + | SwitchChainNotSupportedErrorType + | ChainNotConfiguredErrorType + // connector.switchChain() + | ProviderNotFoundErrorType + | UserRejectedRequestErrorType + // base + | BaseErrorType + | ErrorType + // viem + | viem_SwitchChainErrorType + +/** https://wagmi.sh/core/api/actions/switchChain */ +export async function switchChain< + config extends Config, + chainId extends config['chains'][number]['id'], +>( + config: config, + parameters: SwitchChainParameters, +): Promise> { + const { addEthereumChainParameter, chainId } = parameters + + const connection = config.state.connections.get( + parameters.connector?.uid ?? config.state.current!, + ) + if (connection) { + const connector = connection.connector + if (!connector.switchChain) + throw new SwitchChainNotSupportedError({ connector }) + const chain = await connector.switchChain({ + addEthereumChainParameter, + chainId, + }) + return chain as SwitchChainReturnType + } + + const chain = config.chains.find((x) => x.id === chainId) + if (!chain) throw new ChainNotConfiguredError() + config.setState((x) => ({ ...x, chainId })) + return chain as SwitchChainReturnType +} diff --git a/wagmi-project/packages/core/src/actions/verifyMessage.test.ts b/wagmi-project/packages/core/src/actions/verifyMessage.test.ts new file mode 100644 index 000000000..f2766cbea --- /dev/null +++ b/wagmi-project/packages/core/src/actions/verifyMessage.test.ts @@ -0,0 +1,72 @@ +import { accounts, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { verifyMessage } from './verifyMessage.js' + +const eoaAddress = accounts[0] +const smartAccountAddress = '0x3FCf42e10CC70Fe75A62EB3aDD6D305Aa840d145' + +test('smart account: valid signature', async () => { + expect( + await verifyMessage(config, { + address: smartAccountAddress, + message: 'This is a test message for viem!', + signature: + '0xefd5fb29a274ea6682673d8b3caa9263e936d48d486e5df68893003e0a76496439594d12245008c6fba1c8e3ef28241cffe1bef27ff6bca487b167f261f329251c', + }), + ).toBe(true) +}) + +test('smart account: invalid signature', async () => { + expect( + await verifyMessage(config, { + address: smartAccountAddress, + message: 'This is a test message for viem!', + signature: '0xdead', + }), + ).toBe(false) +}) + +test('smart account: account not deployed', async () => { + expect( + await verifyMessage(config, { + blockNumber: 1234567890n, + address: smartAccountAddress, + message: 'This is a test message for viem!', + signature: + '0xefd5fb29a274ea6682673d8b3caa9263e936d48d486e5df68893003e0a76496439594d12245008c6fba1c8e3ef28241cffe1bef27ff6bca487b167f261f329251c', + }), + ).toBe(false) +}) + +test('eoa: valid signature', async () => { + expect( + await verifyMessage(config, { + address: eoaAddress, + message: 'This is a test message for viem!', + signature: + '0xc4c7f2820177020d66d5fd00d084cdd3f575a868c059c29a2d7f23398d04819709a14f83d98b446dda539ca5dcb87d75aa3340eb15e66d67606850622a3420f61b', + }), + ).toBe(true) +}) + +test('eoa: invalid signature', async () => { + expect( + await verifyMessage(config, { + address: eoaAddress, + message: 'This is a test message for viem!', + signature: '0xdead', + }), + ).toBe(false) +}) + +test('eoa: raw message', async () => { + expect( + await verifyMessage(config, { + address: eoaAddress, + message: { raw: '0x68656c6c6f20776f726c64' }, + signature: + '0xa461f509887bd19e312c0c58467ce8ff8e300d3c1a90b608a760c5b80318eaf15fe57c96f9175d6cd4daad4663763baa7e78836e067d0163e9a2ccf2ff753f5b1b', + }), + ).toBe(true) +}) diff --git a/wagmi-project/packages/core/src/actions/verifyMessage.ts b/wagmi-project/packages/core/src/actions/verifyMessage.ts new file mode 100644 index 000000000..851f8589f --- /dev/null +++ b/wagmi-project/packages/core/src/actions/verifyMessage.ts @@ -0,0 +1,30 @@ +import { + type VerifyMessageErrorType as viem_VerifyMessageErrorType, + type VerifyMessageParameters as viem_VerifyMessageParameters, + type VerifyMessageReturnType as viem_VerifyMessageReturnType, + verifyMessage as viem_verifyMessage, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { ChainIdParameter } from '../types/properties.js' +import type { Compute } from '../types/utils.js' +import { getAction } from '../utils/getAction.js' + +export type VerifyMessageParameters = Compute< + viem_VerifyMessageParameters & ChainIdParameter +> + +export type VerifyMessageReturnType = viem_VerifyMessageReturnType + +export type VerifyMessageErrorType = viem_VerifyMessageErrorType + +/** https://wagmi.sh/core/api/actions/verifyMessage */ +export async function verifyMessage( + config: config, + parameters: VerifyMessageParameters, +): Promise { + const { chainId, ...rest } = parameters + const client = config.getClient({ chainId }) + const action = getAction(client, viem_verifyMessage, 'verifyMessage') + return action(rest) +} diff --git a/wagmi-project/packages/core/src/actions/verifyTypedData.test.ts b/wagmi-project/packages/core/src/actions/verifyTypedData.test.ts new file mode 100644 index 000000000..c4b98c68d --- /dev/null +++ b/wagmi-project/packages/core/src/actions/verifyTypedData.test.ts @@ -0,0 +1,42 @@ +import { config, typedData } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { verifyTypedData } from './verifyTypedData.js' + +const smartAccountAddress = '0x3FCf42e10CC70Fe75A62EB3aDD6D305Aa840d145' +const notDeployedAddress = '0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef' + +test('valid signature', async () => { + expect( + await verifyTypedData(config, { + ...typedData.basic, + primaryType: 'Mail', + address: smartAccountAddress, + signature: + '0x79d756d805073dc97b7bc885b0d56ddf319a2599530fe1e178c2a7de5be88980068d24f20a79b318ea0a84d33ae06f93db77e4235e5d9eeb8b1d7a63922ada3e1c', + }), + ).toBe(true) +}) + +test('invalid signature', async () => { + expect( + await verifyTypedData(config, { + ...typedData.basic, + primaryType: 'Mail', + address: smartAccountAddress, + signature: '0xdead', + }), + ).toBe(false) +}) + +test('account not deployed', async () => { + expect( + await verifyTypedData(config, { + ...typedData.basic, + primaryType: 'Mail', + address: notDeployedAddress, + signature: + '0x79d756d805073dc97b7bc885b0d56ddf319a2599530fe1e178c2a7de5be88980068d24f20a79b318ea0a84d33ae06f93db77e4235e5d9eeb8b1d7a63922ada3e1c', + }), + ).toBe(false) +}) diff --git a/wagmi-project/packages/core/src/actions/verifyTypedData.ts b/wagmi-project/packages/core/src/actions/verifyTypedData.ts new file mode 100644 index 000000000..4fac5463f --- /dev/null +++ b/wagmi-project/packages/core/src/actions/verifyTypedData.ts @@ -0,0 +1,40 @@ +import type { TypedData } from 'viem' +import { + type VerifyTypedDataErrorType as viem_VerifyTypedDataErrorType, + type VerifyTypedDataParameters as viem_VerifyTypedDataParameters, + type VerifyTypedDataReturnType as viem_VerifyTypedDataReturnType, + verifyTypedData as viem_verifyTypedData, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { ChainIdParameter } from '../types/properties.js' +import type { Compute } from '../types/utils.js' +import { getAction } from '../utils/getAction.js' + +export type VerifyTypedDataParameters< + typedData extends TypedData | Record = TypedData, + primaryType extends keyof typedData | 'EIP712Domain' = keyof typedData, + config extends Config = Config, +> = Compute< + viem_VerifyTypedDataParameters & + ChainIdParameter +> + +export type VerifyTypedDataReturnType = viem_VerifyTypedDataReturnType + +export type VerifyTypedDataErrorType = viem_VerifyTypedDataErrorType + +/** https://wagmi.sh/core/api/actions/verifyTypedData */ +export async function verifyTypedData< + config extends Config, + const typedData extends TypedData | Record, + primaryType extends keyof typedData | 'EIP712Domain', +>( + config: config, + parameters: VerifyTypedDataParameters, +): Promise { + const { chainId, ...rest } = parameters + const client = config.getClient({ chainId }) + const action = getAction(client, viem_verifyTypedData, 'verifyTypedData') + return action(rest as viem_VerifyTypedDataParameters) +} diff --git a/wagmi-project/packages/core/src/actions/waitForCallsStatus.test.ts b/wagmi-project/packages/core/src/actions/waitForCallsStatus.test.ts new file mode 100644 index 000000000..338fe0261 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/waitForCallsStatus.test.ts @@ -0,0 +1,77 @@ +import { accounts, config, testClient, wait } from '@wagmi/test' +import { parseEther } from 'viem' +import { expect, test } from 'vitest' + +import { connect } from './connect.js' +import { disconnect } from './disconnect.js' +import { sendCalls } from './sendCalls.js' +import { waitForCallsStatus } from './waitForCallsStatus.js' + +const connector = config.connectors[0]! + +test('default', async () => { + await connect(config, { connector }) + + const { id } = await sendCalls(config, { + calls: [ + { + data: '0xdeadbeef', + to: accounts[1], + value: parseEther('1'), + }, + { + to: accounts[2], + value: parseEther('2'), + }, + { + to: accounts[3], + value: parseEther('3'), + }, + ], + }) + + const [{ receipts, status }] = await Promise.all([ + waitForCallsStatus(config, { + id, + }), + (async () => { + await wait(100) + await testClient.mainnet.mine({ blocks: 1 }) + })(), + ]) + + expect(status).toBe('success') + expect( + receipts?.map((x) => ({ ...x, blockHash: undefined })), + ).toMatchInlineSnapshot( + ` + [ + { + "blockHash": undefined, + "blockNumber": 19258214n, + "gasUsed": 21064n, + "logs": [], + "status": "success", + "transactionHash": "0x13c53b2d4d9da424835525349cd66e553330f323d6fb19458b801ae1f7989a41", + }, + { + "blockHash": undefined, + "blockNumber": 19258214n, + "gasUsed": 21000n, + "logs": [], + "status": "success", + "transactionHash": "0xd8397b3e82b061c26a0c2093f1ceca0c3662a512614f7d6370349e89d0eea007", + }, + { + "blockHash": undefined, + "blockNumber": 19258214n, + "gasUsed": 21000n, + "logs": [], + "status": "success", + "transactionHash": "0x4d26e346593d9ea265bb164b115e89aa92df43b0b8778ac75d4ad28e2a22b101", + }, + ] + `, + ) + await disconnect(config, { connector }) +}) diff --git a/wagmi-project/packages/core/src/actions/waitForCallsStatus.ts b/wagmi-project/packages/core/src/actions/waitForCallsStatus.ts new file mode 100644 index 000000000..a1c5764d3 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/waitForCallsStatus.ts @@ -0,0 +1,27 @@ +import { + type WaitForCallsStatusErrorType as viem_WaitForCallsStatusErrorType, + type WaitForCallsStatusParameters as viem_WaitForCallsStatusParameters, + type WaitForCallsStatusReturnType as viem_WaitForCallsStatusReturnType, + waitForCallsStatus as viem_waitForCallsStatus, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { ConnectorParameter } from '../types/properties.js' +import { getConnectorClient } from './getConnectorClient.js' + +export type WaitForCallsStatusParameters = viem_WaitForCallsStatusParameters & + ConnectorParameter + +export type WaitForCallsStatusReturnType = viem_WaitForCallsStatusReturnType + +export type WaitForCallsStatusErrorType = viem_WaitForCallsStatusErrorType + +/** https://wagmi.sh/core/api/actions/waitForCallsStatus */ +export async function waitForCallsStatus( + config: config, + parameters: WaitForCallsStatusParameters, +): Promise { + const { connector } = parameters + const client = await getConnectorClient(config, { connector }) + return viem_waitForCallsStatus(client, parameters) +} diff --git a/wagmi-project/packages/core/src/actions/waitForTransactionReceipt.test-d.ts b/wagmi-project/packages/core/src/actions/waitForTransactionReceipt.test-d.ts new file mode 100644 index 000000000..0cce58d1e --- /dev/null +++ b/wagmi-project/packages/core/src/actions/waitForTransactionReceipt.test-d.ts @@ -0,0 +1,36 @@ +import { http } from 'viem' +import { mainnet, zkSync } from 'viem/chains' +import type { ZkSyncL2ToL1Log, ZkSyncLog } from 'viem/zksync' +import { expectTypeOf, test } from 'vitest' + +import { createConfig } from '../createConfig.js' +import { waitForTransactionReceipt } from './waitForTransactionReceipt.js' + +test('chain formatters', async () => { + const config = createConfig({ + chains: [mainnet, zkSync], + transports: { [mainnet.id]: http(), [zkSync.id]: http() }, + }) + const result = await waitForTransactionReceipt(config, { hash: '0x123' }) + if (result.chainId === zkSync.id) { + expectTypeOf(result.l1BatchNumber).toEqualTypeOf() + expectTypeOf(result.l1BatchTxIndex).toEqualTypeOf() + expectTypeOf(result.logs).toEqualTypeOf() + expectTypeOf(result.l2ToL1Logs).toEqualTypeOf() + } +}) + +test('chainId', async () => { + const config = createConfig({ + chains: [zkSync], + transports: { [zkSync.id]: http() }, + }) + const result = await waitForTransactionReceipt(config, { + hash: '0x123', + chainId: zkSync.id, + }) + expectTypeOf(result.l1BatchNumber).toEqualTypeOf() + expectTypeOf(result.l1BatchTxIndex).toEqualTypeOf() + expectTypeOf(result.logs).toEqualTypeOf() + expectTypeOf(result.l2ToL1Logs).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/core/src/actions/waitForTransactionReceipt.test.ts b/wagmi-project/packages/core/src/actions/waitForTransactionReceipt.test.ts new file mode 100644 index 000000000..c060e8266 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/waitForTransactionReceipt.test.ts @@ -0,0 +1,58 @@ +import { config, testClient, wait } from '@wagmi/test' +import { parseEther } from 'viem' +import { beforeEach, expect, test } from 'vitest' + +import { connect } from './connect.js' +import { disconnect } from './disconnect.js' +import { sendTransaction } from './sendTransaction.js' +import { waitForTransactionReceipt } from './waitForTransactionReceipt.js' + +const connector = config.connectors[0]! + +beforeEach(async () => { + if (config.state.current === connector.uid) + await disconnect(config, { connector }) +}) + +test('default', async () => { + await connect(config, { connector }) + + const hash = await sendTransaction(config, { + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), + }) + + await testClient.mainnet.mine({ blocks: 1 }) + await wait(100) + + await expect( + waitForTransactionReceipt(config, { hash }), + ).resolves.toMatchObject({ + chainId: 1, + transactionHash: hash, + }) + + await disconnect(config, { connector }) +}) + +test('behavior: transaction reverted', async () => { + await expect( + waitForTransactionReceipt(config, { + hash: '0x745367f76807d411b7fa4c3a552a62e3e45303ef40145fff04d84b867c2575d3', + }), + ).rejects.toThrowErrorMatchingInlineSnapshot(` + [CallExecutionError: Execution reverted with reason: PartyBid::claim: contribution already claimed. + + Raw Call Arguments: + to: 0xf1332f21487e74612ed3a0fb36da729b73f1ae19 + value: 0 ETH + data: 0x1e83409a000000000000000000000000a0cf798816d4b9b9866b5330eea46a18382f251e + gas: 128730 + maxFeePerGas: 43.307900987 gwei + maxPriorityFeePerGas: 1.5 gwei + nonce: 43 + + Details: execution reverted: PartyBid::claim: contribution already claimed + Version: viem@2.29.2] + `) +}) diff --git a/wagmi-project/packages/core/src/actions/waitForTransactionReceipt.ts b/wagmi-project/packages/core/src/actions/waitForTransactionReceipt.ts new file mode 100644 index 000000000..5ac8fcdb2 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/waitForTransactionReceipt.ts @@ -0,0 +1,86 @@ +import type { Chain } from 'viem' +import { hexToString } from 'viem' +import { + call, + getTransaction, + type WaitForTransactionReceiptErrorType as viem_WaitForTransactionReceiptErrorType, + type WaitForTransactionReceiptParameters as viem_WaitForTransactionReceiptParameters, + type WaitForTransactionReceiptReturnType as viem_WaitForTransactionReceiptReturnType, + waitForTransactionReceipt as viem_waitForTransactionReceipt, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { SelectChains } from '../types/chain.js' +import type { ChainIdParameter } from '../types/properties.js' +import type { Compute, IsNarrowable } from '../types/utils.js' +import { getAction } from '../utils/getAction.js' + +export type WaitForTransactionReceiptParameters< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +> = Compute< + viem_WaitForTransactionReceiptParameters & ChainIdParameter +> + +export type WaitForTransactionReceiptReturnType< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + /// + chains extends readonly Chain[] = SelectChains, +> = Compute< + { + [key in keyof chains]: viem_WaitForTransactionReceiptReturnType< + IsNarrowable extends true ? chains[key] : undefined + > & { chainId: chains[key]['id'] } + }[number] +> + +export type WaitForTransactionReceiptErrorType = + viem_WaitForTransactionReceiptErrorType + +export async function waitForTransactionReceipt< + config extends Config, + chainId extends config['chains'][number]['id'], +>( + config: config, + parameters: WaitForTransactionReceiptParameters, +): Promise> { + const { chainId, timeout = 0, ...rest } = parameters + + const client = config.getClient({ chainId }) + const action = getAction( + client, + viem_waitForTransactionReceipt, + 'waitForTransactionReceipt', + ) + const receipt = await action({ ...rest, timeout }) + + if (receipt.status === 'reverted') { + const action_getTransaction = getAction( + client, + getTransaction, + 'getTransaction', + ) + const txn = await action_getTransaction({ hash: receipt.transactionHash }) + const action_call = getAction(client, call, 'call') + const code = await action_call({ + ...(txn as any), + data: txn.input, + gasPrice: txn.type !== 'eip1559' ? txn.gasPrice : undefined, + maxFeePerGas: txn.type === 'eip1559' ? txn.maxFeePerGas : undefined, + maxPriorityFeePerGas: + txn.type === 'eip1559' ? txn.maxPriorityFeePerGas : undefined, + }) + const reason = code?.data + ? hexToString(`0x${code.data.substring(138)}`) + : 'unknown reason' + throw new Error(reason) + } + + return { + ...receipt, + chainId: client.chain.id, + } as WaitForTransactionReceiptReturnType +} diff --git a/wagmi-project/packages/core/src/actions/watchAccount.test.ts b/wagmi-project/packages/core/src/actions/watchAccount.test.ts new file mode 100644 index 000000000..c80316588 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/watchAccount.test.ts @@ -0,0 +1,38 @@ +import { config } from '@wagmi/test' +import type { Address } from 'viem' +import { expect, test } from 'vitest' + +import { connect } from './connect.js' +import { disconnect } from './disconnect.js' +import { watchAccount } from './watchAccount.js' + +test('default', async () => { + const accounts: { address: Address | undefined; status: string }[] = [] + const unwatch = watchAccount(config, { + onChange(data) { + accounts.push({ address: data.address, status: data.status }) + }, + }) + + await connect(config, { connector: config.connectors[0]! }) + await disconnect(config) + + expect(accounts).toMatchInlineSnapshot(` + [ + { + "address": undefined, + "status": "connecting", + }, + { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "status": "connected", + }, + { + "address": undefined, + "status": "disconnected", + }, + ] + `) + + unwatch() +}) diff --git a/wagmi-project/packages/core/src/actions/watchAccount.ts b/wagmi-project/packages/core/src/actions/watchAccount.ts new file mode 100644 index 000000000..dfa8ae490 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/watchAccount.ts @@ -0,0 +1,33 @@ +import type { Config } from '../createConfig.js' +import { deepEqual } from '../utils/deepEqual.js' +import { type GetAccountReturnType, getAccount } from './getAccount.js' + +export type WatchAccountParameters = { + onChange( + account: GetAccountReturnType, + prevAccount: GetAccountReturnType, + ): void +} + +export type WatchAccountReturnType = () => void + +/** https://wagmi.sh/core/api/actions/watchAccount */ +export function watchAccount( + config: config, + parameters: WatchAccountParameters, +): WatchAccountReturnType { + const { onChange } = parameters + + return config.subscribe(() => getAccount(config), onChange, { + equalityFn(a, b) { + const { connector: aConnector, ...aRest } = a + const { connector: bConnector, ...bRest } = b + return ( + deepEqual(aRest, bRest) && + // check connector separately + aConnector?.id === bConnector?.id && + aConnector?.uid === bConnector?.uid + ) + }, + }) +} diff --git a/wagmi-project/packages/core/src/actions/watchAsset.test.ts b/wagmi-project/packages/core/src/actions/watchAsset.test.ts new file mode 100644 index 000000000..6d4cd86b5 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/watchAsset.test.ts @@ -0,0 +1,23 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { connect } from './connect.js' +import { disconnect } from './disconnect.js' +import { watchAsset } from './watchAsset.js' + +const connector = config.connectors[0]! + +test('default', async () => { + await connect(config, { connector }) + await expect( + watchAsset(config, { + type: 'ERC20', + options: { + address: '0x0000000000000000000000000000000000000000', + symbol: 'NULL', + decimals: 18, + }, + }), + ).resolves.toMatchInlineSnapshot('true') + await disconnect(config, { connector }) +}) diff --git a/wagmi-project/packages/core/src/actions/watchAsset.ts b/wagmi-project/packages/core/src/actions/watchAsset.ts new file mode 100644 index 000000000..cd5690bf5 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/watchAsset.ts @@ -0,0 +1,44 @@ +import { + type WatchAssetErrorType as viem_WatchAssetErrorType, + type WatchAssetParameters as viem_WatchAssetParameters, + type WatchAssetReturnType as viem_WatchAssetReturnType, + watchAsset as viem_watchAsset, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { BaseErrorType, ErrorType } from '../errors/base.js' +import type { ConnectorParameter } from '../types/properties.js' +import type { Compute } from '../types/utils.js' +import { getAction } from '../utils/getAction.js' +import { + type GetConnectorClientErrorType, + getConnectorClient, +} from './getConnectorClient.js' + +export type WatchAssetParameters = Compute< + viem_WatchAssetParameters & ConnectorParameter +> + +export type WatchAssetReturnType = viem_WatchAssetReturnType + +export type WatchAssetErrorType = + // getConnectorClient() + | GetConnectorClientErrorType + // base + | BaseErrorType + | ErrorType + // viem + | viem_WatchAssetErrorType + +/** https://wagmi.sh/core/api/actions/watchAsset */ +export async function watchAsset( + config: Config, + parameters: WatchAssetParameters, +): Promise { + const { connector, ...rest } = parameters + + const client = await getConnectorClient(config, { connector }) + + const action = getAction(client, viem_watchAsset, 'watchAsset') + return action(rest as viem_WatchAssetParameters) +} diff --git a/wagmi-project/packages/core/src/actions/watchBlockNumber.test-d.ts b/wagmi-project/packages/core/src/actions/watchBlockNumber.test-d.ts new file mode 100644 index 000000000..ae63ed8af --- /dev/null +++ b/wagmi-project/packages/core/src/actions/watchBlockNumber.test-d.ts @@ -0,0 +1,56 @@ +import { http, webSocket } from 'viem' +import { mainnet, optimism } from 'viem/chains' +import { expectTypeOf, test } from 'vitest' + +import { createConfig } from '../createConfig.js' +import { + type WatchBlockNumberParameters, + watchBlockNumber, +} from './watchBlockNumber.js' + +test('differing transports', () => { + const config = createConfig({ + chains: [mainnet, optimism], + transports: { + [mainnet.id]: http(), + [optimism.id]: webSocket(), + }, + }) + + type Result = WatchBlockNumberParameters< + typeof config, + typeof mainnet.id | typeof optimism.id + > + expectTypeOf().toEqualTypeOf() + watchBlockNumber(config, { + poll: false, + onBlockNumber() {}, + }) + + type Result2 = WatchBlockNumberParameters + expectTypeOf().toEqualTypeOf() + watchBlockNumber(config, { + chainId: mainnet.id, + poll: true, + onBlockNumber() {}, + }) + watchBlockNumber(config, { + chainId: mainnet.id, + // @ts-expect-error + poll: false, + onBlockNumber() {}, + }) + + type Result3 = WatchBlockNumberParameters + expectTypeOf().toEqualTypeOf() + watchBlockNumber(config, { + chainId: optimism.id, + poll: true, + onBlockNumber() {}, + }) + watchBlockNumber(config, { + chainId: optimism.id, + poll: false, + onBlockNumber() {}, + }) +}) diff --git a/wagmi-project/packages/core/src/actions/watchBlockNumber.test.ts b/wagmi-project/packages/core/src/actions/watchBlockNumber.test.ts new file mode 100644 index 000000000..0a4299db5 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/watchBlockNumber.test.ts @@ -0,0 +1,27 @@ +import { config, testClient, wait } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { watchBlockNumber } from './watchBlockNumber.js' + +test('default', async () => { + const blockNumbers: bigint[] = [] + const unwatch = watchBlockNumber(config, { + onBlockNumber(blockNumber) { + blockNumbers.push(blockNumber) + }, + }) + + await testClient.mainnet.mine({ blocks: 1 }) + await wait(100) + await testClient.mainnet.mine({ blocks: 1 }) + await wait(100) + await testClient.mainnet.mine({ blocks: 1 }) + await wait(100) + + expect(blockNumbers.length).toBe(3) + expect( + blockNumbers.map((blockNumber) => blockNumber - blockNumbers[0]!), + ).toEqual([0n, 1n, 2n]) + + unwatch() +}) diff --git a/wagmi-project/packages/core/src/actions/watchBlockNumber.ts b/wagmi-project/packages/core/src/actions/watchBlockNumber.ts new file mode 100644 index 000000000..712849080 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/watchBlockNumber.ts @@ -0,0 +1,78 @@ +import { + type WatchBlockNumberParameters as viem_WatchBlockNumberParameters, + type WatchBlockNumberReturnType as viem_WatchBlockNumberReturnType, + watchBlockNumber as viem_watchBlockNumber, +} from 'viem/actions' + +import type { Chain, Transport, WebSocketTransport } from 'viem' +import type { Config } from '../createConfig.js' +import type { SelectChains } from '../types/chain.js' +import type { + ChainIdParameter, + SyncConnectedChainParameter, +} from '../types/properties.js' +import type { UnionCompute } from '../types/utils.js' +import { getAction } from '../utils/getAction.js' + +export type WatchBlockNumberParameters< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + /// + chains extends readonly Chain[] = SelectChains, +> = { + [key in keyof chains]: UnionCompute< + viem_WatchBlockNumberParameters< + config['_internal']['transports'][chains[key]['id']] extends infer transport extends + Transport + ? Transport extends transport + ? WebSocketTransport + : transport + : WebSocketTransport + > & + ChainIdParameter & + SyncConnectedChainParameter + > +}[number] + +export type WatchBlockNumberReturnType = viem_WatchBlockNumberReturnType + +// TODO: wrap in viem's `observe` to avoid duplicate invocations. +/** https://wagmi.sh/core/api/actions/watchBlockNumber */ +export function watchBlockNumber< + config extends Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +>( + config: config, + parameters: WatchBlockNumberParameters, +): WatchBlockNumberReturnType { + const { syncConnectedChain = config._internal.syncConnectedChain, ...rest } = + parameters as WatchBlockNumberParameters + + let unwatch: WatchBlockNumberReturnType | undefined + const listener = (chainId: number | undefined) => { + if (unwatch) unwatch() + + const client = config.getClient({ chainId }) + const action = getAction(client, viem_watchBlockNumber, 'watchBlockNumber') + unwatch = action(rest as viem_WatchBlockNumberParameters) + return unwatch + } + + // set up listener for block number changes + const unlisten = listener(parameters.chainId) + + // set up subscriber for connected chain changes + let unsubscribe: (() => void) | undefined + if (syncConnectedChain && !parameters.chainId) + unsubscribe = config.subscribe( + ({ chainId }) => chainId, + async (chainId) => listener(chainId), + ) + + return () => { + unlisten?.() + unsubscribe?.() + } +} diff --git a/wagmi-project/packages/core/src/actions/watchBlocks.test-d.ts b/wagmi-project/packages/core/src/actions/watchBlocks.test-d.ts new file mode 100644 index 000000000..1899dcb1a --- /dev/null +++ b/wagmi-project/packages/core/src/actions/watchBlocks.test-d.ts @@ -0,0 +1,59 @@ +import { http, webSocket } from 'viem' +import { mainnet, optimism } from 'viem/chains' +import { expectTypeOf, test } from 'vitest' + +import { createConfig } from '../createConfig.js' +import { type WatchBlocksParameters, watchBlocks } from './watchBlocks.js' + +test('differing transports', () => { + const config = createConfig({ + chains: [mainnet, optimism], + transports: { + [mainnet.id]: http(), + [optimism.id]: webSocket(), + }, + }) + + type Result = WatchBlocksParameters< + false, + 'latest', + typeof config, + typeof mainnet.id | typeof optimism.id + > + expectTypeOf().toEqualTypeOf() + watchBlocks(config, { + poll: false, + onBlock() {}, + }) + + type Result2 = WatchBlocksParameters< + false, + 'latest', + typeof config, + typeof mainnet.id + > + expectTypeOf().toEqualTypeOf() + watchBlocks(config, { + chainId: mainnet.id, + poll: true, + onBlock() {}, + }) + + type Result3 = WatchBlocksParameters< + false, + 'latest', + typeof config, + typeof optimism.id + > + expectTypeOf().toEqualTypeOf() + watchBlocks(config, { + chainId: optimism.id, + poll: true, + onBlock() {}, + }) + watchBlocks(config, { + chainId: optimism.id, + poll: false, + onBlock() {}, + }) +}) diff --git a/wagmi-project/packages/core/src/actions/watchBlocks.test.ts b/wagmi-project/packages/core/src/actions/watchBlocks.test.ts new file mode 100644 index 000000000..caf4c0dc6 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/watchBlocks.test.ts @@ -0,0 +1,30 @@ +import { config, testClient, wait } from '@wagmi/test' +import { expect, test } from 'vitest' + +import type { Block } from 'viem' +import { watchBlocks } from './watchBlocks.js' + +test('default', async () => { + const blocks: Block[] = [] + const unwatch = watchBlocks(config, { + onBlock(block) { + blocks.push(block) + }, + }) + + await testClient.mainnet.mine({ blocks: 1 }) + await wait(100) + await testClient.mainnet.mine({ blocks: 1 }) + await wait(100) + await testClient.mainnet.mine({ blocks: 1 }) + await wait(100) + + expect(blocks.length).toBe(3) + expect(blocks.map((block) => block.number! - blocks[0]?.number!)).toEqual([ + 0n, + 1n, + 2n, + ]) + + unwatch() +}) diff --git a/wagmi-project/packages/core/src/actions/watchBlocks.ts b/wagmi-project/packages/core/src/actions/watchBlocks.ts new file mode 100644 index 000000000..c6f3225dc --- /dev/null +++ b/wagmi-project/packages/core/src/actions/watchBlocks.ts @@ -0,0 +1,90 @@ +import { + type WatchBlocksParameters as viem_WatchBlocksParameters, + type WatchBlocksReturnType as viem_WatchBlocksReturnType, + watchBlocks as viem_watchBlocks, +} from 'viem/actions' + +import type { BlockTag, Chain, Transport, WebSocketTransport } from 'viem' +import type { Config } from '../createConfig.js' +import type { SelectChains } from '../types/chain.js' +import type { + ChainIdParameter, + SyncConnectedChainParameter, +} from '../types/properties.js' +import type { IsNarrowable, UnionCompute } from '../types/utils.js' +import { getAction } from '../utils/getAction.js' + +export type WatchBlocksParameters< + includeTransactions extends boolean = false, + blockTag extends BlockTag = 'latest', + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + /// + chains extends readonly Chain[] = SelectChains, +> = { + [key in keyof chains]: UnionCompute< + viem_WatchBlocksParameters< + config['_internal']['transports'][chains[key]['id']] extends infer transport extends + Transport + ? Transport extends transport + ? WebSocketTransport + : transport + : WebSocketTransport, + IsNarrowable extends true ? chains[key] : undefined, + includeTransactions, + blockTag + > & + ChainIdParameter & + SyncConnectedChainParameter + > +}[number] + +export type WatchBlocksReturnType = viem_WatchBlocksReturnType + +// TODO: wrap in viem's `observe` to avoid duplicate invocations. +/** https://wagmi.sh/core/actions/watchBlocks */ +export function watchBlocks< + config extends Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + includeTransactions extends boolean = false, + blockTag extends BlockTag = 'latest', +>( + config: config, + parameters: WatchBlocksParameters< + includeTransactions, + blockTag, + config, + chainId + >, +): WatchBlocksReturnType { + const { syncConnectedChain = config._internal.syncConnectedChain, ...rest } = + parameters as WatchBlocksParameters + + let unwatch: WatchBlocksReturnType | undefined + const listener = (chainId: number | undefined) => { + if (unwatch) unwatch() + + const client = config.getClient({ chainId }) + const action = getAction(client, viem_watchBlocks, 'watchBlocks') + unwatch = action(rest as viem_WatchBlocksParameters) + return unwatch + } + + // set up listener for block number changes + const unlisten = listener(parameters.chainId) + + // set up subscriber for connected chain changes + let unsubscribe: (() => void) | undefined + if (syncConnectedChain && !parameters.chainId) + unsubscribe = config.subscribe( + ({ chainId }) => chainId, + async (chainId) => listener(chainId), + ) + + return () => { + unlisten?.() + unsubscribe?.() + } +} diff --git a/wagmi-project/packages/core/src/actions/watchChainId.test.ts b/wagmi-project/packages/core/src/actions/watchChainId.test.ts new file mode 100644 index 000000000..9e27ba7ed --- /dev/null +++ b/wagmi-project/packages/core/src/actions/watchChainId.test.ts @@ -0,0 +1,26 @@ +import { chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { watchChainId } from './watchChainId.js' + +test('default', async () => { + const chainIds: number[] = [] + const unwatch = watchChainId(config, { + onChange(chainId) { + chainIds.push(chainId) + }, + }) + config.setState((x) => ({ ...x, chainId: chain.mainnet2.id })) + config.setState((x) => ({ ...x, chainId: chain.mainnet.id })) + config.setState((x) => ({ ...x, chainId: chain.mainnet2.id })) + + expect(chainIds).toMatchInlineSnapshot(` + [ + 456, + 1, + 456, + ] + `) + + unwatch() +}) diff --git a/wagmi-project/packages/core/src/actions/watchChainId.ts b/wagmi-project/packages/core/src/actions/watchChainId.ts new file mode 100644 index 000000000..e3d4f010a --- /dev/null +++ b/wagmi-project/packages/core/src/actions/watchChainId.ts @@ -0,0 +1,20 @@ +import type { Config } from '../createConfig.js' +import type { GetChainIdReturnType } from './getChainId.js' + +export type WatchChainIdParameters = { + onChange( + chainId: GetChainIdReturnType, + prevChainId: GetChainIdReturnType, + ): void +} + +export type WatchChainIdReturnType = () => void + +/** https://wagmi.sh/core/api/actions/watchChainId */ +export function watchChainId( + config: config, + parameters: WatchChainIdParameters, +): WatchChainIdReturnType { + const { onChange } = parameters + return config.subscribe((state) => state.chainId, onChange) +} diff --git a/wagmi-project/packages/core/src/actions/watchChains.test.ts b/wagmi-project/packages/core/src/actions/watchChains.test.ts new file mode 100644 index 000000000..d7d586a83 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/watchChains.test.ts @@ -0,0 +1,37 @@ +import { chain, config } from '@wagmi/test' +import type { Chain } from 'viem' +import { expect, test } from 'vitest' + +import { watchChains } from './watchChains.js' + +test('default', async () => { + let chains: readonly [Chain, ...Chain[]] = config.chains + const unwatch = watchChains(config, { + onChange(nextChains) { + chains = nextChains + }, + }) + + config._internal.chains.setState([chain.mainnet, chain.mainnet2]) + expect(chains.map((x) => x.id)).toMatchInlineSnapshot(` + [ + 1, + 456, + ] + `) + + config._internal.chains.setState([ + chain.mainnet, + chain.mainnet2, + chain.optimism, + ]) + expect(chains.map((x) => x.id)).toMatchInlineSnapshot(` + [ + 1, + 456, + 10, + ] + `) + + unwatch() +}) diff --git a/wagmi-project/packages/core/src/actions/watchChains.ts b/wagmi-project/packages/core/src/actions/watchChains.ts new file mode 100644 index 000000000..db5c496d5 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/watchChains.ts @@ -0,0 +1,29 @@ +import type { Config } from '../createConfig.js' +import type { GetChainsReturnType } from './getChains.js' + +export type WatchChainsParameters = { + onChange( + chains: GetChainsReturnType, + prevChains: GetChainsReturnType, + ): void +} + +export type WatchChainsReturnType = () => void + +/** + * @internal + * We don't expose this because as far as consumers know, you can't chainge (lol) `config.chains` at runtime. + * Setting `config.chains` via `config._internal.chains.setState(...)` is an extremely advanced use case that's not worth documenting or supporting in the public API at this time. + */ +export function watchChains( + config: config, + parameters: WatchChainsParameters, +): WatchChainsReturnType { + const { onChange } = parameters + return config._internal.chains.subscribe((chains, prevChains) => { + onChange( + chains as unknown as GetChainsReturnType, + prevChains as unknown as GetChainsReturnType, + ) + }) +} diff --git a/wagmi-project/packages/core/src/actions/watchClient.test-d.ts b/wagmi-project/packages/core/src/actions/watchClient.test-d.ts new file mode 100644 index 000000000..42830f02c --- /dev/null +++ b/wagmi-project/packages/core/src/actions/watchClient.test-d.ts @@ -0,0 +1,15 @@ +import { config } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' + +import { watchClient } from './watchClient.js' + +test('default', () => { + watchClient(config, { + onChange(client) { + expectTypeOf(client.chain).toEqualTypeOf< + (typeof config)['chains'][number] + >() + expectTypeOf(client.transport.type).toEqualTypeOf<'http'>() + }, + }) +}) diff --git a/wagmi-project/packages/core/src/actions/watchClient.test.ts b/wagmi-project/packages/core/src/actions/watchClient.test.ts new file mode 100644 index 000000000..9cb5f447d --- /dev/null +++ b/wagmi-project/packages/core/src/actions/watchClient.test.ts @@ -0,0 +1,23 @@ +import { config } from '@wagmi/test' +import type { Client } from 'viem' +import { expect, test } from 'vitest' + +import { switchChain } from './switchChain.js' +import { watchClient } from './watchClient.js' + +test('default', async () => { + const clients: Client[] = [] + const unwatch = watchClient(config, { + onChange(client) { + clients.push(client) + }, + }) + + switchChain(config, { chainId: 456 }) + switchChain(config, { chainId: 10 }) + switchChain(config, { chainId: 1 }) + + expect(clients.length).toBe(3) + + unwatch() +}) diff --git a/wagmi-project/packages/core/src/actions/watchClient.ts b/wagmi-project/packages/core/src/actions/watchClient.ts new file mode 100644 index 000000000..424735353 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/watchClient.ts @@ -0,0 +1,35 @@ +import type { Config } from '../createConfig.js' +import { type GetClientReturnType, getClient } from './getClient.js' + +export type WatchClientParameters< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +> = { + onChange( + publicClient: GetClientReturnType, + prevClient: GetClientReturnType, + ): void +} + +export type WatchClientReturnType = () => void + +/** https://wagmi.sh/core/api/actions/watchClient */ +export function watchClient< + config extends Config, + chainId extends config['chains'][number]['id'], +>( + config: config, + parameters: WatchClientParameters, +): WatchClientReturnType { + const { onChange } = parameters + return config.subscribe( + () => getClient(config) as GetClientReturnType, + onChange, + { + equalityFn(a, b) { + return a?.uid === b?.uid + }, + }, + ) +} diff --git a/wagmi-project/packages/core/src/actions/watchConnections.test.ts b/wagmi-project/packages/core/src/actions/watchConnections.test.ts new file mode 100644 index 000000000..9ddf4444a --- /dev/null +++ b/wagmi-project/packages/core/src/actions/watchConnections.test.ts @@ -0,0 +1,25 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import type { Connection } from '../createConfig.js' +import { connect } from './connect.js' +import { disconnect } from './disconnect.js' +import { watchConnections } from './watchConnections.js' + +test('default', async () => { + const connections: Connection[][] = [] + const unwatch = watchConnections(config, { + onChange(connection) { + connections.push(connection) + }, + }) + + const connector = config.connectors[0]! + expect(connections).toEqual([]) + await connect(config, { connector }) + expect(connections[0]?.length).toEqual(1) + await disconnect(config, { connector }) + expect(connections[1]).toEqual([]) + + unwatch() +}) diff --git a/wagmi-project/packages/core/src/actions/watchConnections.ts b/wagmi-project/packages/core/src/actions/watchConnections.ts new file mode 100644 index 000000000..56b94fd45 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/watchConnections.ts @@ -0,0 +1,26 @@ +import type { Config } from '../createConfig.js' +import { deepEqual } from '../utils/deepEqual.js' +import { + type GetConnectionsReturnType, + getConnections, +} from './getConnections.js' + +export type WatchConnectionsParameters = { + onChange( + connections: GetConnectionsReturnType, + prevConnections: GetConnectionsReturnType, + ): void +} + +export type WatchConnectionsReturnType = () => void + +/** https://wagmi.sh/core/api/actions/watchConnections */ +export function watchConnections( + config: Config, + parameters: WatchConnectionsParameters, +): WatchConnectionsReturnType { + const { onChange } = parameters + return config.subscribe(() => getConnections(config), onChange, { + equalityFn: deepEqual, + }) +} diff --git a/wagmi-project/packages/core/src/actions/watchConnectors.test.ts b/wagmi-project/packages/core/src/actions/watchConnectors.test.ts new file mode 100644 index 000000000..6e66f75f9 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/watchConnectors.test.ts @@ -0,0 +1,27 @@ +import { accounts, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { mock } from '../connectors/mock.js' +import type { Connector } from '../createConfig.js' +import { watchConnectors } from './watchConnectors.js' + +test('default', async () => { + const connectors: (readonly Connector[])[] = [] + const unwatch = watchConnectors(config, { + onChange(connector) { + connectors.push(connector) + }, + }) + + const count = config.connectors.length + expect(config.connectors).toEqual(config.connectors) + + config._internal.connectors.setState(() => [ + ...config.connectors, + config._internal.connectors.setup(mock({ accounts })), + ]) + + expect(config.connectors.length).toBe(count + 1) + + unwatch() +}) diff --git a/wagmi-project/packages/core/src/actions/watchConnectors.ts b/wagmi-project/packages/core/src/actions/watchConnectors.ts new file mode 100644 index 000000000..e463ab52f --- /dev/null +++ b/wagmi-project/packages/core/src/actions/watchConnectors.ts @@ -0,0 +1,22 @@ +import type { Config } from '../createConfig.js' +import type { GetConnectorsReturnType } from './getConnectors.js' + +export type WatchConnectorsParameters = { + onChange( + connections: GetConnectorsReturnType, + prevConnectors: GetConnectorsReturnType, + ): void +} + +export type WatchConnectorsReturnType = () => void + +/** https://wagmi.sh/core/api/actions/watchConnectors */ +export function watchConnectors( + config: config, + parameters: WatchConnectorsParameters, +): WatchConnectorsReturnType { + const { onChange } = parameters + return config._internal.connectors.subscribe((connectors, prevConnectors) => { + onChange(Object.values(connectors), prevConnectors) + }) +} diff --git a/wagmi-project/packages/core/src/actions/watchContractEvent.test-d.ts b/wagmi-project/packages/core/src/actions/watchContractEvent.test-d.ts new file mode 100644 index 000000000..e6624fff5 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/watchContractEvent.test-d.ts @@ -0,0 +1,142 @@ +import { abi, config } from '@wagmi/test' +import { http, webSocket } from 'viem' +import { mainnet, optimism } from 'viem/chains' +import { expectTypeOf, test } from 'vitest' + +import { createConfig } from '../createConfig.js' +import { + type WatchContractEventParameters, + watchContractEvent, +} from './watchContractEvent.js' + +test('default', () => { + watchContractEvent(config, { + address: '0x', + abi: abi.erc20, + eventName: 'Transfer', + args: { + from: '0x', + to: '0x', + }, + onLogs(logs) { + expectTypeOf(logs[0]!.eventName).toEqualTypeOf<'Transfer'>() + expectTypeOf(logs[0]!.args).toEqualTypeOf<{ + from?: `0x${string}` | undefined + to?: `0x${string}` | undefined + value?: bigint | undefined + }>() + }, + }) +}) + +test('behavior: no eventName', () => { + type Result = WatchContractEventParameters< + typeof abi.erc20, + undefined, + true, + typeof config + > + expectTypeOf().toEqualTypeOf< + | { + from?: `0x${string}` | `0x${string}`[] | null | undefined + to?: `0x${string}` | `0x${string}`[] | null | undefined + } + | { + owner?: `0x${string}` | `0x${string}`[] | null | undefined + spender?: `0x${string}` | `0x${string}`[] | null | undefined + } + | undefined + >() + + watchContractEvent(config, { + address: '0x', + abi: abi.erc20, + args: { + // TODO: Figure out why this is not working + // @ts-ignore + from: '0x', + to: '0x', + }, + onLogs(logs) { + expectTypeOf(logs[0]!.eventName).toEqualTypeOf<'Transfer' | 'Approval'>() + expectTypeOf(logs[0]!.args).toEqualTypeOf< + | Record + | readonly unknown[] + | { + from?: `0x${string}` | undefined + to?: `0x${string}` | undefined + value?: bigint | undefined + } + | { + owner?: `0x${string}` | undefined + spender?: `0x${string}` | undefined + value?: bigint | undefined + } + >() + }, + }) +}) + +test('differing transports', () => { + const config = createConfig({ + chains: [mainnet, optimism], + transports: { + [mainnet.id]: http(), + [optimism.id]: webSocket(), + }, + }) + + type Result = WatchContractEventParameters< + typeof abi.erc20, + 'Transfer' | 'Approval', + true, + typeof config, + typeof mainnet.id | typeof optimism.id + > + expectTypeOf().toEqualTypeOf() + watchContractEvent(config, { + poll: false, + address: '0x', + abi: abi.erc20, + onLogs() {}, + }) + + type Result2 = WatchContractEventParameters< + typeof abi.erc20, + 'Transfer' | 'Approval', + true, + typeof config, + typeof mainnet.id + > + expectTypeOf().toEqualTypeOf() + watchContractEvent(config, { + chainId: mainnet.id, + poll: true, + address: '0x', + abi: abi.erc20, + onLogs() {}, + }) + + type Result3 = WatchContractEventParameters< + typeof abi.erc20, + 'Transfer' | 'Approval', + true, + typeof config, + typeof optimism.id + > + expectTypeOf().toEqualTypeOf() + watchContractEvent(config, { + chainId: optimism.id, + poll: true, + address: '0x', + abi: abi.erc20, + onLogs() {}, + }) + watchContractEvent(config, { + chainId: optimism.id, + poll: false, + address: '0x', + abi: abi.erc20, + onLogs() {}, + }) +}) diff --git a/wagmi-project/packages/core/src/actions/watchContractEvent.test.ts b/wagmi-project/packages/core/src/actions/watchContractEvent.test.ts new file mode 100644 index 000000000..759a21dd1 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/watchContractEvent.test.ts @@ -0,0 +1,96 @@ +import { + abi, + accounts, + address, + config, + testClient, + transactionHashRegex, + wait, +} from '@wagmi/test' +import { http, createWalletClient, parseEther } from 'viem' +import type { WatchEventOnLogsParameter } from 'viem/actions' +import { beforeEach, expect, test } from 'vitest' + +import { connect } from './connect.js' +import { disconnect } from './disconnect.js' +import { getBalance } from './getBalance.js' +import { watchContractEvent } from './watchContractEvent.js' +import { writeContract } from './writeContract.js' + +const connector = config.connectors[0]! + +// TODO: Some test does not call disconnect after finishing. Remove once fixing it. +beforeEach(async () => { + if (config.state.current) { + const connection = config.state.connections.get(config.state.current)! + const connector = connection.connector + await disconnect(config, { connector }) + } +}) + +test('default', async () => { + const data = await connect(config, { connector }) + const connectedAddress = data.accounts[0] + + // impersonate usdc holder account and transfer usdc to connected account + await testClient.mainnet.impersonateAccount({ address: address.usdcHolder }) + await testClient.mainnet.setBalance({ + address: address.usdcHolder, + value: 10000000000000000000000n, + }) + await createWalletClient({ + account: address.usdcHolder, + chain: testClient.mainnet.chain, + transport: http(), + }).writeContract({ + address: address.usdc, + abi: abi.erc20, + functionName: 'transfer', + args: [connectedAddress, parseEther('10', 'gwei')], + }) + await testClient.mainnet.mine({ blocks: 1 }) + await testClient.mainnet.stopImpersonatingAccount({ + address: address.usdcHolder, + }) + + const balance = await getBalance(config, { + address: connectedAddress, + token: address.usdc, + }) + expect(balance.value).toBeGreaterThan(0n) + + // start watching transfer events + let logs: WatchEventOnLogsParameter = [] + const unwatch = watchContractEvent(config, { + address: address.usdc, + abi: abi.erc20, + eventName: 'Transfer', + onLogs(next) { + logs = logs.concat(next) + }, + }) + + await writeContract(config, { + address: address.usdc, + abi: abi.erc20, + functionName: 'transfer', + args: [accounts[1], parseEther('1', 'gwei')], + }) + + await writeContract(config, { + address: address.usdc, + abi: abi.erc20, + functionName: 'transfer', + args: [accounts[3], parseEther('1', 'gwei')], + }) + + await testClient.mainnet.mine({ blocks: 1 }) + await testClient.mainnet.mine({ blocks: 1 }) + await wait(1000) // wait for events to be emitted + + unwatch() + expect(logs.length).toBe(2) + expect(logs[0]?.transactionHash).toMatch(transactionHashRegex) + + await disconnect(config, { connector }) +}) diff --git a/wagmi-project/packages/core/src/actions/watchContractEvent.ts b/wagmi-project/packages/core/src/actions/watchContractEvent.ts new file mode 100644 index 000000000..ddc15741d --- /dev/null +++ b/wagmi-project/packages/core/src/actions/watchContractEvent.ts @@ -0,0 +1,102 @@ +import type { + Abi, + Chain, + ContractEventName, + Transport, + WebSocketTransport, +} from 'viem' +import { + type WatchContractEventParameters as viem_WatchContractEventParameters, + type WatchContractEventReturnType as viem_WatchContractEventReturnType, + watchContractEvent as viem_watchContractEvent, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { SelectChains } from '../types/chain.js' +import type { + ChainIdParameter, + SyncConnectedChainParameter, +} from '../types/properties.js' +import type { UnionCompute } from '../types/utils.js' +import { getAction } from '../utils/getAction.js' + +export type WatchContractEventParameters< + abi extends Abi | readonly unknown[] = Abi, + eventName extends ContractEventName | undefined = ContractEventName, + strict extends boolean | undefined = undefined, + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + /// + chains extends readonly Chain[] = SelectChains, +> = { + [key in keyof chains]: UnionCompute< + viem_WatchContractEventParameters< + abi, + eventName, + strict, + config['_internal']['transports'][chains[key]['id']] extends infer transport extends + Transport + ? Transport extends transport + ? WebSocketTransport + : transport + : WebSocketTransport + > & + ChainIdParameter & + SyncConnectedChainParameter + > +}[number] + +export type WatchContractEventReturnType = viem_WatchContractEventReturnType + +// TODO: wrap in viem's `observe` to avoid duplicate invocations. +/** https://wagmi.sh/core/api/actions/watchContractEvent */ +export function watchContractEvent< + config extends Config, + chainId extends config['chains'][number]['id'], + const abi extends Abi | readonly unknown[], + eventName extends ContractEventName | undefined, + strict extends boolean | undefined = undefined, +>( + config: config, + parameters: WatchContractEventParameters< + abi, + eventName, + strict, + config, + chainId + >, +) { + const { syncConnectedChain = config._internal.syncConnectedChain, ...rest } = + parameters + + let unwatch: WatchContractEventReturnType | undefined + const listener = (chainId: number | undefined) => { + if (unwatch) unwatch() + + const client = config.getClient({ chainId }) + const action = getAction( + client, + viem_watchContractEvent, + 'watchContractEvent', + ) + unwatch = action(rest as unknown as viem_WatchContractEventParameters) + return unwatch + } + + // set up listener for transaction changes + const unlisten = listener(parameters.chainId) + + // set up subscriber for connected chain changes + let unsubscribe: (() => void) | undefined + if (syncConnectedChain && !parameters.chainId) + unsubscribe = config.subscribe( + ({ chainId }) => chainId, + async (chainId) => listener(chainId), + ) + + return () => { + unlisten?.() + unsubscribe?.() + } +} diff --git a/wagmi-project/packages/core/src/actions/watchPendingTransactions.test-d.ts b/wagmi-project/packages/core/src/actions/watchPendingTransactions.test-d.ts new file mode 100644 index 000000000..0af40a24c --- /dev/null +++ b/wagmi-project/packages/core/src/actions/watchPendingTransactions.test-d.ts @@ -0,0 +1,56 @@ +import { http, webSocket } from 'viem' +import { mainnet, optimism } from 'viem/chains' +import { expectTypeOf, test } from 'vitest' + +import { createConfig } from '../createConfig.js' +import { + type WatchPendingTransactionsParameters, + watchPendingTransactions, +} from './watchPendingTransactions.js' + +test('differing transports', () => { + const config = createConfig({ + chains: [mainnet, optimism], + transports: { + [mainnet.id]: http(), + [optimism.id]: webSocket(), + }, + }) + + type Result = WatchPendingTransactionsParameters< + typeof config, + typeof mainnet.id | typeof optimism.id + > + expectTypeOf().toEqualTypeOf() + watchPendingTransactions(config, { + poll: false, + onTransactions() {}, + }) + + type Result2 = WatchPendingTransactionsParameters< + typeof config, + typeof mainnet.id + > + expectTypeOf().toEqualTypeOf() + watchPendingTransactions(config, { + chainId: mainnet.id, + poll: true, + onTransactions() {}, + }) + + type Result3 = WatchPendingTransactionsParameters< + typeof config, + typeof optimism.id + > + expectTypeOf().toEqualTypeOf() + watchPendingTransactions(config, { + chainId: optimism.id, + poll: true, + onTransactions() {}, + }) + watchPendingTransactions(config, { + chainId: optimism.id, + poll: false, + onTransactions() {}, + }) +}) diff --git a/wagmi-project/packages/core/src/actions/watchPendingTransactions.test.ts b/wagmi-project/packages/core/src/actions/watchPendingTransactions.test.ts new file mode 100644 index 000000000..510b9acce --- /dev/null +++ b/wagmi-project/packages/core/src/actions/watchPendingTransactions.test.ts @@ -0,0 +1,49 @@ +import { + accounts, + config, + testClient, + transactionHashRegex, + wait, +} from '@wagmi/test' +import { parseEther } from 'viem' +import type { OnTransactionsParameter } from 'viem/actions' +import { expect, test } from 'vitest' + +import { connect } from './connect.js' +import { disconnect } from './disconnect.js' +import { sendTransaction } from './sendTransaction.js' +import { watchPendingTransactions } from './watchPendingTransactions.js' + +const connector = config.connectors[0]! + +test('default', async () => { + await connect(config, { connector }) + + let transactions: OnTransactionsParameter = [] + const unwatch = watchPendingTransactions(config, { + onTransactions(next) { + transactions = [...transactions, ...next] + }, + }) + await wait(500) + + await sendTransaction(config, { + to: accounts[1], + value: parseEther('1'), + }) + await wait(100) + + await sendTransaction(config, { + to: accounts[3], + value: parseEther('1'), + }) + await wait(100) + + await testClient.mainnet.mine({ blocks: 1 }) + + unwatch() + expect(transactions.length).toBe(2) + expect(transactions[0]).toMatch(transactionHashRegex) + + await disconnect(config, { connector }) +}) diff --git a/wagmi-project/packages/core/src/actions/watchPendingTransactions.ts b/wagmi-project/packages/core/src/actions/watchPendingTransactions.ts new file mode 100644 index 000000000..29f035450 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/watchPendingTransactions.ts @@ -0,0 +1,82 @@ +import type { Chain, Transport, WebSocketTransport } from 'viem' +import { + type WatchPendingTransactionsParameters as viem_WatchPendingTransactionsParameters, + type WatchPendingTransactionsReturnType as viem_WatchPendingTransactionsReturnType, + watchPendingTransactions as viem_watchPendingTransactions, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { SelectChains } from '../types/chain.js' +import type { + ChainIdParameter, + SyncConnectedChainParameter, +} from '../types/properties.js' +import type { UnionCompute } from '../types/utils.js' +import { getAction } from '../utils/getAction.js' + +export type WatchPendingTransactionsParameters< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + /// + chains extends readonly Chain[] = SelectChains, +> = { + [key in keyof chains]: UnionCompute< + viem_WatchPendingTransactionsParameters< + config['_internal']['transports'][chains[key]['id']] extends infer transport extends + Transport + ? Transport extends transport + ? WebSocketTransport + : transport + : WebSocketTransport + > & + ChainIdParameter & + SyncConnectedChainParameter + > +}[number] + +export type WatchPendingTransactionsReturnType = + viem_WatchPendingTransactionsReturnType + +// TODO: wrap in viem's `observe` to avoid duplicate invocations. +/** https://wagmi.sh/core/api/actions/watchPendingTransactions */ +export function watchPendingTransactions< + config extends Config, + chainId extends config['chains'][number]['id'], +>( + config: config, + parameters: WatchPendingTransactionsParameters, +) { + const { syncConnectedChain = config._internal.syncConnectedChain, ...rest } = + parameters + + let unwatch: WatchPendingTransactionsReturnType | undefined + const listener = (chainId: number | undefined) => { + if (unwatch) unwatch() + + const client = config.getClient({ chainId }) + const action = getAction( + client, + viem_watchPendingTransactions, + 'watchPendingTransactions', + ) + unwatch = action(rest as viem_WatchPendingTransactionsParameters) + return unwatch + } + + // set up listener for transaction changes + const unlisten = listener(parameters.chainId) + + // set up subscriber for connected chain changes + let unsubscribe: (() => void) | undefined + if (syncConnectedChain && !parameters.chainId) + unsubscribe = config.subscribe( + ({ chainId }) => chainId, + async (chainId) => listener(chainId), + ) + + return () => { + unlisten?.() + unsubscribe?.() + } +} diff --git a/wagmi-project/packages/core/src/actions/watchPublicClient.test-d.ts b/wagmi-project/packages/core/src/actions/watchPublicClient.test-d.ts new file mode 100644 index 000000000..a7353636c --- /dev/null +++ b/wagmi-project/packages/core/src/actions/watchPublicClient.test-d.ts @@ -0,0 +1,15 @@ +import { config } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' + +import { watchPublicClient } from './watchPublicClient.js' + +test('default', () => { + watchPublicClient(config, { + onChange(client) { + expectTypeOf(client.chain).toEqualTypeOf< + (typeof config)['chains'][number] + >() + expectTypeOf(client.transport.type).toEqualTypeOf<'http'>() + }, + }) +}) diff --git a/wagmi-project/packages/core/src/actions/watchPublicClient.test.ts b/wagmi-project/packages/core/src/actions/watchPublicClient.test.ts new file mode 100644 index 000000000..3d9594002 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/watchPublicClient.test.ts @@ -0,0 +1,23 @@ +import { config } from '@wagmi/test' +import type { Client } from 'viem' +import { expect, test } from 'vitest' + +import { switchChain } from './switchChain.js' +import { watchPublicClient } from './watchPublicClient.js' + +test('default', async () => { + const clients: Client[] = [] + const unwatch = watchPublicClient(config, { + onChange(client) { + clients.push(client) + }, + }) + + switchChain(config, { chainId: 456 }) + switchChain(config, { chainId: 10 }) + switchChain(config, { chainId: 1 }) + + expect(clients.length).toBe(3) + + unwatch() +}) diff --git a/wagmi-project/packages/core/src/actions/watchPublicClient.ts b/wagmi-project/packages/core/src/actions/watchPublicClient.ts new file mode 100644 index 000000000..b7d854c2a --- /dev/null +++ b/wagmi-project/packages/core/src/actions/watchPublicClient.ts @@ -0,0 +1,38 @@ +import type { Config } from '../createConfig.js' +import { + type GetPublicClientReturnType, + getPublicClient, +} from './getPublicClient.js' + +export type WatchPublicClientParameters< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +> = { + onChange( + publicClient: GetPublicClientReturnType, + prevPublicClient: GetPublicClientReturnType, + ): void +} + +export type WatchPublicClientReturnType = () => void + +/** https://wagmi.sh/core/api/actions/watchPublicClient */ +export function watchPublicClient< + config extends Config, + chainId extends config['chains'][number]['id'], +>( + config: config, + parameters: WatchPublicClientParameters, +): WatchPublicClientReturnType { + const { onChange } = parameters + return config.subscribe( + () => getPublicClient(config) as GetPublicClientReturnType, + onChange, + { + equalityFn(a, b) { + return a?.uid === b?.uid + }, + }, + ) +} diff --git a/wagmi-project/packages/core/src/actions/writeContract.test-d.ts b/wagmi-project/packages/core/src/actions/writeContract.test-d.ts new file mode 100644 index 000000000..68009a377 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/writeContract.test-d.ts @@ -0,0 +1,152 @@ +import { abi, config } from '@wagmi/test' +import { http, type Address, parseAbi } from 'viem' +import { celo, mainnet } from 'viem/chains' +import { expectTypeOf, test } from 'vitest' + +import { createConfig } from '../createConfig.js' +import { simulateContract } from './simulateContract.js' +import { type WriteContractParameters, writeContract } from './writeContract.js' + +test('default', async () => { + await writeContract(config, { + address: '0x', + abi: abi.erc20, + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + chainId: 1, + }) +}) + +test('simulateContract', async () => { + const { request } = await simulateContract(config, { + account: '0x', + address: '0x', + abi: abi.erc20, + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + chainId: 1, + }) + await writeContract(config, request) + await writeContract(config, { + address: '0x', + abi: abi.erc20, + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + }) +}) + +test('chain formatters', () => { + const config = createConfig({ + chains: [mainnet, celo], + transports: { [celo.id]: http(), [mainnet.id]: http() }, + }) + + type Result = WriteContractParameters< + typeof abi.erc20, + 'transferFrom', + [Address, Address, bigint], + typeof config + > + expectTypeOf().toMatchTypeOf<{ + chainId?: typeof celo.id | typeof mainnet.id | undefined + feeCurrency?: `0x${string}` | undefined + }>() + writeContract(config, { + address: '0x', + abi: abi.erc20, + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + feeCurrency: '0x', + }) + + type Result2 = WriteContractParameters< + typeof abi.erc20, + 'transferFrom', + [Address, Address, bigint], + typeof config, + typeof celo.id + > + expectTypeOf().toMatchTypeOf<{ + functionName: 'approve' | 'transfer' | 'transferFrom' + args: readonly [Address, Address, bigint] + feeCurrency?: `0x${string}` | undefined + }>() + writeContract(config, { + chainId: celo.id, + address: '0x', + abi: abi.erc20, + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + feeCurrency: '0x', + }) + + type Result3 = WriteContractParameters< + typeof abi.erc20, + 'transferFrom', + [Address, Address, bigint], + typeof config, + typeof mainnet.id + > + expectTypeOf().toMatchTypeOf<{ + functionName: 'approve' | 'transfer' | 'transferFrom' + args: readonly [Address, Address, bigint] + }>() + expectTypeOf().not.toMatchTypeOf<{ + feeCurrency?: `0x${string}` | undefined + }>() + writeContract(config, { + chainId: mainnet.id, + address: '0x', + abi: abi.erc20, + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + // @ts-expect-error + feeCurrency: '0x', + }) +}) + +test('overloads', async () => { + const abi = parseAbi([ + 'function foo() returns (int8)', + 'function foo(address) returns (string)', + 'function foo(address, address) returns ((address foo, address bar))', + 'function bar(uint256) returns (int8)', + ]) + + type Result = WriteContractParameters + expectTypeOf().toEqualTypeOf<'foo' | 'bar'>() + expectTypeOf().toEqualTypeOf< + | readonly [] + | readonly [`0x${string}`] + | readonly [`0x${string}`, `0x${string}`] + | undefined + >() + writeContract(config, { + address: '0x', + abi, + functionName: 'foo', + }) + writeContract(config, { + address: '0x', + abi, + functionName: 'foo', + args: ['0x'], + }) + writeContract(config, { + address: '0x', + abi, + functionName: 'foo', + args: ['0x', '0x'], + }) + writeContract(config, { + address: '0x', + abi, + functionName: 'foo', + // @ts-expect-error + args: ['0x', 123n], + }) + + type Result2 = WriteContractParameters + expectTypeOf().toEqualTypeOf<'foo' | 'bar'>() + expectTypeOf().toEqualTypeOf() +}) diff --git a/wagmi-project/packages/core/src/actions/writeContract.ts b/wagmi-project/packages/core/src/actions/writeContract.ts new file mode 100644 index 000000000..5fb6d8710 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/writeContract.ts @@ -0,0 +1,114 @@ +import type { + Abi, + Account, + Chain, + Client, + ContractFunctionArgs, + ContractFunctionName, +} from 'viem' +import { + type WriteContractErrorType as viem_WriteContractErrorType, + type WriteContractParameters as viem_WriteContractParameters, + type WriteContractReturnType as viem_WriteContractReturnType, + writeContract as viem_writeContract, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { BaseErrorType, ErrorType } from '../errors/base.js' +import type { SelectChains } from '../types/chain.js' +import type { + ChainIdParameter, + ConnectorParameter, +} from '../types/properties.js' +import type { Compute, UnionCompute } from '../types/utils.js' +import { getAction } from '../utils/getAction.js' +import { + type GetConnectorClientErrorType, + getConnectorClient, +} from './getConnectorClient.js' + +export type WriteContractParameters< + abi extends Abi | readonly unknown[] = Abi, + functionName extends ContractFunctionName< + abi, + 'nonpayable' | 'payable' + > = ContractFunctionName, + args extends ContractFunctionArgs< + abi, + 'nonpayable' | 'payable', + functionName + > = ContractFunctionArgs, + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + /// + allFunctionNames = ContractFunctionName, + chains extends readonly Chain[] = SelectChains, +> = UnionCompute< + { + // TODO: Should use `UnionStrictOmit<..., 'chain'>` on `viem_WriteContractParameters` result instead + // temp workaround that doesn't affect runtime behavior for for https://github.com/wevm/wagmi/issues/3981 + [key in keyof chains]: viem_WriteContractParameters< + abi, + functionName, + args, + chains[key], + Account, + chains[key], + allFunctionNames + > + }[number] & + Compute> & + ConnectorParameter & { + /** @deprecated */ + __mode?: 'prepared' + } +> + +export type WriteContractReturnType = viem_WriteContractReturnType + +export type WriteContractErrorType = + // getConnectorClient() + | GetConnectorClientErrorType + // base + | BaseErrorType + | ErrorType + // viem + | viem_WriteContractErrorType + +/** https://wagmi.sh/core/api/actions/writeContract */ +export async function writeContract< + config extends Config, + const abi extends Abi | readonly unknown[], + functionName extends ContractFunctionName, + args extends ContractFunctionArgs< + abi, + 'nonpayable' | 'payable', + functionName + >, + chainId extends config['chains'][number]['id'], +>( + config: config, + parameters: WriteContractParameters, +): Promise { + const { account, chainId, connector, ...request } = parameters + + let client: Client + if (typeof account === 'object' && account?.type === 'local') + client = config.getClient({ chainId }) + else + client = await getConnectorClient(config, { + account: account ?? undefined, + chainId, + connector, + }) + + const action = getAction(client, viem_writeContract, 'writeContract') + const hash = await action({ + ...(request as any), + ...(account ? { account } : {}), + chain: chainId ? { id: chainId } : null, + }) + + return hash +} diff --git a/wagmi-project/packages/core/src/connectors/createConnector.test.ts b/wagmi-project/packages/core/src/connectors/createConnector.test.ts new file mode 100644 index 000000000..d1ff9f20a --- /dev/null +++ b/wagmi-project/packages/core/src/connectors/createConnector.test.ts @@ -0,0 +1,31 @@ +import type { Address } from 'viem' +import { test } from 'vitest' +import { createConnector } from './createConnector.js' + +test('default', () => { + createConnector(() => { + return { + id: 'test', + name: 'Test Connector', + type: 'test', + async setup() {}, + async connect() { + return { accounts: [] as Address[], chainId: 123 } + }, + async disconnect() {}, + async getAccounts() { + return [] + }, + async getChainId() { + return 123 + }, + async isAuthorized() { + return true + }, + onAccountsChanged() {}, + onChainChanged() {}, + async onDisconnect(_error) {}, + async getProvider() {}, + } + }) +}) diff --git a/wagmi-project/packages/core/src/connectors/createConnector.ts b/wagmi-project/packages/core/src/connectors/createConnector.ts new file mode 100644 index 000000000..54b4d9955 --- /dev/null +++ b/wagmi-project/packages/core/src/connectors/createConnector.ts @@ -0,0 +1,93 @@ +import type { + AddEthereumChainParameter, + Address, + Chain, + Client, + ProviderConnectInfo, + ProviderMessage, +} from 'viem' + +import type { Transport } from '../createConfig.js' +import type { Emitter } from '../createEmitter.js' +import type { Storage } from '../createStorage.js' +import type { Compute, ExactPartial, StrictOmit } from '../types/utils.js' + +export type ConnectorEventMap = { + change: { + accounts?: readonly Address[] | undefined + chainId?: number | undefined + } + connect: { accounts: readonly Address[]; chainId: number } + disconnect: never + error: { error: Error } + message: { type: string; data?: unknown | undefined } +} + +export type CreateConnectorFn< + provider = unknown, + properties extends Record = Record, + storageItem extends Record = Record, +> = (config: { + chains: readonly [Chain, ...Chain[]] + emitter: Emitter + storage?: Compute> | null | undefined + transports?: Record | undefined +}) => Compute< + { + readonly icon?: string | undefined + readonly id: string + readonly name: string + readonly rdns?: string | readonly string[] | undefined + /** @deprecated */ + readonly supportsSimulation?: boolean | undefined + readonly type: string + + setup?(): Promise + connect( + parameters?: + | { chainId?: number | undefined; isReconnecting?: boolean | undefined } + | undefined, + ): Promise<{ + accounts: readonly Address[] + chainId: number + }> + disconnect(): Promise + getAccounts(): Promise + getChainId(): Promise + getProvider( + parameters?: { chainId?: number | undefined } | undefined, + ): Promise + getClient?( + parameters?: { chainId?: number | undefined } | undefined, + ): Promise + isAuthorized(): Promise + switchChain?( + parameters: Compute<{ + addEthereumChainParameter?: + | ExactPartial> + | undefined + chainId: number + }>, + ): Promise + + onAccountsChanged(accounts: string[]): void + onChainChanged(chainId: string): void + onConnect?(connectInfo: ProviderConnectInfo): void + onDisconnect(error?: Error | undefined): void + onMessage?(message: ProviderMessage): void + } & properties +> + +export function createConnector< + provider, + properties extends Record = Record, + storageItem extends Record = Record, + /// + createConnectorFn extends CreateConnectorFn< + provider, + properties, + storageItem + > = CreateConnectorFn, +>(createConnectorFn: createConnectorFn) { + return createConnectorFn +} diff --git a/wagmi-project/packages/core/src/connectors/injected.test.ts b/wagmi-project/packages/core/src/connectors/injected.test.ts new file mode 100644 index 000000000..9188a53ba --- /dev/null +++ b/wagmi-project/packages/core/src/connectors/injected.test.ts @@ -0,0 +1,25 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { injected } from './injected.js' + +test('setup', () => { + const connectorFn = injected() + const connector = config._internal.connectors.setup(connectorFn) + expect(connector.name).toEqual('Injected') +}) + +test.each([ + { wallet: undefined, expected: 'Injected' }, + { wallet: 'coinbaseWallet', expected: 'Coinbase Wallet' }, + { wallet: 'metaMask', expected: 'MetaMask' }, + { wallet: 'phantom', expected: 'Phantom' }, + { wallet: 'rainbow', expected: 'Rainbow' }, +] as const satisfies readonly { + wallet: string | undefined + expected: string +}[])('injected({ wallet: $wallet })', ({ wallet, expected }) => { + const connectorFn = injected({ target: wallet }) + const connector = config._internal.connectors.setup(connectorFn) + expect(connector.name).toEqual(expected) +}) diff --git a/wagmi-project/packages/core/src/connectors/injected.ts b/wagmi-project/packages/core/src/connectors/injected.ts new file mode 100644 index 000000000..d686d0aa2 --- /dev/null +++ b/wagmi-project/packages/core/src/connectors/injected.ts @@ -0,0 +1,697 @@ +import { + type AddEthereumChainParameter, + type Address, + type EIP1193Provider, + type ProviderConnectInfo, + type ProviderRpcError, + ResourceUnavailableRpcError, + type RpcError, + SwitchChainError, + UserRejectedRequestError, + getAddress, + numberToHex, + withRetry, + withTimeout, +} from 'viem' + +import type { Connector } from '../createConfig.js' +import { ChainNotConfiguredError } from '../errors/config.js' +import { ProviderNotFoundError } from '../errors/connector.js' +import type { Compute } from '../types/utils.js' +import { createConnector } from './createConnector.js' + +export type InjectedParameters = { + /** + * Some injected providers do not support programmatic disconnect. + * This flag simulates the disconnect behavior by keeping track of connection status in storage. + * @default true + */ + shimDisconnect?: boolean | undefined + /** + * [EIP-1193](https://eips.ethereum.org/EIPS/eip-1193) Ethereum Provider to target + */ + target?: TargetId | Target | (() => Target | undefined) | undefined + unstable_shimAsyncInject?: boolean | number | undefined +} + +injected.type = 'injected' as const +export function injected(parameters: InjectedParameters = {}) { + const { shimDisconnect = true, unstable_shimAsyncInject } = parameters + + function getTarget(): Compute { + const target = parameters.target + if (typeof target === 'function') { + const result = target() + if (result) return result + } + + if (typeof target === 'object') return target + + if (typeof target === 'string') + return { + ...(targetMap[target as keyof typeof targetMap] ?? { + id: target, + name: `${target[0]!.toUpperCase()}${target.slice(1)}`, + provider: `is${target[0]!.toUpperCase()}${target.slice(1)}`, + }), + } + + return { + id: 'injected', + name: 'Injected', + provider(window) { + return window?.ethereum + }, + } + } + + type Provider = WalletProvider | undefined + type Properties = { + onConnect(connectInfo: ProviderConnectInfo): void + } + type StorageItem = { + [_ in 'injected.connected' | `${string}.disconnected`]: true + } + + let accountsChanged: Connector['onAccountsChanged'] | undefined + let chainChanged: Connector['onChainChanged'] | undefined + let connect: Connector['onConnect'] | undefined + let disconnect: Connector['onDisconnect'] | undefined + + return createConnector((config) => ({ + get icon() { + return getTarget().icon + }, + get id() { + return getTarget().id + }, + get name() { + return getTarget().name + }, + /** @deprecated */ + get supportsSimulation() { + return true + }, + type: injected.type, + async setup() { + const provider = await this.getProvider() + // Only start listening for events if `target` is set, otherwise `injected()` will also receive events + if (provider?.on && parameters.target) { + if (!connect) { + connect = this.onConnect.bind(this) + provider.on('connect', connect) + } + + // We shouldn't need to listen for `'accountsChanged'` here since the `'connect'` event should suffice (and wallet shouldn't be connected yet). + // Some wallets, like MetaMask, do not implement the `'connect'` event and overload `'accountsChanged'` instead. + if (!accountsChanged) { + accountsChanged = this.onAccountsChanged.bind(this) + provider.on('accountsChanged', accountsChanged) + } + } + }, + async connect({ chainId, isReconnecting } = {}) { + const provider = await this.getProvider() + if (!provider) throw new ProviderNotFoundError() + + let accounts: readonly Address[] = [] + if (isReconnecting) accounts = await this.getAccounts().catch(() => []) + else if (shimDisconnect) { + // Attempt to show another prompt for selecting account if `shimDisconnect` flag is enabled + try { + const permissions = await provider.request({ + method: 'wallet_requestPermissions', + params: [{ eth_accounts: {} }], + }) + accounts = (permissions[0]?.caveats?.[0]?.value as string[])?.map( + (x) => getAddress(x), + ) + // `'wallet_requestPermissions'` can return a different order of accounts than `'eth_accounts'` + // switch to `'eth_accounts'` ordering if more than one account is connected + // https://github.com/wevm/wagmi/issues/4140 + if (accounts.length > 0) { + const sortedAccounts = await this.getAccounts() + accounts = sortedAccounts + } + } catch (err) { + const error = err as RpcError + // Not all injected providers support `wallet_requestPermissions` (e.g. MetaMask iOS). + // Only bubble up error if user rejects request + if (error.code === UserRejectedRequestError.code) + throw new UserRejectedRequestError(error) + // Or prompt is already open + if (error.code === ResourceUnavailableRpcError.code) throw error + } + } + + try { + if (!accounts?.length && !isReconnecting) { + const requestedAccounts = await provider.request({ + method: 'eth_requestAccounts', + }) + accounts = requestedAccounts.map((x) => getAddress(x)) + } + + // Manage EIP-1193 event listeners + // https://eips.ethereum.org/EIPS/eip-1193#events + if (connect) { + provider.removeListener('connect', connect) + connect = undefined + } + if (!accountsChanged) { + accountsChanged = this.onAccountsChanged.bind(this) + provider.on('accountsChanged', accountsChanged) + } + if (!chainChanged) { + chainChanged = this.onChainChanged.bind(this) + provider.on('chainChanged', chainChanged) + } + if (!disconnect) { + disconnect = this.onDisconnect.bind(this) + provider.on('disconnect', disconnect) + } + + // Switch to chain if provided + let currentChainId = await this.getChainId() + if (chainId && currentChainId !== chainId) { + const chain = await this.switchChain!({ chainId }).catch((error) => { + if (error.code === UserRejectedRequestError.code) throw error + return { id: currentChainId } + }) + currentChainId = chain?.id ?? currentChainId + } + + // Remove disconnected shim if it exists + if (shimDisconnect) + await config.storage?.removeItem(`${this.id}.disconnected`) + + // Add connected shim if no target exists + if (!parameters.target) + await config.storage?.setItem('injected.connected', true) + + return { accounts, chainId: currentChainId } + } catch (err) { + const error = err as RpcError + if (error.code === UserRejectedRequestError.code) + throw new UserRejectedRequestError(error) + if (error.code === ResourceUnavailableRpcError.code) + throw new ResourceUnavailableRpcError(error) + throw error + } + }, + async disconnect() { + const provider = await this.getProvider() + if (!provider) throw new ProviderNotFoundError() + + // Manage EIP-1193 event listeners + if (chainChanged) { + provider.removeListener('chainChanged', chainChanged) + chainChanged = undefined + } + if (disconnect) { + provider.removeListener('disconnect', disconnect) + disconnect = undefined + } + if (!connect) { + connect = this.onConnect.bind(this) + provider.on('connect', connect) + } + + // Experimental support for MetaMask disconnect + // https://github.com/MetaMask/metamask-improvement-proposals/blob/main/MIPs/mip-2.md + try { + // Adding timeout as not all wallets support this method and can hang + // https://github.com/wevm/wagmi/issues/4064 + await withTimeout( + () => + // TODO: Remove explicit type for viem@3 + provider.request<{ + Method: 'wallet_revokePermissions' + Parameters: [permissions: { eth_accounts: Record }] + ReturnType: null + }>({ + // `'wallet_revokePermissions'` added in `viem@2.10.3` + method: 'wallet_revokePermissions', + params: [{ eth_accounts: {} }], + }), + { timeout: 100 }, + ) + } catch {} + + // Add shim signalling connector is disconnected + if (shimDisconnect) { + await config.storage?.setItem(`${this.id}.disconnected`, true) + } + + if (!parameters.target) + await config.storage?.removeItem('injected.connected') + }, + async getAccounts() { + const provider = await this.getProvider() + if (!provider) throw new ProviderNotFoundError() + const accounts = await provider.request({ method: 'eth_accounts' }) + return accounts.map((x) => getAddress(x)) + }, + async getChainId() { + const provider = await this.getProvider() + if (!provider) throw new ProviderNotFoundError() + const hexChainId = await provider.request({ method: 'eth_chainId' }) + return Number(hexChainId) + }, + async getProvider() { + if (typeof window === 'undefined') return undefined + + let provider: Provider + const target = getTarget() + if (typeof target.provider === 'function') + provider = target.provider(window as Window | undefined) + else if (typeof target.provider === 'string') + provider = findProvider(window, target.provider) + else provider = target.provider + + // Some wallets do not conform to EIP-1193 (e.g. Trust Wallet) + // https://github.com/wevm/wagmi/issues/3526#issuecomment-1912683002 + if (provider && !provider.removeListener) { + // Try using `off` handler if it exists, otherwise noop + if ('off' in provider && typeof provider.off === 'function') + provider.removeListener = + provider.off as typeof provider.removeListener + else provider.removeListener = () => {} + } + + return provider + }, + async isAuthorized() { + try { + const isDisconnected = + shimDisconnect && + // If shim exists in storage, connector is disconnected + (await config.storage?.getItem(`${this.id}.disconnected`)) + if (isDisconnected) return false + + // Don't allow injected connector to connect if no target is set and it hasn't already connected + // (e.g. flag in storage is not set). This prevents a targetless injected connector from connecting + // automatically whenever there is a targeted connector configured. + if (!parameters.target) { + const connected = await config.storage?.getItem('injected.connected') + if (!connected) return false + } + + const provider = await this.getProvider() + if (!provider) { + if ( + unstable_shimAsyncInject !== undefined && + unstable_shimAsyncInject !== false + ) { + // If no provider is found, check for async injection + // https://github.com/wevm/references/issues/167 + // https://github.com/MetaMask/detect-provider + const handleEthereum = async () => { + if (typeof window !== 'undefined') + window.removeEventListener( + 'ethereum#initialized', + handleEthereum, + ) + const provider = await this.getProvider() + return !!provider + } + const timeout = + typeof unstable_shimAsyncInject === 'number' + ? unstable_shimAsyncInject + : 1_000 + const res = await Promise.race([ + ...(typeof window !== 'undefined' + ? [ + new Promise((resolve) => + window.addEventListener( + 'ethereum#initialized', + () => resolve(handleEthereum()), + { once: true }, + ), + ), + ] + : []), + new Promise((resolve) => + setTimeout(() => resolve(handleEthereum()), timeout), + ), + ]) + if (res) return true + } + + throw new ProviderNotFoundError() + } + + // Use retry strategy as some injected wallets (e.g. MetaMask) fail to + // immediately resolve JSON-RPC requests on page load. + const accounts = await withRetry(() => this.getAccounts()) + return !!accounts.length + } catch { + return false + } + }, + async switchChain({ addEthereumChainParameter, chainId }) { + const provider = await this.getProvider() + if (!provider) throw new ProviderNotFoundError() + + const chain = config.chains.find((x) => x.id === chainId) + if (!chain) throw new SwitchChainError(new ChainNotConfiguredError()) + + const promise = new Promise((resolve) => { + const listener = ((data) => { + if ('chainId' in data && data.chainId === chainId) { + config.emitter.off('change', listener) + resolve() + } + }) satisfies Parameters[1] + config.emitter.on('change', listener) + }) + + try { + await Promise.all([ + provider + .request({ + method: 'wallet_switchEthereumChain', + params: [{ chainId: numberToHex(chainId) }], + }) + // During `'wallet_switchEthereumChain'`, MetaMask makes a `'net_version'` RPC call to the target chain. + // If this request fails, MetaMask does not emit the `'chainChanged'` event, but will still switch the chain. + // To counter this behavior, we request and emit the current chain ID to confirm the chain switch either via + // this callback or an externally emitted `'chainChanged'` event. + // https://github.com/MetaMask/metamask-extension/issues/24247 + .then(async () => { + const currentChainId = await this.getChainId() + if (currentChainId === chainId) + config.emitter.emit('change', { chainId }) + }), + promise, + ]) + return chain + } catch (err) { + const error = err as RpcError + + // Indicates chain is not added to provider + if ( + error.code === 4902 || + // Unwrapping for MetaMask Mobile + // https://github.com/MetaMask/metamask-mobile/issues/2944#issuecomment-976988719 + (error as ProviderRpcError<{ originalError?: { code: number } }>) + ?.data?.originalError?.code === 4902 + ) { + try { + const { default: blockExplorer, ...blockExplorers } = + chain.blockExplorers ?? {} + let blockExplorerUrls: string[] | undefined + if (addEthereumChainParameter?.blockExplorerUrls) + blockExplorerUrls = addEthereumChainParameter.blockExplorerUrls + else if (blockExplorer) + blockExplorerUrls = [ + blockExplorer.url, + ...Object.values(blockExplorers).map((x) => x.url), + ] + + let rpcUrls: readonly string[] + if (addEthereumChainParameter?.rpcUrls?.length) + rpcUrls = addEthereumChainParameter.rpcUrls + else rpcUrls = [chain.rpcUrls.default?.http[0] ?? ''] + + const addEthereumChain = { + blockExplorerUrls, + chainId: numberToHex(chainId), + chainName: addEthereumChainParameter?.chainName ?? chain.name, + iconUrls: addEthereumChainParameter?.iconUrls, + nativeCurrency: + addEthereumChainParameter?.nativeCurrency ?? + chain.nativeCurrency, + rpcUrls, + } satisfies AddEthereumChainParameter + + await Promise.all([ + provider + .request({ + method: 'wallet_addEthereumChain', + params: [addEthereumChain], + }) + .then(async () => { + const currentChainId = await this.getChainId() + if (currentChainId === chainId) + config.emitter.emit('change', { chainId }) + else + throw new UserRejectedRequestError( + new Error('User rejected switch after adding network.'), + ) + }), + promise, + ]) + + return chain + } catch (error) { + throw new UserRejectedRequestError(error as Error) + } + } + + if (error.code === UserRejectedRequestError.code) + throw new UserRejectedRequestError(error) + throw new SwitchChainError(error) + } + }, + async onAccountsChanged(accounts) { + // Disconnect if there are no accounts + if (accounts.length === 0) this.onDisconnect() + // Connect if emitter is listening for connect event (e.g. is disconnected and connects through wallet interface) + else if (config.emitter.listenerCount('connect')) { + const chainId = (await this.getChainId()).toString() + this.onConnect({ chainId }) + // Remove disconnected shim if it exists + if (shimDisconnect) + await config.storage?.removeItem(`${this.id}.disconnected`) + } + // Regular change event + else + config.emitter.emit('change', { + accounts: accounts.map((x) => getAddress(x)), + }) + }, + onChainChanged(chain) { + const chainId = Number(chain) + config.emitter.emit('change', { chainId }) + }, + async onConnect(connectInfo) { + const accounts = await this.getAccounts() + if (accounts.length === 0) return + + const chainId = Number(connectInfo.chainId) + config.emitter.emit('connect', { accounts, chainId }) + + // Manage EIP-1193 event listeners + const provider = await this.getProvider() + if (provider) { + if (connect) { + provider.removeListener('connect', connect) + connect = undefined + } + if (!accountsChanged) { + accountsChanged = this.onAccountsChanged.bind(this) + provider.on('accountsChanged', accountsChanged) + } + if (!chainChanged) { + chainChanged = this.onChainChanged.bind(this) + provider.on('chainChanged', chainChanged) + } + if (!disconnect) { + disconnect = this.onDisconnect.bind(this) + provider.on('disconnect', disconnect) + } + } + }, + async onDisconnect(error) { + const provider = await this.getProvider() + + // If MetaMask emits a `code: 1013` error, wait for reconnection before disconnecting + // https://github.com/MetaMask/providers/pull/120 + if (error && (error as RpcError<1013>).code === 1013) { + if (provider && !!(await this.getAccounts()).length) return + } + + // No need to remove `${this.id}.disconnected` from storage because `onDisconnect` is typically + // only called when the wallet is disconnected through the wallet's interface, meaning the wallet + // actually disconnected and we don't need to simulate it. + config.emitter.emit('disconnect') + + // Manage EIP-1193 event listeners + if (provider) { + if (chainChanged) { + provider.removeListener('chainChanged', chainChanged) + chainChanged = undefined + } + if (disconnect) { + provider.removeListener('disconnect', disconnect) + disconnect = undefined + } + if (!connect) { + connect = this.onConnect.bind(this) + provider.on('connect', connect) + } + } + }, + })) +} + +const targetMap = { + coinbaseWallet: { + id: 'coinbaseWallet', + name: 'Coinbase Wallet', + provider(window) { + if (window?.coinbaseWalletExtension) return window.coinbaseWalletExtension + return findProvider(window, 'isCoinbaseWallet') + }, + }, + metaMask: { + id: 'metaMask', + name: 'MetaMask', + provider(window) { + return findProvider(window, (provider) => { + if (!provider.isMetaMask) return false + // Brave tries to make itself look like MetaMask + // Could also try RPC `web3_clientVersion` if following is unreliable + if (provider.isBraveWallet && !provider._events && !provider._state) + return false + // Other wallets that try to look like MetaMask + const flags = [ + 'isApexWallet', + 'isAvalanche', + 'isBitKeep', + 'isBlockWallet', + 'isKuCoinWallet', + 'isMathWallet', + 'isOkxWallet', + 'isOKExWallet', + 'isOneInchIOSWallet', + 'isOneInchAndroidWallet', + 'isOpera', + 'isPhantom', + 'isPortal', + 'isRabby', + 'isTokenPocket', + 'isTokenary', + 'isUniswapWallet', + 'isZerion', + ] satisfies WalletProviderFlags[] + for (const flag of flags) if (provider[flag]) return false + return true + }) + }, + }, + phantom: { + id: 'phantom', + name: 'Phantom', + provider(window) { + if (window?.phantom?.ethereum) return window.phantom?.ethereum + return findProvider(window, 'isPhantom') + }, + }, +} as const satisfies TargetMap + +type TargetMap = { [_ in TargetId]?: Target | undefined } + +type Target = { + icon?: string | undefined + id: string + name: string + provider: + | WalletProviderFlags + | WalletProvider + | ((window?: Window | undefined) => WalletProvider | undefined) +} + +/** @deprecated */ +type TargetId = Compute extends `is${infer name}` + ? name extends `${infer char}${infer rest}` + ? `${Lowercase}${rest}` + : never + : never + +/** + * @deprecated As of 2024/10/16, we are no longer accepting new provider flags as EIP-6963 should be used instead. + */ +type WalletProviderFlags = + | 'isApexWallet' + | 'isAvalanche' + | 'isBackpack' + | 'isBifrost' + | 'isBitKeep' + | 'isBitski' + | 'isBlockWallet' + | 'isBraveWallet' + | 'isCoinbaseWallet' + | 'isDawn' + | 'isEnkrypt' + | 'isExodus' + | 'isFrame' + | 'isFrontier' + | 'isGamestop' + | 'isHyperPay' + | 'isImToken' + | 'isKuCoinWallet' + | 'isMathWallet' + | 'isMetaMask' + | 'isOkxWallet' + | 'isOKExWallet' + | 'isOneInchAndroidWallet' + | 'isOneInchIOSWallet' + | 'isOpera' + | 'isPhantom' + | 'isPortal' + | 'isRabby' + | 'isRainbow' + | 'isStatus' + | 'isTally' + | 'isTokenPocket' + | 'isTokenary' + | 'isTrust' + | 'isTrustWallet' + | 'isUniswapWallet' + | 'isXDEFI' + | 'isZerion' + +type WalletProvider = Compute< + EIP1193Provider & { + [key in WalletProviderFlags]?: true | undefined + } & { + providers?: WalletProvider[] | undefined + /** Only exists in MetaMask as of 2022/04/03 */ + _events?: { connect?: (() => void) | undefined } | undefined + /** Only exists in MetaMask as of 2022/04/03 */ + _state?: + | { + accounts?: string[] + initialized?: boolean + isConnected?: boolean + isPermanentlyDisconnected?: boolean + isUnlocked?: boolean + } + | undefined + } +> + +type Window = { + coinbaseWalletExtension?: WalletProvider | undefined + ethereum?: WalletProvider | undefined + phantom?: { ethereum: WalletProvider } | undefined +} + +function findProvider( + window: globalThis.Window | Window | undefined, + select?: WalletProviderFlags | ((provider: WalletProvider) => boolean), +) { + function isProvider(provider: WalletProvider) { + if (typeof select === 'function') return select(provider) + if (typeof select === 'string') return provider[select] + return true + } + + const ethereum = (window as Window).ethereum + if (ethereum?.providers) + return ethereum.providers.find((provider) => isProvider(provider)) + if (ethereum && isProvider(ethereum)) return ethereum + return undefined +} diff --git a/wagmi-project/packages/core/src/connectors/mock.test.ts b/wagmi-project/packages/core/src/connectors/mock.test.ts new file mode 100644 index 000000000..d8a812a3d --- /dev/null +++ b/wagmi-project/packages/core/src/connectors/mock.test.ts @@ -0,0 +1,112 @@ +import { accounts, config } from '@wagmi/test' +import { expect, expectTypeOf, test } from 'vitest' + +import type { Connector } from '../createConfig.js' +import type { CreateConnectorFn } from './createConnector.js' +import { mock } from './mock.js' + +test('setup', () => { + const connectorFn = mock({ accounts }) + const connector = config._internal.connectors.setup(connectorFn) + expect(connector.name).toEqual('Mock Connector') + + expectTypeOf< + typeof connectorFn extends CreateConnectorFn ? true : false + >().toEqualTypeOf() + expectTypeOf< + typeof connector extends Connector ? true : false + >().toEqualTypeOf() + + type ConnectFnParameters = NonNullable< + Parameters<(typeof connector)['connect']>[0] + > + expectTypeOf().toMatchTypeOf() +}) + +test('behavior: features.connectError', () => { + const connectorFn = mock({ accounts, features: { connectError: true } }) + const connector = config._internal.connectors.setup(connectorFn) + expect(() => connector.connect()).rejects.toThrowErrorMatchingInlineSnapshot(` + [UserRejectedRequestError: User rejected the request. + + Details: Failed to connect. + Version: viem@2.29.2] + `) +}) + +test('behavior: connector.getProvider request errors', async () => { + const connectorFn = mock({ + accounts, + features: { + signMessageError: true, + signTypedDataError: true, + switchChainError: true, + watchAssetError: true, + }, + }) + const connector = config._internal.connectors.setup( + connectorFn, + ) as ReturnType + const provider = await connector.getProvider() + + expect( + provider.request({ + method: 'eth_signTypedData_v4', + params: [] as any, + }), + ).rejects.toThrowErrorMatchingInlineSnapshot(` + [UserRejectedRequestError: User rejected the request. + + Details: Failed to sign typed data. + Version: viem@2.29.2] + `) + + expect( + provider.request({ + method: 'wallet_switchEthereumChain', + params: [] as any, + }), + ).rejects.toThrowErrorMatchingInlineSnapshot(` + [UserRejectedRequestError: User rejected the request. + + Details: Failed to switch chain. + Version: viem@2.29.2] + `) + + expect( + provider.request({ + method: 'wallet_watchAsset', + params: [] as any, + }), + ).rejects.toThrowErrorMatchingInlineSnapshot(` + [UserRejectedRequestError: User rejected the request. + + Details: Failed to switch chain. + Version: viem@2.29.2] + `) + + expect( + provider.request({ + method: 'personal_sign', + params: [] as any, + }), + ).rejects.toThrowErrorMatchingInlineSnapshot(` + [UserRejectedRequestError: User rejected the request. + + Details: Failed to sign message. + Version: viem@2.29.2] + `) +}) + +test('behavior: reconnect', async () => { + const connectorFn = mock({ + accounts, + features: { + defaultConnected: true, + reconnect: true, + }, + }) + const connector = config._internal.connectors.setup(connectorFn) + + await expect(connector.isAuthorized()).resolves.toBeTruthy() +}) diff --git a/wagmi-project/packages/core/src/connectors/mock.ts b/wagmi-project/packages/core/src/connectors/mock.ts new file mode 100644 index 000000000..9d4dc9d84 --- /dev/null +++ b/wagmi-project/packages/core/src/connectors/mock.ts @@ -0,0 +1,315 @@ +import { + type Address, + type EIP1193RequestFn, + type Hex, + RpcRequestError, + SwitchChainError, + type Transport, + UserRejectedRequestError, + type WalletCallReceipt, + type WalletGetCallsStatusReturnType, + type WalletRpcSchema, + custom, + fromHex, + getAddress, + keccak256, + numberToHex, + stringToHex, +} from 'viem' +import { rpc } from 'viem/utils' + +import { + ChainNotConfiguredError, + ConnectorNotConnectedError, +} from '../errors/config.js' +import { createConnector } from './createConnector.js' + +export type MockParameters = { + accounts: readonly [Address, ...Address[]] + features?: + | { + defaultConnected?: boolean | undefined + connectError?: boolean | Error | undefined + switchChainError?: boolean | Error | undefined + signMessageError?: boolean | Error | undefined + signTypedDataError?: boolean | Error | undefined + reconnect?: boolean | undefined + watchAssetError?: boolean | Error | undefined + } + | undefined +} + +mock.type = 'mock' as const +export function mock(parameters: MockParameters) { + const transactionCache = new Map() + const features = + parameters.features ?? + ({ defaultConnected: false } satisfies MockParameters['features']) + + type Provider = ReturnType< + Transport<'custom', unknown, EIP1193RequestFn> + > + type Properties = { + connect(parameters?: { + chainId?: number | undefined + isReconnecting?: boolean | undefined + foo?: string | undefined + }): Promise<{ + accounts: readonly Address[] + chainId: number + }> + } + let connected = features.defaultConnected + let connectedChainId: number + + return createConnector((config) => ({ + id: 'mock', + name: 'Mock Connector', + type: mock.type, + async setup() { + connectedChainId = config.chains[0].id + }, + async connect({ chainId } = {}) { + if (features.connectError) { + if (typeof features.connectError === 'boolean') + throw new UserRejectedRequestError(new Error('Failed to connect.')) + throw features.connectError + } + + const provider = await this.getProvider() + const accounts = await provider.request({ + method: 'eth_requestAccounts', + }) + + let currentChainId = await this.getChainId() + if (chainId && currentChainId !== chainId) { + const chain = await this.switchChain!({ chainId }) + currentChainId = chain.id + } + + connected = true + + return { + accounts: accounts.map((x) => getAddress(x)), + chainId: currentChainId, + } + }, + async disconnect() { + connected = false + }, + async getAccounts() { + if (!connected) throw new ConnectorNotConnectedError() + const provider = await this.getProvider() + const accounts = await provider.request({ method: 'eth_accounts' }) + return accounts.map((x) => getAddress(x)) + }, + async getChainId() { + const provider = await this.getProvider() + const hexChainId = await provider.request({ method: 'eth_chainId' }) + return fromHex(hexChainId, 'number') + }, + async isAuthorized() { + if (!features.reconnect) return false + if (!connected) return false + const accounts = await this.getAccounts() + return !!accounts.length + }, + async switchChain({ chainId }) { + const provider = await this.getProvider() + const chain = config.chains.find((x) => x.id === chainId) + if (!chain) throw new SwitchChainError(new ChainNotConfiguredError()) + + await provider.request({ + method: 'wallet_switchEthereumChain', + params: [{ chainId: numberToHex(chainId) }], + }) + return chain + }, + onAccountsChanged(accounts) { + if (accounts.length === 0) this.onDisconnect() + else + config.emitter.emit('change', { + accounts: accounts.map((x) => getAddress(x)), + }) + }, + onChainChanged(chain) { + const chainId = Number(chain) + config.emitter.emit('change', { chainId }) + }, + async onDisconnect(_error) { + config.emitter.emit('disconnect') + connected = false + }, + async getProvider({ chainId } = {}) { + const chain = + config.chains.find((x) => x.id === chainId) ?? config.chains[0] + const url = chain.rpcUrls.default.http[0]! + + const request: EIP1193RequestFn = async ({ method, params }) => { + // eth methods + if (method === 'eth_chainId') return numberToHex(connectedChainId) + if (method === 'eth_requestAccounts') return parameters.accounts + if (method === 'eth_signTypedData_v4') + if (features.signTypedDataError) { + if (typeof features.signTypedDataError === 'boolean') + throw new UserRejectedRequestError( + new Error('Failed to sign typed data.'), + ) + throw features.signTypedDataError + } + + // wallet methods + if (method === 'wallet_switchEthereumChain') { + if (features.switchChainError) { + if (typeof features.switchChainError === 'boolean') + throw new UserRejectedRequestError( + new Error('Failed to switch chain.'), + ) + throw features.switchChainError + } + type Params = [{ chainId: Hex }] + connectedChainId = fromHex((params as Params)[0].chainId, 'number') + this.onChainChanged(connectedChainId.toString()) + return + } + + if (method === 'wallet_watchAsset') { + if (features.watchAssetError) { + if (typeof features.watchAssetError === 'boolean') + throw new UserRejectedRequestError( + new Error('Failed to switch chain.'), + ) + throw features.watchAssetError + } + return connected + } + + if (method === 'wallet_getCapabilities') + return { + '0x2105': { + paymasterService: { + supported: + (params as [Hex])[0] === + '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', + }, + sessionKeys: { + supported: true, + }, + }, + '0x14A34': { + paymasterService: { + supported: + (params as [Hex])[0] === + '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', + }, + }, + } + + if (method === 'wallet_sendCalls') { + const hashes = [] + const calls = (params as any)[0].calls + for (const call of calls) { + const { result, error } = await rpc.http(url, { + body: { + method: 'eth_sendTransaction', + params: [call], + }, + }) + if (error) + throw new RpcRequestError({ + body: { method, params }, + error, + url, + }) + hashes.push(result) + } + const id = keccak256(stringToHex(JSON.stringify(calls))) + transactionCache.set(id, hashes) + return { id } + } + + if (method === 'wallet_getCallsStatus') { + const hashes = transactionCache.get((params as any)[0]) + if (!hashes) + return { + atomic: false, + chainId: '0x1', + id: (params as any)[0], + status: 100, + receipts: [], + version: '2.0.0', + } satisfies WalletGetCallsStatusReturnType + + const receipts = await Promise.all( + hashes.map(async (hash) => { + const { result, error } = await rpc.http(url, { + body: { + method: 'eth_getTransactionReceipt', + params: [hash], + id: 0, + }, + }) + if (error) + throw new RpcRequestError({ + body: { method, params }, + error, + url, + }) + if (!result) return null + return { + blockHash: result.blockHash, + blockNumber: result.blockNumber, + gasUsed: result.gasUsed, + logs: result.logs, + status: result.status, + transactionHash: result.transactionHash, + } satisfies WalletCallReceipt + }), + ) + const receipts_ = receipts.filter((x) => x !== null) + if (receipts_.length === 0) + return { + atomic: false, + chainId: '0x1', + id: (params as any)[0], + status: 100, + receipts: [], + version: '2.0.0', + } satisfies WalletGetCallsStatusReturnType + return { + atomic: false, + chainId: '0x1', + id: (params as any)[0], + status: 200, + receipts: receipts_, + version: '2.0.0', + } satisfies WalletGetCallsStatusReturnType + } + + if (method === 'wallet_showCallsStatus') return + + // other methods + if (method === 'personal_sign') { + if (features.signMessageError) { + if (typeof features.signMessageError === 'boolean') + throw new UserRejectedRequestError( + new Error('Failed to sign message.'), + ) + throw features.signMessageError + } + // Change `personal_sign` to `eth_sign` and swap params + method = 'eth_sign' + type Params = [data: Hex, address: Address] + params = [(params as Params)[1], (params as Params)[0]] + } + + const body = { method, params } + const { error, result } = await rpc.http(url, { body }) + if (error) throw new RpcRequestError({ body, error, url }) + + return result + } + return custom({ request })({ retryCount: 0 }) + }, + })) +} diff --git a/wagmi-project/packages/core/src/createConfig.test-d.ts b/wagmi-project/packages/core/src/createConfig.test-d.ts new file mode 100644 index 000000000..3daa57bd5 --- /dev/null +++ b/wagmi-project/packages/core/src/createConfig.test-d.ts @@ -0,0 +1,110 @@ +import { accounts } from '@wagmi/test' +import { http, createClient, webSocket } from 'viem' +import { mainnet, sepolia } from 'viem/chains' +import { expectTypeOf, test } from 'vitest' + +import { mock } from './connectors/mock.js' +import { type CreateConfigParameters, createConfig } from './createConfig.js' + +test('high-level config', () => { + // Create config without needing to import viem modules. + const config = createConfig({ + cacheTime: 100, + chains: [mainnet, sepolia], + connectors: [mock({ accounts })], + batch: { multicall: true }, + pollingInterval: { [mainnet.id]: 100 }, + transports: { + [mainnet.id]: webSocket(), + [sepolia.id]: http(), + }, + }) + const client = config.getClient({ chainId: mainnet.id }) + expectTypeOf(client.chain).toEqualTypeOf(mainnet) + expectTypeOf(client.transport.type).toEqualTypeOf<'webSocket'>() +}) + +test('low-level config', () => { + // Create a "multi chain" config using viem modules. + const config = createConfig({ + chains: [mainnet, sepolia], + connectors: [mock({ accounts })], + client({ chain }) { + return createClient({ chain, transport: http() }) + }, + }) + const client = config.getClient({ chainId: mainnet.id }) + expectTypeOf(client.chain).toEqualTypeOf(mainnet) +}) + +test('behavior: `chains` must have at least one chain', () => { + createConfig({ + // @ts-expect-error + chains: [], + connectors: [mock({ accounts })], + transports: { + [mainnet.id]: http(), + }, + }) + createConfig({ + // @ts-expect-error + chains: [], + connectors: [mock({ accounts })], + client: ({ chain }) => + createClient({ + chain, + transport: http(), + }), + }) +}) + +test('behavior: missing transport for chain', () => { + createConfig({ + chains: [mainnet, sepolia], + connectors: [mock({ accounts })], + // @ts-expect-error + transports: { + [mainnet.id]: http(), + }, + }) + createConfig({ + chains: [mainnet, sepolia], + connectors: [mock({ accounts })], + transports: { + [mainnet.id]: http(), + // @ts-expect-error + [123]: http(), + }, + }) +}) + +test('behavior: parameters should not include certain client config properties', () => { + type Result = keyof CreateConfigParameters + expectTypeOf<'account' extends Result ? true : false>().toEqualTypeOf() + expectTypeOf<'chain' extends Result ? true : false>().toEqualTypeOf() + expectTypeOf< + 'transport' extends Result ? true : false + >().toEqualTypeOf() +}) + +test('infer connectors', () => { + const connectorFn = mock({ accounts }) + const config = createConfig({ + chains: [mainnet, sepolia], + connectors: [connectorFn], + transports: { + [mainnet.id]: webSocket(), + [sepolia.id]: http(), + }, + }) + + const connector = config.connectors[0]! + expectTypeOf(connector).toEqualTypeOf( + config._internal.connectors.setup(connectorFn), + ) + + type ConnectFnParameters = NonNullable< + Parameters<(typeof connector)['connect']>[0] + > + expectTypeOf().toMatchTypeOf() +}) diff --git a/wagmi-project/packages/core/src/createConfig.test.ts b/wagmi-project/packages/core/src/createConfig.test.ts new file mode 100644 index 000000000..a6ae41e28 --- /dev/null +++ b/wagmi-project/packages/core/src/createConfig.test.ts @@ -0,0 +1,440 @@ +import { accounts, chain, wait } from '@wagmi/test' +import { + type EIP1193Provider, + type EIP6963ProviderDetail, + announceProvider, +} from 'mipd' +import { http } from 'viem' +import { expect, test, vi } from 'vitest' + +import { connect } from './actions/connect.js' +import { disconnect } from './actions/disconnect.js' +import { switchChain } from './actions/switchChain.js' +import { createConnector } from './connectors/createConnector.js' +import { mock } from './connectors/mock.js' +import { createConfig } from './createConfig.js' +import { createStorage } from './createStorage.js' + +const { mainnet, optimism } = chain + +vi.mock(import('mipd'), async (importOriginal) => { + const mod = await importOriginal() + + let cache: typeof mod | undefined + if (!cache) + cache = { + ...mod, + createStore() { + const store = mod.createStore() + return { + ...store, + getProviders() { + return [ + getProviderDetail({ name: 'Example', rdns: 'com.example' }), + getProviderDetail({ name: 'Mock', rdns: 'com.mock' }), + ] + }, + } + }, + } + return cache +}) + +test('default', () => { + const config = createConfig({ + chains: [mainnet], + connectors: [mock({ accounts })], + transports: { + [mainnet.id]: http(), + }, + }) + expect(config).toBeDefined() +}) + +test('getClient', () => { + const config = createConfig({ + chains: [mainnet, optimism], + connectors: [mock({ accounts })], + syncConnectedChain: true, + transports: { + [mainnet.id]: http(), + [optimism.id]: http(), + }, + }) + + { + const client = config.getClient() + expect(client.chain.id).toBe(mainnet.id) + } + + { + const client = config.getClient({ chainId: mainnet.id }) + expect(client.chain.id).toBe(mainnet.id) + } + + expect(() => + config.getClient({ + // @ts-expect-error + chainId: 123456, + }), + ).toThrowErrorMatchingInlineSnapshot(` + [ChainNotConfiguredError: Chain not configured. + + Version: @wagmi/core@x.y.z] + `) + + expect(() => { + // @ts-expect-error + config.state.chainId = 123456 + config.getClient() + }).toThrowErrorMatchingInlineSnapshot(` + [ChainNotConfiguredError: Chain not configured. + + Version: @wagmi/core@x.y.z] + `) +}) + +test('behavior: syncConnectedChain', async () => { + const config = createConfig({ + chains: [mainnet, optimism], + connectors: [mock({ accounts })], + syncConnectedChain: true, + transports: { + [mainnet.id]: http(), + [optimism.id]: http(), + }, + }) + // defaults to first chain in `createConfig({ chains })` + expect(config.getClient().chain.id).toBe(mainnet.id) + + // switches to optimism + await switchChain(config, { chainId: optimism.id }) + expect(config.getClient().chain.id).toBe(optimism.id) + + // connects to mainnet + await connect(config, { + chainId: mainnet.id, + connector: config.connectors[0]!, + }) + expect(config.getClient().chain.id).toBe(mainnet.id) + + // switches to optimism + await switchChain(config, { chainId: optimism.id }) + expect(config.getClient().chain.id).toBe(optimism.id) + + // disconnects, still connected to optimism + await disconnect(config) + expect(config.getClient().chain.id).toBe(optimism.id) +}) + +test('behavior: migrate for current version', async () => { + const state = { + 'wagmi.store': JSON.stringify({ + state: { + connections: { + __type: 'Map', + value: [ + [ + '983b8aca245', + { + accounts: [ + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + ], + chainId: 1, + connector: { + id: 'io.metamask', + name: 'MetaMask', + type: 'injected', + uid: '983b8aca245', + }, + }, + ], + ], + }, + chainId: 1, + current: '983b8aca245', + }, + version: Number.NaN, // mocked version is `'x.y.z'`, which will get interpreted as `NaN` + }), + } as Record + Object.defineProperty(window, 'localStorage', { + value: { + getItem: vi.fn((key) => state[key] ?? null), + removeItem: vi.fn((key) => state.delete?.[key]), + setItem: vi.fn((key, value) => { + state[key] = value + }), + }, + writable: true, + }) + + const storage = createStorage<{ store: object }>({ + storage: window.localStorage, + }) + + const config = createConfig({ + chains: [mainnet], + storage, + transports: { [mainnet.id]: http() }, + }) + + await wait(100) + + expect(config.state).toMatchInlineSnapshot(` + { + "chainId": 1, + "connections": Map { + "983b8aca245" => { + "accounts": [ + "0xA0Cf798816D4b9b9866b5330EEa46a18382f251e", + "0xd2135CfB216b74109775236E36d4b433F1DF507B", + ], + "chainId": 1, + "connector": { + "id": "io.metamask", + "name": "MetaMask", + "type": "injected", + "uid": "983b8aca245", + }, + }, + }, + "current": "983b8aca245", + "status": "disconnected", + } + `) +}) + +test('behavior: migrate chainId', async () => { + const state = { + 'wagmi.store': JSON.stringify({ + state: { chainId: 10 }, + version: 1, + }), + } as Record + Object.defineProperty(window, 'localStorage', { + value: { + getItem: vi.fn((key) => state[key] ?? null), + removeItem: vi.fn((key) => state.delete?.[key]), + setItem: vi.fn((key, value) => { + state[key] = value + }), + }, + writable: true, + }) + + const storage = createStorage<{ store: object }>({ + storage: window.localStorage, + }) + + const config = createConfig({ + chains: [mainnet, optimism], + storage, + transports: { + [mainnet.id]: http(), + [optimism.id]: http(), + }, + }) + + await wait(100) + + expect(config.state).toMatchInlineSnapshot(` + { + "chainId": 10, + "connections": Map {}, + "current": null, + "status": "disconnected", + } + `) +}) + +test('behavior: properties passed through to Viem Client via getClient', () => { + { + const properties = { + batch: { + multicall: { + batchSize: 102_400, + }, + }, + cacheTime: 5_000, + pollingInterval: 1_000, + } + + const config = createConfig({ + chains: [mainnet, optimism], + transports: { + [mainnet.id]: http(), + [optimism.id]: http(), + }, + ...properties, + }) + + const { + account: _a, + chain: _c, + extend: _e, + key: _k, + name: _n, + request: _r, + transport: _tr, + uid: _u, + type: _ty, + ...rest + } = config.getClient() + expect(rest).toEqual(properties) + } + + { + const config = createConfig({ + chains: [mainnet, optimism], + transports: { + [mainnet.id]: http(), + [optimism.id]: http(), + }, + batch: { + [mainnet.id]: { + multicall: { + batchSize: 1024, + }, + }, + }, + }) + + const client = config.getClient() + expect(client.batch).toMatchInlineSnapshot(` + { + "multicall": { + "batchSize": 1024, + }, + } + `) + + const client2 = config.getClient({ chainId: optimism.id }) + expect(client2.batch).toMatchInlineSnapshot(` + { + "multicall": true, + } + `) + } +}) + +test('behavior: restore unconfigured chainId', () => { + const state = { + 'wagmi.store': JSON.stringify({ + state: { chainId: 10 }, + version: 1, + }), + } as Record + Object.defineProperty(window, 'localStorage', { + value: { + getItem: vi.fn((key) => state[key] ?? null), + removeItem: vi.fn((key) => state.delete?.[key]), + setItem: vi.fn((key, value) => { + state[key] = value + }), + }, + writable: true, + }) + + const storage = createStorage<{ store: object }>({ + storage: window.localStorage, + }) + + const config = createConfig({ + chains: [mainnet], + storage, + transports: { + [mainnet.id]: http(), + }, + }) + + expect(config.state).toMatchInlineSnapshot(` + { + "chainId": 1, + "connections": Map {}, + "current": null, + "status": "disconnected", + } + `) + + const client = config.getClient() + expect(client.chain.id).toBe(mainnet.id) +}) + +test('behavior: setup connector', async () => { + const config = createConfig({ + chains: [mainnet], + transports: { + [mainnet.id]: http(), + }, + }) + + const connectorFn = mock({ accounts }) + const connector = config._internal.connectors.setup(connectorFn) + config._internal.connectors.setState((x) => [...x, connector]) + + await connect(config, { + chainId: mainnet.id, + connector: config.connectors.find((x) => x.uid === connector.uid)!, + }) + + expect(config.state.current).toBe(connector.uid) + + await disconnect(config) +}) + +test('behavior: eip 6963 providers', async () => { + const detail_1 = getProviderDetail({ name: 'Foo Wallet', rdns: 'com.foo' }) + const detail_2 = getProviderDetail({ name: 'Bar Wallet', rdns: 'com.bar' }) + const detail_3 = getProviderDetail({ name: 'Mock', rdns: 'com.mock' }) + + const config = createConfig({ + chains: [mainnet], + connectors: [ + createConnector((c) => { + return { + ...mock({ accounts })(c), + rdns: ['com.mock', 'com.baz'], + } + }), + ], + transports: { + [mainnet.id]: http(), + }, + }) + + await wait(100) + announceProvider(detail_1)() + await wait(100) + announceProvider(detail_1)() + await wait(100) + announceProvider(detail_2)() + await wait(100) + announceProvider(detail_3)() + await wait(100) + + expect( + config.connectors.flatMap((x) => x.rdns ?? x.id), + ).toMatchInlineSnapshot(` + [ + "com.mock", + "com.baz", + "com.example", + "com.foo", + "com.bar", + ] + `) +}) + +function getProviderDetail( + info: Pick, +): EIP6963ProviderDetail { + return { + info: { + icon: 'data:image/svg+xml,', + uuid: crypto.randomUUID(), + ...info, + }, + provider: `` as unknown as EIP1193Provider, + } +} diff --git a/wagmi-project/packages/core/src/createConfig.ts b/wagmi-project/packages/core/src/createConfig.ts new file mode 100644 index 000000000..154eef5f6 --- /dev/null +++ b/wagmi-project/packages/core/src/createConfig.ts @@ -0,0 +1,653 @@ +import { + type EIP6963ProviderDetail, + type Store as MipdStore, + createStore as createMipd, +} from 'mipd' +import { + type Address, + type Chain, + type Client, + type EIP1193RequestFn, + createClient, + type ClientConfig as viem_ClientConfig, + type Transport as viem_Transport, +} from 'viem' +import { persist, subscribeWithSelector } from 'zustand/middleware' +import { type Mutate, type StoreApi, createStore } from 'zustand/vanilla' + +import type { + ConnectorEventMap, + CreateConnectorFn, +} from './connectors/createConnector.js' +import { injected } from './connectors/injected.js' +import { type Emitter, type EventData, createEmitter } from './createEmitter.js' +import { + type Storage, + createStorage, + getDefaultStorage, +} from './createStorage.js' +import { ChainNotConfiguredError } from './errors/config.js' +import type { + Compute, + ExactPartial, + LooseOmit, + OneOf, + RemoveUndefined, +} from './types/utils.js' +import { uid } from './utils/uid.js' +import { version } from './version.js' + +export function createConfig< + const chains extends readonly [Chain, ...Chain[]], + transports extends Record, + const connectorFns extends readonly CreateConnectorFn[], +>( + parameters: CreateConfigParameters, +): Config { + const { + multiInjectedProviderDiscovery = true, + storage = createStorage({ + storage: getDefaultStorage(), + }), + syncConnectedChain = true, + ssr = false, + ...rest + } = parameters + + ///////////////////////////////////////////////////////////////////////////////////////////////// + // Set up connectors, clients, etc. + ///////////////////////////////////////////////////////////////////////////////////////////////// + + const mipd = + typeof window !== 'undefined' && multiInjectedProviderDiscovery + ? createMipd() + : undefined + + const chains = createStore(() => rest.chains) + const connectors = createStore(() => { + const collection = [] + const rdnsSet = new Set() + for (const connectorFns of rest.connectors ?? []) { + const connector = setup(connectorFns) + collection.push(connector) + if (!ssr && connector.rdns) { + const rdnsValues = + typeof connector.rdns === 'string' ? [connector.rdns] : connector.rdns + for (const rdns of rdnsValues) { + rdnsSet.add(rdns) + } + } + } + if (!ssr && mipd) { + const providers = mipd.getProviders() + for (const provider of providers) { + if (rdnsSet.has(provider.info.rdns)) continue + collection.push(setup(providerDetailToConnector(provider))) + } + } + return collection + }) + function setup(connectorFn: CreateConnectorFn): Connector { + // Set up emitter with uid and add to connector so they are "linked" together. + const emitter = createEmitter(uid()) + const connector = { + ...connectorFn({ + emitter, + chains: chains.getState(), + storage, + transports: rest.transports, + }), + emitter, + uid: emitter.uid, + } + + // Start listening for `connect` events on connector setup + // This allows connectors to "connect" themselves without user interaction (e.g. MetaMask's "Manually connect to current site") + emitter.on('connect', connect) + connector.setup?.() + + return connector + } + function providerDetailToConnector(providerDetail: EIP6963ProviderDetail) { + const { info } = providerDetail + const provider = providerDetail.provider as any + return injected({ target: { ...info, id: info.rdns, provider } }) + } + + const clients = new Map>() + function getClient( + config: { chainId?: chainId | chains[number]['id'] | undefined } = {}, + ): Client> { + const chainId = config.chainId ?? store.getState().chainId + const chain = chains.getState().find((x) => x.id === chainId) + + // chainId specified and not configured + if (config.chainId && !chain) throw new ChainNotConfiguredError() + + // If the target chain is not configured, use the client of the current chain. + type Return = Client> + { + const client = clients.get(store.getState().chainId) + if (client && !chain) return client as Return + if (!chain) throw new ChainNotConfiguredError() + } + + // If a memoized client exists for a chain id, use that. + { + const client = clients.get(chainId) + if (client) return client as Return + } + + let client: Client + if (rest.client) client = rest.client({ chain }) + else { + const chainId = chain.id as chains[number]['id'] + const chainIds = chains.getState().map((x) => x.id) + // Grab all properties off `rest` and resolve for use in `createClient` + const properties: Partial = {} + const entries = Object.entries(rest) as [keyof typeof rest, any][] + + for (const [key, value] of entries) { + if ( + key === 'chains' || + key === 'client' || + key === 'connectors' || + key === 'transports' + ) + continue + + if (typeof value === 'object') { + // check if value is chainId-specific since some values can be objects + // e.g. { batch: { multicall: { batchSize: 1024 } } } + if (chainId in value) properties[key] = value[chainId] + else { + // check if value is chainId-specific, but does not have value for current chainId + const hasChainSpecificValue = chainIds.some((x) => x in value) + if (hasChainSpecificValue) continue + properties[key] = value + } + } else properties[key] = value + } + + client = createClient({ + ...properties, + chain, + batch: properties.batch ?? { multicall: true }, + transport: (parameters) => + rest.transports[chainId]({ ...parameters, connectors }), + }) + } + + clients.set(chainId, client) + return client as Return + } + + ///////////////////////////////////////////////////////////////////////////////////////////////// + // Create store + ///////////////////////////////////////////////////////////////////////////////////////////////// + + function getInitialState(): State { + return { + chainId: chains.getState()[0].id, + connections: new Map(), + current: null, + status: 'disconnected', + } + } + + let currentVersion: number + const prefix = '0.0.0-canary-' + if (version.startsWith(prefix)) + currentVersion = Number.parseInt(version.replace(prefix, '')) + // use package major version to version store + else currentVersion = Number.parseInt(version.split('.')[0] ?? '0') + + const store = createStore( + subscribeWithSelector( + // only use persist middleware if storage exists + storage + ? persist(getInitialState, { + migrate(persistedState, version) { + if (version === currentVersion) return persistedState as State + + const initialState = getInitialState() + const chainId = validatePersistedChainId( + persistedState, + initialState.chainId, + ) + return { ...initialState, chainId } + }, + name: 'store', + partialize(state) { + // Only persist "critical" store properties to preserve storage size. + return { + connections: { + __type: 'Map', + value: Array.from(state.connections.entries()).map( + ([key, connection]) => { + const { id, name, type, uid } = connection.connector + const connector = { id, name, type, uid } + return [key, { ...connection, connector }] + }, + ), + } as unknown as PartializedState['connections'], + chainId: state.chainId, + current: state.current, + } satisfies PartializedState + }, + merge(persistedState, currentState) { + // `status` should not be persisted as it messes with reconnection + if ( + typeof persistedState === 'object' && + persistedState && + 'status' in persistedState + ) + delete persistedState.status + // Make sure persisted `chainId` is valid + const chainId = validatePersistedChainId( + persistedState, + currentState.chainId, + ) + return { + ...currentState, + ...(persistedState as object), + chainId, + } + }, + skipHydration: ssr, + storage: storage as Storage>, + version: currentVersion, + }) + : getInitialState, + ), + ) + store.setState(getInitialState()) + + function validatePersistedChainId( + persistedState: unknown, + defaultChainId: number, + ) { + return persistedState && + typeof persistedState === 'object' && + 'chainId' in persistedState && + typeof persistedState.chainId === 'number' && + chains.getState().some((x) => x.id === persistedState.chainId) + ? persistedState.chainId + : defaultChainId + } + + ///////////////////////////////////////////////////////////////////////////////////////////////// + // Subscribe to changes + ///////////////////////////////////////////////////////////////////////////////////////////////// + + // Update default chain when connector chain changes + if (syncConnectedChain) + store.subscribe( + ({ connections, current }) => + current ? connections.get(current)?.chainId : undefined, + (chainId) => { + // If chain is not configured, then don't switch over to it. + const isChainConfigured = chains + .getState() + .some((x) => x.id === chainId) + if (!isChainConfigured) return + + return store.setState((x) => ({ + ...x, + chainId: chainId ?? x.chainId, + })) + }, + ) + + // EIP-6963 subscribe for new wallet providers + mipd?.subscribe((providerDetails) => { + const connectorIdSet = new Set() + const connectorRdnsSet = new Set() + for (const connector of connectors.getState()) { + connectorIdSet.add(connector.id) + if (connector.rdns) { + const rdnsValues = + typeof connector.rdns === 'string' ? [connector.rdns] : connector.rdns + for (const rdns of rdnsValues) { + connectorRdnsSet.add(rdns) + } + } + } + + const newConnectors: Connector[] = [] + for (const providerDetail of providerDetails) { + if (connectorRdnsSet.has(providerDetail.info.rdns)) continue + const connector = setup(providerDetailToConnector(providerDetail)) + if (connectorIdSet.has(connector.id)) continue + newConnectors.push(connector) + } + + if (storage && !store.persist.hasHydrated()) return + connectors.setState((x) => [...x, ...newConnectors], true) + }) + + ///////////////////////////////////////////////////////////////////////////////////////////////// + // Emitter listeners + ///////////////////////////////////////////////////////////////////////////////////////////////// + + function change(data: EventData) { + store.setState((x) => { + const connection = x.connections.get(data.uid) + if (!connection) return x + return { + ...x, + connections: new Map(x.connections).set(data.uid, { + accounts: + (data.accounts as readonly [Address, ...Address[]]) ?? + connection.accounts, + chainId: data.chainId ?? connection.chainId, + connector: connection.connector, + }), + } + }) + } + function connect(data: EventData) { + // Disable handling if reconnecting/connecting + if ( + store.getState().status === 'connecting' || + store.getState().status === 'reconnecting' + ) + return + + store.setState((x) => { + const connector = connectors.getState().find((x) => x.uid === data.uid) + if (!connector) return x + + if (connector.emitter.listenerCount('connect')) + connector.emitter.off('connect', change) + if (!connector.emitter.listenerCount('change')) + connector.emitter.on('change', change) + if (!connector.emitter.listenerCount('disconnect')) + connector.emitter.on('disconnect', disconnect) + + return { + ...x, + connections: new Map(x.connections).set(data.uid, { + accounts: data.accounts as readonly [Address, ...Address[]], + chainId: data.chainId, + connector: connector, + }), + current: data.uid, + status: 'connected', + } + }) + } + function disconnect(data: EventData) { + store.setState((x) => { + const connection = x.connections.get(data.uid) + if (connection) { + const connector = connection.connector + if (connector.emitter.listenerCount('change')) + connection.connector.emitter.off('change', change) + if (connector.emitter.listenerCount('disconnect')) + connection.connector.emitter.off('disconnect', disconnect) + if (!connector.emitter.listenerCount('connect')) + connection.connector.emitter.on('connect', connect) + } + + x.connections.delete(data.uid) + + if (x.connections.size === 0) + return { + ...x, + connections: new Map(), + current: null, + status: 'disconnected', + } + + const nextConnection = x.connections.values().next().value as Connection + return { + ...x, + connections: new Map(x.connections), + current: nextConnection.connector.uid, + } + }) + } + + return { + get chains() { + return chains.getState() as chains + }, + get connectors() { + return connectors.getState() as Connector[] + }, + storage, + + getClient, + get state() { + return store.getState() as unknown as State + }, + setState(value) { + let newState: State + if (typeof value === 'function') newState = value(store.getState() as any) + else newState = value + + // Reset state if it got set to something not matching the base state + const initialState = getInitialState() + if (typeof newState !== 'object') newState = initialState + const isCorrupt = Object.keys(initialState).some((x) => !(x in newState)) + if (isCorrupt) newState = initialState + + store.setState(newState, true) + }, + subscribe(selector, listener, options) { + return store.subscribe( + selector as unknown as (state: State) => any, + listener, + options + ? ({ + ...options, + fireImmediately: options.emitImmediately, + // Workaround cast since Zustand does not support `'exactOptionalPropertyTypes'` + } as RemoveUndefined) + : undefined, + ) + }, + + _internal: { + mipd, + store, + ssr: Boolean(ssr), + syncConnectedChain, + transports: rest.transports as transports, + chains: { + setState(value) { + const nextChains = ( + typeof value === 'function' ? value(chains.getState()) : value + ) as chains + if (nextChains.length === 0) return + return chains.setState(nextChains, true) + }, + subscribe(listener) { + return chains.subscribe(listener) + }, + }, + connectors: { + providerDetailToConnector, + setup: setup as ( + connectorFn: connectorFn, + ) => Connector, + setState(value) { + return connectors.setState( + typeof value === 'function' ? value(connectors.getState()) : value, + true, + ) + }, + subscribe(listener) { + return connectors.subscribe(listener) + }, + }, + events: { change, connect, disconnect }, + }, + } +} + +///////////////////////////////////////////////////////////////////////////////////////////////// +// Types +///////////////////////////////////////////////////////////////////////////////////////////////// + +export type CreateConfigParameters< + chains extends readonly [Chain, ...Chain[]] = readonly [Chain, ...Chain[]], + transports extends Record = Record< + chains[number]['id'], + Transport + >, + connectorFns extends + readonly CreateConnectorFn[] = readonly CreateConnectorFn[], +> = Compute< + { + chains: chains + connectors?: connectorFns | undefined + multiInjectedProviderDiscovery?: boolean | undefined + storage?: Storage | null | undefined + ssr?: boolean | undefined + syncConnectedChain?: boolean | undefined + } & OneOf< + | ({ transports: transports } & { + [key in keyof ClientConfig]?: + | ClientConfig[key] + | { [_ in chains[number]['id']]?: ClientConfig[key] | undefined } + | undefined + }) + | { + client(parameters: { chain: chains[number] }): Client< + transports[chains[number]['id']], + chains[number] + > + } + > +> + +export type Config< + chains extends readonly [Chain, ...Chain[]] = readonly [Chain, ...Chain[]], + transports extends Record = Record< + chains[number]['id'], + Transport + >, + connectorFns extends + readonly CreateConnectorFn[] = readonly CreateConnectorFn[], +> = { + readonly chains: chains + readonly connectors: readonly Connector[] + readonly storage: Storage | null + + readonly state: State + setState( + value: State | ((state: State) => State), + ): void + subscribe( + selector: (state: State) => state, + listener: (state: state, previousState: state) => void, + options?: + | { + emitImmediately?: boolean | undefined + equalityFn?: ((a: state, b: state) => boolean) | undefined + } + | undefined, + ): () => void + + getClient(parameters?: { + chainId?: chainId | chains[number]['id'] | undefined + }): Client> + + /** + * Not part of versioned API, proceed with caution. + * @internal + */ + _internal: Internal +} + +type Internal< + chains extends readonly [Chain, ...Chain[]] = readonly [Chain, ...Chain[]], + transports extends Record = Record< + chains[number]['id'], + Transport + >, +> = { + readonly mipd: MipdStore | undefined + readonly store: Mutate, [['zustand/persist', any]]> + readonly ssr: boolean + readonly syncConnectedChain: boolean + readonly transports: transports + + chains: { + setState( + value: + | readonly [Chain, ...Chain[]] + | (( + state: readonly [Chain, ...Chain[]], + ) => readonly [Chain, ...Chain[]]), + ): void + subscribe( + listener: ( + state: readonly [Chain, ...Chain[]], + prevState: readonly [Chain, ...Chain[]], + ) => void, + ): () => void + } + connectors: { + providerDetailToConnector( + providerDetail: EIP6963ProviderDetail, + ): CreateConnectorFn + setup( + connectorFn: connectorFn, + ): Connector + setState(value: Connector[] | ((state: Connector[]) => Connector[])): void + subscribe( + listener: (state: Connector[], prevState: Connector[]) => void, + ): () => void + } + events: { + change(data: EventData): void + connect(data: EventData): void + disconnect(data: EventData): void + } +} + +export type State< + chains extends readonly [Chain, ...Chain[]] = readonly [Chain, ...Chain[]], +> = { + chainId: chains[number]['id'] + connections: Map + current: string | null + status: 'connected' | 'connecting' | 'disconnected' | 'reconnecting' +} + +export type PartializedState = Compute< + ExactPartial> +> + +export type Connection = { + accounts: readonly [Address, ...Address[]] + chainId: number + connector: Connector +} + +export type Connector< + createConnectorFn extends CreateConnectorFn = CreateConnectorFn, +> = ReturnType & { + emitter: Emitter + uid: string +} + +export type Transport< + type extends string = string, + rpcAttributes = Record, + eip1193RequestFn extends EIP1193RequestFn = EIP1193RequestFn, +> = ( + params: Parameters< + viem_Transport + >[0] & { + connectors?: StoreApi | undefined + }, +) => ReturnType> + +type ClientConfig = LooseOmit< + viem_ClientConfig, + 'account' | 'chain' | 'key' | 'name' | 'transport' | 'type' +> diff --git a/wagmi-project/packages/core/src/createEmitter.test.ts b/wagmi-project/packages/core/src/createEmitter.test.ts new file mode 100644 index 000000000..5eb453bb5 --- /dev/null +++ b/wagmi-project/packages/core/src/createEmitter.test.ts @@ -0,0 +1,19 @@ +import { expect, test, vi } from 'vitest' + +import type { ConnectorEventMap } from './connectors/createConnector.js' +import { createEmitter } from './createEmitter.js' +import { uid } from './utils/uid.js' + +test('default', () => { + const emitter = createEmitter(uid()) + + const onMessage = vi.fn() + emitter.on('message', onMessage) + emitter.emit('message', { type: 'bar', data: 'baz' }) + + expect(onMessage).toHaveBeenCalledWith({ + type: 'bar', + data: 'baz', + uid: emitter.uid, + }) +}) diff --git a/wagmi-project/packages/core/src/createEmitter.ts b/wagmi-project/packages/core/src/createEmitter.ts new file mode 100644 index 000000000..20bf4c5a8 --- /dev/null +++ b/wagmi-project/packages/core/src/createEmitter.ts @@ -0,0 +1,68 @@ +import { EventEmitter } from 'eventemitter3' + +type EventMap = Record +type EventKey = string & keyof eventMap +type EventFn = ( + ...parameters: parameters +) => void +export type EventData< + eventMap extends EventMap, + eventName extends keyof eventMap, +> = (eventMap[eventName] extends [never] ? unknown : eventMap[eventName]) & { + uid: string +} + +export class Emitter { + _emitter = new EventEmitter() + + constructor(public uid: string) {} + + on>( + eventName: key, + fn: EventFn< + eventMap[key] extends [never] + ? [{ uid: string }] + : [data: eventMap[key] & { uid: string }] + >, + ) { + this._emitter.on(eventName, fn as EventFn) + } + + once>( + eventName: key, + fn: EventFn< + eventMap[key] extends [never] + ? [{ uid: string }] + : [data: eventMap[key] & { uid: string }] + >, + ) { + this._emitter.once(eventName, fn as EventFn) + } + + off>( + eventName: key, + fn: EventFn< + eventMap[key] extends [never] + ? [{ uid: string }] + : [data: eventMap[key] & { uid: string }] + >, + ) { + this._emitter.off(eventName, fn as EventFn) + } + + emit>( + eventName: key, + ...params: eventMap[key] extends [never] ? [] : [data: eventMap[key]] + ) { + const data = params[0] + this._emitter.emit(eventName, { uid: this.uid, ...data }) + } + + listenerCount>(eventName: key) { + return this._emitter.listenerCount(eventName) + } +} + +export function createEmitter(uid: string) { + return new Emitter(uid) +} diff --git a/wagmi-project/packages/core/src/createStorage.test-d.ts b/wagmi-project/packages/core/src/createStorage.test-d.ts new file mode 100644 index 000000000..6bb4c7f30 --- /dev/null +++ b/wagmi-project/packages/core/src/createStorage.test-d.ts @@ -0,0 +1,74 @@ +import { expectTypeOf, test } from 'vitest' +import { createStorage } from './createStorage.js' + +import type { Connection } from './createConfig.js' + +test('getItem', () => { + const storage = createStorage({ storage: localStorage }) + + expectTypeOf(storage.getItem('recentConnectorId')).toEqualTypeOf< + string | null | Promise + >() + expectTypeOf(storage.getItem('recentConnectorId', 'foo')).toEqualTypeOf< + string | Promise + >() + expectTypeOf(storage.getItem('foo')).toEqualTypeOf() + // @ts-expect-error incorrect argument type + storage.getItem('recentConnectorId', 1n) + + expectTypeOf(storage.getItem('state')).toEqualTypeOf< + | { + chainId?: number | undefined + connections?: Map | undefined + current?: string | null | undefined + status?: + | 'connected' + | 'connecting' + | 'reconnecting' + | 'disconnected' + | undefined + } + | null + | Promise<{ + chainId?: number | undefined + connections?: Map | undefined + current?: string | null | undefined + status?: + | 'connected' + | 'connecting' + | 'reconnecting' + | 'disconnected' + | undefined + } | null> + >() + + const customStorage = createStorage<{ foo: number }>({ + storage: localStorage, + }) + expectTypeOf(customStorage.getItem('foo')).toEqualTypeOf< + number | null | Promise + >() + expectTypeOf(customStorage.getItem('foo', 1)).toEqualTypeOf< + number | Promise + >() +}) + +test('setItem', () => { + const storage = createStorage({ storage: localStorage }) + + storage.setItem('recentConnectorId', 'foo') + // @ts-expect-error incorrect argument type + storage.setItem('recentConnectorId', 1n) +}) + +test('serialize/deserialize types', () => { + createStorage({ + deserialize(value) { + return value + }, + serialize(value) { + return value + }, + storage: localStorage, + }) +}) diff --git a/wagmi-project/packages/core/src/createStorage.test.ts b/wagmi-project/packages/core/src/createStorage.test.ts new file mode 100644 index 000000000..06aa0f89d --- /dev/null +++ b/wagmi-project/packages/core/src/createStorage.test.ts @@ -0,0 +1,45 @@ +import { expect, test, vi } from 'vitest' + +import { createStorage } from './createStorage.js' + +Object.defineProperty(window, 'localStorage', { + value: { + getItem: vi.fn(() => null), + removeItem: vi.fn(() => null), + setItem: vi.fn(() => null), + }, + writable: true, +}) + +test('inits', () => { + const storage = createStorage({ storage: window.localStorage }) + expect(storage).toBeDefined() +}) + +test('getItem', () => { + const storage = createStorage({ storage: window.localStorage }) + storage.getItem('recentConnectorId') + expect(window.localStorage.getItem).toHaveBeenCalledTimes(1) + expect(window.localStorage.getItem).toHaveBeenCalledWith( + 'wagmi.recentConnectorId', + ) +}) + +test('setItem', () => { + const storage = createStorage({ storage: window.localStorage }) + storage.setItem('recentConnectorId', 'bar') + expect(window.localStorage.setItem).toHaveBeenCalledTimes(1) + expect(window.localStorage.setItem).toHaveBeenCalledWith( + 'wagmi.recentConnectorId', + '"bar"', + ) +}) + +test('removeItem', () => { + const storage = createStorage({ storage: window.localStorage }) + storage.removeItem('recentConnectorId') + expect(window.localStorage.removeItem).toHaveBeenCalledTimes(1) + expect(window.localStorage.removeItem).toHaveBeenCalledWith( + 'wagmi.recentConnectorId', + ) +}) diff --git a/wagmi-project/packages/core/src/createStorage.ts b/wagmi-project/packages/core/src/createStorage.ts new file mode 100644 index 000000000..8995ca320 --- /dev/null +++ b/wagmi-project/packages/core/src/createStorage.ts @@ -0,0 +1,112 @@ +import type { PartializedState } from './createConfig.js' +import type { Compute } from './types/utils.js' +import { deserialize as deserialize_ } from './utils/deserialize.js' +import { serialize as serialize_ } from './utils/serialize.js' + +// key-values for loose autocomplete and typing +export type StorageItemMap = { + recentConnectorId: string + state: PartializedState +} + +export type Storage< + itemMap extends Record = Record, + /// + storageItemMap extends StorageItemMap = StorageItemMap & itemMap, +> = { + key: string + getItem< + key extends keyof storageItemMap, + value extends storageItemMap[key], + defaultValue extends value | null | undefined, + >( + key: key, + defaultValue?: defaultValue | undefined, + ): + | (defaultValue extends null ? value | null : value) + | Promise + setItem< + key extends keyof storageItemMap, + value extends storageItemMap[key] | null, + >(key: key, value: value): void | Promise + removeItem(key: keyof storageItemMap): void | Promise +} + +export type BaseStorage = { + getItem( + key: string, + ): string | null | undefined | Promise + setItem(key: string, value: string): void | Promise + removeItem(key: string): void | Promise +} + +export type CreateStorageParameters = { + deserialize?: ((value: string) => type | unknown) | undefined + key?: string | undefined + serialize?: ((value: type | any) => string) | undefined + storage?: Compute | undefined +} + +export function createStorage< + itemMap extends Record = Record, + storageItemMap extends StorageItemMap = StorageItemMap & itemMap, +>(parameters: CreateStorageParameters): Compute> { + const { + deserialize = deserialize_, + key: prefix = 'wagmi', + serialize = serialize_, + storage = noopStorage, + } = parameters + + function unwrap(value: type): type | Promise { + if (value instanceof Promise) return value.then((x) => x).catch(() => null) + return value + } + + return { + ...storage, + key: prefix, + async getItem(key, defaultValue) { + const value = storage.getItem(`${prefix}.${key as string}`) + const unwrapped = await unwrap(value) + if (unwrapped) return deserialize(unwrapped) ?? null + return (defaultValue ?? null) as any + }, + async setItem(key, value) { + const storageKey = `${prefix}.${key as string}` + if (value === null) await unwrap(storage.removeItem(storageKey)) + else await unwrap(storage.setItem(storageKey, serialize(value))) + }, + async removeItem(key) { + await unwrap(storage.removeItem(`${prefix}.${key as string}`)) + }, + } +} + +export const noopStorage = { + getItem: () => null, + setItem: () => {}, + removeItem: () => {}, +} satisfies BaseStorage + +export function getDefaultStorage() { + const storage = (() => { + if (typeof window !== 'undefined' && window.localStorage) + return window.localStorage + return noopStorage + })() + return { + getItem(key) { + return storage.getItem(key) + }, + removeItem(key) { + storage.removeItem(key) + }, + setItem(key, value) { + try { + storage.setItem(key, value) + // silence errors by default (QuotaExceededError, SecurityError, etc.) + } catch {} + }, + } satisfies BaseStorage +} diff --git a/wagmi-project/packages/core/src/errors/base.test.ts b/wagmi-project/packages/core/src/errors/base.test.ts new file mode 100644 index 000000000..443b1ea3c --- /dev/null +++ b/wagmi-project/packages/core/src/errors/base.test.ts @@ -0,0 +1,155 @@ +import { expect, test } from 'vitest' + +import { BaseError } from './base.js' + +test('BaseError', () => { + expect(new BaseError('An error occurred.')).toMatchInlineSnapshot(` + [WagmiCoreError: An error occurred. + + Version: @wagmi/core@x.y.z] + `) + + expect( + new BaseError('An error occurred.', { details: 'details' }), + ).toMatchInlineSnapshot(` + [WagmiCoreError: An error occurred. + + Details: details + Version: @wagmi/core@x.y.z] + `) + + expect(new BaseError('', { details: 'details' })).toMatchInlineSnapshot(` + [WagmiCoreError: An error occurred. + + Details: details + Version: @wagmi/core@x.y.z] + `) +}) + +test('BaseError (w/ docsPath)', () => { + expect( + new BaseError('An error occurred.', { + details: 'details', + docsPath: '/lol', + }), + ).toMatchInlineSnapshot(` + [WagmiCoreError: An error occurred. + + Docs: https://wagmi.sh/core/lol.html + Details: details + Version: @wagmi/core@x.y.z] + `) + expect( + new BaseError('An error occurred.', { + cause: new BaseError('error', { docsPath: '/docs' }), + }), + ).toMatchInlineSnapshot(` + [WagmiCoreError: An error occurred. + + Docs: https://wagmi.sh/core/docs.html + Version: @wagmi/core@x.y.z] + `) + expect( + new BaseError('An error occurred.', { + cause: new BaseError('error'), + docsPath: '/lol', + }), + ).toMatchInlineSnapshot(` + [WagmiCoreError: An error occurred. + + Docs: https://wagmi.sh/core/lol.html + Version: @wagmi/core@x.y.z] + `) + expect( + new BaseError('An error occurred.', { + details: 'details', + docsPath: '/lol', + docsSlug: 'test', + }), + ).toMatchInlineSnapshot(` + [WagmiCoreError: An error occurred. + + Docs: https://wagmi.sh/core/lol.html#test + Details: details + Version: @wagmi/core@x.y.z] + `) +}) + +test('BaseError (w/ metaMessages)', () => { + expect( + new BaseError('An error occurred.', { + details: 'details', + metaMessages: ['Reason: idk', 'Cause: lol'], + }), + ).toMatchInlineSnapshot(` + [WagmiCoreError: An error occurred. + + Reason: idk + Cause: lol + + Details: details + Version: @wagmi/core@x.y.z] + `) +}) + +test('inherited BaseError', () => { + const err = new BaseError('An error occurred.', { + details: 'details', + docsPath: '/lol', + }) + expect( + new BaseError('An internal error occurred.', { + cause: err, + }), + ).toMatchInlineSnapshot(` + [WagmiCoreError: An internal error occurred. + + Docs: https://wagmi.sh/core/lol.html + Details: details + Version: @wagmi/core@x.y.z] + `) +}) + +test('inherited Error', () => { + const err = new Error('details') + expect( + new BaseError('An internal error occurred.', { + cause: err, + docsPath: '/lol', + }), + ).toMatchInlineSnapshot(` + [WagmiCoreError: An internal error occurred. + + Docs: https://wagmi.sh/core/lol.html + Details: details + Version: @wagmi/core@x.y.z] + `) +}) + +test('walk: no predicate fn (walks to leaf)', () => { + class FooError extends BaseError {} + class BarError extends BaseError {} + + const err = new BaseError('test1', { + cause: new FooError('test2', { cause: new BarError('test3') }), + }) + expect(err.walk()).toMatchInlineSnapshot(` + [WagmiCoreError: test3 + + Version: @wagmi/core@x.y.z] + `) +}) + +test('walk: predicate fn', () => { + class FooError extends BaseError {} + class BarError extends BaseError {} + + const err = new BaseError('test1', { + cause: new FooError('test2', { cause: new BarError('test3') }), + }) + expect(err.walk((err) => err instanceof FooError)).toMatchInlineSnapshot(` + [WagmiCoreError: test2 + + Version: @wagmi/core@x.y.z] + `) +}) diff --git a/wagmi-project/packages/core/src/errors/base.ts b/wagmi-project/packages/core/src/errors/base.ts new file mode 100644 index 000000000..8540c1da7 --- /dev/null +++ b/wagmi-project/packages/core/src/errors/base.ts @@ -0,0 +1,74 @@ +import type { Compute, OneOf } from '../types/utils.js' +import { getVersion } from '../utils/getVersion.js' + +export type ErrorType = Error & { name: name } + +type BaseErrorOptions = Compute< + OneOf<{ details?: string | undefined } | { cause: BaseError | Error }> & { + docsPath?: string | undefined + docsSlug?: string | undefined + metaMessages?: string[] | undefined + } +> + +export type BaseErrorType = BaseError & { name: 'WagmiCoreError' } +export class BaseError extends Error { + details: string + docsPath?: string | undefined + metaMessages?: string[] | undefined + shortMessage: string + + override name = 'WagmiCoreError' + get docsBaseUrl() { + return 'https://wagmi.sh/core' + } + get version() { + return getVersion() + } + + constructor(shortMessage: string, options: BaseErrorOptions = {}) { + super() + + const details = + options.cause instanceof BaseError + ? options.cause.details + : options.cause?.message + ? options.cause.message + : options.details! + const docsPath = + options.cause instanceof BaseError + ? options.cause.docsPath || options.docsPath + : options.docsPath + + this.message = [ + shortMessage || 'An error occurred.', + '', + ...(options.metaMessages ? [...options.metaMessages, ''] : []), + ...(docsPath + ? [ + `Docs: ${this.docsBaseUrl}${docsPath}.html${ + options.docsSlug ? `#${options.docsSlug}` : '' + }`, + ] + : []), + ...(details ? [`Details: ${details}`] : []), + `Version: ${this.version}`, + ].join('\n') + + if (options.cause) this.cause = options.cause + this.details = details + this.docsPath = docsPath + this.metaMessages = options.metaMessages + this.shortMessage = shortMessage + } + + walk(fn?: (err: unknown) => boolean) { + return this.#walk(this, fn) + } + + #walk(err: unknown, fn?: (err: unknown) => boolean): unknown { + if (fn?.(err)) return err + if ((err as Error).cause) return this.#walk((err as Error).cause, fn) + return err + } +} diff --git a/wagmi-project/packages/core/src/errors/config.test.ts b/wagmi-project/packages/core/src/errors/config.test.ts new file mode 100644 index 000000000..1ec07fd10 --- /dev/null +++ b/wagmi-project/packages/core/src/errors/config.test.ts @@ -0,0 +1,68 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { + ChainNotConfiguredError, + ConnectorAccountNotFoundError, + ConnectorAlreadyConnectedError, + ConnectorChainMismatchError, + ConnectorNotConnectedError, + ConnectorNotFoundError, + ConnectorUnavailableReconnectingError, +} from './config.js' + +test('constructors', () => { + expect(new ChainNotConfiguredError()).toMatchInlineSnapshot(` + [ChainNotConfiguredError: Chain not configured. + + Version: @wagmi/core@x.y.z] + `) + expect(new ConnectorAlreadyConnectedError()).toMatchInlineSnapshot(` + [ConnectorAlreadyConnectedError: Connector already connected. + + Version: @wagmi/core@x.y.z] + `) + expect(new ConnectorNotConnectedError()).toMatchInlineSnapshot(` + [ConnectorNotConnectedError: Connector not connected. + + Version: @wagmi/core@x.y.z] + `) + expect(new ConnectorNotFoundError()).toMatchInlineSnapshot(` + [ConnectorNotFoundError: Connector not found. + + Version: @wagmi/core@x.y.z] + `) + expect( + new ConnectorAccountNotFoundError({ + address: '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + connector: config.connectors[0]!, + }), + ).toMatchInlineSnapshot(` + [ConnectorAccountNotFoundError: Account "0xA0Cf798816D4b9b9866b5330EEa46a18382f251e" not found for connector "Mock Connector". + + Version: @wagmi/core@x.y.z] + `) + expect( + new ConnectorChainMismatchError({ + connectionChainId: 1, + connectorChainId: 123, + }), + ).toMatchInlineSnapshot(` + [ConnectorChainMismatchError: The current chain of the connector (id: 123) does not match the connection's chain (id: 1). + + Current Chain ID: 123 + Expected Chain ID: 1 + + Version: @wagmi/core@x.y.z] + `) + expect( + new ConnectorUnavailableReconnectingError({ + connector: { name: 'Rabby Wallet' }, + }), + ).toMatchInlineSnapshot(` + [ConnectorUnavailableReconnectingError: Connector "Rabby Wallet" unavailable while reconnecting. + + Details: During the reconnection step, the only connector methods guaranteed to be available are: \`id\`, \`name\`, \`type\`, \`uid\`. All other methods are not guaranteed to be available until reconnection completes and connectors are fully restored. This error commonly occurs for connectors that asynchronously inject after reconnection has already started. + Version: @wagmi/core@x.y.z] + `) +}) diff --git a/wagmi-project/packages/core/src/errors/config.ts b/wagmi-project/packages/core/src/errors/config.ts new file mode 100644 index 000000000..2956f0132 --- /dev/null +++ b/wagmi-project/packages/core/src/errors/config.ts @@ -0,0 +1,103 @@ +import type { Address } from 'viem' + +import type { Connector } from '../createConfig.js' +import { BaseError } from './base.js' + +export type ChainNotConfiguredErrorType = ChainNotConfiguredError & { + name: 'ChainNotConfiguredError' +} +export class ChainNotConfiguredError extends BaseError { + override name = 'ChainNotConfiguredError' + constructor() { + super('Chain not configured.') + } +} + +export type ConnectorAlreadyConnectedErrorType = + ConnectorAlreadyConnectedError & { + name: 'ConnectorAlreadyConnectedError' + } +export class ConnectorAlreadyConnectedError extends BaseError { + override name = 'ConnectorAlreadyConnectedError' + constructor() { + super('Connector already connected.') + } +} + +export type ConnectorNotConnectedErrorType = ConnectorNotConnectedError & { + name: 'ConnectorNotConnectedError' +} +export class ConnectorNotConnectedError extends BaseError { + override name = 'ConnectorNotConnectedError' + constructor() { + super('Connector not connected.') + } +} + +export type ConnectorNotFoundErrorType = ConnectorNotFoundError & { + name: 'ConnectorNotFoundError' +} +export class ConnectorNotFoundError extends BaseError { + override name = 'ConnectorNotFoundError' + constructor() { + super('Connector not found.') + } +} + +export type ConnectorAccountNotFoundErrorType = + ConnectorAccountNotFoundError & { + name: 'ConnectorAccountNotFoundError' + } +export class ConnectorAccountNotFoundError extends BaseError { + override name = 'ConnectorAccountNotFoundError' + constructor({ + address, + connector, + }: { + address: Address + connector: Connector + }) { + super(`Account "${address}" not found for connector "${connector.name}".`) + } +} + +export type ConnectorChainMismatchErrorType = ConnectorAccountNotFoundError & { + name: 'ConnectorChainMismatchError' +} +export class ConnectorChainMismatchError extends BaseError { + override name = 'ConnectorChainMismatchError' + constructor({ + connectionChainId, + connectorChainId, + }: { + connectionChainId: number + connectorChainId: number + }) { + super( + `The current chain of the connector (id: ${connectorChainId}) does not match the connection's chain (id: ${connectionChainId}).`, + { + metaMessages: [ + `Current Chain ID: ${connectorChainId}`, + `Expected Chain ID: ${connectionChainId}`, + ], + }, + ) + } +} + +export type ConnectorUnavailableReconnectingErrorType = + ConnectorUnavailableReconnectingError & { + name: 'ConnectorUnavailableReconnectingError' + } +export class ConnectorUnavailableReconnectingError extends BaseError { + override name = 'ConnectorUnavailableReconnectingError' + constructor({ connector }: { connector: { name: string } }) { + super(`Connector "${connector.name}" unavailable while reconnecting.`, { + details: [ + 'During the reconnection step, the only connector methods guaranteed to be available are: `id`, `name`, `type`, `uid`.', + 'All other methods are not guaranteed to be available until reconnection completes and connectors are fully restored.', + 'This error commonly occurs for connectors that asynchronously inject after reconnection has already started.', + ].join(' '), + }) + } +} diff --git a/wagmi-project/packages/core/src/errors/connector.test.ts b/wagmi-project/packages/core/src/errors/connector.test.ts new file mode 100644 index 000000000..258ef834c --- /dev/null +++ b/wagmi-project/packages/core/src/errors/connector.test.ts @@ -0,0 +1,24 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { + ProviderNotFoundError, + SwitchChainNotSupportedError, +} from './connector.js' + +test('constructors', () => { + expect(new ProviderNotFoundError()).toMatchInlineSnapshot(` + [ProviderNotFoundError: Provider not found. + + Version: @wagmi/core@x.y.z] + `) + expect( + new SwitchChainNotSupportedError({ + connector: config.connectors[0]!, + }), + ).toMatchInlineSnapshot(` + [SwitchChainNotSupportedError: "Mock Connector" does not support programmatic chain switching. + + Version: @wagmi/core@x.y.z] + `) +}) diff --git a/wagmi-project/packages/core/src/errors/connector.ts b/wagmi-project/packages/core/src/errors/connector.ts new file mode 100644 index 000000000..c6c30ef1a --- /dev/null +++ b/wagmi-project/packages/core/src/errors/connector.ts @@ -0,0 +1,23 @@ +import type { Connector } from '../createConfig.js' +import { BaseError } from './base.js' + +export type ProviderNotFoundErrorType = ProviderNotFoundError & { + name: 'ProviderNotFoundError' +} +export class ProviderNotFoundError extends BaseError { + override name = 'ProviderNotFoundError' + constructor() { + super('Provider not found.') + } +} + +export type SwitchChainNotSupportedErrorType = SwitchChainNotSupportedError & { + name: 'SwitchChainNotSupportedError' +} +export class SwitchChainNotSupportedError extends BaseError { + override name = 'SwitchChainNotSupportedError' + + constructor({ connector }: { connector: Connector }) { + super(`"${connector.name}" does not support programmatic chain switching.`) + } +} diff --git a/wagmi-project/packages/core/src/experimental/actions/writeContracts.test.ts b/wagmi-project/packages/core/src/experimental/actions/writeContracts.test.ts new file mode 100644 index 000000000..b74cd780e --- /dev/null +++ b/wagmi-project/packages/core/src/experimental/actions/writeContracts.test.ts @@ -0,0 +1,99 @@ +import { abi, address, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { connect } from '../../actions/connect.js' +import { disconnect } from '../../actions/disconnect.js' +import { writeContracts } from './writeContracts.js' + +const connector = config.connectors[0]! + +test('default', async () => { + await connect(config, { connector }) + await expect( + writeContracts(config, { + contracts: [ + { + abi: abi.wagmiMintExample, + address: address.wagmiMintExample, + functionName: 'mint', + }, + { + abi: abi.wagmiMintExample, + address: address.wagmiMintExample, + functionName: 'mint', + }, + { + abi: abi.wagmiMintExample, + address: address.wagmiMintExample, + functionName: 'mint', + }, + ], + }), + ).resolves.toMatchInlineSnapshot( + ` + { + "id": "0x8913636bd97cf4bcc0a6343c730905a27ead0f7480ff82190072e916439eb212", + } + `, + ) + await disconnect(config, { connector }) +}) + +test('behavior: not connected', async () => { + await expect( + writeContracts(config, { + contracts: [ + { + abi: abi.wagmiMintExample, + address: address.wagmiMintExample, + functionName: 'mint', + }, + { + abi: abi.wagmiMintExample, + address: address.wagmiMintExample, + functionName: 'mint', + }, + { + abi: abi.wagmiMintExample, + address: address.wagmiMintExample, + functionName: 'mint', + }, + ], + }), + ).rejects.toThrowErrorMatchingInlineSnapshot(` + [ConnectorNotConnectedError: Connector not connected. + + Version: @wagmi/core@x.y.z] + `) +}) + +test('behavior: account does not exist on connector', async () => { + await connect(config, { connector }) + await expect( + writeContracts(config, { + account: '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + contracts: [ + { + abi: abi.wagmiMintExample, + address: address.wagmiMintExample, + functionName: 'mint', + }, + { + abi: abi.wagmiMintExample, + address: address.wagmiMintExample, + functionName: 'mint', + }, + { + abi: abi.wagmiMintExample, + address: address.wagmiMintExample, + functionName: 'mint', + }, + ], + }), + ).rejects.toThrowErrorMatchingInlineSnapshot(` + [ConnectorAccountNotFoundError: Account "0xA0Cf798816D4b9b9866b5330EEa46a18382f251e" not found for connector "Mock Connector". + + Version: @wagmi/core@x.y.z] + `) + await disconnect(config, { connector }) +}) diff --git a/wagmi-project/packages/core/src/experimental/actions/writeContracts.ts b/wagmi-project/packages/core/src/experimental/actions/writeContracts.ts new file mode 100644 index 000000000..06e668759 --- /dev/null +++ b/wagmi-project/packages/core/src/experimental/actions/writeContracts.ts @@ -0,0 +1,78 @@ +import type { Account, Chain, ContractFunctionParameters } from 'viem' +import { + type WriteContractsErrorType as viem_WriteContractsErrorType, + type WriteContractsParameters as viem_WriteContractsParameters, + type WriteContractsReturnType as viem_WriteContractsReturnType, + writeContracts as viem_writeContracts, +} from 'viem/experimental' + +import { + type GetConnectorClientErrorType, + getConnectorClient, +} from '../../actions/getConnectorClient.js' +import type { Config } from '../../createConfig.js' +import type { BaseErrorType, ErrorType } from '../../errors/base.js' +import type { SelectChains } from '../../types/chain.js' +import type { + ChainIdParameter, + ConnectorParameter, +} from '../../types/properties.js' +import type { Compute } from '../../types/utils.js' + +export type WriteContractsParameters< + contracts extends readonly unknown[] = readonly ContractFunctionParameters[], + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + /// + chains extends readonly Chain[] = SelectChains, +> = { + [key in keyof chains]: Compute< + Omit< + viem_WriteContractsParameters< + contracts, + chains[key], + Account, + chains[key] + >, + 'chain' + > & + ChainIdParameter & + ConnectorParameter + > +}[number] + +export type WriteContractsReturnType = viem_WriteContractsReturnType + +export type WriteContractsErrorType = + // getConnectorClient() + | GetConnectorClientErrorType + // base + | BaseErrorType + | ErrorType + // viem + | viem_WriteContractsErrorType + +/** https://wagmi.sh/core/api/actions/writeContracts */ +export async function writeContracts< + const contracts extends readonly unknown[], + config extends Config, + chainId extends config['chains'][number]['id'], +>( + config: config, + parameters: WriteContractsParameters, +): Promise { + const { account, chainId, connector, ...rest } = parameters + + const client = await getConnectorClient(config, { + account, + chainId, + connector, + }) + + return viem_writeContracts(client, { + ...(rest as any), + ...(account ? { account } : {}), + chain: chainId ? { id: chainId } : undefined, + }) +} diff --git a/wagmi-project/packages/core/src/experimental/query/writeContracts.test.ts b/wagmi-project/packages/core/src/experimental/query/writeContracts.test.ts new file mode 100644 index 000000000..5f4a1f28d --- /dev/null +++ b/wagmi-project/packages/core/src/experimental/query/writeContracts.test.ts @@ -0,0 +1,15 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { writeContractsMutationOptions } from './writeContracts.js' + +test('default', () => { + expect(writeContractsMutationOptions(config)).toMatchInlineSnapshot(` + { + "mutationFn": [Function], + "mutationKey": [ + "writeContracts", + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/experimental/query/writeContracts.ts b/wagmi-project/packages/core/src/experimental/query/writeContracts.ts new file mode 100644 index 000000000..192a842ca --- /dev/null +++ b/wagmi-project/packages/core/src/experimental/query/writeContracts.ts @@ -0,0 +1,70 @@ +import type { MutateOptions, MutationOptions } from '@tanstack/query-core' + +import type { Config } from '../../createConfig.js' +import type { Compute } from '../../types/utils.js' +import { + type WriteContractsErrorType, + type WriteContractsParameters, + type WriteContractsReturnType, + writeContracts, +} from '../actions/writeContracts.js' + +export function writeContractsMutationOptions< + const contracts extends readonly unknown[], + config extends Config, +>(config: config) { + return { + mutationFn(variables) { + return writeContracts(config, variables as any) as any + }, + mutationKey: ['writeContracts'], + } as const satisfies MutationOptions< + WriteContractsData, + WriteContractsErrorType, + WriteContractsVariables + > +} + +export type WriteContractsData = Compute + +export type WriteContractsVariables< + contracts extends readonly unknown[], + config extends Config, + chainId extends config['chains'][number]['id'], +> = WriteContractsParameters + +export type WriteContractsMutate< + contracts extends readonly unknown[], + config extends Config, + context = unknown, +> = ( + variables: WriteContractsVariables, + options?: + | Compute< + MutateOptions< + WriteContractsData, + WriteContractsErrorType, + Compute>, + context + > + > + | undefined, +) => void + +export type WriteContractsMutateAsync< + contracts extends readonly unknown[], + config extends Config, + context = unknown, +> = ( + variables: WriteContractsVariables, + options?: + | Compute< + MutateOptions< + WriteContractsData, + WriteContractsErrorType, + Compute>, + context + > + > + | undefined, +) => Promise diff --git a/wagmi-project/packages/core/src/exports/actions.test.ts b/wagmi-project/packages/core/src/exports/actions.test.ts new file mode 100644 index 000000000..eaaedba14 --- /dev/null +++ b/wagmi-project/packages/core/src/exports/actions.test.ts @@ -0,0 +1,86 @@ +import { expect, test } from 'vitest' + +import * as actions from './actions.js' + +test('exports', () => { + expect(Object.keys(actions)).toMatchInlineSnapshot(` + [ + "call", + "connect", + "deployContract", + "disconnect", + "estimateGas", + "estimateFeesPerGas", + "estimateMaxPriorityFeePerGas", + "getAccount", + "getBalance", + "fetchBalance", + "getBlock", + "getBlockNumber", + "fetchBlockNumber", + "getBlockTransactionCount", + "getBytecode", + "getCallsStatus", + "getCapabilities", + "getChainId", + "getChains", + "getClient", + "getConnections", + "getConnectors", + "getConnectorClient", + "getEnsAddress", + "fetchEnsAddress", + "getEnsAvatar", + "fetchEnsAvatar", + "getEnsName", + "fetchEnsName", + "getEnsResolver", + "fetchEnsResolver", + "getEnsText", + "getFeeHistory", + "getGasPrice", + "getProof", + "getPublicClient", + "getStorageAt", + "getToken", + "fetchToken", + "getTransaction", + "fetchTransaction", + "getTransactionConfirmations", + "getTransactionCount", + "getTransactionReceipt", + "getWalletClient", + "multicall", + "prepareTransactionRequest", + "readContract", + "readContracts", + "reconnect", + "sendCalls", + "sendTransaction", + "showCallsStatus", + "signMessage", + "signTypedData", + "simulateContract", + "switchAccount", + "switchChain", + "switchNetwork", + "verifyMessage", + "verifyTypedData", + "waitForCallsStatus", + "watchAccount", + "watchAsset", + "watchBlocks", + "watchBlockNumber", + "watchChainId", + "watchClient", + "watchConnections", + "watchConnectors", + "watchContractEvent", + "watchPendingTransactions", + "watchPublicClient", + "waitForTransactionReceipt", + "waitForTransaction", + "writeContract", + ] + `) +}) diff --git a/wagmi-project/packages/core/src/exports/actions.ts b/wagmi-project/packages/core/src/exports/actions.ts new file mode 100644 index 000000000..d03c2adb7 --- /dev/null +++ b/wagmi-project/packages/core/src/exports/actions.ts @@ -0,0 +1,460 @@ +//////////////////////////////////////////////////////////////////////////////// +// Actions +//////////////////////////////////////////////////////////////////////////////// + +// biome-ignore lint/performance/noBarrelFile: entrypoint module +export { + type CallErrorType, + type CallParameters, + type CallReturnType, + call, +} from '../actions/call.js' + +export { + type ConnectErrorType, + type ConnectParameters, + type ConnectReturnType, + connect, +} from '../actions/connect.js' + +export { + type DeployContractErrorType, + type DeployContractParameters, + type DeployContractReturnType, + deployContract, +} from '../actions/deployContract.js' + +export { + type DisconnectErrorType, + type DisconnectParameters, + type DisconnectReturnType, + disconnect, +} from '../actions/disconnect.js' + +export { + type EstimateGasErrorType, + type EstimateGasParameters, + type EstimateGasReturnType, + estimateGas, +} from '../actions/estimateGas.js' + +export { + type EstimateFeesPerGasErrorType, + type EstimateFeesPerGasParameters, + type EstimateFeesPerGasReturnType, + estimateFeesPerGas, +} from '../actions/estimateFeesPerGas.js' + +export { + type EstimateMaxPriorityFeePerGasErrorType, + type EstimateMaxPriorityFeePerGasParameters, + type EstimateMaxPriorityFeePerGasReturnType, + estimateMaxPriorityFeePerGas, +} from '../actions/estimateMaxPriorityFeePerGas.js' + +export { + type GetAccountReturnType, + getAccount, +} from '../actions/getAccount.js' + +export { + type GetBalanceParameters, + type GetBalanceReturnType, + type GetBalanceErrorType, + getBalance, + /** @deprecated use `getBalance` instead */ + getBalance as fetchBalance, +} from '../actions/getBalance.js' + +export { + type GetBlockErrorType, + type GetBlockParameters, + type GetBlockReturnType, + getBlock, +} from '../actions/getBlock.js' + +export { + type GetBlockNumberErrorType, + type GetBlockNumberParameters, + type GetBlockNumberReturnType, + getBlockNumber, + /** @deprecated use `getBlockNumber` instead */ + getBlockNumber as fetchBlockNumber, +} from '../actions/getBlockNumber.js' + +export { + type GetBlockTransactionCountErrorType, + type GetBlockTransactionCountParameters, + type GetBlockTransactionCountReturnType, + getBlockTransactionCount, +} from '../actions/getBlockTransactionCount.js' + +export { + type GetBytecodeErrorType, + type GetBytecodeParameters, + type GetBytecodeReturnType, + getBytecode, +} from '../actions/getBytecode.js' + +export { + type GetCallsStatusErrorType, + type GetCallsStatusParameters, + type GetCallsStatusReturnType, + getCallsStatus, +} from '../actions/getCallsStatus.js' + +export { + type GetCapabilitiesErrorType, + type GetCapabilitiesParameters, + type GetCapabilitiesReturnType, + getCapabilities, +} from '../actions/getCapabilities.js' + +export { + type GetChainIdReturnType, + getChainId, +} from '../actions/getChainId.js' + +export { + type GetChainsReturnType, + getChains, +} from '../actions/getChains.js' + +export { + type GetClientParameters, + type GetClientReturnType, + getClient, +} from '../actions/getClient.js' + +export { + type GetConnectionsReturnType, + getConnections, +} from '../actions/getConnections.js' + +export { + type GetConnectorsReturnType, + getConnectors, +} from '../actions/getConnectors.js' + +export { + type GetConnectorClientErrorType, + type GetConnectorClientParameters, + type GetConnectorClientReturnType, + getConnectorClient, +} from '../actions/getConnectorClient.js' + +export { + type GetEnsAddressErrorType, + type GetEnsAddressParameters, + type GetEnsAddressReturnType, + getEnsAddress, + /** @deprecated use `getEnsAddress` instead */ + getEnsAddress as fetchEnsAddress, +} from '../actions/getEnsAddress.js' + +export { + type GetEnsAvatarErrorType, + type GetEnsAvatarParameters, + type GetEnsAvatarReturnType, + getEnsAvatar, + /** @deprecated use `getEnsAvatar` instead */ + getEnsAvatar as fetchEnsAvatar, +} from '../actions/getEnsAvatar.js' + +export { + type GetEnsNameErrorType, + type GetEnsNameParameters, + type GetEnsNameReturnType, + getEnsName, + /** @deprecated */ + getEnsName as fetchEnsName, +} from '../actions/getEnsName.js' + +export { + type GetEnsResolverErrorType, + type GetEnsResolverParameters, + type GetEnsResolverReturnType, + getEnsResolver, + /** @deprecated use `getEnsResolver` instead */ + getEnsResolver as fetchEnsResolver, +} from '../actions/getEnsResolver.js' + +export { + type GetEnsTextErrorType, + type GetEnsTextParameters, + type GetEnsTextReturnType, + getEnsText, +} from '../actions/getEnsText.js' + +export { + type GetFeeHistoryErrorType, + type GetFeeHistoryParameters, + type GetFeeHistoryReturnType, + getFeeHistory, +} from '../actions/getFeeHistory.js' + +export { + type GetGasPriceErrorType, + type GetGasPriceParameters, + type GetGasPriceReturnType, + getGasPrice, +} from '../actions/getGasPrice.js' + +export { + type GetProofErrorType, + type GetProofParameters, + type GetProofReturnType, + getProof, +} from '../actions/getProof.js' + +export { + type GetPublicClientParameters, + type GetPublicClientReturnType, + getPublicClient, +} from '../actions/getPublicClient.js' + +export { + type GetStorageAtErrorType, + type GetStorageAtParameters, + type GetStorageAtReturnType, + getStorageAt, +} from '../actions/getStorageAt.js' + +export { + type GetTokenErrorType, + type GetTokenParameters, + type GetTokenReturnType, + getToken, + /** @deprecated use `getToken` instead */ + getToken as fetchToken, +} from '../actions/getToken.js' + +export { + type GetTransactionErrorType, + type GetTransactionParameters, + type GetTransactionReturnType, + getTransaction, + /** @deprecated use `getTransaction` instead */ + getTransaction as fetchTransaction, +} from '../actions/getTransaction.js' + +export { + type GetTransactionConfirmationsErrorType, + type GetTransactionConfirmationsParameters, + type GetTransactionConfirmationsReturnType, + getTransactionConfirmations, +} from '../actions/getTransactionConfirmations.js' + +export { + type GetTransactionCountErrorType, + type GetTransactionCountParameters, + type GetTransactionCountReturnType, + getTransactionCount, +} from '../actions/getTransactionCount.js' + +export { + type GetTransactionReceiptErrorType, + type GetTransactionReceiptParameters, + type GetTransactionReceiptReturnType, + getTransactionReceipt, +} from '../actions/getTransactionReceipt.js' + +export { + type GetWalletClientErrorType, + type GetWalletClientParameters, + type GetWalletClientReturnType, + getWalletClient, +} from '../actions/getWalletClient.js' + +export { + type MulticallParameters, + type MulticallReturnType, + multicall, +} from '../actions/multicall.js' + +export { + type PrepareTransactionRequestParameters, + type PrepareTransactionRequestReturnType, + type PrepareTransactionRequestErrorType, + prepareTransactionRequest, +} from '../actions/prepareTransactionRequest.js' + +export { + type ReadContractParameters, + type ReadContractReturnType, + type ReadContractErrorType, + readContract, +} from '../actions/readContract.js' + +export { + type ReadContractsParameters, + type ReadContractsReturnType, + type ReadContractsErrorType, + readContracts, +} from '../actions/readContracts.js' + +export { + type ReconnectErrorType, + type ReconnectParameters, + type ReconnectReturnType, + reconnect, +} from '../actions/reconnect.js' + +export { + type SendCallsErrorType, + type SendCallsParameters, + type SendCallsReturnType, + sendCalls, +} from '../actions/sendCalls.js' + +export { + type SendTransactionErrorType, + type SendTransactionParameters, + type SendTransactionReturnType, + sendTransaction, +} from '../actions/sendTransaction.js' + +export { + type ShowCallsStatusErrorType, + type ShowCallsStatusParameters, + type ShowCallsStatusReturnType, + showCallsStatus, +} from '../actions/showCallsStatus.js' + +export { + type SignMessageErrorType, + type SignMessageParameters, + type SignMessageReturnType, + signMessage, +} from '../actions/signMessage.js' + +export { + type SignTypedDataErrorType, + type SignTypedDataParameters, + type SignTypedDataReturnType, + signTypedData, +} from '../actions/signTypedData.js' + +export { + type SimulateContractErrorType, + type SimulateContractParameters, + type SimulateContractReturnType, + simulateContract, +} from '../actions/simulateContract.js' + +export { + type SwitchAccountErrorType, + type SwitchAccountParameters, + type SwitchAccountReturnType, + switchAccount, +} from '../actions/switchAccount.js' + +export { + type SwitchChainErrorType, + type SwitchChainParameters, + type SwitchChainReturnType, + switchChain, + /** @deprecated use `switchChain` instead */ + switchChain as switchNetwork, +} from '../actions/switchChain.js' + +export { + type VerifyMessageParameters, + type VerifyMessageReturnType, + verifyMessage, +} from '../actions/verifyMessage.js' + +export { + type VerifyTypedDataParameters, + type VerifyTypedDataReturnType, + verifyTypedData, +} from '../actions/verifyTypedData.js' + +export { + type WaitForCallsStatusErrorType, + type WaitForCallsStatusParameters, + type WaitForCallsStatusReturnType, + waitForCallsStatus, +} from '../actions/waitForCallsStatus.js' + +export { + type WatchAccountParameters, + type WatchAccountReturnType, + watchAccount, +} from '../actions/watchAccount.js' + +export { + type WatchAssetParameters, + type WatchAssetReturnType, + watchAsset, +} from '../actions/watchAsset.js' + +export { + type WatchBlocksParameters, + type WatchBlocksReturnType, + watchBlocks, +} from '../actions/watchBlocks.js' + +export { + type WatchBlockNumberParameters, + type WatchBlockNumberReturnType, + watchBlockNumber, +} from '../actions/watchBlockNumber.js' + +export { + type WatchChainIdParameters, + type WatchChainIdReturnType, + watchChainId, +} from '../actions/watchChainId.js' + +export { + type WatchClientParameters, + type WatchClientReturnType, + watchClient, +} from '../actions/watchClient.js' + +export { + type WatchConnectionsParameters, + type WatchConnectionsReturnType, + watchConnections, +} from '../actions/watchConnections.js' + +export { + type WatchConnectorsParameters, + type WatchConnectorsReturnType, + watchConnectors, +} from '../actions/watchConnectors.js' + +export { + type WatchContractEventParameters, + type WatchContractEventReturnType, + watchContractEvent, +} from '../actions/watchContractEvent.js' + +export { + type WatchPendingTransactionsParameters, + type WatchPendingTransactionsReturnType, + watchPendingTransactions, +} from '../actions/watchPendingTransactions.js' + +export { + type WatchPublicClientParameters, + type WatchPublicClientReturnType, + watchPublicClient, +} from '../actions/watchPublicClient.js' + +export { + type WaitForTransactionReceiptErrorType, + type WaitForTransactionReceiptParameters, + type WaitForTransactionReceiptReturnType, + waitForTransactionReceipt, + /** @deprecated use `waitForTransactionReceipt` instead */ + waitForTransactionReceipt as waitForTransaction, +} from '../actions/waitForTransactionReceipt.js' + +export { + type WriteContractErrorType, + type WriteContractParameters, + type WriteContractReturnType, + writeContract, +} from '../actions/writeContract.js' diff --git a/wagmi-project/packages/core/src/exports/chains.ts b/wagmi-project/packages/core/src/exports/chains.ts new file mode 100644 index 000000000..1fca7f537 --- /dev/null +++ b/wagmi-project/packages/core/src/exports/chains.ts @@ -0,0 +1,7 @@ +//////////////////////////////////////////////////////////////////////////////// +// viem/chains +//////////////////////////////////////////////////////////////////////////////// + +// biome-ignore lint/performance/noBarrelFile: entrypoint module +// biome-ignore lint/performance/noReExportAll: entrypoint module +export * from 'viem/chains' diff --git a/wagmi-project/packages/core/src/exports/codegen.test.ts b/wagmi-project/packages/core/src/exports/codegen.test.ts new file mode 100644 index 000000000..c947b7d18 --- /dev/null +++ b/wagmi-project/packages/core/src/exports/codegen.test.ts @@ -0,0 +1,14 @@ +import { expect, test } from 'vitest' + +import * as codegen from './codegen.js' + +test('exports', () => { + expect(Object.keys(codegen)).toMatchInlineSnapshot(` + [ + "createSimulateContract", + "createReadContract", + "createWatchContractEvent", + "createWriteContract", + ] + `) +}) diff --git a/wagmi-project/packages/core/src/exports/codegen.ts b/wagmi-project/packages/core/src/exports/codegen.ts new file mode 100644 index 000000000..bed8aa1cc --- /dev/null +++ b/wagmi-project/packages/core/src/exports/codegen.ts @@ -0,0 +1,24 @@ +// biome-ignore lint/performance/noBarrelFile: entrypoint module +export { + type CreateSimulateContractParameters, + type CreateSimulateContractReturnType, + createSimulateContract, +} from '../actions/codegen/createSimulateContract.js' + +export { + type CreateReadContractParameters, + type CreateReadContractReturnType, + createReadContract, +} from '../actions/codegen/createReadContract.js' + +export { + type CreateWatchContractEventParameters, + type CreateWatchContractEventReturnType, + createWatchContractEvent, +} from '../actions/codegen/createWatchContractEvent.js' + +export { + type CreateWriteContractParameters, + type CreateWriteContractReturnType, + createWriteContract, +} from '../actions/codegen/createWriteContract.js' diff --git a/wagmi-project/packages/core/src/exports/experimental.ts b/wagmi-project/packages/core/src/exports/experimental.ts new file mode 100644 index 000000000..f74baa82c --- /dev/null +++ b/wagmi-project/packages/core/src/exports/experimental.ts @@ -0,0 +1,158 @@ +//////////////////////////////////////////////////////////////////////////////// +// Actions +//////////////////////////////////////////////////////////////////////////////// + +// biome-ignore lint/performance/noBarrelFile: entrypoint module +export { + /** @deprecated This is no longer experimental – use `import type { GetCallsStatusErrorType } from '@wagmi/core'` instead. */ + type GetCallsStatusErrorType, + /** @deprecated This is no longer experimental – use `import type { GetCallsStatusParameters } from '@wagmi/core'` instead. */ + type GetCallsStatusParameters, + /** @deprecated This is no longer experimental – use `import type { GetCallsStatusReturnType } from '@wagmi/core'` instead. */ + type GetCallsStatusReturnType, + /** @deprecated This is no longer experimental – use `import { getCallsStatus } from '@wagmi/core'` instead. */ + getCallsStatus, +} from '../actions/getCallsStatus.js' + +export { + /** @deprecated This is no longer experimental – use `import type { GetCapabilitiesErrorType } from '@wagmi/core'` instead. */ + type GetCapabilitiesErrorType, + /** @deprecated This is no longer experimental – use `import type { GetCapabilitiesParameters } from '@wagmi/core'` instead. */ + type GetCapabilitiesParameters, + /** @deprecated This is no longer experimental – use `import type { GetCapabilitiesReturnType } from '@wagmi/core'` instead. */ + type GetCapabilitiesReturnType, + /** @deprecated This is no longer experimental – use `import { getCapabilities } from '@wagmi/core'` instead. */ + getCapabilities, +} from '../actions/getCapabilities.js' + +export { + /** @deprecated This is no longer experimental – use `import type { SendCallsErrorType } from '@wagmi/core'` instead. */ + type SendCallsErrorType, + /** @deprecated This is no longer experimental – use `import type { SendCallsParameters } from '@wagmi/core'` instead. */ + type SendCallsParameters, + /** @deprecated This is no longer experimental – use `import type { SendCallsReturnType } from '@wagmi/core'` instead. */ + type SendCallsReturnType, + /** @deprecated This is no longer experimental – use `import { sendCalls } from '@wagmi/core'` instead. */ + sendCalls, +} from '../actions/sendCalls.js' + +export { + /** @deprecated This is no longer experimental – use `import type { ShowCallsStatusErrorType } from '@wagmi/core'` instead. */ + type ShowCallsStatusErrorType, + /** @deprecated This is no longer experimental – use `import type { ShowCallsStatusParameters } from '@wagmi/core'` instead. */ + type ShowCallsStatusParameters, + /** @deprecated This is no longer experimental – use `import type { ShowCallsStatusReturnType } from '@wagmi/core'` instead. */ + type ShowCallsStatusReturnType, + /** @deprecated This is no longer experimental – use `import { showCallsStatus } from '@wagmi/core'` instead. */ + showCallsStatus, +} from '../actions/showCallsStatus.js' + +export { + /** @deprecated This is no longer experimental – use `import type { WaitForCallsStatusErrorType } from '@wagmi/core'` instead. */ + type WaitForCallsStatusErrorType, + /** @deprecated This is no longer experimental – use `import type { WaitForCallsStatusParameters } from '@wagmi/core'` instead. */ + type WaitForCallsStatusParameters, + /** @deprecated This is no longer experimental – use `import type { WaitForCallsStatusReturnType } from '@wagmi/core'` instead. */ + type WaitForCallsStatusReturnType, + /** @deprecated This is no longer experimental – use `import { waitForCallsStatus } from '@wagmi/core'` instead. */ + waitForCallsStatus, +} from '../actions/waitForCallsStatus.js' + +export { + /** @deprecated Use `SendCallsErrorType` instead. */ + type WriteContractsErrorType, + /** @deprecated Use `SendCallsParameters` instead. */ + type WriteContractsParameters, + /** @deprecated Use `SendCallsReturnType` instead. */ + type WriteContractsReturnType, + /** @deprecated Use `sendCalls` instead. */ + writeContracts, +} from '../experimental/actions/writeContracts.js' + +//////////////////////////////////////////////////////////////////////////////// +// Tanstack Query +//////////////////////////////////////////////////////////////////////////////// + +export { + /** @deprecated This is no longer experimental – use `import type { GetCallsStatusData } from '@wagmi/core/query'` instead. */ + type GetCallsStatusData, + /** @deprecated This is no longer experimental – use `import type { GetCallsStatusOptions } from '@wagmi/core/query'` instead. */ + type GetCallsStatusOptions, + /** @deprecated This is no longer experimental – use `import type { GetCallsStatusQueryFnData } from '@wagmi/core/query'` instead. */ + type GetCallsStatusQueryFnData, + /** @deprecated This is no longer experimental – use `import type { GetCallsStatusQueryKey } from '@wagmi/core/query'` instead. */ + type GetCallsStatusQueryKey, + /** @deprecated This is no longer experimental – use `import { getCallsStatusQueryOptions } from '@wagmi/core/query'` instead. */ + getCallsStatusQueryOptions, + /** @deprecated This is no longer experimental – use `import { getCallsStatusQueryKey } from '@wagmi/core/query'` instead. */ + getCallsStatusQueryKey, +} from '../query/getCallsStatus.js' + +export { + /** @deprecated This is no longer experimental – use `import type { GetCapabilitiesData } from '@wagmi/core/query'` instead. */ + type GetCapabilitiesData, + /** @deprecated This is no longer experimental – use `import type { GetCapabilitiesOptions } from '@wagmi/core/query'` instead. */ + type GetCapabilitiesOptions, + /** @deprecated This is no longer experimental – use `import type { GetCapabilitiesQueryFnData } from '@wagmi/core/query'` instead. */ + type GetCapabilitiesQueryFnData, + /** @deprecated This is no longer experimental – use `import type { GetCapabilitiesQueryKey } from '@wagmi/core/query'` instead. */ + type GetCapabilitiesQueryKey, + /** @deprecated This is no longer experimental – use `import { getCapabilitiesQueryOptions } from '@wagmi/core/query'` instead. */ + getCapabilitiesQueryOptions, + /** @deprecated This is no longer experimental – use `import { getCapabilitiesQueryKey } from '@wagmi/core/query'` instead. */ + getCapabilitiesQueryKey, +} from '../query/getCapabilities.js' + +export { + /** @deprecated This is no longer experimental – use `import type { SendCallsData } from '@wagmi/core/query'` instead. */ + type SendCallsData, + /** @deprecated This is no longer experimental – use `import type { SendCallsMutate } from '@wagmi/core/query'` instead. */ + type SendCallsMutate, + /** @deprecated This is no longer experimental – use `import type { SendCallsMutateAsync } from '@wagmi/core/query'` instead. */ + type SendCallsMutateAsync, + /** @deprecated This is no longer experimental – use `import type { SendCallsVariables } from '@wagmi/core/query'` instead. */ + type SendCallsVariables, + /** @deprecated This is no longer experimental – use `import { sendCallsMutationOptions } from '@wagmi/core/query'` instead. */ + sendCallsMutationOptions, +} from '../query/sendCalls.js' + +export { + /** @deprecated This is no longer experimental – use `import type { ShowCallsStatusData } from '@wagmi/core/query'` instead. */ + type ShowCallsStatusData, + /** @deprecated This is no longer experimental – use `import type { ShowCallsStatusMutate } from '@wagmi/core/query'` instead. */ + type ShowCallsStatusMutate, + /** @deprecated This is no longer experimental – use `import type { ShowCallsStatusMutateAsync } from '@wagmi/core/query'` instead. */ + type ShowCallsStatusMutateAsync, + /** @deprecated This is no longer experimental – use `import type { ShowCallsStatusVariables } from '@wagmi/core/query'` instead. */ + type ShowCallsStatusVariables, + /** @deprecated This is no longer experimental – use `import { showCallsStatusMutationOptions } from '@wagmi/core/query'` instead. */ + showCallsStatusMutationOptions, +} from '../query/showCallsStatus.js' + +export { + /** @deprecated This is no longer experimental – use `import type { WaitForCallsStatusData } from '@wagmi/core/query'` instead. */ + type WaitForCallsStatusData, + /** @deprecated This is no longer experimental – use `import type { WaitForCallsStatusOptions } from '@wagmi/core/query'` instead. */ + type WaitForCallsStatusOptions, + /** @deprecated This is no longer experimental – use `import type { WaitForCallsStatusQueryFnData } from '@wagmi/core/query'` instead. */ + type WaitForCallsStatusQueryFnData, + /** @deprecated This is no longer experimental – use `import type { WaitForCallsStatusQueryKey } from '@wagmi/core/query'` instead. */ + type WaitForCallsStatusQueryKey, + /** @deprecated This is no longer experimental – use `import { waitForCallsStatusQueryKey } from '@wagmi/core/query'` instead. */ + waitForCallsStatusQueryKey, + /** @deprecated This is no longer experimental – use `import { waitForCallsStatusQueryOptions } from '@wagmi/core/query'` instead. */ + waitForCallsStatusQueryOptions, +} from '../query/waitForCallsStatus.js' + +export { + /** @deprecated Use `SendCallsData` instead. */ + type WriteContractsData, + /** @deprecated Use `SendCallsMutate` instead. */ + type WriteContractsMutate, + /** @deprecated Use `SendCallsMutateAsync` instead. */ + type WriteContractsMutateAsync, + /** @deprecated Use `SendCallsVariables` instead. */ + type WriteContractsVariables, + /** @deprecated Use `sendCallsMutationOptions` instead. */ + writeContractsMutationOptions, +} from '../experimental/query/writeContracts.js' diff --git a/wagmi-project/packages/core/src/exports/index.test.ts b/wagmi-project/packages/core/src/exports/index.test.ts new file mode 100644 index 000000000..55f388580 --- /dev/null +++ b/wagmi-project/packages/core/src/exports/index.test.ts @@ -0,0 +1,117 @@ +import { expect, test } from 'vitest' + +import * as core from './index.js' + +test('exports', () => { + expect(Object.keys(core)).toMatchInlineSnapshot(` + [ + "call", + "connect", + "deployContract", + "disconnect", + "estimateGas", + "estimateFeesPerGas", + "estimateMaxPriorityFeePerGas", + "getAccount", + "getBalance", + "fetchBalance", + "getBlock", + "getBlockNumber", + "fetchBlockNumber", + "getBlockTransactionCount", + "getBytecode", + "getCallsStatus", + "getCapabilities", + "getChainId", + "getChains", + "getClient", + "getConnections", + "getConnectors", + "getConnectorClient", + "getEnsAddress", + "fetchEnsAddress", + "getEnsAvatar", + "fetchEnsAvatar", + "getEnsName", + "fetchEnsName", + "getEnsResolver", + "fetchEnsResolver", + "getEnsText", + "getFeeHistory", + "getGasPrice", + "getProof", + "getPublicClient", + "getStorageAt", + "getToken", + "fetchToken", + "getTransaction", + "fetchTransaction", + "getTransactionConfirmations", + "getTransactionCount", + "getTransactionReceipt", + "getWalletClient", + "multicall", + "prepareTransactionRequest", + "readContract", + "readContracts", + "reconnect", + "sendCalls", + "sendTransaction", + "showCallsStatus", + "signMessage", + "signTypedData", + "simulateContract", + "switchAccount", + "switchChain", + "switchNetwork", + "verifyMessage", + "verifyTypedData", + "waitForCallsStatus", + "watchAccount", + "watchAsset", + "watchBlocks", + "watchBlockNumber", + "watchChainId", + "watchClient", + "watchConnections", + "watchConnectors", + "watchContractEvent", + "watchPendingTransactions", + "watchPublicClient", + "waitForTransactionReceipt", + "waitForTransaction", + "writeContract", + "createConnector", + "injected", + "mock", + "createConfig", + "createStorage", + "noopStorage", + "hydrate", + "BaseError", + "ChainNotConfiguredError", + "ConnectorNotConnectedError", + "ConnectorAlreadyConnectedError", + "ConnectorNotFoundError", + "ConnectorAccountNotFoundError", + "ConnectorChainMismatchError", + "ConnectorUnavailableReconnectingError", + "ProviderNotFoundError", + "SwitchChainNotSupportedError", + "custom", + "http", + "webSocket", + "unstable_connector", + "fallback", + "cookieStorage", + "cookieToInitialState", + "parseCookie", + "deepEqual", + "deserialize", + "extractRpcUrls", + "normalizeChainId", + "serialize", + "version", + ] + `) +}) diff --git a/wagmi-project/packages/core/src/exports/index.ts b/wagmi-project/packages/core/src/exports/index.ts new file mode 100644 index 000000000..1e0e210ea --- /dev/null +++ b/wagmi-project/packages/core/src/exports/index.ts @@ -0,0 +1,594 @@ +//////////////////////////////////////////////////////////////////////////////// +// Actions +//////////////////////////////////////////////////////////////////////////////// + +// biome-ignore lint/performance/noBarrelFile: entrypoint module +export { + type CallErrorType, + type CallParameters, + type CallReturnType, + call, +} from '../actions/call.js' + +export { + type ConnectErrorType, + type ConnectParameters, + type ConnectReturnType, + connect, +} from '../actions/connect.js' + +export { + type DeployContractErrorType, + type DeployContractParameters, + type DeployContractReturnType, + deployContract, +} from '../actions/deployContract.js' + +export { + type DisconnectErrorType, + type DisconnectParameters, + type DisconnectReturnType, + disconnect, +} from '../actions/disconnect.js' + +export { + type EstimateGasErrorType, + type EstimateGasParameters, + type EstimateGasReturnType, + estimateGas, +} from '../actions/estimateGas.js' + +export { + type EstimateFeesPerGasErrorType, + type EstimateFeesPerGasParameters, + type EstimateFeesPerGasReturnType, + estimateFeesPerGas, +} from '../actions/estimateFeesPerGas.js' + +export { + type EstimateMaxPriorityFeePerGasErrorType, + type EstimateMaxPriorityFeePerGasParameters, + type EstimateMaxPriorityFeePerGasReturnType, + estimateMaxPriorityFeePerGas, +} from '../actions/estimateMaxPriorityFeePerGas.js' + +export { + type GetAccountReturnType, + getAccount, +} from '../actions/getAccount.js' + +export { + type GetBalanceParameters, + type GetBalanceReturnType, + type GetBalanceErrorType, + getBalance, + /** @deprecated use `getBalance` instead */ + getBalance as fetchBalance, +} from '../actions/getBalance.js' + +export { + type GetBlockErrorType, + type GetBlockParameters, + type GetBlockReturnType, + getBlock, +} from '../actions/getBlock.js' + +export { + type GetBlockNumberErrorType, + type GetBlockNumberParameters, + type GetBlockNumberReturnType, + getBlockNumber, + /** @deprecated use `getBlockNumber` instead */ + getBlockNumber as fetchBlockNumber, +} from '../actions/getBlockNumber.js' + +export { + type GetBlockTransactionCountErrorType, + type GetBlockTransactionCountParameters, + type GetBlockTransactionCountReturnType, + getBlockTransactionCount, +} from '../actions/getBlockTransactionCount.js' + +export { + type GetBytecodeErrorType, + type GetBytecodeParameters, + type GetBytecodeReturnType, + getBytecode, +} from '../actions/getBytecode.js' + +export { + type GetCallsStatusErrorType, + type GetCallsStatusParameters, + type GetCallsStatusReturnType, + getCallsStatus, +} from '../actions/getCallsStatus.js' + +export { + type GetCapabilitiesErrorType, + type GetCapabilitiesParameters, + type GetCapabilitiesReturnType, + getCapabilities, +} from '../actions/getCapabilities.js' + +export { + type GetChainIdReturnType, + getChainId, +} from '../actions/getChainId.js' + +export { + type GetChainsReturnType, + getChains, +} from '../actions/getChains.js' + +export { + type GetClientParameters, + type GetClientReturnType, + getClient, +} from '../actions/getClient.js' + +export { + type GetConnectionsReturnType, + getConnections, +} from '../actions/getConnections.js' + +export { + type GetConnectorsReturnType, + getConnectors, +} from '../actions/getConnectors.js' + +export { + type GetConnectorClientErrorType, + type GetConnectorClientParameters, + type GetConnectorClientReturnType, + getConnectorClient, +} from '../actions/getConnectorClient.js' + +export { + type GetEnsAddressErrorType, + type GetEnsAddressParameters, + type GetEnsAddressReturnType, + getEnsAddress, + /** @deprecated use `getEnsAddress` instead */ + getEnsAddress as fetchEnsAddress, +} from '../actions/getEnsAddress.js' + +export { + type GetEnsAvatarErrorType, + type GetEnsAvatarParameters, + type GetEnsAvatarReturnType, + getEnsAvatar, + /** @deprecated use `getEnsAvatar` instead */ + getEnsAvatar as fetchEnsAvatar, +} from '../actions/getEnsAvatar.js' + +export { + type GetEnsNameErrorType, + type GetEnsNameParameters, + type GetEnsNameReturnType, + getEnsName, + /** @deprecated */ + getEnsName as fetchEnsName, +} from '../actions/getEnsName.js' + +export { + type GetEnsResolverErrorType, + type GetEnsResolverParameters, + type GetEnsResolverReturnType, + getEnsResolver, + /** @deprecated use `getEnsResolver` instead */ + getEnsResolver as fetchEnsResolver, +} from '../actions/getEnsResolver.js' + +export { + type GetEnsTextErrorType, + type GetEnsTextParameters, + type GetEnsTextReturnType, + getEnsText, +} from '../actions/getEnsText.js' + +export { + type GetFeeHistoryErrorType, + type GetFeeHistoryParameters, + type GetFeeHistoryReturnType, + getFeeHistory, +} from '../actions/getFeeHistory.js' + +export { + type GetGasPriceErrorType, + type GetGasPriceParameters, + type GetGasPriceReturnType, + getGasPrice, +} from '../actions/getGasPrice.js' + +export { + type GetProofErrorType, + type GetProofParameters, + type GetProofReturnType, + getProof, +} from '../actions/getProof.js' + +export { + type GetPublicClientParameters, + type GetPublicClientReturnType, + getPublicClient, +} from '../actions/getPublicClient.js' + +export { + type GetStorageAtErrorType, + type GetStorageAtParameters, + type GetStorageAtReturnType, + getStorageAt, +} from '../actions/getStorageAt.js' + +export { + type GetTokenErrorType, + type GetTokenParameters, + type GetTokenReturnType, + getToken, + /** @deprecated use `getToken` instead */ + getToken as fetchToken, +} from '../actions/getToken.js' + +export { + type GetTransactionErrorType, + type GetTransactionParameters, + type GetTransactionReturnType, + getTransaction, + /** @deprecated use `getTransaction` instead */ + getTransaction as fetchTransaction, +} from '../actions/getTransaction.js' + +export { + type GetTransactionConfirmationsErrorType, + type GetTransactionConfirmationsParameters, + type GetTransactionConfirmationsReturnType, + getTransactionConfirmations, +} from '../actions/getTransactionConfirmations.js' + +export { + type GetTransactionCountErrorType, + type GetTransactionCountParameters, + type GetTransactionCountReturnType, + getTransactionCount, +} from '../actions/getTransactionCount.js' + +export { + type GetTransactionReceiptErrorType, + type GetTransactionReceiptParameters, + type GetTransactionReceiptReturnType, + getTransactionReceipt, +} from '../actions/getTransactionReceipt.js' + +export { + type GetWalletClientErrorType, + type GetWalletClientParameters, + type GetWalletClientReturnType, + getWalletClient, +} from '../actions/getWalletClient.js' + +export { + type MulticallParameters, + type MulticallReturnType, + multicall, +} from '../actions/multicall.js' + +export { + type PrepareTransactionRequestErrorType, + type PrepareTransactionRequestParameters, + type PrepareTransactionRequestReturnType, + prepareTransactionRequest, +} from '../actions/prepareTransactionRequest.js' + +export { + type ReadContractParameters, + type ReadContractReturnType, + type ReadContractErrorType, + readContract, +} from '../actions/readContract.js' + +export { + type ReadContractsParameters, + type ReadContractsReturnType, + type ReadContractsErrorType, + readContracts, +} from '../actions/readContracts.js' + +export { + type ReconnectErrorType, + type ReconnectParameters, + type ReconnectReturnType, + reconnect, +} from '../actions/reconnect.js' + +export { + type SendCallsErrorType, + type SendCallsParameters, + type SendCallsReturnType, + sendCalls, +} from '../actions/sendCalls.js' + +export { + type SendTransactionErrorType, + type SendTransactionParameters, + type SendTransactionReturnType, + sendTransaction, +} from '../actions/sendTransaction.js' + +export { + type ShowCallsStatusErrorType, + type ShowCallsStatusParameters, + type ShowCallsStatusReturnType, + showCallsStatus, +} from '../actions/showCallsStatus.js' + +export { + type SignMessageErrorType, + type SignMessageParameters, + type SignMessageReturnType, + signMessage, +} from '../actions/signMessage.js' + +export { + type SignTypedDataErrorType, + type SignTypedDataParameters, + type SignTypedDataReturnType, + signTypedData, +} from '../actions/signTypedData.js' + +export { + type SimulateContractErrorType, + type SimulateContractParameters, + type SimulateContractReturnType, + simulateContract, +} from '../actions/simulateContract.js' + +export { + type SwitchAccountErrorType, + type SwitchAccountParameters, + type SwitchAccountReturnType, + switchAccount, +} from '../actions/switchAccount.js' + +export { + type SwitchChainErrorType, + type SwitchChainParameters, + type SwitchChainReturnType, + switchChain, + /** @deprecated use `switchChain` instead */ + switchChain as switchNetwork, +} from '../actions/switchChain.js' + +export { + type VerifyMessageErrorType, + type VerifyMessageParameters, + type VerifyMessageReturnType, + verifyMessage, +} from '../actions/verifyMessage.js' + +export { + type VerifyTypedDataErrorType, + type VerifyTypedDataParameters, + type VerifyTypedDataReturnType, + verifyTypedData, +} from '../actions/verifyTypedData.js' + +export { + type WaitForCallsStatusErrorType, + type WaitForCallsStatusParameters, + type WaitForCallsStatusReturnType, + waitForCallsStatus, +} from '../actions/waitForCallsStatus.js' + +export { + type WatchAccountParameters, + type WatchAccountReturnType, + watchAccount, +} from '../actions/watchAccount.js' + +export { + type WatchAssetParameters, + type WatchAssetErrorType, + type WatchAssetReturnType, + watchAsset, +} from '../actions/watchAsset.js' + +export { + type WatchBlocksParameters, + type WatchBlocksReturnType, + watchBlocks, +} from '../actions/watchBlocks.js' + +export { + type WatchBlockNumberParameters, + type WatchBlockNumberReturnType, + watchBlockNumber, +} from '../actions/watchBlockNumber.js' + +export { + type WatchChainIdParameters, + type WatchChainIdReturnType, + watchChainId, +} from '../actions/watchChainId.js' + +export { + type WatchClientParameters, + type WatchClientReturnType, + watchClient, +} from '../actions/watchClient.js' + +export { + type WatchConnectionsParameters, + type WatchConnectionsReturnType, + watchConnections, +} from '../actions/watchConnections.js' + +export { + type WatchConnectorsParameters, + type WatchConnectorsReturnType, + watchConnectors, +} from '../actions/watchConnectors.js' + +export { + type WatchContractEventParameters, + type WatchContractEventReturnType, + watchContractEvent, +} from '../actions/watchContractEvent.js' + +export { + type WatchPendingTransactionsParameters, + type WatchPendingTransactionsReturnType, + watchPendingTransactions, +} from '../actions/watchPendingTransactions.js' + +export { + type WatchPublicClientParameters, + type WatchPublicClientReturnType, + watchPublicClient, +} from '../actions/watchPublicClient.js' + +export { + type WaitForTransactionReceiptErrorType, + type WaitForTransactionReceiptParameters, + type WaitForTransactionReceiptReturnType, + waitForTransactionReceipt, + /** @deprecated use `waitForTransactionReceipt` instead */ + waitForTransactionReceipt as waitForTransaction, +} from '../actions/waitForTransactionReceipt.js' + +export { + type WriteContractErrorType, + type WriteContractParameters, + type WriteContractReturnType, + writeContract, +} from '../actions/writeContract.js' + +//////////////////////////////////////////////////////////////////////////////// +// Connectors +//////////////////////////////////////////////////////////////////////////////// + +export { + type ConnectorEventMap, + type CreateConnectorFn, + createConnector, +} from '../connectors/createConnector.js' + +export { + type InjectedParameters, + injected, +} from '../connectors/injected.js' + +export { + type MockParameters, + mock, +} from '../connectors/mock.js' + +//////////////////////////////////////////////////////////////////////////////// +// createConfig +//////////////////////////////////////////////////////////////////////////////// + +export { + type Connection, + type Connector, + type Config, + type CreateConfigParameters, + type PartializedState, + type State, + type Transport, + createConfig, +} from '../createConfig.js' + +//////////////////////////////////////////////////////////////////////////////// +// createStorage +//////////////////////////////////////////////////////////////////////////////// + +export { + type CreateStorageParameters, + type Storage, + type StorageItemMap, + createStorage, + noopStorage, +} from '../createStorage.js' + +//////////////////////////////////////////////////////////////////////////////// +// Hydrate +//////////////////////////////////////////////////////////////////////////////// + +export { hydrate } from '../hydrate.js' + +//////////////////////////////////////////////////////////////////////////////// +// Errors +//////////////////////////////////////////////////////////////////////////////// + +export { BaseError } from '../errors/base.js' + +export { + type ChainNotConfiguredErrorType, + ChainNotConfiguredError, + type ConnectorNotConnectedErrorType, + ConnectorNotConnectedError, + type ConnectorAlreadyConnectedErrorType, + ConnectorAlreadyConnectedError, + type ConnectorNotFoundErrorType, + ConnectorNotFoundError, + type ConnectorAccountNotFoundErrorType, + ConnectorAccountNotFoundError, + type ConnectorChainMismatchErrorType, + ConnectorChainMismatchError, + type ConnectorUnavailableReconnectingErrorType, + ConnectorUnavailableReconnectingError, +} from '../errors/config.js' + +export { + type ProviderNotFoundErrorType, + ProviderNotFoundError, + type SwitchChainNotSupportedErrorType, + SwitchChainNotSupportedError, +} from '../errors/connector.js' + +//////////////////////////////////////////////////////////////////////////////// +// Transports +//////////////////////////////////////////////////////////////////////////////// + +export { custom, http, webSocket } from 'viem' + +export { + type ConnectorTransportConfig, + type ConnectorTransport, + unstable_connector, +} from '../transports/connector.js' + +export { fallback } from '../transports/fallback.js' + +//////////////////////////////////////////////////////////////////////////////// +// Types +//////////////////////////////////////////////////////////////////////////////// + +export type { SelectChains } from '../types/chain.js' + +export type { Register, ResolvedRegister } from '../types/register.js' + +//////////////////////////////////////////////////////////////////////////////// +// Utilities +//////////////////////////////////////////////////////////////////////////////// + +export { + cookieStorage, + cookieToInitialState, + parseCookie, +} from '../utils/cookie.js' + +export { deepEqual } from '../utils/deepEqual.js' + +export { deserialize } from '../utils/deserialize.js' + +export { extractRpcUrls } from '../utils/extractRpcUrls.js' + +export { normalizeChainId } from '../utils/normalizeChainId.js' + +export { serialize } from '../utils/serialize.js' + +//////////////////////////////////////////////////////////////////////////////// +// Version +//////////////////////////////////////////////////////////////////////////////// + +export { version } from '../version.js' diff --git a/wagmi-project/packages/core/src/exports/internal.test.ts b/wagmi-project/packages/core/src/exports/internal.test.ts new file mode 100644 index 000000000..425a1b4eb --- /dev/null +++ b/wagmi-project/packages/core/src/exports/internal.test.ts @@ -0,0 +1,15 @@ +import { expect, test } from 'vitest' + +import * as internal from './internal.js' + +test('exports', () => { + expect(Object.keys(internal)).toMatchInlineSnapshot(` + [ + "watchChains", + "Emitter", + "createEmitter", + "deepEqual", + "uid", + ] + `) +}) diff --git a/wagmi-project/packages/core/src/exports/internal.ts b/wagmi-project/packages/core/src/exports/internal.ts new file mode 100644 index 000000000..670420d89 --- /dev/null +++ b/wagmi-project/packages/core/src/exports/internal.ts @@ -0,0 +1,52 @@ +//////////////////////////////////////////////////////////////////////////////// +// Actions +//////////////////////////////////////////////////////////////////////////////// + +// biome-ignore lint/performance/noBarrelFile: entrypoint module +export { + type WatchChainsParameters, + type WatchChainsReturnType, + watchChains, +} from '../actions/watchChains.js' + +//////////////////////////////////////////////////////////////////////////////// +// Emitter +//////////////////////////////////////////////////////////////////////////////// + +export { + type EventData, + Emitter, + createEmitter, +} from '../createEmitter.js' + +//////////////////////////////////////////////////////////////////////////////// +// Types +//////////////////////////////////////////////////////////////////////////////// + +export type { SelectChains } from '../types/chain.js' + +export type { + ChainIdParameter, + ConnectorParameter, + ScopeKeyParameter, +} from '../types/properties.js' + +export type { + Compute, + ExactPartial, + Mutable, + StrictOmit as Omit, + OneOf, + RemoveUndefined, + UnionCompute, + UnionStrictOmit, + UnionExactPartial, +} from '../types/utils.js' + +//////////////////////////////////////////////////////////////////////////////// +// Utilities +//////////////////////////////////////////////////////////////////////////////// + +export { deepEqual } from '../utils/deepEqual.js' + +export { uid } from '../utils/uid.js' diff --git a/wagmi-project/packages/core/src/exports/query.test.ts b/wagmi-project/packages/core/src/exports/query.test.ts new file mode 100644 index 000000000..cbdaf925d --- /dev/null +++ b/wagmi-project/packages/core/src/exports/query.test.ts @@ -0,0 +1,97 @@ +import { expect, test } from 'vitest' + +import * as query from './query.js' + +test('exports', () => { + expect(Object.keys(query)).toMatchInlineSnapshot(` + [ + "callQueryKey", + "callQueryOptions", + "connectMutationOptions", + "deployContractMutationOptions", + "disconnectMutationOptions", + "estimateFeesPerGasQueryKey", + "estimateFeesPerGasQueryOptions", + "estimateGasQueryKey", + "estimateGasQueryOptions", + "estimateMaxPriorityFeePerGasQueryKey", + "estimateMaxPriorityFeePerGasQueryOptions", + "getBalanceQueryKey", + "getBalanceQueryOptions", + "getBlockQueryKey", + "getBlockQueryOptions", + "getBlockNumberQueryKey", + "getBlockNumberQueryOptions", + "getBlockTransactionCountQueryKey", + "getBlockTransactionCountQueryOptions", + "getBytecodeQueryKey", + "getBytecodeQueryOptions", + "getCallsStatusQueryKey", + "getCallsStatusQueryOptions", + "getCapabilitiesQueryKey", + "getCapabilitiesQueryOptions", + "getConnectorClientQueryKey", + "getConnectorClientQueryOptions", + "getEnsAddressQueryKey", + "getEnsAddressQueryOptions", + "getEnsAvatarQueryKey", + "getEnsAvatarQueryOptions", + "getEnsNameQueryKey", + "getEnsNameQueryOptions", + "getEnsResolverQueryKey", + "getEnsResolverQueryOptions", + "getEnsTextQueryKey", + "getEnsTextQueryOptions", + "getFeeHistoryQueryKey", + "getFeeHistoryQueryOptions", + "getGasPriceQueryKey", + "getGasPriceQueryOptions", + "getProofQueryKey", + "getProofQueryOptions", + "getStorageAtQueryKey", + "getStorageAtQueryOptions", + "getTokenQueryKey", + "getTokenQueryOptions", + "getTransactionQueryKey", + "getTransactionQueryOptions", + "getTransactionConfirmationsQueryKey", + "getTransactionConfirmationsQueryOptions", + "getTransactionCountQueryKey", + "getTransactionCountQueryOptions", + "getTransactionReceiptQueryKey", + "getTransactionReceiptQueryOptions", + "getWalletClientQueryKey", + "getWalletClientQueryOptions", + "infiniteReadContractsQueryKey", + "infiniteReadContractsQueryOptions", + "prepareTransactionRequestQueryKey", + "prepareTransactionRequestQueryOptions", + "readContractQueryKey", + "readContractQueryOptions", + "readContractsQueryKey", + "readContractsQueryOptions", + "reconnectMutationOptions", + "sendCallsMutationOptions", + "showCallsStatusMutationOptions", + "sendTransactionMutationOptions", + "signMessageMutationOptions", + "signTypedDataMutationOptions", + "switchAccountMutationOptions", + "simulateContractQueryKey", + "simulateContractQueryOptions", + "switchChainMutationOptions", + "verifyMessageQueryKey", + "verifyMessageQueryOptions", + "verifyTypedDataQueryKey", + "verifyTypedDataQueryOptions", + "waitForCallsStatusQueryKey", + "waitForCallsStatusQueryOptions", + "waitForTransactionReceiptQueryKey", + "waitForTransactionReceiptQueryOptions", + "watchAssetMutationOptions", + "writeContractMutationOptions", + "hashFn", + "structuralSharing", + ] + `) +}) diff --git a/wagmi-project/packages/core/src/exports/query.ts b/wagmi-project/packages/core/src/exports/query.ts new file mode 100644 index 000000000..d689f558d --- /dev/null +++ b/wagmi-project/packages/core/src/exports/query.ts @@ -0,0 +1,434 @@ +//////////////////////////////////////////////////////////////////////////////// +// Tanstack Query +//////////////////////////////////////////////////////////////////////////////// + +// biome-ignore lint/performance/noBarrelFile: entrypoint module +export { + type CallData, + type CallOptions, + type CallQueryFnData, + type CallQueryKey, + callQueryKey, + callQueryOptions, +} from '../query/call.js' + +export { + type ConnectData, + type ConnectVariables, + type ConnectMutate, + type ConnectMutateAsync, + connectMutationOptions, +} from '../query/connect.js' + +export { + type DeployContractData, + type DeployContractVariables, + type DeployContractMutate, + type DeployContractMutateAsync, + deployContractMutationOptions, +} from '../query/deployContract.js' + +export { + type DisconnectData, + type DisconnectVariables, + type DisconnectMutate, + type DisconnectMutateAsync, + disconnectMutationOptions, +} from '../query/disconnect.js' + +export { + type EstimateFeesPerGasData, + type EstimateFeesPerGasOptions, + type EstimateFeesPerGasQueryFnData, + type EstimateFeesPerGasQueryKey, + estimateFeesPerGasQueryKey, + estimateFeesPerGasQueryOptions, +} from '../query/estimateFeesPerGas.js' + +export { + type EstimateGasData, + type EstimateGasOptions, + type EstimateGasQueryFnData, + type EstimateGasQueryKey, + estimateGasQueryKey, + estimateGasQueryOptions, +} from '../query/estimateGas.js' + +export { + type EstimateMaxPriorityFeePerGasData, + type EstimateMaxPriorityFeePerGasOptions, + type EstimateMaxPriorityFeePerGasQueryFnData, + type EstimateMaxPriorityFeePerGasQueryKey, + estimateMaxPriorityFeePerGasQueryKey, + estimateMaxPriorityFeePerGasQueryOptions, +} from '../query/estimateMaxPriorityFeePerGas.js' + +export { + type GetBalanceData, + type GetBalanceOptions, + type GetBalanceQueryFnData, + type GetBalanceQueryKey, + getBalanceQueryKey, + getBalanceQueryOptions, +} from '../query/getBalance.js' + +export { + type GetBlockData, + type GetBlockOptions, + type GetBlockQueryFnData, + type GetBlockQueryKey, + getBlockQueryKey, + getBlockQueryOptions, +} from '../query/getBlock.js' + +export { + type GetBlockNumberData, + type GetBlockNumberOptions, + type GetBlockNumberQueryFnData, + type GetBlockNumberQueryKey, + getBlockNumberQueryKey, + getBlockNumberQueryOptions, +} from '../query/getBlockNumber.js' + +export { + type GetBlockTransactionCountData, + type GetBlockTransactionCountOptions, + type GetBlockTransactionCountQueryFnData, + type GetBlockTransactionCountQueryKey, + getBlockTransactionCountQueryKey, + getBlockTransactionCountQueryOptions, +} from '../query/getBlockTransactionCount.js' + +export { + type GetBytecodeData, + type GetBytecodeOptions, + type GetBytecodeQueryFnData, + type GetBytecodeQueryKey, + getBytecodeQueryKey, + getBytecodeQueryOptions, +} from '../query/getBytecode.js' + +export { + type GetCallsStatusData, + type GetCallsStatusOptions, + type GetCallsStatusQueryFnData, + type GetCallsStatusQueryKey, + getCallsStatusQueryKey, + getCallsStatusQueryOptions, +} from '../query/getCallsStatus.js' + +export { + type GetCapabilitiesData, + type GetCapabilitiesOptions, + type GetCapabilitiesQueryFnData, + type GetCapabilitiesQueryKey, + getCapabilitiesQueryKey, + getCapabilitiesQueryOptions, +} from '../query/getCapabilities.js' + +export { + type GetConnectorClientData, + type GetConnectorClientOptions, + type GetConnectorClientQueryFnData, + type GetConnectorClientQueryKey, + getConnectorClientQueryKey, + getConnectorClientQueryOptions, +} from '../query/getConnectorClient.js' + +export { + type GetEnsAddressData, + type GetEnsAddressOptions, + type GetEnsAddressQueryFnData, + type GetEnsAddressQueryKey, + getEnsAddressQueryKey, + getEnsAddressQueryOptions, +} from '../query/getEnsAddress.js' + +export { + type GetEnsAvatarData, + type GetEnsAvatarOptions, + type GetEnsAvatarQueryFnData, + type GetEnsAvatarQueryKey, + getEnsAvatarQueryKey, + getEnsAvatarQueryOptions, +} from '../query/getEnsAvatar.js' + +export { + type GetEnsNameData, + type GetEnsNameOptions, + type GetEnsNameQueryFnData, + type GetEnsNameQueryKey, + getEnsNameQueryKey, + getEnsNameQueryOptions, +} from '../query/getEnsName.js' + +export { + type GetEnsResolverData, + type GetEnsResolverOptions, + type GetEnsResolverQueryFnData, + type GetEnsResolverQueryKey, + getEnsResolverQueryKey, + getEnsResolverQueryOptions, +} from '../query/getEnsResolver.js' + +export { + type GetEnsTextData, + type GetEnsTextOptions, + type GetEnsTextQueryFnData, + type GetEnsTextQueryKey, + getEnsTextQueryKey, + getEnsTextQueryOptions, +} from '../query/getEnsText.js' + +export { + type GetFeeHistoryData, + type GetFeeHistoryOptions, + type GetFeeHistoryQueryFnData, + type GetFeeHistoryQueryKey, + getFeeHistoryQueryKey, + getFeeHistoryQueryOptions, +} from '../query/getFeeHistory.js' + +export { + type GetGasPriceData, + type GetGasPriceOptions, + type GetGasPriceQueryFnData, + type GetGasPriceQueryKey, + getGasPriceQueryKey, + getGasPriceQueryOptions, +} from '../query/getGasPrice.js' + +export { + type GetProofData, + type GetProofOptions, + type GetProofQueryFnData, + type GetProofQueryKey, + getProofQueryKey, + getProofQueryOptions, +} from '../query/getProof.js' + +export { + type GetStorageAtData, + type GetStorageAtOptions, + type GetStorageAtQueryFnData, + type GetStorageAtQueryKey, + getStorageAtQueryKey, + getStorageAtQueryOptions, +} from '../query/getStorageAt.js' + +export { + type GetTokenData, + type GetTokenOptions, + type GetTokenQueryFnData, + type GetTokenQueryKey, + getTokenQueryKey, + getTokenQueryOptions, +} from '../query/getToken.js' + +export { + type GetTransactionData, + type GetTransactionOptions, + type GetTransactionQueryFnData, + type GetTransactionQueryKey, + getTransactionQueryKey, + getTransactionQueryOptions, +} from '../query/getTransaction.js' + +export { + type GetTransactionConfirmationsData, + type GetTransactionConfirmationsOptions, + type GetTransactionConfirmationsQueryFnData, + type GetTransactionConfirmationsQueryKey, + getTransactionConfirmationsQueryKey, + getTransactionConfirmationsQueryOptions, +} from '../query/getTransactionConfirmations.js' + +export { + type GetTransactionCountData, + type GetTransactionCountOptions, + type GetTransactionCountQueryFnData, + type GetTransactionCountQueryKey, + getTransactionCountQueryKey, + getTransactionCountQueryOptions, +} from '../query/getTransactionCount.js' + +export { + type GetTransactionReceiptData, + type GetTransactionReceiptOptions, + type GetTransactionReceiptQueryFnData, + type GetTransactionReceiptQueryKey, + getTransactionReceiptQueryKey, + getTransactionReceiptQueryOptions, +} from '../query/getTransactionReceipt.js' + +export { + type GetWalletClientData, + type GetWalletClientOptions, + type GetWalletClientQueryFnData, + type GetWalletClientQueryKey, + getWalletClientQueryKey, + getWalletClientQueryOptions, +} from '../query/getWalletClient.js' + +export { + type InfiniteReadContractsData, + type InfiniteReadContractsOptions, + type InfiniteReadContractsQueryFnData, + type InfiniteReadContractsQueryKey, + infiniteReadContractsQueryKey, + infiniteReadContractsQueryOptions, +} from '../query/infiniteReadContracts.js' + +export { + type PrepareTransactionRequestData, + type PrepareTransactionRequestOptions, + type PrepareTransactionRequestQueryFnData, + type PrepareTransactionRequestQueryKey, + prepareTransactionRequestQueryKey, + prepareTransactionRequestQueryOptions, +} from '../query/prepareTransactionRequest.js' + +export { + type ReadContractData, + type ReadContractOptions, + type ReadContractQueryFnData, + type ReadContractQueryKey, + readContractQueryKey, + readContractQueryOptions, +} from '../query/readContract.js' + +export { + type ReadContractsData, + type ReadContractsOptions, + type ReadContractsQueryFnData, + type ReadContractsQueryKey, + readContractsQueryKey, + readContractsQueryOptions, +} from '../query/readContracts.js' + +export { + type ReconnectData, + type ReconnectVariables, + type ReconnectMutate, + type ReconnectMutateAsync, + reconnectMutationOptions, +} from '../query/reconnect.js' + +export { + type SendCallsData, + type SendCallsVariables, + type SendCallsMutate, + type SendCallsMutateAsync, + sendCallsMutationOptions, +} from '../query/sendCalls.js' + +export { + type ShowCallsStatusData, + type ShowCallsStatusVariables, + type ShowCallsStatusMutate, + type ShowCallsStatusMutateAsync, + showCallsStatusMutationOptions, +} from '../query/showCallsStatus.js' + +export { + type SendTransactionData, + type SendTransactionVariables, + type SendTransactionMutate, + type SendTransactionMutateAsync, + sendTransactionMutationOptions, +} from '../query/sendTransaction.js' + +export { + type SignMessageData, + type SignMessageVariables, + type SignMessageMutate, + type SignMessageMutateAsync, + signMessageMutationOptions, +} from '../query/signMessage.js' + +export { + type SignTypedDataData, + type SignTypedDataVariables, + type SignTypedDataMutate, + type SignTypedDataMutateAsync, + signTypedDataMutationOptions, +} from '../query/signTypedData.js' + +export { + type SwitchAccountData, + type SwitchAccountVariables, + type SwitchAccountMutate, + type SwitchAccountMutateAsync, + switchAccountMutationOptions, +} from '../query/switchAccount.js' + +export { + type SimulateContractData, + type SimulateContractOptions, + type SimulateContractQueryFnData, + type SimulateContractQueryKey, + simulateContractQueryKey, + simulateContractQueryOptions, +} from '../query/simulateContract.js' + +export { + type SwitchChainData, + type SwitchChainVariables, + type SwitchChainMutate, + type SwitchChainMutateAsync, + switchChainMutationOptions, +} from '../query/switchChain.js' + +export { + type VerifyMessageData, + type VerifyMessageOptions, + type VerifyMessageQueryFnData, + type VerifyMessageQueryKey, + verifyMessageQueryKey, + verifyMessageQueryOptions, +} from '../query/verifyMessage.js' + +export { + type VerifyTypedDataData, + type VerifyTypedDataOptions, + type VerifyTypedDataQueryFnData, + type VerifyTypedDataQueryKey, + verifyTypedDataQueryKey, + verifyTypedDataQueryOptions, +} from '../query/verifyTypedData.js' + +export { + type WaitForCallsStatusData, + type WaitForCallsStatusOptions, + type WaitForCallsStatusQueryFnData, + type WaitForCallsStatusQueryKey, + waitForCallsStatusQueryKey, + waitForCallsStatusQueryOptions, +} from '../query/waitForCallsStatus.js' + +export { + type WaitForTransactionReceiptData, + type WaitForTransactionReceiptOptions, + type WaitForTransactionReceiptQueryFnData, + type WaitForTransactionReceiptQueryKey, + waitForTransactionReceiptQueryKey, + waitForTransactionReceiptQueryOptions, +} from '../query/waitForTransactionReceipt.js' + +export { + type WatchAssetData, + type WatchAssetVariables, + type WatchAssetMutate, + type WatchAssetMutateAsync, + watchAssetMutationOptions, +} from '../query/watchAsset.js' + +export { + type WriteContractData, + type WriteContractVariables, + type WriteContractMutate, + type WriteContractMutateAsync, + writeContractMutationOptions, +} from '../query/writeContract.js' + +export { hashFn, structuralSharing } from '../query/utils.js' diff --git a/wagmi-project/packages/core/src/hydrate.test.ts b/wagmi-project/packages/core/src/hydrate.test.ts new file mode 100644 index 000000000..3dc6e2854 --- /dev/null +++ b/wagmi-project/packages/core/src/hydrate.test.ts @@ -0,0 +1,114 @@ +import { accounts, config, wait } from '@wagmi/test' +import type { EIP1193Provider } from 'mipd' +import { http } from 'viem' +import { mainnet } from 'viem/chains' +import { expect, test, vi } from 'vitest' + +import { createConnector } from './connectors/createConnector.js' +import { mock } from './connectors/mock.js' +import { createConfig } from './createConfig.js' +import { createStorage } from './createStorage.js' +import { hydrate } from './hydrate.js' +import { cookieStorage } from './utils/cookie.js' + +vi.mock(import('mipd'), async (importOriginal) => { + const mod = await importOriginal() + + let cache: typeof mod | undefined + if (!cache) + cache = { + ...mod, + createStore() { + const store = mod.createStore() + return { + ...store, + getProviders() { + const info = { + icon: 'data:image/svg+xml,', + uuid: crypto.randomUUID(), + } as const + const provider = '' as unknown as EIP1193Provider + return [ + { info: { ...info, name: 'Foo', rdns: 'com.foo' }, provider }, + { info: { ...info, name: 'Bar', rdns: 'com.bar' }, provider }, + { info: { ...info, name: 'Mock', rdns: 'com.mock' }, provider }, + ] + }, + } + }, + } + return cache +}) + +test('default', () => { + const { onMount } = hydrate(config, { + initialState: undefined, + reconnectOnMount: false, + }) + onMount() + + expect(onMount).toBeDefined() +}) + +test('initialState', () => { + const config = createConfig({ + chains: [mainnet], + transports: { [mainnet.id]: http() }, + ssr: true, + storage: createStorage({ storage: cookieStorage }), + }) + + const { onMount } = hydrate(config, { + initialState: { + chainId: 1, + current: null, + connections: new Map(), + status: 'disconnected', + }, + reconnectOnMount: true, + }) + onMount() + + expect(onMount).toBeDefined() +}) + +test('ssr', async () => { + const config = createConfig({ + chains: [mainnet], + connectors: [ + createConnector((c) => { + return { + ...mock({ accounts })(c), + rdns: 'com.mock', + } + }), + ], + ssr: true, + storage: createStorage({ storage: cookieStorage }), + transports: { [mainnet.id]: http() }, + }) + + const { onMount } = hydrate(config, { + initialState: { + chainId: 10, + current: null, + connections: new Map(), + status: 'disconnected', + }, + reconnectOnMount: false, + }) + onMount() + expect(onMount).toBeDefined() + expect(config.chains[0].id).toBe(1) + + await wait(100) + expect(config.connectors.map((x) => x.rdns ?? x.id)).toMatchInlineSnapshot( + ` + [ + "com.mock", + "com.foo", + "com.bar", + ] + `, + ) +}) diff --git a/wagmi-project/packages/core/src/hydrate.ts b/wagmi-project/packages/core/src/hydrate.ts new file mode 100644 index 000000000..70bc2199e --- /dev/null +++ b/wagmi-project/packages/core/src/hydrate.ts @@ -0,0 +1,62 @@ +import { reconnect } from './actions/reconnect.js' +import type { Config, State } from './createConfig.js' + +type HydrateParameters = { + initialState?: State | undefined + reconnectOnMount?: boolean | undefined +} + +export function hydrate(config: Config, parameters: HydrateParameters) { + const { initialState, reconnectOnMount } = parameters + + if (initialState && !config._internal.store.persist.hasHydrated()) + config.setState({ + ...initialState, + chainId: config.chains.some((x) => x.id === initialState.chainId) + ? initialState.chainId + : config.chains[0].id, + connections: reconnectOnMount ? initialState.connections : new Map(), + status: reconnectOnMount ? 'reconnecting' : 'disconnected', + }) + + return { + async onMount() { + if (config._internal.ssr) { + await config._internal.store.persist.rehydrate() + if (config._internal.mipd) { + config._internal.connectors.setState((connectors) => { + const rdnsSet = new Set() + for (const connector of connectors ?? []) { + if (connector.rdns) { + const rdnsValues = Array.isArray(connector.rdns) + ? connector.rdns + : [connector.rdns] + for (const rdns of rdnsValues) { + rdnsSet.add(rdns) + } + } + } + const mipdConnectors = [] + const providers = config._internal.mipd?.getProviders() ?? [] + for (const provider of providers) { + if (rdnsSet.has(provider.info.rdns)) continue + const connectorFn = + config._internal.connectors.providerDetailToConnector(provider) + const connector = config._internal.connectors.setup(connectorFn) + mipdConnectors.push(connector) + } + return [...connectors, ...mipdConnectors] + }) + } + } + + if (reconnectOnMount) reconnect(config) + else if (config.storage) + // Reset connections that may have been hydrated from storage. + config.setState((x) => ({ + ...x, + connections: new Map(), + })) + }, + } +} diff --git a/wagmi-project/packages/core/src/query/call.test.ts b/wagmi-project/packages/core/src/query/call.test.ts new file mode 100644 index 000000000..1e9ee03f7 --- /dev/null +++ b/wagmi-project/packages/core/src/query/call.test.ts @@ -0,0 +1,306 @@ +import { accounts, address, chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { parseEther, parseGwei } from 'viem' +import { callQueryOptions } from './call.js' + +const name4bytes = '0x06fdde03' +const account = accounts[0] + +test('default', () => { + expect( + callQueryOptions(config, { + account, + data: name4bytes, + to: address.wagmiMintExample, + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "call", + { + "account": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "data": "0x06fdde03", + "to": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + }, + ], + } + `) +}) + +test('parameters: accessList', () => { + expect( + callQueryOptions(config, { + account, + data: name4bytes, + to: address.wagmiMintExample, + accessList: [ + { + address: '0x1', + storageKeys: ['0x1'], + }, + ], + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "call", + { + "accessList": [ + { + "address": "0x1", + "storageKeys": [ + "0x1", + ], + }, + ], + "account": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "data": "0x06fdde03", + "to": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + }, + ], + } + `) +}) + +test('parameters: blockNumber', () => { + expect( + callQueryOptions(config, { + account, + data: name4bytes, + to: address.wagmiMintExample, + blockNumber: 1234567890n, + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "call", + { + "account": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "blockNumber": 1234567890n, + "data": "0x06fdde03", + "to": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + }, + ], + } + `) +}) + +test('parameters: blockTag', () => { + expect( + callQueryOptions(config, { + account, + data: name4bytes, + to: address.wagmiMintExample, + blockTag: 'safe', + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "call", + { + "account": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "blockTag": "safe", + "data": "0x06fdde03", + "to": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + }, + ], + } + `) +}) + +test('parameters: chainId', () => { + expect( + callQueryOptions(config, { + account, + data: name4bytes, + to: address.wagmiMintExample, + chainId: chain.mainnet2.id, + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "call", + { + "account": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "chainId": 456, + "data": "0x06fdde03", + "to": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + }, + ], + } + `) +}) + +test('parameters: gas', () => { + expect( + callQueryOptions(config, { + account, + data: name4bytes, + to: address.wagmiMintExample, + gas: 100000n, + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "call", + { + "account": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "data": "0x06fdde03", + "gas": 100000n, + "to": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + }, + ], + } + `) +}) + +test('parameters: gasPrice', () => { + expect( + callQueryOptions(config, { + account, + data: name4bytes, + to: address.wagmiMintExample, + gasPrice: parseGwei('20'), + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "call", + { + "account": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "data": "0x06fdde03", + "gasPrice": 20000000000n, + "to": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + }, + ], + } + `) +}) + +test('parameters: maxFeePerGas', () => { + expect( + callQueryOptions(config, { + account, + data: name4bytes, + to: address.wagmiMintExample, + maxFeePerGas: parseGwei('20'), + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "call", + { + "account": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "data": "0x06fdde03", + "maxFeePerGas": 20000000000n, + "to": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + }, + ], + } + `) +}) + +test('parameters: maxPriorityFeePerGas', () => { + expect( + callQueryOptions(config, { + account, + data: name4bytes, + to: address.wagmiMintExample, + maxPriorityFeePerGas: parseGwei('2'), + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "call", + { + "account": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "data": "0x06fdde03", + "maxPriorityFeePerGas": 2000000000n, + "to": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + }, + ], + } + `) +}) + +test('parameters: nonce', () => { + expect( + callQueryOptions(config, { + account, + data: name4bytes, + to: address.wagmiMintExample, + nonce: 123, + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "call", + { + "account": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "data": "0x06fdde03", + "nonce": 123, + "to": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + }, + ], + } + `) +}) + +test('parameters: type', () => { + expect( + callQueryOptions(config, { + account, + data: name4bytes, + to: address.wagmiMintExample, + type: 'eip1559', + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "call", + { + "account": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "data": "0x06fdde03", + "to": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "type": "eip1559", + }, + ], + } + `) +}) + +test('parameters: value', () => { + expect( + callQueryOptions(config, { + account, + data: name4bytes, + to: address.wagmiMintExample, + value: parseEther('1'), + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "call", + { + "account": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "data": "0x06fdde03", + "to": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "value": 1000000000000000000n, + }, + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/call.ts b/wagmi-project/packages/core/src/query/call.ts new file mode 100644 index 000000000..2ca4491b8 --- /dev/null +++ b/wagmi-project/packages/core/src/query/call.ts @@ -0,0 +1,51 @@ +import type { QueryOptions } from '@tanstack/query-core' + +import { + type CallErrorType, + type CallParameters, + type CallReturnType, + call, +} from '../actions/call.js' +import type { Config } from '../createConfig.js' +import type { ScopeKeyParameter } from '../types/properties.js' +import type { Compute, ExactPartial } from '../types/utils.js' +import { filterQueryOptions } from './utils.js' + +export type CallOptions = Compute< + ExactPartial> & ScopeKeyParameter +> + +export function callQueryOptions( + config: config, + options: CallOptions = {}, +) { + return { + async queryFn({ queryKey }) { + const { scopeKey: _, ...parameters } = queryKey[1] + const data = await call(config, { + ...parameters, + } as CallParameters) + return data ?? null + }, + queryKey: callQueryKey(options), + } as const satisfies QueryOptions< + CallQueryFnData, + CallErrorType, + CallData, + CallQueryKey + > +} + +export type CallQueryFnData = CallReturnType + +export type CallData = CallQueryFnData + +export function callQueryKey( + options: CallOptions, +) { + return ['call', filterQueryOptions(options)] as const +} + +export type CallQueryKey = ReturnType< + typeof callQueryKey +> diff --git a/wagmi-project/packages/core/src/query/connect.test.ts b/wagmi-project/packages/core/src/query/connect.test.ts new file mode 100644 index 000000000..b8300ee0e --- /dev/null +++ b/wagmi-project/packages/core/src/query/connect.test.ts @@ -0,0 +1,15 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { connectMutationOptions } from './connect.js' + +test('default', () => { + expect(connectMutationOptions(config)).toMatchInlineSnapshot(` + { + "mutationFn": [Function], + "mutationKey": [ + "connect", + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/connect.ts b/wagmi-project/packages/core/src/query/connect.ts new file mode 100644 index 000000000..f52151278 --- /dev/null +++ b/wagmi-project/packages/core/src/query/connect.ts @@ -0,0 +1,70 @@ +import type { MutateOptions, MutationOptions } from '@tanstack/query-core' + +import { + type ConnectErrorType, + type ConnectParameters, + type ConnectReturnType, + connect, +} from '../actions/connect.js' +import type { Config, Connector } from '../createConfig.js' + +import type { CreateConnectorFn } from '../connectors/createConnector.js' +import type { Compute } from '../types/utils.js' + +export function connectMutationOptions(config: config) { + return { + mutationFn(variables) { + return connect(config, variables) + }, + mutationKey: ['connect'], + } as const satisfies MutationOptions< + ConnectData, + ConnectErrorType, + ConnectVariables + > +} + +export type ConnectData = ConnectReturnType + +export type ConnectVariables< + config extends Config, + connector extends Connector | CreateConnectorFn, +> = ConnectParameters + +export type ConnectMutate = < + connector extends + | config['connectors'][number] + | Connector + | CreateConnectorFn, +>( + variables: ConnectVariables, + options?: + | Compute< + MutateOptions< + ConnectData, + ConnectErrorType, + Compute>, + context + > + > + | undefined, +) => void + +export type ConnectMutateAsync = < + connector extends + | config['connectors'][number] + | Connector + | CreateConnectorFn, +>( + variables: ConnectVariables, + options?: + | Compute< + MutateOptions< + ConnectData, + ConnectErrorType, + Compute>, + context + > + > + | undefined, +) => Promise> diff --git a/wagmi-project/packages/core/src/query/deployContract.test.ts b/wagmi-project/packages/core/src/query/deployContract.test.ts new file mode 100644 index 000000000..51157c03d --- /dev/null +++ b/wagmi-project/packages/core/src/query/deployContract.test.ts @@ -0,0 +1,15 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { deployContractMutationOptions } from './deployContract.js' + +test('default', () => { + expect(deployContractMutationOptions(config)).toMatchInlineSnapshot(` + { + "mutationFn": [Function], + "mutationKey": [ + "deployContract", + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/deployContract.ts b/wagmi-project/packages/core/src/query/deployContract.ts new file mode 100644 index 000000000..d4fac0453 --- /dev/null +++ b/wagmi-project/packages/core/src/query/deployContract.ts @@ -0,0 +1,73 @@ +import type { MutateOptions, MutationOptions } from '@tanstack/query-core' +import type { Abi, ContractConstructorArgs } from 'viem' + +import { + type DeployContractErrorType, + type DeployContractParameters, + type DeployContractReturnType, + deployContract, +} from '../actions/deployContract.js' +import type { Config } from '../createConfig.js' +import type { Compute } from '../types/utils.js' + +export function deployContractMutationOptions( + config: config, +) { + return { + mutationFn(variables) { + return deployContract(config, variables) + }, + mutationKey: ['deployContract'], + } as const satisfies MutationOptions< + DeployContractData, + DeployContractErrorType, + DeployContractVariables + > +} + +export type DeployContractData = Compute + +export type DeployContractVariables< + abi extends Abi | readonly unknown[], + config extends Config, + chainId extends config['chains'][number]['id'], + /// + allArgs = ContractConstructorArgs, +> = DeployContractParameters + +export type DeployContractMutate = < + abi extends Abi | readonly unknown[], + chainId extends config['chains'][number]['id'], +>( + variables: DeployContractVariables, + options?: + | Compute< + MutateOptions< + DeployContractData, + DeployContractErrorType, + Compute>, + context + > + > + | undefined, +) => void + +export type DeployContractMutateAsync< + config extends Config, + context = unknown, +> = < + abi extends Abi | readonly unknown[], + chainId extends config['chains'][number]['id'], +>( + variables: DeployContractVariables, + options?: + | Compute< + MutateOptions< + DeployContractData, + DeployContractErrorType, + Compute>, + context + > + > + | undefined, +) => Promise diff --git a/wagmi-project/packages/core/src/query/disconnect.test.ts b/wagmi-project/packages/core/src/query/disconnect.test.ts new file mode 100644 index 000000000..4637c7e88 --- /dev/null +++ b/wagmi-project/packages/core/src/query/disconnect.test.ts @@ -0,0 +1,15 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { disconnectMutationOptions } from './disconnect.js' + +test('default', () => { + expect(disconnectMutationOptions(config)).toMatchInlineSnapshot(` + { + "mutationFn": [Function], + "mutationKey": [ + "disconnect", + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/disconnect.ts b/wagmi-project/packages/core/src/query/disconnect.ts new file mode 100644 index 000000000..018873da0 --- /dev/null +++ b/wagmi-project/packages/core/src/query/disconnect.ts @@ -0,0 +1,43 @@ +import type { MutationOptions } from '@tanstack/query-core' + +import { + type DisconnectErrorType, + type DisconnectParameters, + type DisconnectReturnType, + disconnect, +} from '../actions/disconnect.js' +import type { Config } from '../createConfig.js' +import type { Mutate, MutateAsync } from './types.js' + +export function disconnectMutationOptions( + config: config, +) { + return { + mutationFn(variables) { + return disconnect(config, variables) + }, + mutationKey: ['disconnect'], + } as const satisfies MutationOptions< + DisconnectData, + DisconnectErrorType, + DisconnectVariables + > +} + +export type DisconnectData = DisconnectReturnType + +export type DisconnectVariables = DisconnectParameters | undefined + +export type DisconnectMutate = Mutate< + DisconnectData, + DisconnectErrorType, + DisconnectVariables, + context +> + +export type DisconnectMutateAsync = MutateAsync< + DisconnectData, + DisconnectErrorType, + DisconnectVariables, + context +> diff --git a/wagmi-project/packages/core/src/query/estimateFeesPerGas.test.ts b/wagmi-project/packages/core/src/query/estimateFeesPerGas.test.ts new file mode 100644 index 000000000..6b9965e65 --- /dev/null +++ b/wagmi-project/packages/core/src/query/estimateFeesPerGas.test.ts @@ -0,0 +1,32 @@ +import { chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { estimateFeesPerGasQueryOptions } from './estimateFeesPerGas.js' + +test('default', () => { + expect(estimateFeesPerGasQueryOptions(config)).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "estimateFeesPerGas", + {}, + ], + } + `) +}) + +test('parameters: chainId', () => { + expect( + estimateFeesPerGasQueryOptions(config, { chainId: chain.mainnet.id }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "estimateFeesPerGas", + { + "chainId": 1, + }, + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/estimateFeesPerGas.ts b/wagmi-project/packages/core/src/query/estimateFeesPerGas.ts new file mode 100644 index 000000000..7cf2f607c --- /dev/null +++ b/wagmi-project/packages/core/src/query/estimateFeesPerGas.ts @@ -0,0 +1,56 @@ +import type { QueryOptions } from '@tanstack/query-core' +import type { FeeValuesType } from 'viem' + +import { + type EstimateFeesPerGasErrorType, + type EstimateFeesPerGasParameters, + type EstimateFeesPerGasReturnType, + estimateFeesPerGas, +} from '../actions/estimateFeesPerGas.js' +import type { Config } from '../createConfig.js' +import type { ScopeKeyParameter } from '../types/properties.js' +import type { Compute, ExactPartial } from '../types/utils.js' +import { filterQueryOptions } from './utils.js' + +export type EstimateFeesPerGasOptions< + type extends FeeValuesType, + config extends Config, +> = Compute< + ExactPartial> & ScopeKeyParameter +> + +export function estimateFeesPerGasQueryOptions< + config extends Config, + type extends FeeValuesType = 'eip1559', +>(config: config, options: EstimateFeesPerGasOptions = {}) { + return { + async queryFn({ queryKey }) { + const { scopeKey: _, ...parameters } = queryKey[1] + return estimateFeesPerGas(config, parameters) + }, + queryKey: estimateFeesPerGasQueryKey(options), + } as const satisfies QueryOptions< + EstimateFeesPerGasQueryFnData, + EstimateFeesPerGasErrorType, + EstimateFeesPerGasData, + EstimateFeesPerGasQueryKey + > +} + +export type EstimateFeesPerGasQueryFnData = + EstimateFeesPerGasReturnType + +export type EstimateFeesPerGasData = + EstimateFeesPerGasQueryFnData + +export function estimateFeesPerGasQueryKey< + config extends Config, + type extends FeeValuesType = 'eip1559', +>(options: EstimateFeesPerGasOptions = {}) { + return ['estimateFeesPerGas', filterQueryOptions(options)] as const +} + +export type EstimateFeesPerGasQueryKey< + config extends Config, + type extends FeeValuesType, +> = ReturnType> diff --git a/wagmi-project/packages/core/src/query/estimateGas.test-d.ts b/wagmi-project/packages/core/src/query/estimateGas.test-d.ts new file mode 100644 index 000000000..e48c4b089 --- /dev/null +++ b/wagmi-project/packages/core/src/query/estimateGas.test-d.ts @@ -0,0 +1,55 @@ +import { http, type Address, parseEther } from 'viem' +import { celo, mainnet } from 'viem/chains' +import { expectTypeOf, test } from 'vitest' + +import { createConfig } from '../createConfig.js' +import { + type EstimateGasOptions, + estimateGasQueryOptions, +} from './estimateGas.js' + +test('chain formatters', () => { + const config = createConfig({ + chains: [mainnet, celo], + transports: { [celo.id]: http(), [mainnet.id]: http() }, + }) + + type Result = EstimateGasOptions< + typeof config, + (typeof config)['chains'][number]['id'] + > + expectTypeOf().toMatchTypeOf<{ + chainId?: typeof celo.id | typeof mainnet.id | undefined + feeCurrency?: `0x${string}` | undefined + }>() + estimateGasQueryOptions(config, { + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), + feeCurrency: '0x', + }) + + type Result2 = EstimateGasOptions + expectTypeOf().toMatchTypeOf<{ + functionName?: 'approve' | 'transfer' | 'transferFrom' | undefined + args?: readonly [Address, Address, bigint] | undefined + feeCurrency?: `0x${string}` | undefined + }>() + estimateGasQueryOptions(config, { + chainId: celo.id, + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), + feeCurrency: '0x', + }) + + type Result3 = EstimateGasOptions + expectTypeOf().not.toMatchTypeOf<{ + feeCurrency?: `0x${string}` | undefined + }>() + estimateGasQueryOptions(config, { + chainId: mainnet.id, + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), + // @ts-expect-error + feeCurrency: '0x', + }) +}) diff --git a/wagmi-project/packages/core/src/query/estimateGas.test.ts b/wagmi-project/packages/core/src/query/estimateGas.test.ts new file mode 100644 index 000000000..6c31cadbc --- /dev/null +++ b/wagmi-project/packages/core/src/query/estimateGas.test.ts @@ -0,0 +1,25 @@ +import { config } from '@wagmi/test' +import { parseEther } from 'viem' +import { expect, test } from 'vitest' + +import { estimateGasQueryOptions } from './estimateGas.js' + +test('default', () => { + expect( + estimateGasQueryOptions(config, { + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "estimateGas", + { + "to": "0xd2135CfB216b74109775236E36d4b433F1DF507B", + "value": 10000000000000000n, + }, + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/estimateGas.ts b/wagmi-project/packages/core/src/query/estimateGas.ts new file mode 100644 index 000000000..749002f92 --- /dev/null +++ b/wagmi-project/packages/core/src/query/estimateGas.ts @@ -0,0 +1,56 @@ +import type { QueryOptions } from '@tanstack/query-core' + +import { + type EstimateGasErrorType, + type EstimateGasParameters, + type EstimateGasReturnType, + estimateGas, +} from '../actions/estimateGas.js' +import type { Config } from '../createConfig.js' +import type { ScopeKeyParameter } from '../types/properties.js' +import type { UnionExactPartial } from '../types/utils.js' +import { filterQueryOptions } from './utils.js' + +export type EstimateGasOptions< + config extends Config, + chainId extends config['chains'][number]['id'] | undefined, +> = UnionExactPartial> & + ScopeKeyParameter + +export function estimateGasQueryOptions< + config extends Config, + chainId extends config['chains'][number]['id'], +>(config: config, options: EstimateGasOptions = {} as any) { + return { + async queryFn({ queryKey }) { + const { connector } = options + const { account, scopeKey: _, ...parameters } = queryKey[1] + if (!account && !connector) + throw new Error('account or connector is required') + return estimateGas(config, { account, connector, ...(parameters as any) }) + }, + queryKey: estimateGasQueryKey(options), + } as const satisfies QueryOptions< + EstimateGasQueryFnData, + EstimateGasErrorType, + EstimateGasData, + EstimateGasQueryKey + > +} + +export type EstimateGasQueryFnData = EstimateGasReturnType + +export type EstimateGasData = EstimateGasQueryFnData + +export function estimateGasQueryKey< + config extends Config, + chainId extends config['chains'][number]['id'] | undefined, +>(options: EstimateGasOptions = {} as any) { + const { connector: _, ...rest } = options + return ['estimateGas', filterQueryOptions(rest)] as const +} + +export type EstimateGasQueryKey< + config extends Config, + chainId extends config['chains'][number]['id'] | undefined, +> = ReturnType> diff --git a/wagmi-project/packages/core/src/query/estimateMaxPriorityFeePerGas.test.ts b/wagmi-project/packages/core/src/query/estimateMaxPriorityFeePerGas.test.ts new file mode 100644 index 000000000..38bcde076 --- /dev/null +++ b/wagmi-project/packages/core/src/query/estimateMaxPriorityFeePerGas.test.ts @@ -0,0 +1,36 @@ +import { chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { estimateMaxPriorityFeePerGasQueryOptions } from './estimateMaxPriorityFeePerGas.js' + +test('default', () => { + expect( + estimateMaxPriorityFeePerGasQueryOptions(config), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "estimateMaxPriorityFeePerGas", + {}, + ], + } + `) +}) + +test('parameters: chainId', () => { + expect( + estimateMaxPriorityFeePerGasQueryOptions(config, { + chainId: chain.mainnet.id, + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "estimateMaxPriorityFeePerGas", + { + "chainId": 1, + }, + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/estimateMaxPriorityFeePerGas.ts b/wagmi-project/packages/core/src/query/estimateMaxPriorityFeePerGas.ts new file mode 100644 index 000000000..cb58e65a7 --- /dev/null +++ b/wagmi-project/packages/core/src/query/estimateMaxPriorityFeePerGas.ts @@ -0,0 +1,51 @@ +import type { QueryOptions } from '@tanstack/query-core' + +import { + type EstimateMaxPriorityFeePerGasErrorType, + type EstimateMaxPriorityFeePerGasParameters, + type EstimateMaxPriorityFeePerGasReturnType, + estimateMaxPriorityFeePerGas, +} from '../actions/estimateMaxPriorityFeePerGas.js' +import type { Config } from '../createConfig.js' +import type { ScopeKeyParameter } from '../types/properties.js' +import type { Compute, ExactPartial } from '../types/utils.js' +import { filterQueryOptions } from './utils.js' + +export type EstimateMaxPriorityFeePerGasOptions = + Compute< + ExactPartial> & + ScopeKeyParameter + > + +export function estimateMaxPriorityFeePerGasQueryOptions( + config: config, + options: EstimateMaxPriorityFeePerGasOptions = {}, +) { + return { + async queryFn({ queryKey }) { + const { scopeKey: _, ...parameters } = queryKey[1] + return estimateMaxPriorityFeePerGas(config, parameters) + }, + queryKey: estimateMaxPriorityFeePerGasQueryKey(options), + } as const satisfies QueryOptions< + EstimateMaxPriorityFeePerGasQueryFnData, + EstimateMaxPriorityFeePerGasErrorType, + EstimateMaxPriorityFeePerGasData, + EstimateMaxPriorityFeePerGasQueryKey + > +} + +export type EstimateMaxPriorityFeePerGasQueryFnData = + EstimateMaxPriorityFeePerGasReturnType + +export type EstimateMaxPriorityFeePerGasData = + EstimateMaxPriorityFeePerGasQueryFnData + +export function estimateMaxPriorityFeePerGasQueryKey( + options: EstimateMaxPriorityFeePerGasOptions = {}, +) { + return ['estimateMaxPriorityFeePerGas', filterQueryOptions(options)] as const +} + +export type EstimateMaxPriorityFeePerGasQueryKey = + ReturnType> diff --git a/wagmi-project/packages/core/src/query/getBalance.test.ts b/wagmi-project/packages/core/src/query/getBalance.test.ts new file mode 100644 index 000000000..1f9e1ecda --- /dev/null +++ b/wagmi-project/packages/core/src/query/getBalance.test.ts @@ -0,0 +1,63 @@ +import { accounts, chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getBalanceQueryOptions } from './getBalance.js' + +const address = accounts[0] + +test('default', () => { + expect(getBalanceQueryOptions(config, { address })).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "balance", + { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + }, + ], + } + `) +}) + +test('parameters: chainId', () => { + expect( + getBalanceQueryOptions(config, { address, chainId: chain.mainnet.id }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "balance", + { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "chainId": 1, + }, + ], + } + `) +}) + +test.todo('parameters: token') + +test('parameters: unit', () => { + expect( + getBalanceQueryOptions(config, { + address, + chainId: chain.mainnet.id, + token: '0x0000000000000000000000000000000000000000', + unit: 'gwei', + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "balance", + { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "chainId": 1, + "token": "0x0000000000000000000000000000000000000000", + "unit": "gwei", + }, + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/getBalance.ts b/wagmi-project/packages/core/src/query/getBalance.ts new file mode 100644 index 000000000..e1dd28763 --- /dev/null +++ b/wagmi-project/packages/core/src/query/getBalance.ts @@ -0,0 +1,53 @@ +import type { QueryOptions } from '@tanstack/query-core' + +import { + type GetBalanceErrorType, + type GetBalanceParameters, + type GetBalanceReturnType, + getBalance, +} from '../actions/getBalance.js' +import type { Config } from '../createConfig.js' +import type { ScopeKeyParameter } from '../types/properties.js' +import type { Compute, PartialBy } from '../types/utils.js' +import { filterQueryOptions } from './utils.js' + +export type GetBalanceOptions = Compute< + PartialBy, 'address'> & ScopeKeyParameter +> + +export function getBalanceQueryOptions( + config: config, + options: GetBalanceOptions = {}, +) { + return { + async queryFn({ queryKey }) { + const { address, scopeKey: _, ...parameters } = queryKey[1] + if (!address) throw new Error('address is required') + const balance = await getBalance(config, { + ...(parameters as GetBalanceParameters), + address, + }) + return balance ?? null + }, + queryKey: getBalanceQueryKey(options), + } as const satisfies QueryOptions< + GetBalanceQueryFnData, + GetBalanceErrorType, + GetBalanceData, + GetBalanceQueryKey + > +} + +export type GetBalanceQueryFnData = Compute + +export type GetBalanceData = GetBalanceQueryFnData + +export function getBalanceQueryKey( + options: GetBalanceOptions = {}, +) { + return ['balance', filterQueryOptions(options)] as const +} + +export type GetBalanceQueryKey = ReturnType< + typeof getBalanceQueryKey +> diff --git a/wagmi-project/packages/core/src/query/getBlock.test.ts b/wagmi-project/packages/core/src/query/getBlock.test.ts new file mode 100644 index 000000000..f31fb8c26 --- /dev/null +++ b/wagmi-project/packages/core/src/query/getBlock.test.ts @@ -0,0 +1,32 @@ +import { chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getBlockQueryOptions } from './getBlock.js' + +test('default', () => { + expect(getBlockQueryOptions(config)).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "block", + {}, + ], + } + `) +}) + +test('parameters: chainId', () => { + expect( + getBlockQueryOptions(config, { chainId: chain.mainnet.id }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "block", + { + "chainId": 1, + }, + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/getBlock.ts b/wagmi-project/packages/core/src/query/getBlock.ts new file mode 100644 index 000000000..f8f4db841 --- /dev/null +++ b/wagmi-project/packages/core/src/query/getBlock.ts @@ -0,0 +1,84 @@ +import type { QueryOptions } from '@tanstack/query-core' +import type { BlockTag } from 'viem' + +import { + type GetBlockErrorType, + type GetBlockParameters, + type GetBlockReturnType, + getBlock, +} from '../actions/getBlock.js' +import type { Config } from '../createConfig.js' +import type { ScopeKeyParameter } from '../types/properties.js' +import type { Compute, ExactPartial } from '../types/utils.js' +import { filterQueryOptions } from './utils.js' + +export type GetBlockOptions< + includeTransactions extends boolean, + blockTag extends BlockTag, + config extends Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +> = Compute< + ExactPartial< + GetBlockParameters + > & + ScopeKeyParameter +> + +export function getBlockQueryOptions< + config extends Config, + chainId extends config['chains'][number]['id'], + includeTransactions extends boolean, + blockTag extends BlockTag, +>( + config: config, + options: GetBlockOptions = {}, +) { + return { + async queryFn({ queryKey }) { + const { scopeKey: _, ...parameters } = queryKey[1] + const block = await getBlock(config, parameters) + return (block ?? null) as any + }, + queryKey: getBlockQueryKey(options), + } as const satisfies QueryOptions< + GetBlockQueryFnData, + GetBlockErrorType, + GetBlockData, + GetBlockQueryKey + > +} + +export type GetBlockQueryFnData< + includeTransactions extends boolean, + blockTag extends BlockTag, + config extends Config, + chainId extends config['chains'][number]['id'], +> = GetBlockReturnType + +export type GetBlockData< + includeTransactions extends boolean, + blockTag extends BlockTag, + config extends Config, + chainId extends config['chains'][number]['id'], +> = GetBlockQueryFnData + +export function getBlockQueryKey< + config extends Config, + chainId extends config['chains'][number]['id'], + includeTransactions extends boolean = false, + blockTag extends BlockTag = 'latest', +>( + options: GetBlockOptions = {}, +) { + return ['block', filterQueryOptions(options)] as const +} + +export type GetBlockQueryKey< + includeTransactions extends boolean, + blockTag extends BlockTag, + config extends Config, + chainId extends config['chains'][number]['id'], +> = ReturnType< + typeof getBlockQueryKey +> diff --git a/wagmi-project/packages/core/src/query/getBlockNumber.test.ts b/wagmi-project/packages/core/src/query/getBlockNumber.test.ts new file mode 100644 index 000000000..b2ff0c2d1 --- /dev/null +++ b/wagmi-project/packages/core/src/query/getBlockNumber.test.ts @@ -0,0 +1,34 @@ +import { chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getBlockNumberQueryOptions } from './getBlockNumber.js' + +test('default', () => { + expect(getBlockNumberQueryOptions(config)).toMatchInlineSnapshot(` + { + "gcTime": 0, + "queryFn": [Function], + "queryKey": [ + "blockNumber", + {}, + ], + } + `) +}) + +test('parameters: chainId', () => { + expect( + getBlockNumberQueryOptions(config, { chainId: chain.mainnet.id }), + ).toMatchInlineSnapshot(` + { + "gcTime": 0, + "queryFn": [Function], + "queryKey": [ + "blockNumber", + { + "chainId": 1, + }, + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/getBlockNumber.ts b/wagmi-project/packages/core/src/query/getBlockNumber.ts new file mode 100644 index 000000000..9585068a9 --- /dev/null +++ b/wagmi-project/packages/core/src/query/getBlockNumber.ts @@ -0,0 +1,55 @@ +import type { QueryOptions } from '@tanstack/query-core' + +import { + type GetBlockNumberErrorType, + type GetBlockNumberParameters, + type GetBlockNumberReturnType, + getBlockNumber, +} from '../actions/getBlockNumber.js' +import type { Config } from '../createConfig.js' +import type { ScopeKeyParameter } from '../types/properties.js' +import type { Compute, ExactPartial } from '../types/utils.js' +import { filterQueryOptions } from './utils.js' + +export type GetBlockNumberOptions< + config extends Config, + chainId extends config['chains'][number]['id'], +> = Compute< + ExactPartial> & ScopeKeyParameter +> + +export function getBlockNumberQueryOptions< + config extends Config, + chainId extends config['chains'][number]['id'], +>(config: config, options: GetBlockNumberOptions = {}) { + return { + gcTime: 0, + async queryFn({ queryKey }) { + const { scopeKey: _, ...parameters } = queryKey[1] + const blockNumber = await getBlockNumber(config, parameters) + return blockNumber ?? null + }, + queryKey: getBlockNumberQueryKey(options), + } as const satisfies QueryOptions< + GetBlockNumberQueryFnData, + GetBlockNumberErrorType, + GetBlockNumberData, + GetBlockNumberQueryKey + > +} + +export type GetBlockNumberQueryFnData = GetBlockNumberReturnType + +export type GetBlockNumberData = GetBlockNumberQueryFnData + +export function getBlockNumberQueryKey< + config extends Config, + chainId extends config['chains'][number]['id'], +>(options: GetBlockNumberOptions = {}) { + return ['blockNumber', filterQueryOptions(options)] as const +} + +export type GetBlockNumberQueryKey< + config extends Config, + chainId extends config['chains'][number]['id'], +> = ReturnType> diff --git a/wagmi-project/packages/core/src/query/getBlockTransactionCount.test.ts b/wagmi-project/packages/core/src/query/getBlockTransactionCount.test.ts new file mode 100644 index 000000000..d6c45ee09 --- /dev/null +++ b/wagmi-project/packages/core/src/query/getBlockTransactionCount.test.ts @@ -0,0 +1,50 @@ +import { chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getBlockTransactionCountQueryOptions } from './getBlockTransactionCount.js' + +test('default', () => { + expect(getBlockTransactionCountQueryOptions(config)).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "blockTransactionCount", + {}, + ], + } + `) +}) + +test('parameters: chainId', () => { + expect( + getBlockTransactionCountQueryOptions(config, { chainId: chain.mainnet.id }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "blockTransactionCount", + { + "chainId": 1, + }, + ], + } + `) +}) + +test('parameters: blockTag', () => { + expect( + getBlockTransactionCountQueryOptions(config, { + blockTag: 'earliest', + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "blockTransactionCount", + { + "blockTag": "earliest", + }, + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/getBlockTransactionCount.ts b/wagmi-project/packages/core/src/query/getBlockTransactionCount.ts new file mode 100644 index 000000000..453e95e00 --- /dev/null +++ b/wagmi-project/packages/core/src/query/getBlockTransactionCount.ts @@ -0,0 +1,62 @@ +import type { QueryOptions } from '@tanstack/query-core' + +import { + type GetBlockTransactionCountErrorType, + type GetBlockTransactionCountParameters, + type GetBlockTransactionCountReturnType, + getBlockTransactionCount, +} from '../actions/getBlockTransactionCount.js' +import type { Config } from '../createConfig.js' +import type { ScopeKeyParameter } from '../types/properties.js' +import type { ExactPartial, UnionCompute } from '../types/utils.js' +import { filterQueryOptions } from './utils.js' + +export type GetBlockTransactionCountOptions< + config extends Config, + chainId extends config['chains'][number]['id'], +> = UnionCompute< + ExactPartial> & + ScopeKeyParameter +> + +export function getBlockTransactionCountQueryOptions< + config extends Config, + chainId extends config['chains'][number]['id'], +>( + config: config, + options: GetBlockTransactionCountOptions = {}, +) { + return { + async queryFn({ queryKey }) { + const { scopeKey: _, ...parameters } = queryKey[1] + const blockTransactionCount = await getBlockTransactionCount( + config, + parameters, + ) + return blockTransactionCount ?? null + }, + queryKey: getBlockTransactionCountQueryKey(options), + } as const satisfies QueryOptions< + GetBlockTransactionCountQueryFnData, + GetBlockTransactionCountErrorType, + GetBlockTransactionCountData, + GetBlockTransactionCountQueryKey + > +} + +export type GetBlockTransactionCountQueryFnData = + GetBlockTransactionCountReturnType + +export type GetBlockTransactionCountData = GetBlockTransactionCountQueryFnData + +export function getBlockTransactionCountQueryKey< + config extends Config, + chainId extends config['chains'][number]['id'], +>(options: GetBlockTransactionCountOptions = {}) { + return ['blockTransactionCount', filterQueryOptions(options)] as const +} + +export type GetBlockTransactionCountQueryKey< + config extends Config, + chainId extends config['chains'][number]['id'], +> = ReturnType> diff --git a/wagmi-project/packages/core/src/query/getBytecode.test.ts b/wagmi-project/packages/core/src/query/getBytecode.test.ts new file mode 100644 index 000000000..83f22ebf2 --- /dev/null +++ b/wagmi-project/packages/core/src/query/getBytecode.test.ts @@ -0,0 +1,82 @@ +import { address, chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getBytecodeQueryOptions } from './getBytecode.js' + +test('default', () => { + expect( + getBytecodeQueryOptions(config, { + address: address.wagmiMintExample, + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "getBytecode", + { + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + }, + ], + } + `) +}) + +test('parameters: chainId', () => { + expect( + getBytecodeQueryOptions(config, { + address: address.wagmiMintExample, + chainId: chain.mainnet2.id, + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "getBytecode", + { + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "chainId": 456, + }, + ], + } + `) +}) + +test('parameters: blockNumber', () => { + expect( + getBytecodeQueryOptions(config, { + address: address.wagmiMintExample, + blockNumber: 1234567890n, + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "getBytecode", + { + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "blockNumber": 1234567890n, + }, + ], + } + `) +}) + +test('parameters: blockTag', () => { + expect( + getBytecodeQueryOptions(config, { + address: address.wagmiMintExample, + blockTag: 'safe', + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "getBytecode", + { + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "blockTag": "safe", + }, + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/getBytecode.ts b/wagmi-project/packages/core/src/query/getBytecode.ts new file mode 100644 index 000000000..7000c50ea --- /dev/null +++ b/wagmi-project/packages/core/src/query/getBytecode.ts @@ -0,0 +1,49 @@ +import type { QueryOptions } from '@tanstack/query-core' + +import { + type GetBytecodeErrorType, + type GetBytecodeParameters, + type GetBytecodeReturnType, + getBytecode, +} from '../actions/getBytecode.js' +import type { Config } from '../createConfig.js' +import type { ScopeKeyParameter } from '../types/properties.js' +import type { Compute, ExactPartial } from '../types/utils.js' +import { filterQueryOptions } from './utils.js' + +export type GetBytecodeOptions = Compute< + ExactPartial> & ScopeKeyParameter +> + +export function getBytecodeQueryOptions( + config: config, + options: GetBytecodeOptions = {}, +) { + return { + async queryFn({ queryKey }) { + const { address, scopeKey: _, ...parameters } = queryKey[1] + if (!address) throw new Error('address is required') + const bytecode = await getBytecode(config, { ...parameters, address }) + return (bytecode ?? null) as any + }, + queryKey: getBytecodeQueryKey(options), + } as const satisfies QueryOptions< + GetBytecodeQueryFnData, + GetBytecodeErrorType, + GetBytecodeData, + GetBytecodeQueryKey + > +} +export type GetBytecodeQueryFnData = GetBytecodeReturnType + +export type GetBytecodeData = GetBytecodeQueryFnData + +export function getBytecodeQueryKey( + options: GetBytecodeOptions, +) { + return ['getBytecode', filterQueryOptions(options)] as const +} + +export type GetBytecodeQueryKey = ReturnType< + typeof getBytecodeQueryKey +> diff --git a/wagmi-project/packages/core/src/query/getCallsStatus.test.ts b/wagmi-project/packages/core/src/query/getCallsStatus.test.ts new file mode 100644 index 000000000..fe834ecc7 --- /dev/null +++ b/wagmi-project/packages/core/src/query/getCallsStatus.test.ts @@ -0,0 +1,23 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getCallsStatusQueryOptions } from './getCallsStatus.js' + +test('default', () => { + expect( + getCallsStatusQueryOptions(config, { + id: '0x0000000000000000000000000000000000000000', + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "callsStatus", + { + "id": "0x0000000000000000000000000000000000000000", + }, + ], + "retry": [Function], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/getCallsStatus.ts b/wagmi-project/packages/core/src/query/getCallsStatus.ts new file mode 100644 index 000000000..869263eef --- /dev/null +++ b/wagmi-project/packages/core/src/query/getCallsStatus.ts @@ -0,0 +1,50 @@ +import type { QueryOptions } from '@tanstack/query-core' + +import { + type GetCallsStatusErrorType, + type GetCallsStatusParameters, + type GetCallsStatusReturnType, + getCallsStatus, +} from '../actions/getCallsStatus.js' +import type { Config } from '../createConfig.js' +import { ConnectorNotConnectedError } from '../errors/config.js' +import { filterQueryOptions } from '../query/utils.js' +import type { ScopeKeyParameter } from '../types/properties.js' +import type { Compute } from '../types/utils.js' + +export type GetCallsStatusOptions = Compute< + GetCallsStatusParameters & ScopeKeyParameter +> + +export function getCallsStatusQueryOptions( + config: config, + options: GetCallsStatusOptions, +) { + return { + async queryFn({ queryKey }) { + const { scopeKey: _, ...parameters } = queryKey[1] + const status = await getCallsStatus(config, parameters) + return status + }, + queryKey: getCallsStatusQueryKey(options), + retry(failureCount, error) { + if (error instanceof ConnectorNotConnectedError) return false + return failureCount < 3 + }, + } as const satisfies QueryOptions< + GetCallsStatusQueryFnData, + GetCallsStatusErrorType, + GetCallsStatusData, + GetCallsStatusQueryKey + > +} + +export type GetCallsStatusQueryFnData = GetCallsStatusReturnType + +export type GetCallsStatusData = GetCallsStatusQueryFnData + +export function getCallsStatusQueryKey(options: GetCallsStatusOptions) { + return ['callsStatus', filterQueryOptions(options)] as const +} + +export type GetCallsStatusQueryKey = ReturnType diff --git a/wagmi-project/packages/core/src/query/getCapabilities.test.ts b/wagmi-project/packages/core/src/query/getCapabilities.test.ts new file mode 100644 index 000000000..942eb37e0 --- /dev/null +++ b/wagmi-project/packages/core/src/query/getCapabilities.test.ts @@ -0,0 +1,36 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getCapabilitiesQueryOptions } from './getCapabilities.js' + +test('default', () => { + expect(getCapabilitiesQueryOptions(config)).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "capabilities", + {}, + ], + "retry": [Function], + } + `) +}) + +test('parameters: chainId', () => { + expect( + getCapabilitiesQueryOptions(config, { + account: '0x0000000000000000000000000000000000000000', + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "capabilities", + { + "account": "0x0000000000000000000000000000000000000000", + }, + ], + "retry": [Function], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/getCapabilities.ts b/wagmi-project/packages/core/src/query/getCapabilities.ts new file mode 100644 index 000000000..754b77b55 --- /dev/null +++ b/wagmi-project/packages/core/src/query/getCapabilities.ts @@ -0,0 +1,65 @@ +import type { QueryOptions } from '@tanstack/query-core' + +import { + type GetCapabilitiesErrorType, + type GetCapabilitiesParameters, + type GetCapabilitiesReturnType, + getCapabilities, +} from '../actions/getCapabilities.js' +import type { Config } from '../createConfig.js' +import { ConnectorNotConnectedError } from '../errors/config.js' +import { filterQueryOptions } from '../query/utils.js' +import type { ScopeKeyParameter } from '../types/properties.js' +import type { Compute, ExactPartial } from '../types/utils.js' + +export type GetCapabilitiesOptions< + config extends Config = Config, + chainId extends config['chains'][number]['id'] | undefined = undefined, +> = Compute< + ExactPartial> & ScopeKeyParameter +> + +export function getCapabilitiesQueryOptions< + config extends Config, + chainId extends config['chains'][number]['id'] | undefined = undefined, +>(config: config, options: GetCapabilitiesOptions = {}) { + return { + async queryFn({ queryKey }) { + const { scopeKey: _, ...parameters } = queryKey[1] + const capabilities = await getCapabilities(config, parameters) + return capabilities + }, + queryKey: getCapabilitiesQueryKey(options), + retry(failureCount, error) { + if (error instanceof ConnectorNotConnectedError) return false + return failureCount < 3 + }, + } as const satisfies QueryOptions< + GetCapabilitiesQueryFnData, + GetCapabilitiesErrorType, + GetCapabilitiesData, + GetCapabilitiesQueryKey + > +} + +export type GetCapabilitiesQueryFnData< + config extends Config = Config, + chainId extends config['chains'][number]['id'] | undefined = undefined, +> = GetCapabilitiesReturnType + +export type GetCapabilitiesData< + config extends Config = Config, + chainId extends config['chains'][number]['id'] | undefined = undefined, +> = GetCapabilitiesQueryFnData + +export function getCapabilitiesQueryKey< + config extends Config, + chainId extends config['chains'][number]['id'] | undefined = undefined, +>(options: GetCapabilitiesOptions = {}) { + return ['capabilities', filterQueryOptions(options)] as const +} + +export type GetCapabilitiesQueryKey< + config extends Config, + chainId extends config['chains'][number]['id'] | undefined = undefined, +> = ReturnType> diff --git a/wagmi-project/packages/core/src/query/getConnectorClient.test.ts b/wagmi-project/packages/core/src/query/getConnectorClient.test.ts new file mode 100644 index 000000000..fdec57969 --- /dev/null +++ b/wagmi-project/packages/core/src/query/getConnectorClient.test.ts @@ -0,0 +1,37 @@ +import { chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getConnectorClientQueryOptions } from './getConnectorClient.js' + +test('default', () => { + expect(getConnectorClientQueryOptions(config)).toMatchInlineSnapshot(` + { + "gcTime": 0, + "queryFn": [Function], + "queryKey": [ + "connectorClient", + { + "connectorUid": undefined, + }, + ], + } + `) +}) + +test('parameters: chainId', () => { + expect( + getConnectorClientQueryOptions(config, { chainId: chain.mainnet.id }), + ).toMatchInlineSnapshot(` + { + "gcTime": 0, + "queryFn": [Function], + "queryKey": [ + "connectorClient", + { + "chainId": 1, + "connectorUid": undefined, + }, + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/getConnectorClient.ts b/wagmi-project/packages/core/src/query/getConnectorClient.ts new file mode 100644 index 000000000..7bc65029f --- /dev/null +++ b/wagmi-project/packages/core/src/query/getConnectorClient.ts @@ -0,0 +1,69 @@ +import type { QueryOptions } from '@tanstack/query-core' + +import { + type GetConnectorClientErrorType, + type GetConnectorClientParameters, + type GetConnectorClientReturnType, + getConnectorClient, +} from '../actions/getConnectorClient.js' +import type { Config } from '../createConfig.js' +import type { ScopeKeyParameter } from '../types/properties.js' +import type { Compute, ExactPartial } from '../types/utils.js' +import { filterQueryOptions } from './utils.js' + +export type GetConnectorClientOptions< + config extends Config, + chainId extends config['chains'][number]['id'], +> = Compute< + ExactPartial> & + ScopeKeyParameter +> + +export function getConnectorClientQueryOptions< + config extends Config, + chainId extends config['chains'][number]['id'], +>(config: config, options: GetConnectorClientOptions = {}) { + return { + gcTime: 0, + async queryFn({ queryKey }) { + const { connector } = options + const { connectorUid: _, scopeKey: _s, ...parameters } = queryKey[1] + return getConnectorClient(config, { + ...parameters, + connector, + }) as unknown as Promise> + }, + queryKey: getConnectorClientQueryKey(options), + } as const satisfies QueryOptions< + GetConnectorClientQueryFnData, + GetConnectorClientErrorType, + GetConnectorClientData, + GetConnectorClientQueryKey + > +} + +export type GetConnectorClientQueryFnData< + config extends Config, + chainId extends config['chains'][number]['id'], +> = GetConnectorClientReturnType + +export type GetConnectorClientData< + config extends Config, + chainId extends config['chains'][number]['id'], +> = GetConnectorClientQueryFnData + +export function getConnectorClientQueryKey< + config extends Config, + chainId extends config['chains'][number]['id'], +>(options: GetConnectorClientOptions = {}) { + const { connector, ...parameters } = options + return [ + 'connectorClient', + { ...filterQueryOptions(parameters), connectorUid: connector?.uid }, + ] as const +} + +export type GetConnectorClientQueryKey< + config extends Config, + chainId extends config['chains'][number]['id'], +> = ReturnType> diff --git a/wagmi-project/packages/core/src/query/getEnsAddress.test.ts b/wagmi-project/packages/core/src/query/getEnsAddress.test.ts new file mode 100644 index 000000000..0e88461e6 --- /dev/null +++ b/wagmi-project/packages/core/src/query/getEnsAddress.test.ts @@ -0,0 +1,32 @@ +import { chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getEnsAddressQueryOptions } from './getEnsAddress.js' + +test('default', () => { + expect(getEnsAddressQueryOptions(config)).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "ensAddress", + {}, + ], + } + `) +}) + +test('parameters: chainId', () => { + expect( + getEnsAddressQueryOptions(config, { chainId: chain.mainnet.id }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "ensAddress", + { + "chainId": 1, + }, + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/getEnsAddress.ts b/wagmi-project/packages/core/src/query/getEnsAddress.ts new file mode 100644 index 000000000..7f18c9dd6 --- /dev/null +++ b/wagmi-project/packages/core/src/query/getEnsAddress.ts @@ -0,0 +1,49 @@ +import type { QueryOptions } from '@tanstack/query-core' + +import { + type GetEnsAddressErrorType, + type GetEnsAddressParameters, + type GetEnsAddressReturnType, + getEnsAddress, +} from '../actions/getEnsAddress.js' +import type { Config } from '../createConfig.js' +import type { ScopeKeyParameter } from '../types/properties.js' +import type { Compute, ExactPartial } from '../types/utils.js' +import { filterQueryOptions } from './utils.js' + +export type GetEnsAddressOptions = Compute< + ExactPartial> & ScopeKeyParameter +> + +export function getEnsAddressQueryOptions( + config: config, + options: GetEnsAddressOptions = {}, +) { + return { + async queryFn({ queryKey }) { + const { name, scopeKey: _, ...parameters } = queryKey[1] + if (!name) throw new Error('name is required') + return getEnsAddress(config, { ...parameters, name }) + }, + queryKey: getEnsAddressQueryKey(options), + } as const satisfies QueryOptions< + GetEnsAddressQueryFnData, + GetEnsAddressErrorType, + GetEnsAddressData, + GetEnsAddressQueryKey + > +} + +export type GetEnsAddressQueryFnData = GetEnsAddressReturnType + +export type GetEnsAddressData = GetEnsAddressQueryFnData + +export function getEnsAddressQueryKey( + options: GetEnsAddressOptions = {}, +) { + return ['ensAddress', filterQueryOptions(options)] as const +} + +export type GetEnsAddressQueryKey = ReturnType< + typeof getEnsAddressQueryKey +> diff --git a/wagmi-project/packages/core/src/query/getEnsAvatar.test.ts b/wagmi-project/packages/core/src/query/getEnsAvatar.test.ts new file mode 100644 index 000000000..8b6252642 --- /dev/null +++ b/wagmi-project/packages/core/src/query/getEnsAvatar.test.ts @@ -0,0 +1,32 @@ +import { chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getEnsAvatarQueryOptions } from './getEnsAvatar.js' + +test('default', () => { + expect(getEnsAvatarQueryOptions(config)).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "ensAvatar", + {}, + ], + } + `) +}) + +test('parameters: chainId', () => { + expect( + getEnsAvatarQueryOptions(config, { chainId: chain.mainnet.id }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "ensAvatar", + { + "chainId": 1, + }, + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/getEnsAvatar.ts b/wagmi-project/packages/core/src/query/getEnsAvatar.ts new file mode 100644 index 000000000..f399736e0 --- /dev/null +++ b/wagmi-project/packages/core/src/query/getEnsAvatar.ts @@ -0,0 +1,49 @@ +import type { QueryOptions } from '@tanstack/query-core' + +import { + type GetEnsAvatarErrorType, + type GetEnsAvatarParameters, + type GetEnsAvatarReturnType, + getEnsAvatar, +} from '../actions/getEnsAvatar.js' +import type { Config } from '../createConfig.js' +import type { ScopeKeyParameter } from '../types/properties.js' +import type { Compute, ExactPartial } from '../types/utils.js' +import { filterQueryOptions } from './utils.js' + +export type GetEnsAvatarOptions = Compute< + ExactPartial> & ScopeKeyParameter +> + +export function getEnsAvatarQueryOptions( + config: config, + options: GetEnsAvatarOptions = {}, +) { + return { + async queryFn({ queryKey }) { + const { name, scopeKey: _, ...parameters } = queryKey[1] + if (!name) throw new Error('name is required') + return getEnsAvatar(config, { ...parameters, name }) + }, + queryKey: getEnsAvatarQueryKey(options), + } as const satisfies QueryOptions< + GetEnsAvatarQueryFnData, + GetEnsAvatarErrorType, + GetEnsAvatarData, + GetEnsAvatarQueryKey + > +} + +export type GetEnsAvatarQueryFnData = GetEnsAvatarReturnType + +export type GetEnsAvatarData = GetEnsAvatarQueryFnData + +export function getEnsAvatarQueryKey( + options: GetEnsAvatarOptions = {}, +) { + return ['ensAvatar', filterQueryOptions(options)] as const +} + +export type GetEnsAvatarQueryKey = ReturnType< + typeof getEnsAvatarQueryKey +> diff --git a/wagmi-project/packages/core/src/query/getEnsName.test.ts b/wagmi-project/packages/core/src/query/getEnsName.test.ts new file mode 100644 index 000000000..006c76a12 --- /dev/null +++ b/wagmi-project/packages/core/src/query/getEnsName.test.ts @@ -0,0 +1,32 @@ +import { chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getEnsNameQueryOptions } from './getEnsName.js' + +test('default', () => { + expect(getEnsNameQueryOptions(config)).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "ensName", + {}, + ], + } + `) +}) + +test('parameters: chainId', () => { + expect( + getEnsNameQueryOptions(config, { chainId: chain.mainnet.id }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "ensName", + { + "chainId": 1, + }, + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/getEnsName.ts b/wagmi-project/packages/core/src/query/getEnsName.ts new file mode 100644 index 000000000..cff1534e0 --- /dev/null +++ b/wagmi-project/packages/core/src/query/getEnsName.ts @@ -0,0 +1,49 @@ +import type { QueryOptions } from '@tanstack/query-core' + +import { + type GetEnsNameErrorType, + type GetEnsNameParameters, + type GetEnsNameReturnType, + getEnsName, +} from '../actions/getEnsName.js' +import type { Config } from '../createConfig.js' +import type { ScopeKeyParameter } from '../types/properties.js' +import type { Compute, ExactPartial } from '../types/utils.js' +import { filterQueryOptions } from './utils.js' + +export type GetEnsNameOptions = Compute< + ExactPartial> & ScopeKeyParameter +> + +export function getEnsNameQueryOptions( + config: config, + options: GetEnsNameOptions = {}, +) { + return { + async queryFn({ queryKey }) { + const { address, scopeKey: _, ...parameters } = queryKey[1] + if (!address) throw new Error('address is required') + return getEnsName(config, { ...parameters, address }) + }, + queryKey: getEnsNameQueryKey(options), + } as const satisfies QueryOptions< + GetEnsNameQueryFnData, + GetEnsNameErrorType, + GetEnsNameData, + GetEnsNameQueryKey + > +} + +export type GetEnsNameQueryFnData = GetEnsNameReturnType + +export type GetEnsNameData = GetEnsNameQueryFnData + +export function getEnsNameQueryKey( + options: GetEnsNameOptions = {}, +) { + return ['ensName', filterQueryOptions(options)] as const +} + +export type GetEnsNameQueryKey = ReturnType< + typeof getEnsNameQueryKey +> diff --git a/wagmi-project/packages/core/src/query/getEnsResolver.test.ts b/wagmi-project/packages/core/src/query/getEnsResolver.test.ts new file mode 100644 index 000000000..36baf9ba9 --- /dev/null +++ b/wagmi-project/packages/core/src/query/getEnsResolver.test.ts @@ -0,0 +1,32 @@ +import { chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getEnsResolverQueryOptions } from './getEnsResolver.js' + +test('default', () => { + expect(getEnsResolverQueryOptions(config)).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "ensResolver", + {}, + ], + } + `) +}) + +test('parameters: chainId', () => { + expect( + getEnsResolverQueryOptions(config, { chainId: chain.mainnet.id }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "ensResolver", + { + "chainId": 1, + }, + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/getEnsResolver.ts b/wagmi-project/packages/core/src/query/getEnsResolver.ts new file mode 100644 index 000000000..124499325 --- /dev/null +++ b/wagmi-project/packages/core/src/query/getEnsResolver.ts @@ -0,0 +1,49 @@ +import type { QueryOptions } from '@tanstack/query-core' + +import { + type GetEnsResolverErrorType, + type GetEnsResolverParameters, + type GetEnsResolverReturnType, + getEnsResolver, +} from '../actions/getEnsResolver.js' +import type { Config } from '../createConfig.js' +import type { ScopeKeyParameter } from '../types/properties.js' +import type { Compute, ExactPartial } from '../types/utils.js' +import { filterQueryOptions } from './utils.js' + +export type GetEnsResolverOptions = Compute< + ExactPartial> & ScopeKeyParameter +> + +export function getEnsResolverQueryOptions( + config: config, + options: GetEnsResolverOptions = {}, +) { + return { + async queryFn({ queryKey }) { + const { name, scopeKey: _, ...parameters } = queryKey[1] + if (!name) throw new Error('name is required') + return getEnsResolver(config, { ...parameters, name }) + }, + queryKey: getEnsResolverQueryKey(options), + } as const satisfies QueryOptions< + GetEnsResolverQueryFnData, + GetEnsResolverErrorType, + GetEnsResolverData, + GetEnsResolverQueryKey + > +} + +export type GetEnsResolverQueryFnData = GetEnsResolverReturnType + +export type GetEnsResolverData = GetEnsResolverQueryFnData + +export function getEnsResolverQueryKey( + options: GetEnsResolverOptions = {}, +) { + return ['ensResolver', filterQueryOptions(options)] as const +} + +export type GetEnsResolverQueryKey = ReturnType< + typeof getEnsResolverQueryKey +> diff --git a/wagmi-project/packages/core/src/query/getEnsText.test.ts b/wagmi-project/packages/core/src/query/getEnsText.test.ts new file mode 100644 index 000000000..137041063 --- /dev/null +++ b/wagmi-project/packages/core/src/query/getEnsText.test.ts @@ -0,0 +1,46 @@ +import { chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getEnsTextQueryOptions } from './getEnsText.js' + +test('default', () => { + expect( + getEnsTextQueryOptions(config, { + name: 'wevm.eth', + key: 'com.twitter', + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "ensText", + { + "key": "com.twitter", + "name": "wevm.eth", + }, + ], + } + `) +}) + +test('parameters: chainId', () => { + expect( + getEnsTextQueryOptions(config, { + chainId: chain.mainnet.id, + name: 'wevm.eth', + key: 'com.twitter', + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "ensText", + { + "chainId": 1, + "key": "com.twitter", + "name": "wevm.eth", + }, + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/getEnsText.ts b/wagmi-project/packages/core/src/query/getEnsText.ts new file mode 100644 index 000000000..2f1c464de --- /dev/null +++ b/wagmi-project/packages/core/src/query/getEnsText.ts @@ -0,0 +1,49 @@ +import type { QueryOptions } from '@tanstack/query-core' + +import { + type GetEnsTextErrorType, + type GetEnsTextParameters, + type GetEnsTextReturnType, + getEnsText, +} from '../actions/getEnsText.js' +import type { Config } from '../createConfig.js' +import type { ScopeKeyParameter } from '../types/properties.js' +import type { Compute, ExactPartial } from '../types/utils.js' +import { filterQueryOptions } from './utils.js' + +export type GetEnsTextOptions = Compute< + ExactPartial> & ScopeKeyParameter +> + +export function getEnsTextQueryOptions( + config: config, + options: GetEnsTextOptions = {}, +) { + return { + async queryFn({ queryKey }) { + const { key, name, scopeKey: _, ...parameters } = queryKey[1] + if (!key || !name) throw new Error('key and name are required') + return getEnsText(config, { ...parameters, key, name }) + }, + queryKey: getEnsTextQueryKey(options), + } as const satisfies QueryOptions< + GetEnsTextQueryFnData, + GetEnsTextErrorType, + GetEnsTextData, + GetEnsTextQueryKey + > +} + +export type GetEnsTextQueryFnData = GetEnsTextReturnType + +export type GetEnsTextData = GetEnsTextQueryFnData + +export function getEnsTextQueryKey( + options: GetEnsTextOptions = {}, +) { + return ['ensText', filterQueryOptions(options)] as const +} + +export type GetEnsTextQueryKey = ReturnType< + typeof getEnsTextQueryKey +> diff --git a/wagmi-project/packages/core/src/query/getFeeHistory.test.ts b/wagmi-project/packages/core/src/query/getFeeHistory.test.ts new file mode 100644 index 000000000..aa4079323 --- /dev/null +++ b/wagmi-project/packages/core/src/query/getFeeHistory.test.ts @@ -0,0 +1,128 @@ +import { chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getFeeHistoryQueryOptions } from './getFeeHistory.js' + +test('default', async () => { + expect( + getFeeHistoryQueryOptions(config, { + blockCount: 4, + rewardPercentiles: [25, 75], + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "feeHistory", + { + "blockCount": 4, + "rewardPercentiles": [ + 25, + 75, + ], + }, + ], + } + `) +}) + +test('parameters: chainId', async () => { + expect( + getFeeHistoryQueryOptions(config, { + blockCount: 4, + rewardPercentiles: [25, 75], + chainId: chain.mainnet2.id, + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "feeHistory", + { + "blockCount": 4, + "chainId": 456, + "rewardPercentiles": [ + 25, + 75, + ], + }, + ], + } + `) +}) + +test('parameters: blockNumber', async () => { + expect( + getFeeHistoryQueryOptions(config, { + blockCount: 4, + rewardPercentiles: [25, 75], + blockNumber: 18677379n, + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "feeHistory", + { + "blockCount": 4, + "blockNumber": 18677379n, + "rewardPercentiles": [ + 25, + 75, + ], + }, + ], + } + `) +}) + +test('parameters: blockTag', async () => { + expect( + getFeeHistoryQueryOptions(config, { + blockCount: 4, + rewardPercentiles: [25, 75], + blockTag: 'safe', + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "feeHistory", + { + "blockCount": 4, + "blockTag": "safe", + "rewardPercentiles": [ + 25, + 75, + ], + }, + ], + } + `) +}) + +test('behavior: blockCount is required', async () => { + const options = getFeeHistoryQueryOptions(config, {}) + expect( + options.queryFn({ + queryKey: options.queryKey, + signal: new AbortSignal(), + meta: undefined, + }), + ).rejects.toThrowErrorMatchingInlineSnapshot( + '[Error: blockCount is required]', + ) +}) + +test('behavior: rewardPercentiles is required', async () => { + const options = getFeeHistoryQueryOptions(config, { blockCount: 4 }) + expect( + options.queryFn({ + queryKey: options.queryKey, + signal: new AbortSignal(), + meta: undefined, + }), + ).rejects.toThrowErrorMatchingInlineSnapshot( + '[Error: rewardPercentiles is required]', + ) +}) diff --git a/wagmi-project/packages/core/src/query/getFeeHistory.ts b/wagmi-project/packages/core/src/query/getFeeHistory.ts new file mode 100644 index 000000000..6eeef0d68 --- /dev/null +++ b/wagmi-project/packages/core/src/query/getFeeHistory.ts @@ -0,0 +1,69 @@ +import type { QueryOptions } from '@tanstack/query-core' + +import { + type GetFeeHistoryErrorType, + type GetFeeHistoryParameters, + type GetFeeHistoryReturnType, + getFeeHistory, +} from '../actions/getFeeHistory.js' +import type { Config } from '../createConfig.js' +import type { ScopeKeyParameter } from '../types/properties.js' +import type { Compute, PartialBy } from '../types/utils.js' +import { filterQueryOptions } from './utils.js' + +export type GetFeeHistoryOptions< + config extends Config, + chainId extends config['chains'][number]['id'], +> = Compute< + PartialBy< + GetFeeHistoryParameters, + 'blockCount' | 'rewardPercentiles' + > & + ScopeKeyParameter +> + +export function getFeeHistoryQueryOptions< + config extends Config, + chainId extends config['chains'][number]['id'], +>(config: config, options: GetFeeHistoryOptions = {}) { + return { + async queryFn({ queryKey }) { + const { + blockCount, + rewardPercentiles, + scopeKey: _, + ...parameters + } = queryKey[1] + if (!blockCount) throw new Error('blockCount is required') + if (!rewardPercentiles) throw new Error('rewardPercentiles is required') + const feeHistory = await getFeeHistory(config, { + ...(parameters as GetFeeHistoryParameters), + blockCount, + rewardPercentiles, + }) + return feeHistory ?? null + }, + queryKey: getFeeHistoryQueryKey(options), + } as const satisfies QueryOptions< + GetFeeHistoryQueryFnData, + GetFeeHistoryErrorType, + GetFeeHistoryData, + GetFeeHistoryQueryKey + > +} + +export type GetFeeHistoryQueryFnData = GetFeeHistoryReturnType + +export type GetFeeHistoryData = GetFeeHistoryQueryFnData + +export function getFeeHistoryQueryKey< + config extends Config, + chainId extends config['chains'][number]['id'], +>(options: GetFeeHistoryOptions = {}) { + return ['feeHistory', filterQueryOptions(options)] as const +} + +export type GetFeeHistoryQueryKey< + config extends Config, + chainId extends config['chains'][number]['id'], +> = ReturnType> diff --git a/wagmi-project/packages/core/src/query/getGasPrice.test.ts b/wagmi-project/packages/core/src/query/getGasPrice.test.ts new file mode 100644 index 000000000..2b9030366 --- /dev/null +++ b/wagmi-project/packages/core/src/query/getGasPrice.test.ts @@ -0,0 +1,32 @@ +import { chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getGasPriceQueryOptions } from './getGasPrice.js' + +test('default', () => { + expect(getGasPriceQueryOptions(config)).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "gasPrice", + {}, + ], + } + `) +}) + +test('parameters: chainId', () => { + expect( + getGasPriceQueryOptions(config, { chainId: chain.mainnet.id }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "gasPrice", + { + "chainId": 1, + }, + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/getGasPrice.ts b/wagmi-project/packages/core/src/query/getGasPrice.ts new file mode 100644 index 000000000..153d4a102 --- /dev/null +++ b/wagmi-project/packages/core/src/query/getGasPrice.ts @@ -0,0 +1,54 @@ +import type { QueryOptions } from '@tanstack/query-core' + +import { + type GetGasPriceErrorType, + type GetGasPriceParameters, + type GetGasPriceReturnType, + getGasPrice, +} from '../actions/getGasPrice.js' +import type { Config } from '../createConfig.js' +import type { ScopeKeyParameter } from '../types/properties.js' +import type { Compute, ExactPartial } from '../types/utils.js' +import { filterQueryOptions } from './utils.js' + +export type GetGasPriceOptions< + config extends Config, + chainId extends config['chains'][number]['id'], +> = Compute< + ExactPartial> & ScopeKeyParameter +> + +export function getGasPriceQueryOptions< + config extends Config, + chainId extends config['chains'][number]['id'], +>(config: config, options: GetGasPriceOptions = {}) { + return { + async queryFn({ queryKey }) { + const { scopeKey: _, ...parameters } = queryKey[1] + const gasPrice = await getGasPrice(config, parameters) + return gasPrice ?? null + }, + queryKey: getGasPriceQueryKey(options), + } as const satisfies QueryOptions< + GetGasPriceQueryFnData, + GetGasPriceErrorType, + GetGasPriceData, + GetGasPriceQueryKey + > +} + +export type GetGasPriceQueryFnData = GetGasPriceReturnType + +export type GetGasPriceData = GetGasPriceQueryFnData + +export function getGasPriceQueryKey< + config extends Config, + chainId extends config['chains'][number]['id'], +>(options: GetGasPriceOptions = {}) { + return ['gasPrice', filterQueryOptions(options)] as const +} + +export type GetGasPriceQueryKey< + config extends Config, + chainId extends config['chains'][number]['id'], +> = ReturnType> diff --git a/wagmi-project/packages/core/src/query/getProof.test.ts b/wagmi-project/packages/core/src/query/getProof.test.ts new file mode 100644 index 000000000..30c02256c --- /dev/null +++ b/wagmi-project/packages/core/src/query/getProof.test.ts @@ -0,0 +1,106 @@ +import { chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getProofQueryOptions } from './getProof.js' + +test('default', () => { + expect( + getProofQueryOptions(config, { + address: '0x4200000000000000000000000000000000000016', + storageKeys: [ + '0x4a932049252365b3eedbc5190e18949f2ec11f39d3bef2d259764799a1b27d99', + ], + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "getProof", + { + "address": "0x4200000000000000000000000000000000000016", + "storageKeys": [ + "0x4a932049252365b3eedbc5190e18949f2ec11f39d3bef2d259764799a1b27d99", + ], + }, + ], + } + `) +}) + +test('parameters: blockNumber', () => { + expect( + getProofQueryOptions(config, { + address: '0x4200000000000000000000000000000000000016', + blockNumber: 1234567890n, + storageKeys: [ + '0x4a932049252365b3eedbc5190e18949f2ec11f39d3bef2d259764799a1b27d99', + ], + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "getProof", + { + "address": "0x4200000000000000000000000000000000000016", + "blockNumber": 1234567890n, + "storageKeys": [ + "0x4a932049252365b3eedbc5190e18949f2ec11f39d3bef2d259764799a1b27d99", + ], + }, + ], + } + `) +}) + +test('parameters: blockTag', () => { + expect( + getProofQueryOptions(config, { + address: '0x4200000000000000000000000000000000000016', + blockTag: 'safe', + storageKeys: [ + '0x4a932049252365b3eedbc5190e18949f2ec11f39d3bef2d259764799a1b27d99', + ], + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "getProof", + { + "address": "0x4200000000000000000000000000000000000016", + "blockTag": "safe", + "storageKeys": [ + "0x4a932049252365b3eedbc5190e18949f2ec11f39d3bef2d259764799a1b27d99", + ], + }, + ], + } + `) +}) + +test('parameters: chainId', () => { + expect( + getProofQueryOptions(config, { + address: '0x4200000000000000000000000000000000000016', + chainId: chain.mainnet2.id, + storageKeys: [ + '0x4a932049252365b3eedbc5190e18949f2ec11f39d3bef2d259764799a1b27d99', + ], + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "getProof", + { + "address": "0x4200000000000000000000000000000000000016", + "chainId": 456, + "storageKeys": [ + "0x4a932049252365b3eedbc5190e18949f2ec11f39d3bef2d259764799a1b27d99", + ], + }, + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/getProof.ts b/wagmi-project/packages/core/src/query/getProof.ts new file mode 100644 index 000000000..8da0b42b1 --- /dev/null +++ b/wagmi-project/packages/core/src/query/getProof.ts @@ -0,0 +1,50 @@ +import type { QueryOptions } from '@tanstack/query-core' + +import { + type GetProofErrorType, + type GetProofParameters, + type GetProofReturnType, + getProof, +} from '../actions/getProof.js' +import type { Config } from '../createConfig.js' +import type { ScopeKeyParameter } from '../types/properties.js' +import type { Compute, ExactPartial } from '../types/utils.js' +import { filterQueryOptions } from './utils.js' + +export type GetProofOptions = Compute< + ExactPartial> & ScopeKeyParameter +> + +export function getProofQueryOptions( + config: config, + options: GetProofOptions = {}, +) { + return { + async queryFn({ queryKey }) { + const { address, scopeKey: _, storageKeys, ...parameters } = queryKey[1] + if (!address || !storageKeys) + throw new Error('address and storageKeys are required') + return getProof(config, { ...parameters, address, storageKeys }) + }, + queryKey: getProofQueryKey(options), + } as const satisfies QueryOptions< + GetProofQueryFnData, + GetProofErrorType, + GetProofData, + GetProofQueryKey + > +} + +export type GetProofQueryFnData = GetProofReturnType + +export type GetProofData = GetProofQueryFnData + +export function getProofQueryKey( + options: GetProofOptions, +) { + return ['getProof', filterQueryOptions(options)] as const +} + +export type GetProofQueryKey = ReturnType< + typeof getProofQueryKey +> diff --git a/wagmi-project/packages/core/src/query/getStorageAt.test.ts b/wagmi-project/packages/core/src/query/getStorageAt.test.ts new file mode 100644 index 000000000..87193c1e6 --- /dev/null +++ b/wagmi-project/packages/core/src/query/getStorageAt.test.ts @@ -0,0 +1,90 @@ +import { address, chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getStorageAtQueryOptions } from './getStorageAt.js' + +test('default', () => { + expect( + getStorageAtQueryOptions(config, { + address: address.wagmiMintExample, + slot: '0x0', + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "getStorageAt", + { + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "slot": "0x0", + }, + ], + } + `) +}) + +test('parameters: blockNumber', () => { + expect( + getStorageAtQueryOptions(config, { + address: address.wagmiMintExample, + blockNumber: 16280770n, + slot: '0x0', + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "getStorageAt", + { + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "blockNumber": 16280770n, + "slot": "0x0", + }, + ], + } + `) +}) + +test('parameters: blockTag', () => { + expect( + getStorageAtQueryOptions(config, { + address: address.wagmiMintExample, + blockTag: 'safe', + slot: '0x0', + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "getStorageAt", + { + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "blockTag": "safe", + "slot": "0x0", + }, + ], + } + `) +}) + +test('parameters: chainId', () => { + expect( + getStorageAtQueryOptions(config, { + address: address.wagmiMintExample, + chainId: chain.mainnet2.id, + slot: '0x0', + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "getStorageAt", + { + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "chainId": 456, + "slot": "0x0", + }, + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/getStorageAt.ts b/wagmi-project/packages/core/src/query/getStorageAt.ts new file mode 100644 index 000000000..c2ed90c92 --- /dev/null +++ b/wagmi-project/packages/core/src/query/getStorageAt.ts @@ -0,0 +1,49 @@ +import type { QueryOptions } from '@tanstack/query-core' + +import { + type GetStorageAtErrorType, + type GetStorageAtParameters, + type GetStorageAtReturnType, + getStorageAt, +} from '../actions/getStorageAt.js' +import type { Config } from '../createConfig.js' +import type { ScopeKeyParameter } from '../types/properties.js' +import type { Compute, ExactPartial } from '../types/utils.js' +import { filterQueryOptions } from './utils.js' + +export type GetStorageAtOptions = Compute< + ExactPartial> & ScopeKeyParameter +> + +export function getStorageAtQueryOptions( + config: config, + options: GetStorageAtOptions = {}, +) { + return { + queryFn({ queryKey }) { + const { address, slot, scopeKey: _, ...parameters } = queryKey[1] + if (!address || !slot) throw new Error('address and slot are required') + return getStorageAt(config, { ...parameters, address, slot }) + }, + queryKey: getStorageAtQueryKey(options), + } as const satisfies QueryOptions< + GetStorageAtQueryFnData, + GetStorageAtErrorType, + GetStorageAtData, + GetStorageAtQueryKey + > +} + +export type GetStorageAtQueryFnData = GetStorageAtReturnType + +export type GetStorageAtData = GetStorageAtQueryFnData + +export function getStorageAtQueryKey( + options: GetStorageAtOptions, +) { + return ['getStorageAt', filterQueryOptions(options)] as const +} + +export type GetStorageAtQueryKey = ReturnType< + typeof getStorageAtQueryKey +> diff --git a/wagmi-project/packages/core/src/query/getToken.test.ts b/wagmi-project/packages/core/src/query/getToken.test.ts new file mode 100644 index 000000000..87ec1731c --- /dev/null +++ b/wagmi-project/packages/core/src/query/getToken.test.ts @@ -0,0 +1,32 @@ +import { chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getTokenQueryOptions } from './getToken.js' + +test('default', () => { + expect(getTokenQueryOptions(config)).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "token", + {}, + ], + } + `) +}) + +test('parameters: chainId', () => { + expect( + getTokenQueryOptions(config, { chainId: chain.mainnet.id }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "token", + { + "chainId": 1, + }, + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/getToken.ts b/wagmi-project/packages/core/src/query/getToken.ts new file mode 100644 index 000000000..8e4a2b866 --- /dev/null +++ b/wagmi-project/packages/core/src/query/getToken.ts @@ -0,0 +1,49 @@ +import type { QueryOptions } from '@tanstack/query-core' + +import { + type GetTokenErrorType, + type GetTokenParameters, + type GetTokenReturnType, + getToken, +} from '../actions/getToken.js' +import type { Config } from '../createConfig.js' +import type { ScopeKeyParameter } from '../types/properties.js' +import type { Compute, ExactPartial } from '../types/utils.js' +import { filterQueryOptions } from './utils.js' + +export type GetTokenOptions = Compute< + ExactPartial> & ScopeKeyParameter +> + +export function getTokenQueryOptions( + config: config, + options: GetTokenOptions = {}, +) { + return { + async queryFn({ queryKey }) { + const { address, scopeKey: _, ...parameters } = queryKey[1] + if (!address) throw new Error('address is required') + return getToken(config, { ...parameters, address }) + }, + queryKey: getTokenQueryKey(options), + } as const satisfies QueryOptions< + GetTokenQueryFnData, + GetTokenErrorType, + GetTokenData, + GetTokenQueryKey + > +} + +export type GetTokenQueryFnData = GetTokenReturnType + +export type GetTokenData = GetTokenQueryFnData + +export function getTokenQueryKey( + options: GetTokenOptions = {}, +) { + return ['token', filterQueryOptions(options)] as const +} + +export type GetTokenQueryKey = ReturnType< + typeof getTokenQueryKey +> diff --git a/wagmi-project/packages/core/src/query/getTransaction.test.ts b/wagmi-project/packages/core/src/query/getTransaction.test.ts new file mode 100644 index 000000000..e1db72b32 --- /dev/null +++ b/wagmi-project/packages/core/src/query/getTransaction.test.ts @@ -0,0 +1,32 @@ +import { chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getTransactionQueryOptions } from './getTransaction.js' + +test('default', () => { + expect(getTransactionQueryOptions(config)).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "transaction", + {}, + ], + } + `) +}) + +test('parameters: chainId', () => { + expect( + getTransactionQueryOptions(config, { chainId: chain.mainnet.id }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "transaction", + { + "chainId": 1, + }, + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/getTransaction.ts b/wagmi-project/packages/core/src/query/getTransaction.ts new file mode 100644 index 000000000..856485477 --- /dev/null +++ b/wagmi-project/packages/core/src/query/getTransaction.ts @@ -0,0 +1,69 @@ +import type { QueryOptions } from '@tanstack/query-core' + +import { + type GetTransactionErrorType, + type GetTransactionParameters, + type GetTransactionReturnType, + getTransaction, +} from '../actions/getTransaction.js' +import type { Config } from '../createConfig.js' +import type { ScopeKeyParameter } from '../types/properties.js' +import type { Compute, ExactPartial } from '../types/utils.js' +import { filterQueryOptions } from './utils.js' + +export type GetTransactionOptions< + config extends Config, + chainId extends config['chains'][number]['id'], +> = Compute< + ExactPartial> & ScopeKeyParameter +> + +export function getTransactionQueryOptions< + config extends Config, + chainId extends config['chains'][number]['id'], +>(config: config, options: GetTransactionOptions = {}) { + return { + async queryFn({ queryKey }) { + const { blockHash, blockNumber, blockTag, hash, index } = queryKey[1] + if (!blockHash && !blockNumber && !blockTag && !hash) + throw new Error('blockHash, blockNumber, blockTag, or hash is required') + if (!hash && !index) + throw new Error( + 'index is required for blockHash, blockNumber, or blockTag', + ) + const { scopeKey: _, ...rest } = queryKey[1] + return getTransaction( + config, + rest as GetTransactionParameters, + ) as unknown as Promise> + }, + queryKey: getTransactionQueryKey(options), + } as const satisfies QueryOptions< + GetTransactionQueryFnData, + GetTransactionErrorType, + GetTransactionData, + GetTransactionQueryKey + > +} + +export type GetTransactionQueryFnData< + config extends Config, + chainId extends config['chains'][number]['id'], +> = GetTransactionReturnType + +export type GetTransactionData< + config extends Config, + chainId extends config['chains'][number]['id'], +> = GetTransactionQueryFnData + +export function getTransactionQueryKey< + config extends Config, + chainId extends config['chains'][number]['id'], +>(options: GetTransactionOptions = {}) { + return ['transaction', filterQueryOptions(options)] as const +} + +export type GetTransactionQueryKey< + config extends Config, + chainId extends config['chains'][number]['id'], +> = ReturnType> diff --git a/wagmi-project/packages/core/src/query/getTransactionConfirmations.test.ts b/wagmi-project/packages/core/src/query/getTransactionConfirmations.test.ts new file mode 100644 index 000000000..ac4d6d4f4 --- /dev/null +++ b/wagmi-project/packages/core/src/query/getTransactionConfirmations.test.ts @@ -0,0 +1,42 @@ +import { chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getTransactionConfirmationsQueryOptions } from './getTransactionConfirmations.js' + +test('default', () => { + expect( + getTransactionConfirmationsQueryOptions(config, { + hash: '0xa559259bd2d0e8372421e222ff3545f705b5da60005bd787a23c2e68d6d7fefd', + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "transactionConfirmations", + { + "hash": "0xa559259bd2d0e8372421e222ff3545f705b5da60005bd787a23c2e68d6d7fefd", + }, + ], + } + `) +}) + +test('parameters: chainId', () => { + expect( + getTransactionConfirmationsQueryOptions(config, { + chainId: chain.mainnet.id, + hash: '0xa559259bd2d0e8372421e222ff3545f705b5da60005bd787a23c2e68d6d7fefd', + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "transactionConfirmations", + { + "chainId": 1, + "hash": "0xa559259bd2d0e8372421e222ff3545f705b5da60005bd787a23c2e68d6d7fefd", + }, + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/getTransactionConfirmations.ts b/wagmi-project/packages/core/src/query/getTransactionConfirmations.ts new file mode 100644 index 000000000..5c34decf3 --- /dev/null +++ b/wagmi-project/packages/core/src/query/getTransactionConfirmations.ts @@ -0,0 +1,78 @@ +import type { QueryOptions } from '@tanstack/query-core' + +import { + type GetTransactionConfirmationsErrorType, + type GetTransactionConfirmationsParameters, + type GetTransactionConfirmationsReturnType, + getTransactionConfirmations, +} from '../actions/getTransactionConfirmations.js' +import type { Config } from '../createConfig.js' +import type { ScopeKeyParameter } from '../types/properties.js' +import type { UnionExactPartial } from '../types/utils.js' +import { filterQueryOptions } from './utils.js' + +export type GetTransactionConfirmationsOptions< + config extends Config, + chainId extends + | config['chains'][number]['id'] + | undefined = config['chains'][number]['id'], +> = UnionExactPartial> & + ScopeKeyParameter + +export function getTransactionConfirmationsQueryOptions< + config extends Config, + chainId extends + | config['chains'][number]['id'] + | undefined = config['chains'][number]['id'], +>( + config: config, + options: GetTransactionConfirmationsOptions = {} as any, +) { + return { + async queryFn({ queryKey }) { + const { + hash, + transactionReceipt, + scopeKey: _, + ...parameters + } = queryKey[1] + if (!hash && !transactionReceipt) + throw new Error('hash or transactionReceipt is required') + + const confirmations = await getTransactionConfirmations(config, { + hash, + transactionReceipt, + ...(parameters as any), + }) + return confirmations ?? null + }, + queryKey: getTransactionConfirmationsQueryKey(options), + } as const satisfies QueryOptions< + GetTransactionConfirmationsQueryFnData, + GetTransactionConfirmationsErrorType, + GetTransactionConfirmationsData, + GetTransactionConfirmationsQueryKey + > +} + +export type GetTransactionConfirmationsQueryFnData = + GetTransactionConfirmationsReturnType + +export type GetTransactionConfirmationsData = + GetTransactionConfirmationsQueryFnData + +export function getTransactionConfirmationsQueryKey< + config extends Config, + chainId extends + | config['chains'][number]['id'] + | undefined = config['chains'][number]['id'], +>(options: GetTransactionConfirmationsOptions = {} as any) { + return ['transactionConfirmations', filterQueryOptions(options)] as const +} + +export type GetTransactionConfirmationsQueryKey< + config extends Config, + chainId extends + | config['chains'][number]['id'] + | undefined = config['chains'][number]['id'], +> = ReturnType> diff --git a/wagmi-project/packages/core/src/query/getTransactionCount.test.ts b/wagmi-project/packages/core/src/query/getTransactionCount.test.ts new file mode 100644 index 000000000..666953629 --- /dev/null +++ b/wagmi-project/packages/core/src/query/getTransactionCount.test.ts @@ -0,0 +1,82 @@ +import { accounts, chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getTransactionCountQueryOptions } from './getTransactionCount.js' + +const address = accounts[0] + +test('default', () => { + expect( + getTransactionCountQueryOptions(config, { address }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "transactionCount", + { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + }, + ], + } + `) +}) + +test('parameters: chainId', () => { + expect( + getTransactionCountQueryOptions(config, { + address, + chainId: chain.mainnet.id, + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "transactionCount", + { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "chainId": 1, + }, + ], + } + `) +}) + +test('parameters: blockNumber', () => { + expect( + getTransactionCountQueryOptions(config, { + address, + blockNumber: 13677382n, + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "transactionCount", + { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "blockNumber": 13677382n, + }, + ], + } + `) +}) + +test('parameters: blockTag', () => { + expect( + getTransactionCountQueryOptions(config, { + address, + blockTag: 'earliest', + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "transactionCount", + { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "blockTag": "earliest", + }, + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/getTransactionCount.ts b/wagmi-project/packages/core/src/query/getTransactionCount.ts new file mode 100644 index 000000000..31fd2c1d8 --- /dev/null +++ b/wagmi-project/packages/core/src/query/getTransactionCount.ts @@ -0,0 +1,55 @@ +import type { QueryOptions } from '@tanstack/query-core' + +import { + type GetTransactionCountErrorType, + type GetTransactionCountParameters, + type GetTransactionCountReturnType, + getTransactionCount, +} from '../actions/getTransactionCount.js' +import type { Config } from '../createConfig.js' +import type { ScopeKeyParameter } from '../types/properties.js' +import type { Compute, PartialBy } from '../types/utils.js' +import { filterQueryOptions } from './utils.js' + +export type GetTransactionCountOptions = Compute< + PartialBy, 'address'> & + ScopeKeyParameter +> + +export function getTransactionCountQueryOptions( + config: config, + options: GetTransactionCountOptions = {}, +) { + return { + async queryFn({ queryKey }) { + const { address, scopeKey: _, ...parameters } = queryKey[1] + if (!address) throw new Error('address is required') + const transactionCount = await getTransactionCount(config, { + ...(parameters as GetTransactionCountParameters), + address, + }) + return transactionCount ?? null + }, + queryKey: getTransactionCountQueryKey(options), + } as const satisfies QueryOptions< + GetTransactionCountQueryFnData, + GetTransactionCountErrorType, + GetTransactionCountData, + GetTransactionCountQueryKey + > +} + +export type GetTransactionCountQueryFnData = + Compute + +export type GetTransactionCountData = GetTransactionCountQueryFnData + +export function getTransactionCountQueryKey( + options: GetTransactionCountOptions = {}, +) { + return ['transactionCount', filterQueryOptions(options)] as const +} + +export type GetTransactionCountQueryKey = ReturnType< + typeof getTransactionCountQueryKey +> diff --git a/wagmi-project/packages/core/src/query/getTransactionReceipt.test.ts b/wagmi-project/packages/core/src/query/getTransactionReceipt.test.ts new file mode 100644 index 000000000..7c719b8d8 --- /dev/null +++ b/wagmi-project/packages/core/src/query/getTransactionReceipt.test.ts @@ -0,0 +1,42 @@ +import { chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getTransactionReceiptQueryOptions } from './getTransactionReceipt.js' + +test('default', () => { + expect( + getTransactionReceiptQueryOptions(config, { + hash: '0xbf7d27700d053765c9638d3b9d39eb3c56bfc48377583e8be483d61f9f18a871', + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "getTransactionReceipt", + { + "hash": "0xbf7d27700d053765c9638d3b9d39eb3c56bfc48377583e8be483d61f9f18a871", + }, + ], + } + `) +}) + +test('parameters: chainId', () => { + expect( + getTransactionReceiptQueryOptions(config, { + chainId: chain.mainnet2.id, + hash: '0xbf7d27700d053765c9638d3b9d39eb3c56bfc48377583e8be483d61f9f18a871', + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "getTransactionReceipt", + { + "chainId": 456, + "hash": "0xbf7d27700d053765c9638d3b9d39eb3c56bfc48377583e8be483d61f9f18a871", + }, + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/getTransactionReceipt.ts b/wagmi-project/packages/core/src/query/getTransactionReceipt.ts new file mode 100644 index 000000000..0d7d559d4 --- /dev/null +++ b/wagmi-project/packages/core/src/query/getTransactionReceipt.ts @@ -0,0 +1,60 @@ +import type { QueryOptions } from '@tanstack/query-core' + +import { + type GetTransactionReceiptErrorType, + type GetTransactionReceiptParameters, + getTransactionReceipt, +} from '../actions/getTransactionReceipt.js' +import type { GetTransactionReceiptReturnType } from '../actions/getTransactionReceipt.js' +import type { Config } from '../createConfig.js' +import type { ScopeKeyParameter } from '../types/properties.js' +import type { Compute, ExactPartial } from '../types/utils.js' +import { filterQueryOptions } from './utils.js' + +export type GetTransactionReceiptOptions< + config extends Config, + chainId extends config['chains'][number]['id'], +> = Compute< + ExactPartial> & + ScopeKeyParameter +> + +export function getTransactionReceiptQueryOptions< + config extends Config, + chainId extends config['chains'][number]['id'], +>(config: config, options: GetTransactionReceiptOptions = {}) { + return { + queryFn({ queryKey }) { + const { hash, scopeKey: _, ...parameters } = queryKey[1] + if (!hash) throw new Error('hash is required') + return getTransactionReceipt(config, { ...parameters, hash }) + }, + queryKey: getTransactionReceiptQueryKey(options), + } as const satisfies QueryOptions< + GetTransactionReceiptQueryFnData, + GetTransactionReceiptErrorType, + GetTransactionReceiptData, + GetTransactionReceiptQueryKey + > +} +export type GetTransactionReceiptQueryFnData< + config extends Config, + chainId extends config['chains'][number]['id'], +> = GetTransactionReceiptReturnType + +export type GetTransactionReceiptData< + config extends Config, + chainId extends config['chains'][number]['id'], +> = GetTransactionReceiptQueryFnData + +export function getTransactionReceiptQueryKey< + config extends Config, + chainId extends config['chains'][number]['id'], +>(options: GetTransactionReceiptOptions) { + return ['getTransactionReceipt', filterQueryOptions(options)] as const +} + +export type GetTransactionReceiptQueryKey< + config extends Config, + chainId extends config['chains'][number]['id'], +> = ReturnType> diff --git a/wagmi-project/packages/core/src/query/getWalletClient.test.ts b/wagmi-project/packages/core/src/query/getWalletClient.test.ts new file mode 100644 index 000000000..899b48088 --- /dev/null +++ b/wagmi-project/packages/core/src/query/getWalletClient.test.ts @@ -0,0 +1,37 @@ +import { chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getWalletClientQueryOptions } from './getWalletClient.js' + +test('default', () => { + expect(getWalletClientQueryOptions(config)).toMatchInlineSnapshot(` + { + "gcTime": 0, + "queryFn": [Function], + "queryKey": [ + "walletClient", + { + "connectorUid": undefined, + }, + ], + } + `) +}) + +test('parameters: chainId', () => { + expect( + getWalletClientQueryOptions(config, { chainId: chain.mainnet.id }), + ).toMatchInlineSnapshot(` + { + "gcTime": 0, + "queryFn": [Function], + "queryKey": [ + "walletClient", + { + "chainId": 1, + "connectorUid": undefined, + }, + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/getWalletClient.ts b/wagmi-project/packages/core/src/query/getWalletClient.ts new file mode 100644 index 000000000..3c64b39a0 --- /dev/null +++ b/wagmi-project/packages/core/src/query/getWalletClient.ts @@ -0,0 +1,65 @@ +import type { QueryOptions } from '@tanstack/query-core' + +import { + type GetWalletClientErrorType, + type GetWalletClientParameters, + type GetWalletClientReturnType, + getWalletClient, +} from '../actions/getWalletClient.js' +import type { Config } from '../createConfig.js' +import type { ScopeKeyParameter } from '../types/properties.js' +import type { Compute, ExactPartial } from '../types/utils.js' +import { filterQueryOptions } from './utils.js' + +export type GetWalletClientOptions< + config extends Config, + chainId extends config['chains'][number]['id'], +> = Compute< + ExactPartial> & ScopeKeyParameter +> + +export function getWalletClientQueryOptions< + config extends Config, + chainId extends config['chains'][number]['id'], +>(config: config, options: GetWalletClientOptions = {}) { + return { + gcTime: 0, + async queryFn({ queryKey }) { + const { connector } = options + const { connectorUid: _, scopeKey: _s, ...parameters } = queryKey[1] + return getWalletClient(config, { ...parameters, connector }) + }, + queryKey: getWalletClientQueryKey(options), + } as const satisfies QueryOptions< + GetWalletClientQueryFnData, + GetWalletClientErrorType, + GetWalletClientData, + GetWalletClientQueryKey + > +} + +export type GetWalletClientQueryFnData< + config extends Config, + chainId extends config['chains'][number]['id'], +> = GetWalletClientReturnType + +export type GetWalletClientData< + config extends Config, + chainId extends config['chains'][number]['id'], +> = GetWalletClientQueryFnData + +export function getWalletClientQueryKey< + config extends Config, + chainId extends config['chains'][number]['id'], +>(options: GetWalletClientOptions = {}) { + const { connector, ...parameters } = options + return [ + 'walletClient', + { ...filterQueryOptions(parameters), connectorUid: connector?.uid }, + ] as const +} + +export type GetWalletClientQueryKey< + config extends Config, + chainId extends config['chains'][number]['id'], +> = ReturnType> diff --git a/wagmi-project/packages/core/src/query/infiniteReadContracts.test-d.ts b/wagmi-project/packages/core/src/query/infiniteReadContracts.test-d.ts new file mode 100644 index 000000000..c76dd3bcc --- /dev/null +++ b/wagmi-project/packages/core/src/query/infiniteReadContracts.test-d.ts @@ -0,0 +1,201 @@ +import { abi, config } from '@wagmi/test' +import type { MulticallResponse } from 'viem' +import { expectTypeOf, test } from 'vitest' + +import { infiniteReadContractsQueryOptions } from './infiniteReadContracts.js' + +test('default', async () => { + const options = infiniteReadContractsQueryOptions(config, { + cacheKey: 'foo', + contracts(pageParam) { + expectTypeOf(pageParam).toEqualTypeOf(options.initialPageParam) + return [ + { + address: '0x', + abi: abi.erc20, + functionName: 'balanceOf', + args: ['0x'], + }, + { + address: '0x', + abi: abi.wagmiMintExample, + functionName: 'tokenURI', + args: [123n], + }, + ] + }, + query: { + initialPageParam: 0, + getNextPageParam(lastPage, allPages, lastPageParam, allPageParams) { + expectTypeOf(lastPage).toEqualTypeOf< + [MulticallResponse, MulticallResponse] + >() + expectTypeOf(allPages).toEqualTypeOf< + [MulticallResponse, MulticallResponse][] + >() + expectTypeOf(lastPageParam).toEqualTypeOf(options.initialPageParam) + expectTypeOf(allPageParams).toEqualTypeOf([options.initialPageParam]) + return lastPageParam + 1 + }, + }, + }) + const result = await options.queryFn({} as any) + expectTypeOf(result).toEqualTypeOf< + [MulticallResponse, MulticallResponse] + >() +}) + +test('allowFailure: false', async () => { + const options = infiniteReadContractsQueryOptions(config, { + allowFailure: false, + cacheKey: 'foo', + contracts(pageParam) { + expectTypeOf(pageParam).toEqualTypeOf(options.initialPageParam) + return [ + { + address: '0x', + abi: abi.erc20, + functionName: 'balanceOf', + args: ['0x'], + }, + { + address: '0x', + abi: abi.wagmiMintExample, + functionName: 'tokenURI', + args: [123n], + }, + ] + }, + query: { + initialPageParam: 0, + getNextPageParam(lastPage, allPages, lastPageParam, allPageParams) { + expectTypeOf(lastPage).toEqualTypeOf<[bigint, string]>() + expectTypeOf(allPages).toEqualTypeOf<[bigint, string][]>() + expectTypeOf(lastPageParam).toEqualTypeOf(options.initialPageParam) + expectTypeOf(allPageParams).toEqualTypeOf([options.initialPageParam]) + return lastPageParam + 1 + }, + }, + }) + const result = await options.queryFn({} as any) + expectTypeOf(result).toEqualTypeOf<[bigint, string]>() +}) + +test('initialPageParam', async () => { + const options = infiniteReadContractsQueryOptions(config, { + allowFailure: false, + cacheKey: 'foo', + contracts(pageParam) { + expectTypeOf(pageParam).toEqualTypeOf(options.initialPageParam) + return [ + { + address: '0x', + abi: abi.erc20, + functionName: 'balanceOf', + args: ['0x'], + }, + { + address: '0x', + abi: abi.wagmiMintExample, + functionName: 'tokenURI', + args: [123n], + }, + ] + }, + query: { + initialPageParam: 'bar', + getNextPageParam(lastPage, allPages, lastPageParam, allPageParams) { + expectTypeOf(lastPage).toEqualTypeOf<[bigint, string]>() + expectTypeOf(allPages).toEqualTypeOf<[bigint, string][]>() + expectTypeOf(lastPageParam).toEqualTypeOf(options.initialPageParam) + expectTypeOf(allPageParams).toEqualTypeOf([options.initialPageParam]) + return lastPageParam + 1 + }, + }, + }) + const result = await options.queryFn({} as any) + expectTypeOf(result).toEqualTypeOf<[bigint, string]>() +}) + +test('behavior: `contracts` after `getNextPageParam`', async () => { + const options = infiniteReadContractsQueryOptions(config, { + allowFailure: false, + cacheKey: 'foo', + query: { + initialPageParam: 0, + getNextPageParam(lastPage, allPages, lastPageParam, allPageParams) { + expectTypeOf(lastPage).toEqualTypeOf() + expectTypeOf(allPages).toEqualTypeOf() + expectTypeOf(lastPageParam).toEqualTypeOf(options.initialPageParam) + expectTypeOf(allPageParams).toEqualTypeOf([options.initialPageParam]) + return lastPageParam + 1 + }, + }, + contracts(pageParam) { + expectTypeOf(pageParam).toEqualTypeOf(options.initialPageParam) + return [ + { + address: '0x', + abi: abi.erc20, + functionName: 'balanceOf', + args: ['0x'], + }, + { + address: '0x', + abi: abi.wagmiMintExample, + functionName: 'tokenURI', + args: [123n], + }, + ] + }, + }) + const result = await options.queryFn({} as any) + expectTypeOf(result).toEqualTypeOf() +}) + +test('overloads', async () => { + const options = infiniteReadContractsQueryOptions(config, { + allowFailure: false, + cacheKey: 'foo', + contracts(pageParam) { + expectTypeOf(pageParam).toEqualTypeOf() + return [ + { + address: '0x', + abi: abi.viewOverloads, + functionName: 'foo', + }, + { + address: '0x', + abi: abi.viewOverloads, + functionName: 'foo', + args: ['0x'], + }, + { + address: '0x', + abi: abi.viewOverloads, + functionName: 'foo', + args: ['0x', '0x'], + }, + ] + }, + query: { + initialPageParam: 0, + getNextPageParam(_, allPages) { + return allPages.length + 1 + }, + }, + }) + + const result = await options.queryFn({} as any) + expectTypeOf(result).toEqualTypeOf< + [ + number, + string, + { + foo: `0x${string}` + bar: `0x${string}` + }, + ] + >() +}) diff --git a/wagmi-project/packages/core/src/query/infiniteReadContracts.test.ts b/wagmi-project/packages/core/src/query/infiniteReadContracts.test.ts new file mode 100644 index 000000000..509e98483 --- /dev/null +++ b/wagmi-project/packages/core/src/query/infiniteReadContracts.test.ts @@ -0,0 +1,60 @@ +import { abi, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { infiniteReadContractsQueryOptions } from './infiniteReadContracts.js' + +test('default', () => { + expect( + infiniteReadContractsQueryOptions(config, { + allowFailure: true, + batchSize: 1024, + blockNumber: 123n, + blockTag: 'latest', + cacheKey: 'foo', + chainId: 1, + multicallAddress: '0x', + scopeKey: 'bar', + contracts(_pageParam) { + return [ + { + address: '0x', + abi: abi.erc20, + functionName: 'balanceOf', + args: ['0x'], + }, + { + address: '0x', + abi: abi.wagmiMintExample, + functionName: 'tokenURI', + args: [123n], + }, + ] + }, + query: { + initialPageParam: 0, + getNextPageParam(_lastPage, _allPages, lastPageParam, _allPageParams) { + return lastPageParam + 1 + }, + }, + }), + ).toMatchInlineSnapshot(` + { + "getNextPageParam": [Function], + "initialPageParam": 0, + "queryFn": [Function], + "queryKey": [ + "infiniteReadContracts", + { + "allowFailure": true, + "batchSize": 1024, + "blockNumber": 123n, + "blockTag": "latest", + "cacheKey": "foo", + "chainId": 1, + "multicallAddress": "0x", + "scopeKey": "bar", + }, + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/infiniteReadContracts.ts b/wagmi-project/packages/core/src/query/infiniteReadContracts.ts new file mode 100644 index 000000000..28a8d3f52 --- /dev/null +++ b/wagmi-project/packages/core/src/query/infiniteReadContracts.ts @@ -0,0 +1,127 @@ +import type { ContractFunctionParameters } from 'viem' +import { + type ReadContractsErrorType, + type ReadContractsParameters, + type ReadContractsReturnType, + readContracts, +} from '../actions/readContracts.js' +import type { Config } from '../createConfig.js' +import type { + ChainIdParameter, + ScopeKeyParameter, +} from '../types/properties.js' +import type { StrictOmit } from '../types/utils.js' +import type { InfiniteQueryOptions } from './types.js' +import { filterQueryOptions } from './utils.js' + +export type InfiniteReadContractsOptions< + contracts extends readonly unknown[], + allowFailure extends boolean, + pageParam, + config extends Config, +> = { + cacheKey: string + contracts( + pageParam: pageParam, + ): ReadContractsParameters['contracts'] +} & StrictOmit< + ReadContractsParameters, + 'contracts' +> & + ScopeKeyParameter + +export function infiniteReadContractsQueryOptions< + config extends Config, + const contracts extends readonly ContractFunctionParameters[], + allowFailure extends boolean = true, + pageParam = unknown, +>( + config: config, + options: InfiniteReadContractsOptions< + contracts, + allowFailure, + pageParam, + config + > & + ChainIdParameter & + RequiredPageParamsParameters, +) { + return { + ...options.query, + async queryFn({ pageParam, queryKey }) { + const { contracts } = options + const { cacheKey: _, scopeKey: _s, ...parameters } = queryKey[1] + return (await readContracts(config, { + ...parameters, + contracts: contracts(pageParam as any), + })) as ReadContractsReturnType + }, + queryKey: infiniteReadContractsQueryKey(options), + } as const satisfies InfiniteQueryOptions< + InfiniteReadContractsQueryFnData, + ReadContractsErrorType, + InfiniteReadContractsData, + InfiniteReadContractsData, + InfiniteReadContractsQueryKey, + pageParam + > +} + +type RequiredPageParamsParameters< + contracts extends readonly unknown[], + allowFailure extends boolean, + pageParam, +> = { + query: { + initialPageParam: pageParam + getNextPageParam( + lastPage: InfiniteReadContractsQueryFnData, + allPages: InfiniteReadContractsQueryFnData[], + lastPageParam: pageParam, + allPageParams: pageParam[], + ): pageParam | undefined | null + } +} + +export type InfiniteReadContractsQueryFnData< + contracts extends readonly unknown[], + allowFailure extends boolean, +> = ReadContractsReturnType + +export type InfiniteReadContractsData< + contracts extends readonly unknown[], + allowFailure extends boolean, +> = InfiniteReadContractsQueryFnData + +export function infiniteReadContractsQueryKey< + config extends Config, + const contracts extends readonly unknown[], + allowFailure extends boolean, + pageParam, +>( + options: InfiniteReadContractsOptions< + contracts, + allowFailure, + pageParam, + config + > & + ChainIdParameter & + RequiredPageParamsParameters, +) { + const { contracts: _, query: _q, ...parameters } = options + return ['infiniteReadContracts', filterQueryOptions(parameters)] as const +} + +export type InfiniteReadContractsQueryKey< + contracts extends readonly unknown[], + allowFailure extends boolean, + pageParam, + config extends Config, +> = ReturnType< + typeof infiniteReadContractsQueryKey< + config, + contracts, + allowFailure, + pageParam + > +> diff --git a/wagmi-project/packages/core/src/query/prepareTransactionRequest.test.ts b/wagmi-project/packages/core/src/query/prepareTransactionRequest.test.ts new file mode 100644 index 000000000..d33c156be --- /dev/null +++ b/wagmi-project/packages/core/src/query/prepareTransactionRequest.test.ts @@ -0,0 +1,241 @@ +import { accounts, chain, config } from '@wagmi/test' +import { parseEther, parseGwei } from 'viem' +import { privateKeyToAccount } from 'viem/accounts' +import { expect, test } from 'vitest' + +import { prepareTransactionRequestQueryOptions } from './prepareTransactionRequest.js' + +const targetAccount = accounts[0] + +test('default', () => { + expect( + prepareTransactionRequestQueryOptions(config, { + to: targetAccount, + value: parseEther('1'), + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "prepareTransactionRequest", + { + "to": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "value": 1000000000000000000n, + }, + ], + } + `) +}) + +test('parameters: account', () => { + expect( + prepareTransactionRequestQueryOptions(config, { + account: privateKeyToAccount( + '0x0123456789012345678901234567890123456789012345678901234567890123', + ), + to: targetAccount, + value: parseEther('1'), + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "prepareTransactionRequest", + { + "account": { + "address": "0x14791697260E4c9A71f18484C9f997B308e59325", + "nonceManager": undefined, + "publicKey": "0x046655feed4d214c261e0a6b554395596f1f1476a77d999560e5a8df9b8a1a3515217e88dd05e938efdd71b2cce322bf01da96cd42087b236e8f5043157a9c068e", + "sign": [Function], + "signAuthorization": [Function], + "signMessage": [Function], + "signTransaction": [Function], + "signTypedData": [Function], + "source": "privateKey", + "type": "local", + }, + "to": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "value": 1000000000000000000n, + }, + ], + } + `) +}) + +test('parameters: data', () => { + expect( + prepareTransactionRequestQueryOptions(config, { + data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + to: targetAccount, + value: parseEther('1'), + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "prepareTransactionRequest", + { + "data": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", + "to": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "value": 1000000000000000000n, + }, + ], + } + `) +}) + +test('parameters: chainId', () => { + expect( + prepareTransactionRequestQueryOptions(config, { + chainId: chain.mainnet2.id, + to: targetAccount, + value: parseEther('1'), + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "prepareTransactionRequest", + { + "chainId": 456, + "to": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "value": 1000000000000000000n, + }, + ], + } + `) +}) + +test('parameters: nonce', () => { + expect( + prepareTransactionRequestQueryOptions(config, { + nonce: 5, + to: targetAccount, + value: parseEther('1'), + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "prepareTransactionRequest", + { + "nonce": 5, + "to": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "value": 1000000000000000000n, + }, + ], + } + `) +}) + +test('parameters: gasPrice', () => { + expect( + prepareTransactionRequestQueryOptions(config, { + gasPrice: parseGwei('10'), + to: targetAccount, + value: parseEther('1'), + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "prepareTransactionRequest", + { + "gasPrice": 10000000000n, + "to": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "value": 1000000000000000000n, + }, + ], + } + `) +}) + +test('parameters: maxFeePerGas', () => { + expect( + prepareTransactionRequestQueryOptions(config, { + maxFeePerGas: parseGwei('100'), + to: targetAccount, + value: parseEther('1'), + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "prepareTransactionRequest", + { + "maxFeePerGas": 100000000000n, + "to": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "value": 1000000000000000000n, + }, + ], + } + `) +}) + +test('parameters: maxPriorityFeePerGas', () => { + expect( + prepareTransactionRequestQueryOptions(config, { + maxPriorityFeePerGas: parseGwei('5'), + to: targetAccount, + value: parseEther('1'), + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "prepareTransactionRequest", + { + "maxPriorityFeePerGas": 5000000000n, + "to": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "value": 1000000000000000000n, + }, + ], + } + `) +}) + +test('parameters: type', () => { + expect( + prepareTransactionRequestQueryOptions(config, { + type: 'eip1559', + to: targetAccount, + value: parseEther('1'), + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "prepareTransactionRequest", + { + "to": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "type": "eip1559", + "value": 1000000000000000000n, + }, + ], + } + `) +}) + +test('parameters: parameters', () => { + expect( + prepareTransactionRequestQueryOptions(config, { + parameters: ['gas'], + to: targetAccount, + value: parseEther('1'), + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "prepareTransactionRequest", + { + "parameters": [ + "gas", + ], + "to": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "value": 1000000000000000000n, + }, + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/prepareTransactionRequest.ts b/wagmi-project/packages/core/src/query/prepareTransactionRequest.ts new file mode 100644 index 000000000..5ed4b419f --- /dev/null +++ b/wagmi-project/packages/core/src/query/prepareTransactionRequest.ts @@ -0,0 +1,101 @@ +import type { QueryOptions } from '@tanstack/query-core' + +import type { PrepareTransactionRequestRequest as viem_PrepareTransactionRequestRequest } from 'viem' + +import { + type PrepareTransactionRequestErrorType, + type PrepareTransactionRequestParameters, + type PrepareTransactionRequestReturnType, + prepareTransactionRequest, +} from '../actions/prepareTransactionRequest.js' +import type { Config } from '../createConfig.js' +import type { SelectChains } from '../types/chain.js' +import type { ScopeKeyParameter } from '../types/properties.js' +import type { UnionExactPartial } from '../types/utils.js' +import { filterQueryOptions } from './utils.js' + +export type PrepareTransactionRequestOptions< + config extends Config, + chainId extends config['chains'][number]['id'] | undefined, + request extends viem_PrepareTransactionRequestRequest< + SelectChains[0], + SelectChains[0] + >, +> = UnionExactPartial< + PrepareTransactionRequestParameters +> & + ScopeKeyParameter + +export function prepareTransactionRequestQueryOptions< + config extends Config, + chainId extends config['chains'][number]['id'] | undefined, + request extends viem_PrepareTransactionRequestRequest< + SelectChains[0], + SelectChains[0] + >, +>( + config: config, + options: PrepareTransactionRequestOptions< + config, + chainId, + request + > = {} as any, +) { + return { + queryFn({ queryKey }) { + const { scopeKey: _, to, ...parameters } = queryKey[1] + if (!to) throw new Error('to is required') + return prepareTransactionRequest(config, { + to, + ...(parameters as any), + }) as unknown as Promise< + PrepareTransactionRequestQueryFnData + > + }, + queryKey: prepareTransactionRequestQueryKey(options), + } as const satisfies QueryOptions< + PrepareTransactionRequestQueryFnData, + PrepareTransactionRequestErrorType, + PrepareTransactionRequestData, + PrepareTransactionRequestQueryKey + > +} +export type PrepareTransactionRequestQueryFnData< + config extends Config, + chainId extends config['chains'][number]['id'] | undefined, + request extends viem_PrepareTransactionRequestRequest< + SelectChains[0], + SelectChains[0] + >, +> = PrepareTransactionRequestReturnType + +export type PrepareTransactionRequestData< + config extends Config, + chainId extends config['chains'][number]['id'] | undefined, + request extends viem_PrepareTransactionRequestRequest< + SelectChains[0], + SelectChains[0] + >, +> = PrepareTransactionRequestQueryFnData + +export function prepareTransactionRequestQueryKey< + config extends Config, + chainId extends config['chains'][number]['id'] | undefined, + request extends viem_PrepareTransactionRequestRequest< + SelectChains[0], + SelectChains[0] + >, +>(options: PrepareTransactionRequestOptions) { + return ['prepareTransactionRequest', filterQueryOptions(options)] as const +} + +export type PrepareTransactionRequestQueryKey< + config extends Config, + chainId extends config['chains'][number]['id'] | undefined, + request extends viem_PrepareTransactionRequestRequest< + SelectChains[0], + SelectChains[0] + >, +> = ReturnType< + typeof prepareTransactionRequestQueryKey +> diff --git a/wagmi-project/packages/core/src/query/readContract.test-d.ts b/wagmi-project/packages/core/src/query/readContract.test-d.ts new file mode 100644 index 000000000..286b8819c --- /dev/null +++ b/wagmi-project/packages/core/src/query/readContract.test-d.ts @@ -0,0 +1,15 @@ +import { abi, config } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' + +import { readContractQueryOptions } from './readContract.js' + +test('default', async () => { + const options = readContractQueryOptions(config, { + address: '0x', + abi: abi.erc20, + functionName: 'balanceOf', + args: ['0x'], + }) + const result = await options.queryFn({} as any) + expectTypeOf(result).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/core/src/query/readContract.test.ts b/wagmi-project/packages/core/src/query/readContract.test.ts new file mode 100644 index 000000000..6c17b849a --- /dev/null +++ b/wagmi-project/packages/core/src/query/readContract.test.ts @@ -0,0 +1,29 @@ +import { abi, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { readContractQueryOptions } from './readContract.js' + +test('default', () => { + expect( + readContractQueryOptions(config, { + address: '0x', + abi: abi.erc20, + functionName: 'balanceOf', + args: ['0x'], + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "readContract", + { + "address": "0x", + "args": [ + "0x", + ], + "functionName": "balanceOf", + }, + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/readContract.ts b/wagmi-project/packages/core/src/query/readContract.ts new file mode 100644 index 000000000..52c586665 --- /dev/null +++ b/wagmi-project/packages/core/src/query/readContract.ts @@ -0,0 +1,93 @@ +import type { QueryOptions } from '@tanstack/query-core' +import type { Abi, ContractFunctionArgs, ContractFunctionName } from 'viem' + +import { + type ReadContractErrorType, + type ReadContractParameters, + type ReadContractReturnType, + readContract, +} from '../actions/readContract.js' +import type { Config } from '../createConfig.js' +import type { ScopeKeyParameter } from '../types/properties.js' +import type { UnionExactPartial } from '../types/utils.js' +import { filterQueryOptions } from './utils.js' + +export type ReadContractOptions< + abi extends Abi | readonly unknown[], + functionName extends ContractFunctionName, + args extends ContractFunctionArgs, + config extends Config, +> = UnionExactPartial> & + ScopeKeyParameter + +export function readContractQueryOptions< + config extends Config, + const abi extends Abi | readonly unknown[], + functionName extends ContractFunctionName, + args extends ContractFunctionArgs, +>( + config: config, + options: ReadContractOptions = {} as any, +) { + return { + // TODO: Support `signal` once Viem actions allow passthrough + // https://tkdodo.eu/blog/why-you-want-react-query#bonus-cancellation + async queryFn({ queryKey }) { + const abi = options.abi as Abi + if (!abi) throw new Error('abi is required') + + const { functionName, scopeKey: _, ...parameters } = queryKey[1] + const addressOrCodeParams = (() => { + const params = queryKey[1] as unknown as ReadContractParameters + if (params.address) return { address: params.address } + if (params.code) return { code: params.code } + throw new Error('address or code is required') + })() + + if (!functionName) throw new Error('functionName is required') + + return readContract(config, { + abi, + functionName, + args: parameters.args as readonly unknown[], + ...addressOrCodeParams, + ...parameters, + }) as Promise> + }, + queryKey: readContractQueryKey(options as any) as any, + } as const satisfies QueryOptions< + ReadContractQueryFnData, + ReadContractErrorType, + ReadContractData, + ReadContractQueryKey + > +} + +export type ReadContractQueryFnData< + abi extends Abi | readonly unknown[], + functionName extends ContractFunctionName, + args extends ContractFunctionArgs, +> = ReadContractReturnType + +export type ReadContractData< + abi extends Abi | readonly unknown[], + functionName extends ContractFunctionName, + args extends ContractFunctionArgs, +> = ReadContractQueryFnData + +export function readContractQueryKey< + config extends Config, + const abi extends Abi | readonly unknown[], + functionName extends ContractFunctionName, + args extends ContractFunctionArgs, +>(options: ReadContractOptions = {} as any) { + const { abi: _, ...rest } = options + return ['readContract', filterQueryOptions(rest)] as const +} + +export type ReadContractQueryKey< + abi extends Abi | readonly unknown[], + functionName extends ContractFunctionName, + args extends ContractFunctionArgs, + config extends Config, +> = ReturnType> diff --git a/wagmi-project/packages/core/src/query/readContracts.test-d.ts b/wagmi-project/packages/core/src/query/readContracts.test-d.ts new file mode 100644 index 000000000..b6236e191 --- /dev/null +++ b/wagmi-project/packages/core/src/query/readContracts.test-d.ts @@ -0,0 +1,58 @@ +import { abi, config } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' + +import { readContractsQueryOptions } from './readContracts.js' + +test('default', async () => { + const options = readContractsQueryOptions(config, { + contracts: [ + { + address: '0x', + abi: abi.erc20, + functionName: 'balanceOf', + args: ['0x'], + }, + { + address: '0x', + abi: abi.wagmiMintExample, + functionName: 'tokenURI', + args: [123n], + }, + ], + }) + const result = await options.queryFn({} as any) + expectTypeOf(result).toEqualTypeOf< + [ + ( + | { error: Error; result?: undefined; status: 'failure' } + | { error?: undefined; result: bigint; status: 'success' } + ), + ( + | { error: Error; result?: undefined; status: 'failure' } + | { error?: undefined; result: string; status: 'success' } + ), + ] + >() +}) + +test('allowFailure: false', async () => { + const options = readContractsQueryOptions(config, { + allowFailure: false, + contracts: [ + { + address: '0x', + abi: abi.erc20, + functionName: 'balanceOf', + args: ['0x'], + }, + { + address: '0x', + abi: abi.wagmiMintExample, + functionName: 'tokenURI', + args: [123n], + }, + ], + }) + const result = await options.queryFn({} as any) + expectTypeOf(result).toEqualTypeOf<[bigint, string]>() +}) diff --git a/wagmi-project/packages/core/src/query/readContracts.test.ts b/wagmi-project/packages/core/src/query/readContracts.test.ts new file mode 100644 index 000000000..755b80c20 --- /dev/null +++ b/wagmi-project/packages/core/src/query/readContracts.test.ts @@ -0,0 +1,38 @@ +import { abi, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { readContractsQueryOptions } from './readContracts.js' + +test('default', () => { + expect( + readContractsQueryOptions(config, { + contracts: [ + { + address: '0x', + abi: abi.erc20, + functionName: 'balanceOf', + args: ['0x'], + }, + ], + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "readContracts", + { + "contracts": [ + { + "address": "0x", + "args": [ + "0x", + ], + "chainId": undefined, + "functionName": "balanceOf", + }, + ], + }, + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/readContracts.ts b/wagmi-project/packages/core/src/query/readContracts.ts new file mode 100644 index 000000000..96bb2163c --- /dev/null +++ b/wagmi-project/packages/core/src/query/readContracts.ts @@ -0,0 +1,98 @@ +import type { QueryOptions } from '@tanstack/query-core' +import type { + ContractFunctionParameters, + MulticallParameters as viem_MulticallParameters, +} from 'viem' + +import { + type ReadContractsErrorType, + type ReadContractsReturnType, + readContracts, +} from '../actions/readContracts.js' +import type { Config } from '../createConfig.js' +import type { ChainIdParameter } from '../types/properties.js' +import type { ScopeKeyParameter } from '../types/properties.js' +import type { ExactPartial } from '../types/utils.js' +import { filterQueryOptions } from './utils.js' + +export type ReadContractsOptions< + contracts extends readonly unknown[], + allowFailure extends boolean, + config extends Config, +> = ExactPartial< + viem_MulticallParameters< + contracts, + allowFailure, + { optional: true; properties: ChainIdParameter } + > +> & + ScopeKeyParameter + +export function readContractsQueryOptions< + config extends Config, + const contracts extends readonly unknown[], + allowFailure extends boolean = true, +>( + config: config, + options: ReadContractsOptions & + ChainIdParameter = {}, +) { + return { + async queryFn({ queryKey }) { + const contracts: ContractFunctionParameters[] = [] + const length = queryKey[1].contracts.length + for (let i = 0; i < length; i++) { + const contract = queryKey[1].contracts[i]! + const abi = (options.contracts?.[i] as ContractFunctionParameters).abi + contracts.push({ ...contract, abi }) + } + const { scopeKey: _, ...parameters } = queryKey[1] + return readContracts(config, { + ...parameters, + contracts, + }) as Promise> + }, + queryKey: readContractsQueryKey(options), + } as const satisfies QueryOptions< + ReadContractsQueryFnData, + ReadContractsErrorType, + ReadContractsData, + ReadContractsQueryKey + > +} + +export type ReadContractsQueryFnData< + contracts extends readonly unknown[], + allowFailure extends boolean, +> = ReadContractsReturnType + +export type ReadContractsData< + contracts extends readonly unknown[], + allowFailure extends boolean, +> = ReadContractsQueryFnData + +export function readContractsQueryKey< + config extends Config, + const contracts extends readonly unknown[], + allowFailure extends boolean, +>( + options: ReadContractsOptions & + ChainIdParameter = {}, +) { + const contracts = [] + for (const contract of (options.contracts ?? + []) as (ContractFunctionParameters & { chainId: number })[]) { + const { abi: _, ...rest } = contract + contracts.push({ ...rest, chainId: rest.chainId ?? options.chainId }) + } + return [ + 'readContracts', + filterQueryOptions({ ...options, contracts }), + ] as const +} + +export type ReadContractsQueryKey< + contracts extends readonly unknown[], + allowFailure extends boolean, + config extends Config, +> = ReturnType> diff --git a/wagmi-project/packages/core/src/query/reconnect.test.ts b/wagmi-project/packages/core/src/query/reconnect.test.ts new file mode 100644 index 000000000..fbcb56c3f --- /dev/null +++ b/wagmi-project/packages/core/src/query/reconnect.test.ts @@ -0,0 +1,15 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { reconnectMutationOptions } from './reconnect.js' + +test('default', () => { + expect(reconnectMutationOptions(config)).toMatchInlineSnapshot(` + { + "mutationFn": [Function], + "mutationKey": [ + "reconnect", + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/reconnect.ts b/wagmi-project/packages/core/src/query/reconnect.ts new file mode 100644 index 000000000..13126cdd3 --- /dev/null +++ b/wagmi-project/packages/core/src/query/reconnect.ts @@ -0,0 +1,42 @@ +import type { MutationOptions } from '@tanstack/query-core' + +import { + type ReconnectErrorType, + type ReconnectParameters, + type ReconnectReturnType, + reconnect, +} from '../actions/reconnect.js' +import type { Config } from '../createConfig.js' +import type { Compute } from '../types/utils.js' +import type { Mutate, MutateAsync } from './types.js' + +export function reconnectMutationOptions(config: Config) { + return { + mutationFn(variables) { + return reconnect(config, variables) + }, + mutationKey: ['reconnect'], + } as const satisfies MutationOptions< + ReconnectData, + ReconnectErrorType, + ReconnectVariables + > +} + +export type ReconnectData = Compute + +export type ReconnectVariables = ReconnectParameters | undefined + +export type ReconnectMutate = Mutate< + ReconnectData, + ReconnectErrorType, + ReconnectVariables, + context +> + +export type ReconnectMutateAsync = MutateAsync< + ReconnectData, + ReconnectErrorType, + ReconnectVariables, + context +> diff --git a/wagmi-project/packages/core/src/query/sendCalls.test.ts b/wagmi-project/packages/core/src/query/sendCalls.test.ts new file mode 100644 index 000000000..9892aa43e --- /dev/null +++ b/wagmi-project/packages/core/src/query/sendCalls.test.ts @@ -0,0 +1,15 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { sendCallsMutationOptions } from './sendCalls.js' + +test('default', () => { + expect(sendCallsMutationOptions(config)).toMatchInlineSnapshot(` + { + "mutationFn": [Function], + "mutationKey": [ + "sendCalls", + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/sendCalls.ts b/wagmi-project/packages/core/src/query/sendCalls.ts new file mode 100644 index 000000000..5d07b89b8 --- /dev/null +++ b/wagmi-project/packages/core/src/query/sendCalls.ts @@ -0,0 +1,67 @@ +import type { MutateOptions, MutationOptions } from '@tanstack/query-core' + +import { + type SendCallsErrorType, + type SendCallsParameters, + type SendCallsReturnType, + sendCalls, +} from '../actions/sendCalls.js' +import type { Config } from '../createConfig.js' +import type { Compute } from '../types/utils.js' + +export function sendCallsMutationOptions( + config: config, +) { + return { + mutationFn(variables) { + return sendCalls(config, variables) + }, + mutationKey: ['sendCalls'], + } as const satisfies MutationOptions< + SendCallsData, + SendCallsErrorType, + SendCallsVariables + > +} + +export type SendCallsData = Compute + +export type SendCallsVariables< + config extends Config, + chainId extends config['chains'][number]['id'], + calls extends readonly unknown[] = readonly unknown[], +> = SendCallsParameters + +export type SendCallsMutate = < + const calls extends readonly unknown[], + chainId extends config['chains'][number]['id'], +>( + variables: SendCallsVariables, + options?: + | Compute< + MutateOptions< + SendCallsData, + SendCallsErrorType, + Compute>, + context + > + > + | undefined, +) => void + +export type SendCallsMutateAsync = < + const calls extends readonly unknown[], + chainId extends config['chains'][number]['id'], +>( + variables: SendCallsVariables, + options?: + | Compute< + MutateOptions< + SendCallsData, + SendCallsErrorType, + Compute>, + context + > + > + | undefined, +) => Promise diff --git a/wagmi-project/packages/core/src/query/sendTransaction.test.ts b/wagmi-project/packages/core/src/query/sendTransaction.test.ts new file mode 100644 index 000000000..4cda333e7 --- /dev/null +++ b/wagmi-project/packages/core/src/query/sendTransaction.test.ts @@ -0,0 +1,15 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { sendTransactionMutationOptions } from './sendTransaction.js' + +test('default', () => { + expect(sendTransactionMutationOptions(config)).toMatchInlineSnapshot(` + { + "mutationFn": [Function], + "mutationKey": [ + "sendTransaction", + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/sendTransaction.ts b/wagmi-project/packages/core/src/query/sendTransaction.ts new file mode 100644 index 000000000..e6df10fef --- /dev/null +++ b/wagmi-project/packages/core/src/query/sendTransaction.ts @@ -0,0 +1,65 @@ +import type { MutateOptions, MutationOptions } from '@tanstack/query-core' + +import { + type SendTransactionErrorType, + type SendTransactionParameters, + type SendTransactionReturnType, + sendTransaction, +} from '../actions/sendTransaction.js' +import type { Config } from '../createConfig.js' +import type { Compute } from '../types/utils.js' + +export function sendTransactionMutationOptions( + config: config, +) { + return { + mutationFn(variables) { + return sendTransaction(config, variables) + }, + mutationKey: ['sendTransaction'], + } as const satisfies MutationOptions< + SendTransactionData, + SendTransactionErrorType, + SendTransactionVariables + > +} + +export type SendTransactionData = Compute + +export type SendTransactionVariables< + config extends Config, + chainId extends config['chains'][number]['id'], +> = SendTransactionParameters + +export type SendTransactionMutate = < + chainId extends config['chains'][number]['id'], +>( + variables: SendTransactionVariables, + options?: + | Compute< + MutateOptions< + SendTransactionData, + SendTransactionErrorType, + Compute>, + context + > + > + | undefined, +) => void + +export type SendTransactionMutateAsync< + config extends Config, + context = unknown, +> = ( + variables: SendTransactionVariables, + options?: + | Compute< + MutateOptions< + SendTransactionData, + SendTransactionErrorType, + Compute>, + context + > + > + | undefined, +) => Promise diff --git a/wagmi-project/packages/core/src/query/showCallsStatus.test.ts b/wagmi-project/packages/core/src/query/showCallsStatus.test.ts new file mode 100644 index 000000000..ad26ab617 --- /dev/null +++ b/wagmi-project/packages/core/src/query/showCallsStatus.test.ts @@ -0,0 +1,15 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { showCallsStatusMutationOptions } from './showCallsStatus.js' + +test('default', () => { + expect(showCallsStatusMutationOptions(config)).toMatchInlineSnapshot(` + { + "mutationFn": [Function], + "mutationKey": [ + "showCallsStatus", + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/showCallsStatus.ts b/wagmi-project/packages/core/src/query/showCallsStatus.ts new file mode 100644 index 000000000..86a703cbc --- /dev/null +++ b/wagmi-project/packages/core/src/query/showCallsStatus.ts @@ -0,0 +1,57 @@ +import type { MutateOptions, MutationOptions } from '@tanstack/query-core' + +import { + type ShowCallsStatusErrorType, + type ShowCallsStatusParameters, + type ShowCallsStatusReturnType, + showCallsStatus, +} from '../actions/showCallsStatus.js' +import type { Config } from '../createConfig.js' +import type { Compute } from '../types/utils.js' + +export function showCallsStatusMutationOptions( + config: config, +) { + return { + mutationFn(variables) { + return showCallsStatus(config, variables) + }, + mutationKey: ['showCallsStatus'], + } as const satisfies MutationOptions< + ShowCallsStatusData, + ShowCallsStatusErrorType, + ShowCallsStatusVariables + > +} + +export type ShowCallsStatusData = Compute + +export type ShowCallsStatusVariables = ShowCallsStatusParameters + +export type ShowCallsStatusMutate = ( + variables: ShowCallsStatusVariables, + options?: + | Compute< + MutateOptions< + ShowCallsStatusData, + ShowCallsStatusErrorType, + Compute, + context + > + > + | undefined, +) => void + +export type ShowCallsStatusMutateAsync = ( + variables: ShowCallsStatusVariables, + options?: + | Compute< + MutateOptions< + ShowCallsStatusData, + ShowCallsStatusErrorType, + Compute, + context + > + > + | undefined, +) => Promise diff --git a/wagmi-project/packages/core/src/query/signMessage.test.ts b/wagmi-project/packages/core/src/query/signMessage.test.ts new file mode 100644 index 000000000..b8ad84d0a --- /dev/null +++ b/wagmi-project/packages/core/src/query/signMessage.test.ts @@ -0,0 +1,15 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { signMessageMutationOptions } from './signMessage.js' + +test('default', () => { + expect(signMessageMutationOptions(config)).toMatchInlineSnapshot(` + { + "mutationFn": [Function], + "mutationKey": [ + "signMessage", + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/signMessage.ts b/wagmi-project/packages/core/src/query/signMessage.ts new file mode 100644 index 000000000..d2a4d8156 --- /dev/null +++ b/wagmi-project/packages/core/src/query/signMessage.ts @@ -0,0 +1,42 @@ +import type { MutationOptions } from '@tanstack/query-core' + +import { + type SignMessageErrorType, + type SignMessageParameters, + type SignMessageReturnType, + signMessage, +} from '../actions/signMessage.js' +import type { Config } from '../createConfig.js' +import type { Compute } from '../types/utils.js' +import type { Mutate, MutateAsync } from './types.js' + +export function signMessageMutationOptions(config: Config) { + return { + mutationFn(variables) { + return signMessage(config, variables) + }, + mutationKey: ['signMessage'], + } as const satisfies MutationOptions< + SignMessageData, + SignMessageErrorType, + SignMessageVariables + > +} + +export type SignMessageData = SignMessageReturnType + +export type SignMessageVariables = Compute + +export type SignMessageMutate = Mutate< + SignMessageData, + SignMessageErrorType, + SignMessageVariables, + context +> + +export type SignMessageMutateAsync = MutateAsync< + SignMessageData, + SignMessageErrorType, + SignMessageVariables, + context +> diff --git a/wagmi-project/packages/core/src/query/signTypedData.test.ts b/wagmi-project/packages/core/src/query/signTypedData.test.ts new file mode 100644 index 000000000..02cbb6648 --- /dev/null +++ b/wagmi-project/packages/core/src/query/signTypedData.test.ts @@ -0,0 +1,15 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { signTypedDataMutationOptions } from './signTypedData.js' + +test('default', () => { + expect(signTypedDataMutationOptions(config)).toMatchInlineSnapshot(` + { + "mutationFn": [Function], + "mutationKey": [ + "signTypedData", + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/signTypedData.ts b/wagmi-project/packages/core/src/query/signTypedData.ts new file mode 100644 index 000000000..fe8eeb026 --- /dev/null +++ b/wagmi-project/packages/core/src/query/signTypedData.ts @@ -0,0 +1,75 @@ +import type { MutateOptions, MutationOptions } from '@tanstack/query-core' + +import type { TypedData } from 'viem' +import { + type SignTypedDataErrorType, + type SignTypedDataParameters, + type SignTypedDataReturnType, + signTypedData, +} from '../actions/signTypedData.js' +import type { Config } from '../createConfig.js' +import type { Compute } from '../types/utils.js' + +export function signTypedDataMutationOptions( + config: config, +) { + return { + mutationFn(variables) { + return signTypedData(config, variables) + }, + mutationKey: ['signTypedData'], + } as const satisfies MutationOptions< + SignTypedDataData, + SignTypedDataErrorType, + SignTypedDataVariables + > +} + +export type SignTypedDataData = Compute + +export type SignTypedDataVariables< + typedData extends TypedData | Record = TypedData, + primaryType extends keyof typedData | 'EIP712Domain' = keyof typedData, + /// + primaryTypes = typedData extends TypedData ? keyof typedData : string, +> = SignTypedDataParameters + +export type SignTypedDataMutate = < + const typedData extends TypedData | Record, + primaryType extends keyof typedData | 'EIP712Domain', +>( + variables: SignTypedDataVariables, + options?: + | MutateOptions< + SignTypedDataData, + SignTypedDataErrorType, + SignTypedDataVariables< + typedData, + primaryType, + // use `primaryType` to make sure it's not union of all possible primary types + primaryType + >, + context + > + | undefined, +) => void + +export type SignTypedDataMutateAsync = < + const typedData extends TypedData | Record, + primaryType extends keyof typedData | 'EIP712Domain', +>( + variables: SignTypedDataVariables, + options?: + | MutateOptions< + SignTypedDataData, + SignTypedDataErrorType, + SignTypedDataVariables< + typedData, + primaryType, + // use `primaryType` to make sure it's not union of all possible primary types + primaryType + >, + context + > + | undefined, +) => Promise diff --git a/wagmi-project/packages/core/src/query/simulateContract.test-d.ts b/wagmi-project/packages/core/src/query/simulateContract.test-d.ts new file mode 100644 index 000000000..11023e729 --- /dev/null +++ b/wagmi-project/packages/core/src/query/simulateContract.test-d.ts @@ -0,0 +1,81 @@ +import { abi } from '@wagmi/test' +import { http, type Address } from 'viem' +import { celo, mainnet } from 'viem/chains' +import { expectTypeOf, test } from 'vitest' + +import { createConfig } from '../createConfig.js' +import { + type SimulateContractOptions, + simulateContractQueryOptions, +} from './simulateContract.js' + +test('chain formatters', () => { + const config = createConfig({ + chains: [mainnet, celo], + transports: { [celo.id]: http(), [mainnet.id]: http() }, + }) + + type Result = SimulateContractOptions< + typeof abi.erc20, + 'transferFrom', + [Address, Address, bigint], + typeof config, + (typeof config)['chains'][number]['id'] + > + expectTypeOf().toMatchTypeOf<{ + chainId?: typeof celo.id | typeof mainnet.id | undefined + feeCurrency?: `0x${string}` | undefined + }>() + simulateContractQueryOptions(config, { + address: '0x', + abi: abi.erc20, + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + feeCurrency: '0x', + }) + + type Result2 = SimulateContractOptions< + typeof abi.erc20, + 'transferFrom', + [Address, Address, bigint], + typeof config, + typeof celo.id + > + expectTypeOf().toMatchTypeOf<{ + functionName?: 'approve' | 'transfer' | 'transferFrom' | undefined + args?: readonly [Address, Address, bigint] | undefined + feeCurrency?: `0x${string}` | undefined + }>() + simulateContractQueryOptions(config, { + chainId: celo.id, + address: '0x', + abi: abi.erc20, + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + feeCurrency: '0x', + }) + + type Result3 = SimulateContractOptions< + typeof abi.erc20, + 'transferFrom', + [Address, Address, bigint], + typeof config, + typeof mainnet.id + > + expectTypeOf().toMatchTypeOf<{ + functionName?: 'approve' | 'transfer' | 'transferFrom' | undefined + args?: readonly [Address, Address, bigint] | undefined + }>() + expectTypeOf().not.toMatchTypeOf<{ + feeCurrency?: `0x${string}` | undefined + }>() + simulateContractQueryOptions(config, { + chainId: mainnet.id, + address: '0x', + abi: abi.erc20, + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + // @ts-expect-error + feeCurrency: '0x', + }) +}) diff --git a/wagmi-project/packages/core/src/query/simulateContract.test.ts b/wagmi-project/packages/core/src/query/simulateContract.test.ts new file mode 100644 index 000000000..354e4b0f0 --- /dev/null +++ b/wagmi-project/packages/core/src/query/simulateContract.test.ts @@ -0,0 +1,31 @@ +import { abi, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { simulateContractQueryOptions } from './simulateContract.js' + +test('default', () => { + expect( + simulateContractQueryOptions(config, { + address: '0x', + abi: abi.erc20, + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "simulateContract", + { + "address": "0x", + "args": [ + "0x", + "0x", + 123n, + ], + "functionName": "transferFrom", + }, + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/simulateContract.ts b/wagmi-project/packages/core/src/query/simulateContract.ts new file mode 100644 index 000000000..c3970999d --- /dev/null +++ b/wagmi-project/packages/core/src/query/simulateContract.ts @@ -0,0 +1,132 @@ +import type { QueryOptions } from '@tanstack/query-core' +import type { Abi, ContractFunctionArgs, ContractFunctionName } from 'viem' + +import { + type SimulateContractErrorType, + type SimulateContractParameters, + type SimulateContractReturnType, + simulateContract, +} from '../actions/simulateContract.js' +import type { Config } from '../createConfig.js' +import type { ScopeKeyParameter } from '../types/properties.js' +import type { UnionExactPartial } from '../types/utils.js' +import { filterQueryOptions } from './utils.js' + +export type SimulateContractOptions< + abi extends Abi | readonly unknown[], + functionName extends ContractFunctionName, + args extends ContractFunctionArgs< + abi, + 'nonpayable' | 'payable', + functionName + >, + config extends Config, + chainId extends config['chains'][number]['id'] | undefined, +> = UnionExactPartial< + SimulateContractParameters +> & + ScopeKeyParameter + +export function simulateContractQueryOptions< + config extends Config, + const abi extends Abi | readonly unknown[], + functionName extends ContractFunctionName, + args extends ContractFunctionArgs< + abi, + 'nonpayable' | 'payable', + functionName + >, + chainId extends config['chains'][number]['id'] | undefined, +>( + config: config, + options: SimulateContractOptions< + abi, + functionName, + args, + config, + chainId + > = {} as any, +) { + return { + async queryFn({ queryKey }) { + const { abi, connector } = options + if (!abi) throw new Error('abi is required') + const { scopeKey: _, ...parameters } = queryKey[1] + const { address, functionName } = parameters + if (!address) throw new Error('address is required') + if (!functionName) throw new Error('functionName is required') + return simulateContract(config, { + abi, + connector, + ...(parameters as any), + }) + }, + queryKey: simulateContractQueryKey(options), + } as const satisfies QueryOptions< + SimulateContractQueryFnData, + SimulateContractErrorType, + SimulateContractData, + SimulateContractQueryKey + > +} + +export type SimulateContractQueryFnData< + abi extends Abi | readonly unknown[], + functionName extends ContractFunctionName, + args extends ContractFunctionArgs< + abi, + 'nonpayable' | 'payable', + functionName + >, + config extends Config, + chainId extends config['chains'][number]['id'] | undefined, +> = SimulateContractReturnType + +export type SimulateContractData< + abi extends Abi | readonly unknown[], + functionName extends ContractFunctionName, + args extends ContractFunctionArgs< + abi, + 'nonpayable' | 'payable', + functionName + >, + config extends Config, + chainId extends config['chains'][number]['id'] | undefined, +> = SimulateContractQueryFnData + +export function simulateContractQueryKey< + config extends Config, + abi extends Abi | readonly unknown[], + functionName extends ContractFunctionName, + args extends ContractFunctionArgs< + abi, + 'nonpayable' | 'payable', + functionName + >, + chainId extends config['chains'][number]['id'] | undefined, +>( + options: SimulateContractOptions< + abi, + functionName, + args, + config, + chainId + > = {} as any, +) { + const { abi: _, connector: _c, ...rest } = options + return ['simulateContract', filterQueryOptions(rest)] as const +} + +export type SimulateContractQueryKey< + abi extends Abi | readonly unknown[], + functionName extends ContractFunctionName, + args extends ContractFunctionArgs< + abi, + 'nonpayable' | 'payable', + functionName + >, + config extends Config, + chainId extends config['chains'][number]['id'] | undefined, +> = ReturnType< + typeof simulateContractQueryKey +> diff --git a/wagmi-project/packages/core/src/query/switchAccount.test.ts b/wagmi-project/packages/core/src/query/switchAccount.test.ts new file mode 100644 index 000000000..25a7066c6 --- /dev/null +++ b/wagmi-project/packages/core/src/query/switchAccount.test.ts @@ -0,0 +1,15 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { switchAccountMutationOptions } from './switchAccount.js' + +test('default', () => { + expect(switchAccountMutationOptions(config)).toMatchInlineSnapshot(` + { + "mutationFn": [Function], + "mutationKey": [ + "switchAccount", + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/switchAccount.ts b/wagmi-project/packages/core/src/query/switchAccount.ts new file mode 100644 index 000000000..29a10b2ce --- /dev/null +++ b/wagmi-project/packages/core/src/query/switchAccount.ts @@ -0,0 +1,52 @@ +import type { MutationOptions } from '@tanstack/query-core' + +import { + type SwitchAccountErrorType, + type SwitchAccountParameters, + type SwitchAccountReturnType, + switchAccount, +} from '../actions/switchAccount.js' +import type { Config } from '../createConfig.js' +import type { Compute } from '../types/utils.js' +import type { Mutate, MutateAsync } from './types.js' + +export function switchAccountMutationOptions( + config: config, +) { + return { + mutationFn(variables) { + return switchAccount(config, variables) + }, + mutationKey: ['switchAccount'], + } as const satisfies MutationOptions< + SwitchAccountData, + SwitchAccountErrorType, + SwitchAccountVariables + > +} + +export type SwitchAccountData = Compute< + SwitchAccountReturnType +> + +export type SwitchAccountVariables = Compute + +export type SwitchAccountMutate< + config extends Config, + context = unknown, +> = Mutate< + SwitchAccountData, + SwitchAccountErrorType, + SwitchAccountVariables, + context +> + +export type SwitchAccountMutateAsync< + config extends Config, + context = unknown, +> = MutateAsync< + SwitchAccountData, + SwitchAccountErrorType, + SwitchAccountVariables, + context +> diff --git a/wagmi-project/packages/core/src/query/switchChain.test.ts b/wagmi-project/packages/core/src/query/switchChain.test.ts new file mode 100644 index 000000000..09a4277c2 --- /dev/null +++ b/wagmi-project/packages/core/src/query/switchChain.test.ts @@ -0,0 +1,15 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { switchChainMutationOptions } from './switchChain.js' + +test('default', () => { + expect(switchChainMutationOptions(config)).toMatchInlineSnapshot(` + { + "mutationFn": [Function], + "mutationKey": [ + "switchChain", + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/switchChain.ts b/wagmi-project/packages/core/src/query/switchChain.ts new file mode 100644 index 000000000..1924ca842 --- /dev/null +++ b/wagmi-project/packages/core/src/query/switchChain.ts @@ -0,0 +1,67 @@ +import type { MutateOptions, MutationOptions } from '@tanstack/query-core' + +import { + type SwitchChainErrorType, + type SwitchChainParameters, + type SwitchChainReturnType, + switchChain, +} from '../actions/switchChain.js' +import type { Config } from '../createConfig.js' +import type { Compute } from '../types/utils.js' + +export function switchChainMutationOptions( + config: config, +) { + return { + mutationFn(variables) { + return switchChain(config, variables) + }, + mutationKey: ['switchChain'], + } as const satisfies MutationOptions< + SwitchChainData, + SwitchChainErrorType, + SwitchChainVariables + > +} + +export type SwitchChainData< + config extends Config, + chainId extends config['chains'][number]['id'], +> = Compute> + +export type SwitchChainVariables< + config extends Config, + chainId extends config['chains'][number]['id'], +> = Compute> + +export type SwitchChainMutate = < + chainId extends config['chains'][number]['id'], +>( + variables: SwitchChainVariables, + options?: + | Compute< + MutateOptions< + SwitchChainData, + SwitchChainErrorType, + Compute>, + context + > + > + | undefined, +) => void + +export type SwitchChainMutateAsync = < + chainId extends config['chains'][number]['id'], +>( + variables: SwitchChainVariables, + options?: + | Compute< + MutateOptions< + SwitchChainData, + SwitchChainErrorType, + Compute>, + context + > + > + | undefined, +) => Promise> diff --git a/wagmi-project/packages/core/src/query/types.ts b/wagmi-project/packages/core/src/query/types.ts new file mode 100644 index 000000000..6a279d52d --- /dev/null +++ b/wagmi-project/packages/core/src/query/types.ts @@ -0,0 +1,84 @@ +import type { + DefaultError, + InfiniteQueryObserverOptions, + MutateOptions, + QueryFunction, + QueryKey, +} from '@tanstack/query-core' + +import type { Compute, StrictOmit } from '../types/utils.js' + +export type InfiniteQueryOptions< + queryFnData = unknown, + error = DefaultError, + data = queryFnData, + queryData = queryFnData, + queryKey extends QueryKey = QueryKey, + pageParam = unknown, + /// + options extends InfiniteQueryObserverOptions< + queryFnData, + error, + data, + queryData, + queryKey, + pageParam + > = InfiniteQueryObserverOptions< + queryFnData, + error, + data, + queryData, + queryKey, + pageParam + >, +> = Compute< + // `queryFn` doesn't pass through `pageParam` correctly + StrictOmit & { + queryFn?( + context: QueryFunctionContext, + ): options['queryFn'] extends (...args: any) => any + ? ReturnType> + : unknown + } +> + +// `QueryFunctionContext` not exported resulting in TS2742 error so grabbing from `QueryFunction` +type QueryFunctionContext< + TQueryKey extends QueryKey = QueryKey, + TPageParam = never, +> = Parameters>[0] + +export type Mutate< + data = unknown, + error = unknown, + variables = void, + context = unknown, +> = ( + ...args: Parameters, context>> +) => void + +export type MutateAsync< + data = unknown, + error = unknown, + variables = void, + context = unknown, +> = MutateFn, context> + +type MutateFn< + data = unknown, + error = unknown, + variables = void, + context = unknown, +> = undefined extends variables + ? ( + variables?: variables, + options?: + | Compute> + | undefined, + ) => Promise + : ( + variables: variables, + options?: + | Compute> + | undefined, + ) => Promise diff --git a/wagmi-project/packages/core/src/query/utils.test.ts b/wagmi-project/packages/core/src/query/utils.test.ts new file mode 100644 index 000000000..920b2e5f3 --- /dev/null +++ b/wagmi-project/packages/core/src/query/utils.test.ts @@ -0,0 +1,20 @@ +import { expect, test } from 'vitest' + +import { structuralSharing } from './utils.js' + +test('structuralSharing', () => { + expect( + structuralSharing({ foo: 'bar' }, { foo: 'bar' }), + ).toMatchInlineSnapshot(` + { + "foo": "bar", + } + `) + expect( + structuralSharing({ foo: 'bar' }, { foo: 'baz' }), + ).toMatchInlineSnapshot(` + { + "foo": "baz", + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/utils.ts b/wagmi-project/packages/core/src/query/utils.ts new file mode 100644 index 000000000..ab4ea3b98 --- /dev/null +++ b/wagmi-project/packages/core/src/query/utils.ts @@ -0,0 +1,73 @@ +import { type QueryKey, replaceEqualDeep } from '@tanstack/query-core' + +export function structuralSharing( + oldData: data | undefined, + newData: data, +): data { + return replaceEqualDeep(oldData, newData) +} + +export function hashFn(queryKey: QueryKey): string { + return JSON.stringify(queryKey, (_, value) => { + if (isPlainObject(value)) + return Object.keys(value) + .sort() + .reduce((result, key) => { + result[key] = value[key] + return result + }, {} as any) + if (typeof value === 'bigint') return value.toString() + return value + }) +} + +// biome-ignore lint/complexity/noBannedTypes: +function isPlainObject(value: any): value is Object { + if (!hasObjectPrototype(value)) { + return false + } + + // If has modified constructor + const ctor = value.constructor + if (typeof ctor === 'undefined') return true + + // If has modified prototype + const prot = ctor.prototype + if (!hasObjectPrototype(prot)) return false + + // If constructor does not have an Object-specific method + // biome-ignore lint/suspicious/noPrototypeBuiltins: + if (!prot.hasOwnProperty('isPrototypeOf')) return false + + // Most likely a plain Object + return true +} + +function hasObjectPrototype(o: any): boolean { + return Object.prototype.toString.call(o) === '[object Object]' +} + +export function filterQueryOptions>( + options: type, +): type { + // destructuring is super fast + // biome-ignore format: no formatting + const { + // import('@tanstack/query-core').QueryOptions + _defaulted, behavior, gcTime, initialData, initialDataUpdatedAt, maxPages, meta, networkMode, queryFn, queryHash, queryKey, queryKeyHashFn, retry, retryDelay, structuralSharing, + + // import('@tanstack/query-core').InfiniteQueryObserverOptions + getPreviousPageParam, getNextPageParam, initialPageParam, + + // import('@tanstack/react-query').UseQueryOptions + _optimisticResults, enabled, notifyOnChangeProps, placeholderData, refetchInterval, refetchIntervalInBackground, refetchOnMount, refetchOnReconnect, refetchOnWindowFocus, retryOnMount, select, staleTime, suspense, throwOnError, + + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // wagmi + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + config, connector, query, + ...rest + } = options + + return rest as type +} diff --git a/wagmi-project/packages/core/src/query/verifyMessage.test.ts b/wagmi-project/packages/core/src/query/verifyMessage.test.ts new file mode 100644 index 000000000..ae43f6b07 --- /dev/null +++ b/wagmi-project/packages/core/src/query/verifyMessage.test.ts @@ -0,0 +1,104 @@ +import { accounts, chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { verifyMessageQueryOptions } from './verifyMessage.js' + +const address = accounts[0] + +test('default', () => { + expect( + verifyMessageQueryOptions(config, { + address, + message: 'This is a test message for viem!', + signature: + '0xefd5fb29a274ea6682673d8b3caa9263e936d48d486e5df68893003e0a76496439594d12245008c6fba1c8e3ef28241cffe1bef27ff6bca487b167f261f329251c', + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "verifyMessage", + { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "message": "This is a test message for viem!", + "signature": "0xefd5fb29a274ea6682673d8b3caa9263e936d48d486e5df68893003e0a76496439594d12245008c6fba1c8e3ef28241cffe1bef27ff6bca487b167f261f329251c", + }, + ], + } + `) +}) + +test('parameters: chainId', () => { + expect( + verifyMessageQueryOptions(config, { + chainId: chain.mainnet2.id, + address, + message: 'This is a test message for viem!', + signature: + '0xefd5fb29a274ea6682673d8b3caa9263e936d48d486e5df68893003e0a76496439594d12245008c6fba1c8e3ef28241cffe1bef27ff6bca487b167f261f329251c', + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "verifyMessage", + { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "chainId": 456, + "message": "This is a test message for viem!", + "signature": "0xefd5fb29a274ea6682673d8b3caa9263e936d48d486e5df68893003e0a76496439594d12245008c6fba1c8e3ef28241cffe1bef27ff6bca487b167f261f329251c", + }, + ], + } + `) +}) + +test('parameters: blockNumber', () => { + expect( + verifyMessageQueryOptions(config, { + blockNumber: 1234567890n, + address, + message: 'This is a test message for viem!', + signature: + '0xefd5fb29a274ea6682673d8b3caa9263e936d48d486e5df68893003e0a76496439594d12245008c6fba1c8e3ef28241cffe1bef27ff6bca487b167f261f329251c', + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "verifyMessage", + { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "blockNumber": 1234567890n, + "message": "This is a test message for viem!", + "signature": "0xefd5fb29a274ea6682673d8b3caa9263e936d48d486e5df68893003e0a76496439594d12245008c6fba1c8e3ef28241cffe1bef27ff6bca487b167f261f329251c", + }, + ], + } + `) +}) + +test('parameters: blockTag', () => { + expect( + verifyMessageQueryOptions(config, { + blockTag: 'safe', + address, + message: 'This is a test message for viem!', + signature: + '0xefd5fb29a274ea6682673d8b3caa9263e936d48d486e5df68893003e0a76496439594d12245008c6fba1c8e3ef28241cffe1bef27ff6bca487b167f261f329251c', + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "verifyMessage", + { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "blockTag": "safe", + "message": "This is a test message for viem!", + "signature": "0xefd5fb29a274ea6682673d8b3caa9263e936d48d486e5df68893003e0a76496439594d12245008c6fba1c8e3ef28241cffe1bef27ff6bca487b167f261f329251c", + }, + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/verifyMessage.ts b/wagmi-project/packages/core/src/query/verifyMessage.ts new file mode 100644 index 000000000..d827e64b2 --- /dev/null +++ b/wagmi-project/packages/core/src/query/verifyMessage.ts @@ -0,0 +1,56 @@ +import type { QueryOptions } from '@tanstack/query-core' + +import { + type VerifyMessageErrorType, + type VerifyMessageParameters, + type VerifyMessageReturnType, + verifyMessage, +} from '../actions/verifyMessage.js' +import type { Config } from '../createConfig.js' +import type { ScopeKeyParameter } from '../types/properties.js' +import type { Compute, ExactPartial } from '../types/utils.js' +import { filterQueryOptions } from './utils.js' + +export type VerifyMessageOptions = Compute< + ExactPartial> & ScopeKeyParameter +> + +export function verifyMessageQueryOptions( + config: config, + options: VerifyMessageOptions = {}, +) { + return { + async queryFn({ queryKey }) { + const { address, message, signature } = queryKey[1] + if (!address || !message || !signature) + throw new Error('address, message, and signature are required') + + const { scopeKey: _, ...parameters } = queryKey[1] + + const verified = await verifyMessage( + config, + parameters as VerifyMessageParameters, + ) + return verified ?? null + }, + queryKey: verifyMessageQueryKey(options), + } as const satisfies QueryOptions< + VerifyMessageQueryFnData, + VerifyMessageErrorType, + VerifyMessageData, + VerifyMessageQueryKey + > +} +export type VerifyMessageQueryFnData = VerifyMessageReturnType + +export type VerifyMessageData = VerifyMessageQueryFnData + +export function verifyMessageQueryKey( + options: VerifyMessageOptions, +) { + return ['verifyMessage', filterQueryOptions(options)] as const +} + +export type VerifyMessageQueryKey = ReturnType< + typeof verifyMessageQueryKey +> diff --git a/wagmi-project/packages/core/src/query/verifyTypedData.test.ts b/wagmi-project/packages/core/src/query/verifyTypedData.test.ts new file mode 100644 index 000000000..f4145099c --- /dev/null +++ b/wagmi-project/packages/core/src/query/verifyTypedData.test.ts @@ -0,0 +1,284 @@ +import { accounts, chain, config, typedData } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { verifyTypedDataQueryOptions } from './verifyTypedData.js' + +const address = accounts[0] + +test('default', () => { + expect( + verifyTypedDataQueryOptions(config, { + address, + ...typedData.basic, + primaryType: 'Mail', + signature: + '0xefd5fb29a274ea6682673d8b3caa9263e936d48d486e5df68893003e0a76496439594d12245008c6fba1c8e3ef28241cffe1bef27ff6bca487b167f261f329251c', + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "verifyTypedData", + { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "domain": { + "chainId": 1, + "name": "Ether Mail", + "verifyingContract": "0x0000000000000000000000000000000000000000", + "version": "1", + }, + "message": { + "contents": "Hello, Bob!", + "from": { + "name": "Cow", + "wallet": "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826", + }, + "to": { + "name": "Bob", + "wallet": "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB", + }, + }, + "primaryType": "Mail", + "signature": "0xefd5fb29a274ea6682673d8b3caa9263e936d48d486e5df68893003e0a76496439594d12245008c6fba1c8e3ef28241cffe1bef27ff6bca487b167f261f329251c", + "types": { + "Mail": [ + { + "name": "from", + "type": "Person", + }, + { + "name": "to", + "type": "Person", + }, + { + "name": "contents", + "type": "string", + }, + ], + "Person": [ + { + "name": "name", + "type": "string", + }, + { + "name": "wallet", + "type": "address", + }, + ], + }, + }, + ], + } + `) +}) + +test('parameters: chainId', () => { + expect( + verifyTypedDataQueryOptions(config, { + ...typedData.basic, + domain: { + ...typedData.basic.domain, + chainId: chain.mainnet2.id, + }, + chainId: chain.mainnet2.id, + address, + primaryType: 'Mail', + signature: + '0xefd5fb29a274ea6682673d8b3caa9263e936d48d486e5df68893003e0a76496439594d12245008c6fba1c8e3ef28241cffe1bef27ff6bca487b167f261f329251c', + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "verifyTypedData", + { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "chainId": 456, + "domain": { + "chainId": 456, + "name": "Ether Mail", + "verifyingContract": "0x0000000000000000000000000000000000000000", + "version": "1", + }, + "message": { + "contents": "Hello, Bob!", + "from": { + "name": "Cow", + "wallet": "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826", + }, + "to": { + "name": "Bob", + "wallet": "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB", + }, + }, + "primaryType": "Mail", + "signature": "0xefd5fb29a274ea6682673d8b3caa9263e936d48d486e5df68893003e0a76496439594d12245008c6fba1c8e3ef28241cffe1bef27ff6bca487b167f261f329251c", + "types": { + "Mail": [ + { + "name": "from", + "type": "Person", + }, + { + "name": "to", + "type": "Person", + }, + { + "name": "contents", + "type": "string", + }, + ], + "Person": [ + { + "name": "name", + "type": "string", + }, + { + "name": "wallet", + "type": "address", + }, + ], + }, + }, + ], + } + `) +}) + +test('parameters: blockNumber', () => { + expect( + verifyTypedDataQueryOptions(config, { + blockNumber: 1234567890n, + address, + ...typedData.basic, + primaryType: 'Mail', + signature: + '0xefd5fb29a274ea6682673d8b3caa9263e936d48d486e5df68893003e0a76496439594d12245008c6fba1c8e3ef28241cffe1bef27ff6bca487b167f261f329251c', + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "verifyTypedData", + { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "blockNumber": 1234567890n, + "domain": { + "chainId": 1, + "name": "Ether Mail", + "verifyingContract": "0x0000000000000000000000000000000000000000", + "version": "1", + }, + "message": { + "contents": "Hello, Bob!", + "from": { + "name": "Cow", + "wallet": "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826", + }, + "to": { + "name": "Bob", + "wallet": "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB", + }, + }, + "primaryType": "Mail", + "signature": "0xefd5fb29a274ea6682673d8b3caa9263e936d48d486e5df68893003e0a76496439594d12245008c6fba1c8e3ef28241cffe1bef27ff6bca487b167f261f329251c", + "types": { + "Mail": [ + { + "name": "from", + "type": "Person", + }, + { + "name": "to", + "type": "Person", + }, + { + "name": "contents", + "type": "string", + }, + ], + "Person": [ + { + "name": "name", + "type": "string", + }, + { + "name": "wallet", + "type": "address", + }, + ], + }, + }, + ], + } + `) +}) + +test('parameters: blockTag', () => { + expect( + verifyTypedDataQueryOptions(config, { + blockTag: 'pending', + address, + ...typedData.basic, + primaryType: 'Mail', + signature: + '0xefd5fb29a274ea6682673d8b3caa9263e936d48d486e5df68893003e0a76496439594d12245008c6fba1c8e3ef28241cffe1bef27ff6bca487b167f261f329251c', + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "verifyTypedData", + { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "blockTag": "pending", + "domain": { + "chainId": 1, + "name": "Ether Mail", + "verifyingContract": "0x0000000000000000000000000000000000000000", + "version": "1", + }, + "message": { + "contents": "Hello, Bob!", + "from": { + "name": "Cow", + "wallet": "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826", + }, + "to": { + "name": "Bob", + "wallet": "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB", + }, + }, + "primaryType": "Mail", + "signature": "0xefd5fb29a274ea6682673d8b3caa9263e936d48d486e5df68893003e0a76496439594d12245008c6fba1c8e3ef28241cffe1bef27ff6bca487b167f261f329251c", + "types": { + "Mail": [ + { + "name": "from", + "type": "Person", + }, + { + "name": "to", + "type": "Person", + }, + { + "name": "contents", + "type": "string", + }, + ], + "Person": [ + { + "name": "name", + "type": "string", + }, + { + "name": "wallet", + "type": "address", + }, + ], + }, + }, + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/verifyTypedData.ts b/wagmi-project/packages/core/src/query/verifyTypedData.ts new file mode 100644 index 000000000..d7d3970b7 --- /dev/null +++ b/wagmi-project/packages/core/src/query/verifyTypedData.ts @@ -0,0 +1,82 @@ +import type { QueryOptions } from '@tanstack/query-core' +import type { TypedData } from 'viem' + +import { + type VerifyTypedDataErrorType, + type VerifyTypedDataParameters, + type VerifyTypedDataReturnType, + verifyTypedData, +} from '../actions/verifyTypedData.js' +import type { Config } from '../createConfig.js' +import type { ScopeKeyParameter } from '../types/properties.js' +import type { ExactPartial } from '../types/utils.js' +import { filterQueryOptions } from './utils.js' + +export type VerifyTypedDataOptions< + typedData extends TypedData | Record, + primaryType extends keyof typedData | 'EIP712Domain', + config extends Config, +> = ExactPartial> & + ScopeKeyParameter + +export function verifyTypedDataQueryOptions< + config extends Config, + const typedData extends TypedData | Record, + primaryType extends keyof typedData | 'EIP712Domain', +>( + config: config, + options: VerifyTypedDataOptions = {} as any, +) { + return { + async queryFn({ queryKey }) { + const { + address, + message, + primaryType, + signature, + types, + scopeKey: _, + ...parameters + } = queryKey[1] + if (!address) throw new Error('address is required') + if (!message) throw new Error('message is required') + if (!primaryType) throw new Error('primaryType is required') + if (!signature) throw new Error('signature is required') + if (!types) throw new Error('types is required') + + const verified = await verifyTypedData(config, { + ...parameters, + address, + message, + primaryType, + signature, + types, + } as VerifyTypedDataParameters) + return verified ?? null + }, + queryKey: verifyTypedDataQueryKey(options), + } as const satisfies QueryOptions< + VerifyTypedDataQueryFnData, + VerifyTypedDataErrorType, + VerifyTypedDataData, + VerifyTypedDataQueryKey + > +} + +export type VerifyTypedDataQueryFnData = VerifyTypedDataReturnType + +export type VerifyTypedDataData = VerifyTypedDataQueryFnData + +export function verifyTypedDataQueryKey< + config extends Config, + const typedData extends TypedData | Record, + primaryType extends keyof typedData | 'EIP712Domain', +>(options: VerifyTypedDataOptions) { + return ['verifyTypedData', filterQueryOptions(options)] as const +} + +export type VerifyTypedDataQueryKey< + typedData extends TypedData | Record, + primaryType extends keyof typedData | 'EIP712Domain', + config extends Config, +> = ReturnType> diff --git a/wagmi-project/packages/core/src/query/waitForCallsStatus.test.ts b/wagmi-project/packages/core/src/query/waitForCallsStatus.test.ts new file mode 100644 index 000000000..215ec7275 --- /dev/null +++ b/wagmi-project/packages/core/src/query/waitForCallsStatus.test.ts @@ -0,0 +1,23 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { waitForCallsStatusQueryOptions } from './waitForCallsStatus.js' + +test('default', () => { + expect( + waitForCallsStatusQueryOptions(config, { + id: '0x0000000000000000000000000000000000000000', + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "callsStatus", + { + "id": "0x0000000000000000000000000000000000000000", + }, + ], + "retry": [Function], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/waitForCallsStatus.ts b/wagmi-project/packages/core/src/query/waitForCallsStatus.ts new file mode 100644 index 000000000..197c279e9 --- /dev/null +++ b/wagmi-project/packages/core/src/query/waitForCallsStatus.ts @@ -0,0 +1,53 @@ +import type { QueryOptions } from '@tanstack/query-core' + +import { + type WaitForCallsStatusErrorType, + type WaitForCallsStatusParameters, + type WaitForCallsStatusReturnType, + waitForCallsStatus, +} from '../actions/waitForCallsStatus.js' +import type { Config } from '../createConfig.js' +import { ConnectorNotConnectedError } from '../errors/config.js' +import { filterQueryOptions } from '../query/utils.js' +import type { ScopeKeyParameter } from '../types/properties.js' +import type { Compute, PartialBy } from '../types/utils.js' + +export type WaitForCallsStatusOptions = Compute< + PartialBy & ScopeKeyParameter +> + +export function waitForCallsStatusQueryOptions( + config: config, + options: WaitForCallsStatusOptions, +) { + return { + async queryFn({ queryKey }) { + const { scopeKey: _, id, ...parameters } = queryKey[1] + if (!id) throw new Error('id is required') + const status = await waitForCallsStatus(config, { ...parameters, id }) + return status + }, + queryKey: waitForCallsStatusQueryKey(options), + retry(failureCount, error) { + if (error instanceof ConnectorNotConnectedError) return false + return failureCount < 3 + }, + } as const satisfies QueryOptions< + WaitForCallsStatusQueryFnData, + WaitForCallsStatusErrorType, + WaitForCallsStatusData, + WaitForCallsStatusQueryKey + > +} + +export type WaitForCallsStatusQueryFnData = WaitForCallsStatusReturnType + +export type WaitForCallsStatusData = WaitForCallsStatusQueryFnData + +export function waitForCallsStatusQueryKey(options: WaitForCallsStatusOptions) { + return ['callsStatus', filterQueryOptions(options)] as const +} + +export type WaitForCallsStatusQueryKey = ReturnType< + typeof waitForCallsStatusQueryKey +> diff --git a/wagmi-project/packages/core/src/query/waitForTransactionReceipt.test.ts b/wagmi-project/packages/core/src/query/waitForTransactionReceipt.test.ts new file mode 100644 index 000000000..1877e1bfe --- /dev/null +++ b/wagmi-project/packages/core/src/query/waitForTransactionReceipt.test.ts @@ -0,0 +1,18 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { waitForTransactionReceiptQueryOptions } from './waitForTransactionReceipt.js' + +test('default', () => { + expect( + waitForTransactionReceiptQueryOptions(config, {}), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "waitForTransactionReceipt", + {}, + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/waitForTransactionReceipt.ts b/wagmi-project/packages/core/src/query/waitForTransactionReceipt.ts new file mode 100644 index 000000000..3507dabeb --- /dev/null +++ b/wagmi-project/packages/core/src/query/waitForTransactionReceipt.ts @@ -0,0 +1,71 @@ +import type { QueryOptions } from '@tanstack/query-core' + +import { + type WaitForTransactionReceiptErrorType, + type WaitForTransactionReceiptParameters, + type WaitForTransactionReceiptReturnType, + waitForTransactionReceipt, +} from '../actions/waitForTransactionReceipt.js' +import type { Config } from '../createConfig.js' +import type { ScopeKeyParameter } from '../types/properties.js' +import type { Compute, ExactPartial } from '../types/utils.js' +import { filterQueryOptions } from './utils.js' + +export type WaitForTransactionReceiptOptions< + config extends Config, + chainId extends config['chains'][number]['id'], +> = Compute< + ExactPartial> & + ScopeKeyParameter +> + +export function waitForTransactionReceiptQueryOptions< + config extends Config, + chainId extends config['chains'][number]['id'], +>( + config: config, + options: WaitForTransactionReceiptOptions = {}, +) { + return { + async queryFn({ queryKey }) { + const { hash, ...parameters } = queryKey[1] + if (!hash) throw new Error('hash is required') + return waitForTransactionReceipt(config, { + ...parameters, + onReplaced: options.onReplaced, + hash, + }) as unknown as Promise< + WaitForTransactionReceiptReturnType + > + }, + queryKey: waitForTransactionReceiptQueryKey(options), + } as const satisfies QueryOptions< + WaitForTransactionReceiptQueryFnData, + WaitForTransactionReceiptErrorType, + WaitForTransactionReceiptData, + WaitForTransactionReceiptQueryKey + > +} + +export type WaitForTransactionReceiptQueryFnData< + config extends Config, + chainId extends config['chains'][number]['id'], +> = WaitForTransactionReceiptReturnType + +export type WaitForTransactionReceiptData< + config extends Config, + chainId extends config['chains'][number]['id'], +> = WaitForTransactionReceiptQueryFnData + +export function waitForTransactionReceiptQueryKey< + config extends Config, + chainId extends config['chains'][number]['id'], +>(options: WaitForTransactionReceiptOptions = {}) { + const { onReplaced: _, ...rest } = options + return ['waitForTransactionReceipt', filterQueryOptions(rest)] as const +} + +export type WaitForTransactionReceiptQueryKey< + config extends Config, + chainId extends config['chains'][number]['id'], +> = ReturnType> diff --git a/wagmi-project/packages/core/src/query/watchAsset.test.ts b/wagmi-project/packages/core/src/query/watchAsset.test.ts new file mode 100644 index 000000000..b580beadb --- /dev/null +++ b/wagmi-project/packages/core/src/query/watchAsset.test.ts @@ -0,0 +1,15 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { watchAssetMutationOptions } from './watchAsset.js' + +test('default', () => { + expect(watchAssetMutationOptions(config)).toMatchInlineSnapshot(` + { + "mutationFn": [Function], + "mutationKey": [ + "watchAsset", + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/watchAsset.ts b/wagmi-project/packages/core/src/query/watchAsset.ts new file mode 100644 index 000000000..52ab82be6 --- /dev/null +++ b/wagmi-project/packages/core/src/query/watchAsset.ts @@ -0,0 +1,42 @@ +import type { MutationOptions } from '@tanstack/query-core' + +import { + type WatchAssetErrorType, + type WatchAssetParameters, + type WatchAssetReturnType, + watchAsset, +} from '../actions/watchAsset.js' +import type { Config } from '../createConfig.js' +import type { Compute } from '../types/utils.js' +import type { Mutate, MutateAsync } from './types.js' + +export function watchAssetMutationOptions(config: Config) { + return { + mutationFn(variables) { + return watchAsset(config, variables) + }, + mutationKey: ['watchAsset'], + } as const satisfies MutationOptions< + WatchAssetData, + WatchAssetErrorType, + WatchAssetVariables + > +} + +export type WatchAssetData = WatchAssetReturnType + +export type WatchAssetVariables = Compute + +export type WatchAssetMutate = Mutate< + WatchAssetData, + WatchAssetErrorType, + WatchAssetVariables, + context +> + +export type WatchAssetMutateAsync = MutateAsync< + WatchAssetData, + WatchAssetErrorType, + WatchAssetVariables, + context +> diff --git a/wagmi-project/packages/core/src/query/writeContract.test-d.ts b/wagmi-project/packages/core/src/query/writeContract.test-d.ts new file mode 100644 index 000000000..3c80a8313 --- /dev/null +++ b/wagmi-project/packages/core/src/query/writeContract.test-d.ts @@ -0,0 +1,145 @@ +import { http } from 'viem' +import { writeContract } from 'viem/actions' +import { base } from 'viem/chains' +import { test } from 'vitest' + +import { createConfig } from '../createConfig.js' +import type { WriteContractMutate } from './writeContract.js' + +// https://github.com/wevm/wagmi/issues/3981 +test('gh#3981', () => { + const config = createConfig({ + chains: [base], + transports: { + [base.id]: http(), + }, + }) + + const abi = [ + { + type: 'function', + name: 'example1', + inputs: [ + { name: 'exampleName', type: 'address', internalType: 'address' }, + ], + outputs: [], + stateMutability: 'payable', + }, + { + type: 'function', + name: 'example2', + inputs: [ + { name: 'exampleName', type: 'address', internalType: 'address' }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + ] as const + + const write: WriteContractMutate = () => {} + write({ + abi, + address: '0x...', + functionName: 'example1', + args: ['0x...'], + value: 123n, + }) + write({ + abi: [ + { + type: 'function', + name: 'example1', + inputs: [ + { name: 'exampleName', type: 'address', internalType: 'address' }, + ], + outputs: [], + stateMutability: 'payable', + }, + { + type: 'function', + name: 'example2', + inputs: [ + { name: 'exampleName', type: 'address', internalType: 'address' }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + ] as const, + address: '0x...', + functionName: 'example1', + args: ['0x...'], + value: 123n, + }) + + write({ + abi, + address: '0x...', + functionName: 'example2', + args: ['0x...'], + // @ts-expect-error + value: 123n, + }) + write({ + abi: [ + { + type: 'function', + name: 'example1', + inputs: [ + { name: 'exampleName', type: 'address', internalType: 'address' }, + ], + outputs: [], + stateMutability: 'payable', + }, + { + type: 'function', + name: 'example2', + inputs: [ + { name: 'exampleName', type: 'address', internalType: 'address' }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + ], + address: '0x...', + functionName: 'example1', + args: ['0x...'], + value: 123n, + }) + + const client = config.getClient({ chainId: base.id }) + writeContract(client, { + abi, + address: '0x...', + account: '0x...', + functionName: 'example1', + args: ['0x...'], + value: 123n, + }) + writeContract(client, { + abi: [ + { + type: 'function', + name: 'example1', + inputs: [ + { name: 'exampleName', type: 'address', internalType: 'address' }, + ], + outputs: [], + stateMutability: 'payable', + }, + { + type: 'function', + name: 'example2', + inputs: [ + { name: 'exampleName', type: 'address', internalType: 'address' }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + ] as const, + address: '0x...', + account: '0x...', + functionName: 'example1', + args: ['0x...'], + value: 123n, + }) +}) diff --git a/wagmi-project/packages/core/src/query/writeContract.test.ts b/wagmi-project/packages/core/src/query/writeContract.test.ts new file mode 100644 index 000000000..04cde53c7 --- /dev/null +++ b/wagmi-project/packages/core/src/query/writeContract.test.ts @@ -0,0 +1,15 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { writeContractMutationOptions } from './writeContract.js' + +test('default', () => { + expect(writeContractMutationOptions(config)).toMatchInlineSnapshot(` + { + "mutationFn": [Function], + "mutationKey": [ + "writeContract", + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/writeContract.ts b/wagmi-project/packages/core/src/query/writeContract.ts new file mode 100644 index 000000000..0e368fe40 --- /dev/null +++ b/wagmi-project/packages/core/src/query/writeContract.ts @@ -0,0 +1,116 @@ +import type { MutateOptions, MutationOptions } from '@tanstack/query-core' +import type { Abi, ContractFunctionArgs, ContractFunctionName } from 'viem' + +import { + type WriteContractErrorType, + type WriteContractParameters, + type WriteContractReturnType, + writeContract, +} from '../actions/writeContract.js' +import type { Config } from '../createConfig.js' +import type { Compute } from '../types/utils.js' + +export function writeContractMutationOptions( + config: config, +) { + return { + mutationFn(variables) { + return writeContract(config, variables) + }, + mutationKey: ['writeContract'], + } as const satisfies MutationOptions< + WriteContractData, + WriteContractErrorType, + WriteContractVariables< + Abi, + string, + readonly unknown[], + config, + config['chains'][number]['id'] + > + > +} + +export type WriteContractData = Compute + +export type WriteContractVariables< + abi extends Abi | readonly unknown[], + functionName extends ContractFunctionName, + args extends ContractFunctionArgs< + abi, + 'nonpayable' | 'payable', + functionName + >, + config extends Config, + chainId extends config['chains'][number]['id'], + /// + allFunctionNames = ContractFunctionName, +> = WriteContractParameters< + abi, + functionName, + args, + config, + chainId, + allFunctionNames +> + +export type WriteContractMutate = < + const abi extends Abi | readonly unknown[], + functionName extends ContractFunctionName, + args extends ContractFunctionArgs< + abi, + 'nonpayable' | 'payable', + functionName + >, + chainId extends config['chains'][number]['id'], +>( + variables: WriteContractVariables, + options?: + | MutateOptions< + WriteContractData, + WriteContractErrorType, + WriteContractVariables< + abi, + functionName, + args, + config, + chainId, + // use `functionName` to make sure it's not union of all possible function names + functionName + >, + context + > + | undefined, +) => void + +export type WriteContractMutateAsync< + config extends Config, + context = unknown, +> = < + const abi extends Abi | readonly unknown[], + functionName extends ContractFunctionName, + args extends ContractFunctionArgs< + abi, + 'nonpayable' | 'payable', + functionName + >, + chainId extends config['chains'][number]['id'], +>( + variables: WriteContractVariables, + options?: + | MutateOptions< + WriteContractData, + WriteContractErrorType, + WriteContractVariables< + abi, + functionName, + args, + config, + chainId, + // use `functionName` to make sure it's not union of all possible function names + functionName + >, + context + > + | undefined, +) => Promise diff --git a/wagmi-project/packages/core/src/transports/connector.test.ts b/wagmi-project/packages/core/src/transports/connector.test.ts new file mode 100644 index 000000000..4b71c2b46 --- /dev/null +++ b/wagmi-project/packages/core/src/transports/connector.test.ts @@ -0,0 +1,97 @@ +import { config } from '@wagmi/test' +import { optimism } from 'viem/chains' +import { expect, test } from 'vitest' +import { createStore } from 'zustand' + +import { injected } from '../connectors/injected.js' +import { mock } from '../connectors/mock.js' +import { unstable_connector } from './connector.js' + +const connector = config.connectors[0]! + +test('setup', () => { + expect(unstable_connector(injected)({})).toMatchInlineSnapshot(` + { + "config": { + "key": "connector", + "methods": undefined, + "name": "Connector", + "request": [Function], + "retryCount": 3, + "retryDelay": 150, + "timeout": undefined, + "type": "connector", + }, + "request": [Function], + "value": undefined, + } + `) +}) + +test('behavior: connector type not found', () => { + const transport = unstable_connector({ type: 'foo' })({}) + expect(() => + transport.request({ method: 'eth_chainId' }), + ).rejects.toThrowErrorMatchingInlineSnapshot(` + [ProviderDisconnectedError: The Provider is disconnected from all chains. + + Details: Could not find connector of type "foo" in \`connectors\` passed to \`createConfig\`. + Version: viem@2.29.2] + `) +}) + +test('behavior: provider is disconnected', () => { + const transport = unstable_connector(mock)({ + connectors: createStore(() => [ + { + ...connector, + async getProvider() { + return undefined + }, + }, + ]), + }) + + expect(() => + transport.request({ method: 'eth_chainId' }), + ).rejects.toThrowErrorMatchingInlineSnapshot(` + [ProviderDisconnectedError: The Provider is disconnected from all chains. + + Details: Provider is disconnected. + Version: viem@2.29.2] + `) +}) + +test('behavior: chainId mismatch', () => { + const transport = unstable_connector(mock)({ + chain: optimism, + connectors: createStore(() => [ + { + ...connector, + async getProvider(options = {}) { + if (options.chainId === optimism.id) return connector.getProvider() + return undefined + }, + }, + ]), + }) + + expect(() => + transport.request({ method: 'eth_chainId' }), + ).rejects.toThrowErrorMatchingInlineSnapshot(` + [ChainDisconnectedError: The Provider is not connected to the requested chain. + + Details: The current chain of the connector (id: 1) does not match the target chain for the request (id: 10 – OP Mainnet). + Version: viem@2.29.2] + `) +}) + +test('behavior: request', () => { + const transport = unstable_connector(mock)({ + connectors: createStore(() => [connector]), + }) + + expect( + transport.request({ method: 'eth_chainId' }), + ).resolves.toThrowErrorMatchingInlineSnapshot(`"0x1"`) +}) diff --git a/wagmi-project/packages/core/src/transports/connector.ts b/wagmi-project/packages/core/src/transports/connector.ts new file mode 100644 index 000000000..0f03d4318 --- /dev/null +++ b/wagmi-project/packages/core/src/transports/connector.ts @@ -0,0 +1,87 @@ +import { + ChainDisconnectedError, + type EIP1193Parameters, + type EIP1193Provider, + type EIP1193RequestFn, + ProviderDisconnectedError, + type TransportConfig, + type WalletRpcSchema, + createTransport, + hexToNumber, + withRetry, + withTimeout, +} from 'viem' + +import type { Connector, Transport } from '../createConfig.js' + +export type ConnectorTransportConfig = { + /** The key of the transport. */ + key?: TransportConfig['key'] | undefined + /** The name of the transport. */ + name?: TransportConfig['name'] | undefined + /** The max number of times to retry. */ + retryCount?: TransportConfig['retryCount'] | undefined + /** The base delay (in ms) between retries. */ + retryDelay?: TransportConfig['retryDelay'] | undefined +} + +export type ConnectorTransport = Transport + +export function unstable_connector( + connector: Pick, + config: ConnectorTransportConfig = {}, +): Transport<'connector'> { + const { type } = connector + const { key = 'connector', name = 'Connector', retryDelay } = config + + return (parameters) => { + const { chain, connectors } = parameters + const retryCount = config.retryCount ?? parameters.retryCount + + const request: EIP1193RequestFn = async ({ method, params }) => { + const connector = connectors?.getState().find((c) => c.type === type) + if (!connector) + throw new ProviderDisconnectedError( + new Error( + `Could not find connector of type "${type}" in \`connectors\` passed to \`createConfig\`.`, + ), + ) + + const provider = (await connector.getProvider({ + chainId: chain?.id, + })) as EIP1193Provider | undefined + if (!provider) + throw new ProviderDisconnectedError( + new Error('Provider is disconnected.'), + ) + + // We are applying a retry & timeout strategy here as some injected wallets (e.g. MetaMask) fail to + // immediately resolve a JSON-RPC request on page load. + const chainId = hexToNumber( + await withRetry(() => + withTimeout(() => provider.request({ method: 'eth_chainId' }), { + timeout: 100, + }), + ), + ) + if (chain && chainId !== chain.id) + throw new ChainDisconnectedError( + new Error( + `The current chain of the connector (id: ${chainId}) does not match the target chain for the request (id: ${chain.id} – ${chain.name}).`, + ), + ) + + const body = { method, params } as EIP1193Parameters + return provider.request(body) + } + + return createTransport({ + key, + name, + request, + retryCount, + retryDelay, + type: 'connector', + }) + } +} diff --git a/wagmi-project/packages/core/src/transports/fallback.test.ts b/wagmi-project/packages/core/src/transports/fallback.test.ts new file mode 100644 index 000000000..dcae23cb7 --- /dev/null +++ b/wagmi-project/packages/core/src/transports/fallback.test.ts @@ -0,0 +1,63 @@ +import { http } from 'viem' +import { expect, test } from 'vitest' +import { unstable_connector } from './connector.js' +import { fallback } from './fallback.js' + +test('setup', () => { + expect( + fallback([ + unstable_connector({ type: 'injected' }), + http('https://example.com'), + ])({}), + ).toMatchInlineSnapshot(` + { + "config": { + "key": "fallback", + "methods": undefined, + "name": "Fallback", + "request": [Function], + "retryCount": 3, + "retryDelay": 150, + "timeout": undefined, + "type": "fallback", + }, + "request": [Function], + "value": { + "onResponse": [Function], + "transports": [ + { + "config": { + "key": "connector", + "methods": undefined, + "name": "Connector", + "request": [Function], + "retryCount": 0, + "retryDelay": 150, + "timeout": undefined, + "type": "connector", + }, + "request": [Function], + "value": undefined, + }, + { + "config": { + "key": "http", + "methods": undefined, + "name": "HTTP JSON-RPC", + "request": [Function], + "retryCount": 0, + "retryDelay": 150, + "timeout": 10000, + "type": "http", + }, + "request": [Function], + "value": { + "fetchOptions": undefined, + "url": "https://example.com", + }, + }, + ], + }, + } + `) +}) diff --git a/wagmi-project/packages/core/src/transports/fallback.ts b/wagmi-project/packages/core/src/transports/fallback.ts new file mode 100644 index 000000000..67069f5de --- /dev/null +++ b/wagmi-project/packages/core/src/transports/fallback.ts @@ -0,0 +1,10 @@ +import { fallback as viem_fallback } from 'viem' + +import type { Transport } from '../createConfig.js' + +export function fallback( + transports: Transport[], + config?: Parameters[1], +) { + return viem_fallback(transports, config) +} diff --git a/wagmi-project/packages/core/src/types/chain.test-d.ts b/wagmi-project/packages/core/src/types/chain.test-d.ts new file mode 100644 index 000000000..65632709e --- /dev/null +++ b/wagmi-project/packages/core/src/types/chain.test-d.ts @@ -0,0 +1,33 @@ +import type { Chain, mainnet, optimism, sepolia } from 'viem/chains' +import { expectTypeOf, test } from 'vitest' + +import type { Config } from '../createConfig.js' +import type { SelectChains } from './chain.js' +import type { Merge } from './utils.js' + +test('not narrowable', () => { + type Result = SelectChains + expectTypeOf().toEqualTypeOf() +}) + +test('chainId', () => { + type Result = SelectChains< + Config, + 1 + > + expectTypeOf().toEqualTypeOf() +}) + +test('at least one chain has formatters', () => { + type Result = SelectChains> + expectTypeOf().toEqualTypeOf< + readonly [typeof mainnet, typeof optimism] + >() +}) + +test('no formatters', () => { + type Result = SelectChains> + expectTypeOf().toEqualTypeOf< + readonly [Merge] + >() +}) diff --git a/wagmi-project/packages/core/src/types/chain.ts b/wagmi-project/packages/core/src/types/chain.ts new file mode 100644 index 000000000..5f8178317 --- /dev/null +++ b/wagmi-project/packages/core/src/types/chain.ts @@ -0,0 +1,26 @@ +import type { Chain, ChainFormatters } from 'viem' + +import type { Config } from '../createConfig.js' +import type { IsNarrowable, Merge } from './utils.js' + +/** Filters {@link Config} chains by {@link chainId} or simplifies if no `ChainFormatters` are present. */ +export type SelectChains< + config extends Config, + chainId extends config['chains'][number]['id'] | undefined = undefined, +> = Config extends config + ? readonly [Chain] // chains not inferrable, return default + : IsNarrowable extends true + ? readonly [Extract] // select specific chain + : HasFormatter extends true + ? config['chains'] // return all chains since one has formatter + : // return default chain with ID set to union (allows for more simple type since the only thing that is different is the chain ID for each chain) + readonly [Merge] + +type HasFormatter = chains extends readonly [ + infer head extends Chain, + ...infer tail extends readonly Chain[], +] + ? IsNarrowable extends true + ? true + : HasFormatter + : false diff --git a/wagmi-project/packages/core/src/types/properties.ts b/wagmi-project/packages/core/src/types/properties.ts new file mode 100644 index 000000000..760cc46bd --- /dev/null +++ b/wagmi-project/packages/core/src/types/properties.ts @@ -0,0 +1,23 @@ +import type { Config, Connector } from '../createConfig.js' + +export type ChainIdParameter< + config extends Config, + chainId extends + | config['chains'][number]['id'] + | undefined = config['chains'][number]['id'], +> = { + chainId?: + | (chainId extends config['chains'][number]['id'] ? chainId : undefined) + | config['chains'][number]['id'] + | undefined +} + +export type ConnectorParameter = { + connector?: Connector | undefined +} + +export type ScopeKeyParameter = { scopeKey?: string | undefined } + +export type SyncConnectedChainParameter = { + syncConnectedChain?: boolean | undefined +} diff --git a/wagmi-project/packages/core/src/types/register.ts b/wagmi-project/packages/core/src/types/register.ts new file mode 100644 index 000000000..db420adfd --- /dev/null +++ b/wagmi-project/packages/core/src/types/register.ts @@ -0,0 +1,9 @@ +import type { Config } from '../createConfig.js' + +// biome-ignore lint/suspicious/noEmptyInterface: +export interface Register {} +export type ResolvedRegister = { + config: Register extends { config: infer config extends Config } + ? config + : Config +} diff --git a/wagmi-project/packages/core/src/types/unit.ts b/wagmi-project/packages/core/src/types/unit.ts new file mode 100644 index 000000000..a64f794a8 --- /dev/null +++ b/wagmi-project/packages/core/src/types/unit.ts @@ -0,0 +1 @@ +export type Unit = 'ether' | 'gwei' | 'wei' | number diff --git a/wagmi-project/packages/core/src/types/utils.test-d.ts b/wagmi-project/packages/core/src/types/utils.test-d.ts new file mode 100644 index 000000000..523f9f2e3 --- /dev/null +++ b/wagmi-project/packages/core/src/types/utils.test-d.ts @@ -0,0 +1,40 @@ +import { assertType, expectTypeOf, test } from 'vitest' + +import type { + Compute, + ExactPartial, + IsNever, + Mutable, + OneOf, + PartialBy, +} from './utils.js' + +test('ExactPartial', () => { + expectTypeOf>().toEqualTypeOf<{ + foo?: boolean | undefined + bar?: boolean | undefined + }>() +}) + +test('IsNever', () => { + expectTypeOf>().toEqualTypeOf() +}) + +test('Mutable', () => { + expectTypeOf< + Mutable<{ foo: boolean; readonly bar: boolean }> + >().toEqualTypeOf<{ foo: boolean; bar: boolean }>() +}) + +test('OneOf', () => { + assertType>({ foo: false }) + assertType>({ bar: false }) +}) + +test('PartialBy', () => { + type Result = Compute> + expectTypeOf().toEqualTypeOf<{ + foo?: string | undefined + bar: number + }>() +}) diff --git a/wagmi-project/packages/core/src/types/utils.ts b/wagmi-project/packages/core/src/types/utils.ts new file mode 100644 index 000000000..aecd58a14 --- /dev/null +++ b/wagmi-project/packages/core/src/types/utils.ts @@ -0,0 +1,101 @@ +/** Combines members of an intersection into a readable type. */ +// https://twitter.com/mattpocockuk/status/1622730173446557697?s=20&t=NdpAcmEFXY01xkqU3KO0Mg +export type Compute = { [key in keyof type]: type[key] } & unknown + +/** + * Makes all properties of an object optional. + * + * Compatible with [`exactOptionalPropertyTypes`](https://www.typescriptlang.org/tsconfig#exactOptionalPropertyTypes). + */ +export type ExactPartial = { + [key in keyof type]?: type[key] | undefined +} + +/** Checks if {@link type} can be narrowed further than {@link type2} */ +export type IsNarrowable = IsUnknown extends true + ? false + : undefined extends type + ? false + : IsNever< + (type extends type2 ? true : false) & + (type2 extends type ? false : true) + > extends true + ? false + : true + +/** + * @internal + * Checks if {@link type} is `never` + */ +export type IsNever = [type] extends [never] ? true : false + +/** + * @internal + * Checks if {@link type} is `unknown` + */ +export type IsUnknown = unknown extends type ? true : false + +/** Merges two object types into new type */ +export type Merge = Compute< + LooseOmit & + obj2 +> + +/** Removes `readonly` from all properties of an object. */ +export type Mutable = { + -readonly [key in keyof type]: type[key] +} + +/** Strict version of built-in Omit type */ +export type StrictOmit = Pick< + type, + Exclude +> + +/** Makes objects destructurable. */ +export type OneOf< + union extends object, + /// + keys extends KeyofUnion = KeyofUnion, +> = union extends infer Item + ? Compute]?: undefined }> + : never +type KeyofUnion = type extends type ? keyof type : never + +/** Makes {@link key} optional in {@link type} while preserving type inference. */ +// s/o trpc (https://github.com/trpc/trpc/blob/main/packages/server/src/types.ts#L6) +export type PartialBy = ExactPartial< + Pick +> & + StrictOmit + +/* Removes `undefined` from object property */ +export type RemoveUndefined = { + [key in keyof type]: NonNullable +} + +/////////////////////////////////////////////////////////////////////////// +// Loose types + +/** Loose version of {@link StrictOmit} */ +export type LooseOmit = Pick< + type, + Exclude +> + +/////////////////////////////////////////////////////////////////////////// +// Union types + +export type UnionCompute = type extends object ? Compute : type + +export type UnionLooseOmit = type extends any + ? LooseOmit + : never + +export type UnionStrictOmit = type extends any + ? StrictOmit + : never + +export type UnionExactPartial = type extends object + ? ExactPartial + : type diff --git a/wagmi-project/packages/core/src/utils/cookie.test.ts b/wagmi-project/packages/core/src/utils/cookie.test.ts new file mode 100644 index 000000000..f21f5ccee --- /dev/null +++ b/wagmi-project/packages/core/src/utils/cookie.test.ts @@ -0,0 +1,69 @@ +import { http } from 'viem' +import { mainnet } from 'viem/chains' +import { expect, test } from 'vitest' + +import { createConfig } from '../createConfig.js' +import { createStorage } from '../createStorage.js' +import { cookieStorage, cookieToInitialState, parseCookie } from './cookie.js' + +test('cookieStorage', () => { + expect(cookieStorage.getItem('recentConnectorId')).toMatchInlineSnapshot( + 'null', + ) + cookieStorage.setItem('recentConnectorId', 'foo') + expect(cookieStorage.getItem('recentConnectorId')).toMatchInlineSnapshot( + `"foo"`, + ) + cookieStorage.removeItem('recentConnectorId') + expect(cookieStorage.getItem('recentConnectorId')).toMatchInlineSnapshot( + 'null', + ) +}) + +test('cookieToInitialState', () => { + const config = createConfig({ + chains: [mainnet], + transports: { [mainnet.id]: http() }, + storage: createStorage({ storage: cookieStorage }), + }) + + expect( + cookieToInitialState( + config, + 'wagmi.store={"state":{"connections":{"__type":"Map","value":[]},"chainId":1,"current":null},"version":2}; ', + ), + ).toMatchInlineSnapshot(` + { + "chainId": 1, + "connections": Map {}, + "current": null, + } + `) + + expect(cookieToInitialState(config)).toMatchInlineSnapshot('undefined') + expect(cookieToInitialState(config), 'foo').toMatchInlineSnapshot('undefined') +}) + +test('parseCookie', () => { + expect( + parseCookie( + 'wagmi.store={"state":{"connections":{"__type":"Map","value":[]},"chainId":1,"current":null},"version":2}; ', + 'wagmi.store', + ), + ).toMatchInlineSnapshot( + `"{"state":{"connections":{"__type":"Map","value":[]},"chainId":1,"current":null},"version":2}"`, + ) + + expect( + parseCookie( + 'foo="bar"; wagmi.store={"state":{"connections":{"__type":"Map","value":[]},"chainId":1,"current":null},"version":2}; ', + 'wagmi.store', + ), + ).toMatchInlineSnapshot( + `"{"state":{"connections":{"__type":"Map","value":[]},"chainId":1,"current":null},"version":2}"`, + ) + + expect(parseCookie('foo="bar"; ', 'wagmi.store')).toMatchInlineSnapshot( + 'undefined', + ) +}) diff --git a/wagmi-project/packages/core/src/utils/cookie.ts b/wagmi-project/packages/core/src/utils/cookie.ts new file mode 100644 index 000000000..ccd07bc7b --- /dev/null +++ b/wagmi-project/packages/core/src/utils/cookie.ts @@ -0,0 +1,33 @@ +import type { Config, State } from '../createConfig.js' +import type { BaseStorage } from '../createStorage.js' +import { deserialize } from './deserialize.js' + +export const cookieStorage = { + getItem(key) { + if (typeof window === 'undefined') return null + const value = parseCookie(document.cookie, key) + return value ?? null + }, + setItem(key, value) { + if (typeof window === 'undefined') return + document.cookie = `${key}=${value};path=/;samesite=Lax` + }, + removeItem(key) { + if (typeof window === 'undefined') return + document.cookie = `${key}=;max-age=-1;path=/` + }, +} satisfies BaseStorage + +export function cookieToInitialState(config: Config, cookie?: string | null) { + if (!cookie) return undefined + const key = `${config.storage?.key}.store` + const parsed = parseCookie(cookie, key) + if (!parsed) return undefined + return deserialize<{ state: State }>(parsed).state +} + +export function parseCookie(cookie: string, key: string) { + const keyValue = cookie.split('; ').find((x) => x.startsWith(`${key}=`)) + if (!keyValue) return undefined + return keyValue.substring(key.length + 1) +} diff --git a/wagmi-project/packages/core/src/utils/deepEqual.test.ts b/wagmi-project/packages/core/src/utils/deepEqual.test.ts new file mode 100644 index 000000000..6105fe496 --- /dev/null +++ b/wagmi-project/packages/core/src/utils/deepEqual.test.ts @@ -0,0 +1,40 @@ +import { expect, test } from 'vitest' + +import { deepEqual } from './deepEqual.js' + +test('compares primitive values', () => { + expect(deepEqual(true, true)).toBe(true) + expect(deepEqual(true, false)).toBe(false) + + expect(deepEqual(1, 1)).toBe(true) + expect(deepEqual(1, 2)).toBe(false) + + expect(deepEqual('zustand', 'zustand')).toBe(true) + expect(deepEqual('zustand', 'redux')).toBe(false) +}) + +test('compares objects', () => { + expect(deepEqual({ foo: 'bar', asd: 123 }, { foo: 'bar', asd: 123 })).toBe( + true, + ) + + expect( + deepEqual({ foo: 'bar', asd: 123 }, { foo: 'bar', foobar: true }), + ).toBe(false) + + expect( + deepEqual({ foo: 'bar', asd: 123 }, { foo: 'bar', asd: 123, foobar: true }), + ).toBe(false) +}) + +test('compares arrays', () => { + expect(deepEqual([1, 2, 3], [1, 2, 3])).toBe(true) + + expect(deepEqual([1, 2, 3], [2, 3, 4])).toBe(false) + + expect( + deepEqual([{ foo: 'bar' }, { asd: 123 }], [{ foo: 'bar' }, { asd: 123 }]), + ).toBe(true) + + expect(deepEqual([{ foo: 'bar' }], [{ foo: 'bar', asd: 123 }])).toBe(false) +}) diff --git a/wagmi-project/packages/core/src/utils/deepEqual.ts b/wagmi-project/packages/core/src/utils/deepEqual.ts new file mode 100644 index 000000000..89b47a6bd --- /dev/null +++ b/wagmi-project/packages/core/src/utils/deepEqual.ts @@ -0,0 +1,43 @@ +/** Forked from https://github.com/epoberezkin/fast-deep-equal */ + +export function deepEqual(a: any, b: any) { + if (a === b) return true + + if (a && b && typeof a === 'object' && typeof b === 'object') { + if (a.constructor !== b.constructor) return false + + let length: number + let i: number + + if (Array.isArray(a) && Array.isArray(b)) { + length = a.length + if (length !== b.length) return false + for (i = length; i-- !== 0; ) if (!deepEqual(a[i], b[i])) return false + return true + } + + if (a.valueOf !== Object.prototype.valueOf) + return a.valueOf() === b.valueOf() + if (a.toString !== Object.prototype.toString) + return a.toString() === b.toString() + + const keys = Object.keys(a) + length = keys.length + if (length !== Object.keys(b).length) return false + + for (i = length; i-- !== 0; ) + if (!Object.prototype.hasOwnProperty.call(b, keys[i]!)) return false + + for (i = length; i-- !== 0; ) { + const key = keys[i] + + if (key && !deepEqual(a[key], b[key])) return false + } + + return true + } + + // true if both NaN, false otherwise + // biome-ignore lint/suspicious/noSelfCompare: + return a !== a && b !== b +} diff --git a/wagmi-project/packages/core/src/utils/deserialize.test.ts b/wagmi-project/packages/core/src/utils/deserialize.test.ts new file mode 100644 index 000000000..11f73ff79 --- /dev/null +++ b/wagmi-project/packages/core/src/utils/deserialize.test.ts @@ -0,0 +1,114 @@ +import { expect, test } from 'vitest' + +import { deserialize } from './deserialize.js' +import { serialize } from './serialize.js' + +test('deserializes', () => { + const deserializedCache = deserialize( + serialize({ + some: 'complex', + object: { + that: 'has', + many: [ + { many: 'many', manymany: 'many' }, + { many: 'many' }, + { many: 'many' }, + { + many: { + properties: { + ones: { + that: { + have: { + functions: () => null, + }, + }, + }, + }, + }, + }, + ], + }, + and: { + ones: { + that: { + have: { + bigints: 123456789012345678901234567890n, + }, + }, + }, + }, + also: { + ones: { + that: { + have: { + proxies: new Proxy({ lol: 'nice' }, {}), + }, + }, + }, + }, + }), + ) + expect(deserializedCache).toMatchInlineSnapshot(` + { + "also": { + "ones": { + "that": { + "have": { + "proxies": { + "lol": "nice", + }, + }, + }, + }, + }, + "and": { + "ones": { + "that": { + "have": { + "bigints": 123456789012345678901234567890n, + }, + }, + }, + }, + "object": { + "many": [ + { + "many": "many", + "manymany": "many", + }, + { + "many": "many", + }, + { + "many": "many", + }, + { + "many": { + "properties": { + "ones": { + "that": { + "have": {}, + }, + }, + }, + }, + }, + ], + "that": "has", + }, + "some": "complex", + } + `) +}) + +test('Map', () => { + const map = new Map().set('foo', { bar: 'baz' }) + const deserializedCache = deserialize(serialize({ map })) + expect(deserializedCache).toEqual({ map }) +}) + +test('bigint', () => { + const bigint = 123n + const deserializedCache = deserialize(serialize({ bigint })) + expect(deserializedCache).toEqual({ bigint }) +}) diff --git a/wagmi-project/packages/core/src/utils/deserialize.ts b/wagmi-project/packages/core/src/utils/deserialize.ts new file mode 100644 index 000000000..36fe30dab --- /dev/null +++ b/wagmi-project/packages/core/src/utils/deserialize.ts @@ -0,0 +1,10 @@ +type Reviver = (key: string, value: any) => any + +export function deserialize(value: string, reviver?: Reviver): type { + return JSON.parse(value, (key, value_) => { + let value = value_ + if (value?.__type === 'bigint') value = BigInt(value.value) + if (value?.__type === 'Map') value = new Map(value.value) + return reviver?.(key, value) ?? value + }) +} diff --git a/wagmi-project/packages/core/src/utils/extractRpcUrls.test.ts b/wagmi-project/packages/core/src/utils/extractRpcUrls.test.ts new file mode 100644 index 000000000..6d2c21e26 --- /dev/null +++ b/wagmi-project/packages/core/src/utils/extractRpcUrls.test.ts @@ -0,0 +1,92 @@ +import { http } from 'viem' +import { mainnet, optimism, sepolia } from 'viem/chains' +import { expect, test } from 'vitest' + +import { injected } from '../connectors/injected.js' +import { unstable_connector } from '../transports/connector.js' +import { fallback } from '../transports/fallback.js' +import { extractRpcUrls } from './extractRpcUrls.js' + +test('default', () => { + expect( + extractRpcUrls({ + chain: mainnet, + transports: { + [mainnet.id]: fallback([ + http('https://wagmi.com'), + http('https://lol.com'), + ]), + [sepolia.id]: http('https://sepoliarocks.com'), + [optimism.id]: http(), + }, + }), + ).toMatchInlineSnapshot(` + [ + "https://wagmi.com", + "https://lol.com", + ] + `) + + expect( + extractRpcUrls({ + chain: sepolia, + transports: { + [mainnet.id]: fallback([ + http('https://wagmi.com'), + http('https://lol.com'), + ]), + [sepolia.id]: http('https://sepoliarocks.com'), + [optimism.id]: http(), + }, + }), + ).toMatchInlineSnapshot(` + [ + "https://sepoliarocks.com", + ] + `) + + expect( + extractRpcUrls({ + chain: optimism, + transports: { + [mainnet.id]: fallback([ + http('https://wagmi.com'), + http('https://lol.com'), + ]), + [sepolia.id]: http('https://sepoliarocks.com'), + [optimism.id]: http(), + }, + }), + ).toMatchInlineSnapshot(` + [ + "https://mainnet.optimism.io", + ] + `) + + expect( + extractRpcUrls({ + chain: mainnet, + }), + ).toMatchInlineSnapshot(` + [ + "https://eth.merkle.io", + ] + `) + + expect( + extractRpcUrls({ + chain: mainnet, + transports: { + [mainnet.id]: fallback([ + unstable_connector(injected), + http('https://lol.com'), + ]), + }, + }), + ).toMatchInlineSnapshot(` + [ + "https://eth.merkle.io", + "https://lol.com", + ] + `) +}) diff --git a/wagmi-project/packages/core/src/utils/extractRpcUrls.ts b/wagmi-project/packages/core/src/utils/extractRpcUrls.ts new file mode 100644 index 000000000..a617eac13 --- /dev/null +++ b/wagmi-project/packages/core/src/utils/extractRpcUrls.ts @@ -0,0 +1,19 @@ +import type { Chain, Transport } from 'viem' + +type ExtractRpcUrlsParameters = { + transports?: Record | undefined + chain: Chain +} + +export function extractRpcUrls(parameters: ExtractRpcUrlsParameters) { + const { chain } = parameters + const fallbackUrl = chain.rpcUrls.default.http[0] + + if (!parameters.transports) return [fallbackUrl] + + const transport = parameters.transports?.[chain.id]?.({ chain }) + const transports = (transport?.value?.transports as NonNullable< + typeof transport + >[]) || [transport] + return transports.map(({ value }) => value?.url || fallbackUrl) +} diff --git a/wagmi-project/packages/core/src/utils/getAction.test.ts b/wagmi-project/packages/core/src/utils/getAction.test.ts new file mode 100644 index 000000000..717385294 --- /dev/null +++ b/wagmi-project/packages/core/src/utils/getAction.test.ts @@ -0,0 +1,49 @@ +import { abi, address, config } from '@wagmi/test' +import * as viem_actions from 'viem/actions' +import { expect, test, vi } from 'vitest' + +import { getAction } from './getAction.js' + +test('uses tree-shakable action', async () => { + const client = config.getClient({ chainId: 1 }) + + const name = 'getBlockNumber' + const actions = { ...viem_actions } + const spy = vi.spyOn(actions, name) + const action = getAction(client, actions[name], name) + + await action({}) + expect(spy).toBeCalledWith(client, {}) +}) + +test('uses client action', async () => { + const client = config + .getClient({ chainId: 1 }) + .extend(() => ({ getBlockNumber: async () => 69n })) + + const name = 'getBlockNumber' + const spy = vi.spyOn(client, name) + const action = getAction(client, client[name], name) + + await action({}) + expect(spy).toBeCalledWith({}) +}) + +test('internal call', async () => { + const client = config.getClient({ chainId: 1 }).extend(() => ({ + async call() { + return { + data: '0x0000000000000000000000000000000000000000000000000000000000000045', + } + }, + })) + + await expect( + viem_actions.readContract(client, { + address: address.wagmiMintExample, + abi: abi.erc20, + functionName: 'balanceOf', + args: ['0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC'], + }), + ).resolves.toEqual(69n) +}) diff --git a/wagmi-project/packages/core/src/utils/getAction.ts b/wagmi-project/packages/core/src/utils/getAction.ts new file mode 100644 index 000000000..514ceb5d5 --- /dev/null +++ b/wagmi-project/packages/core/src/utils/getAction.ts @@ -0,0 +1,44 @@ +import type { + Account, + Chain, + Client, + PublicActions, + RpcSchema, + Transport, + WalletActions, +} from 'viem' + +/** + * Retrieves and returns an action from the client (if exists), and falls + * back to the tree-shakable action. + * + * Useful for extracting overridden actions from a client (ie. if a consumer + * wants to override the `sendTransaction` implementation). + */ +export function getAction< + transport extends Transport, + chain extends Chain | undefined, + account extends Account | undefined, + rpcSchema extends RpcSchema | undefined, + extended extends { [key: string]: unknown }, + client extends Client, + parameters, + returnType, +>( + client: client, + actionFn: (_: any, parameters: parameters) => returnType, + // Some minifiers drop `Function.prototype.name`, or replace it with short letters, + // meaning that `actionFn.name` will not always work. For that case, the consumer + // needs to pass the name explicitly. + name: keyof PublicActions | keyof WalletActions, +): (parameters: parameters) => returnType { + const action_implicit = client[actionFn.name] + if (typeof action_implicit === 'function') + return action_implicit as (params: parameters) => returnType + + const action_explicit = client[name] + if (typeof action_explicit === 'function') + return action_explicit as (params: parameters) => returnType + + return (params) => actionFn(client, params) +} diff --git a/wagmi-project/packages/core/src/utils/getUnit.test.ts b/wagmi-project/packages/core/src/utils/getUnit.test.ts new file mode 100644 index 000000000..1054303de --- /dev/null +++ b/wagmi-project/packages/core/src/utils/getUnit.test.ts @@ -0,0 +1,9 @@ +import { expect, test } from 'vitest' + +import { getUnit } from './getUnit.js' + +test('default', () => { + expect(getUnit(1)).toMatchInlineSnapshot('1') + expect(getUnit('wei')).toMatchInlineSnapshot('0') + expect(getUnit('ether')).toMatchInlineSnapshot('18') +}) diff --git a/wagmi-project/packages/core/src/utils/getUnit.ts b/wagmi-project/packages/core/src/utils/getUnit.ts new file mode 100644 index 000000000..084f45b62 --- /dev/null +++ b/wagmi-project/packages/core/src/utils/getUnit.ts @@ -0,0 +1,9 @@ +import { weiUnits } from 'viem' + +import type { Unit } from '../types/unit.js' + +export function getUnit(unit: Unit) { + if (typeof unit === 'number') return unit + if (unit === 'wei') return 0 + return Math.abs(weiUnits[unit]) +} diff --git a/wagmi-project/packages/core/src/utils/getVersion.test.ts b/wagmi-project/packages/core/src/utils/getVersion.test.ts new file mode 100644 index 000000000..29fa25617 --- /dev/null +++ b/wagmi-project/packages/core/src/utils/getVersion.test.ts @@ -0,0 +1,7 @@ +import { expect, test } from 'vitest' + +import { getVersion } from './getVersion.js' + +test('default', () => { + expect(getVersion()).toMatchInlineSnapshot(`"@wagmi/core@x.y.z"`) +}) diff --git a/wagmi-project/packages/core/src/utils/getVersion.ts b/wagmi-project/packages/core/src/utils/getVersion.ts new file mode 100644 index 000000000..350636526 --- /dev/null +++ b/wagmi-project/packages/core/src/utils/getVersion.ts @@ -0,0 +1,3 @@ +import { version } from '../version.js' + +export const getVersion = () => `@wagmi/core@${version}` diff --git a/wagmi-project/packages/core/src/utils/normalizeChainId.test.ts b/wagmi-project/packages/core/src/utils/normalizeChainId.test.ts new file mode 100644 index 000000000..de9d1882e --- /dev/null +++ b/wagmi-project/packages/core/src/utils/normalizeChainId.test.ts @@ -0,0 +1,24 @@ +import { expect, test } from 'vitest' + +import { normalizeChainId } from './normalizeChainId.js' + +test.each([ + { chainId: 1, expected: 1 }, + { chainId: '1', expected: 1 }, + { chainId: '0x1', expected: 1 }, + { chainId: '0x4', expected: 4 }, + { chainId: 42, expected: 42 }, + { chainId: '42', expected: 42 }, + { chainId: '0x2a', expected: 42 }, + { chainId: ' 0x2a', expected: 42 }, + { chainId: BigInt(1), expected: 1 }, + { chainId: BigInt(10), expected: 10 }, +])('normalizeChainId($chainId)', ({ chainId, expected }) => { + expect(normalizeChainId(chainId)).toEqual(expected) +}) + +test('unknown type', () => { + expect(() => normalizeChainId({})).toThrow( + 'Cannot normalize chainId "[object Object]" of type "object"', + ) +}) diff --git a/wagmi-project/packages/core/src/utils/normalizeChainId.ts b/wagmi-project/packages/core/src/utils/normalizeChainId.ts new file mode 100644 index 000000000..a1017c095 --- /dev/null +++ b/wagmi-project/packages/core/src/utils/normalizeChainId.ts @@ -0,0 +1,13 @@ +/** @deprecated use `Number` instead */ +export function normalizeChainId(chainId: bigint | number | string | unknown) { + if (typeof chainId === 'string') + return Number.parseInt( + chainId, + chainId.trim().substring(0, 2) === '0x' ? 16 : 10, + ) + if (typeof chainId === 'bigint') return Number(chainId) + if (typeof chainId === 'number') return chainId + throw new Error( + `Cannot normalize chainId "${chainId}" of type "${typeof chainId}"`, + ) +} diff --git a/wagmi-project/packages/core/src/utils/serialize.test.ts b/wagmi-project/packages/core/src/utils/serialize.test.ts new file mode 100644 index 000000000..e18210113 --- /dev/null +++ b/wagmi-project/packages/core/src/utils/serialize.test.ts @@ -0,0 +1,241 @@ +import { describe, expect, it } from 'vitest' + +import { serialize } from './serialize.js' + +class Foo { + value: string + + constructor(value: string) { + this.value = value + } +} + +const simpleObject = { + boolean: true, + fn() { + return 'foo' + }, + nan: Number.NaN, + nil: null, + number: 123, + string: 'foo', + undef: undefined, + [Symbol('key')]: 'value', +} + +const bigintObject = Object.assign({}, simpleObject, { + bigint: 123n, + nested: { + bigint: { + value: 69n, + }, + }, +}) + +const bufferString = 'this is a test buffer' +const complexObject = Object.assign({}, simpleObject, { + array: ['foo', { bar: 'baz' }], + buffer: Buffer.alloc(bufferString.length, bufferString), + error: new Error('boom'), + foo: new Foo('value'), + map: new Map().set('foo', { bar: 'baz' }), + object: { foo: { bar: 'baz' } }, + promise: Promise.resolve('foo'), + regexp: /foo/, + set: new Set().add('foo').add({ bar: 'baz' }), + weakmap: new WeakMap([ + [{}, 'foo'], + [{}, 'bar'], + ]), + weakset: new WeakSet([{}, {}]), +}) + +const circularObject = Object.assign( + {}, + complexObject, + { + map: { __type: 'Map', value: [['foo', { bar: 'baz' }]] }, + }, + { + deeply: { + nested: { + reference: {}, + }, + }, + }, +) + +circularObject.deeply.nested.reference = circularObject + +describe('stringify', () => { + describe('handling of object types', () => { + it('should handle simple objects', () => { + const result = serialize(simpleObject) + + expect(result).toMatchInlineSnapshot( + `"{"boolean":true,"nan":null,"nil":null,"number":123,"string":"foo"}"`, + ) + }) + + it('should handle objects with bigints', () => { + const result = serialize(bigintObject) + + expect(result).toMatchInlineSnapshot( + `"{"boolean":true,"nan":null,"nil":null,"number":123,"string":"foo","bigint":{"__type":"bigint","value":"123"},"nested":{"bigint":{"value":{"__type":"bigint","value":"69"}}}}"`, + ) + }) + + it('should handle simple objects with a custom replacer', () => { + const replacer = (_key: string, value: any) => + value && typeof value === 'object' ? value : `primitive-${value}` + + const result = serialize(simpleObject, replacer) + + expect(result).toMatchInlineSnapshot( + `"{"boolean":"primitive-true","fn":"primitive-fn() {\\n return \\"foo\\";\\n }","nan":"primitive-NaN","nil":"primitive-null","number":"primitive-123","string":"primitive-foo","undef":"primitive-undefined"}"`, + ) + }) + + it('should handle simple objects with indentation', () => { + const result = serialize(simpleObject, null, 2) + + expect(result).toMatchInlineSnapshot(` + "{ + "boolean": true, + "nan": null, + "nil": null, + "number": 123, + "string": "foo" + }" + `) + }) + + it('should handle bigint objects with indentation', () => { + const result = serialize(bigintObject, null, 2) + + expect(result).toMatchInlineSnapshot(` + "{ + "boolean": true, + "nan": null, + "nil": null, + "number": 123, + "string": "foo", + "bigint": { + "__type": "bigint", + "value": "123" + }, + "nested": { + "bigint": { + "value": { + "__type": "bigint", + "value": "69" + } + } + } + }" + `) + }) + + it('should handle complex objects', () => { + const result = serialize(complexObject) + + expect(result).toMatchInlineSnapshot( + `"{"boolean":true,"nan":null,"nil":null,"number":123,"string":"foo","array":["foo",{"bar":"baz"}],"buffer":{"type":"Buffer","data":[116,104,105,115,32,105,115,32,97,32,116,101,115,116,32,98,117,102,102,101,114]},"error":{},"foo":{"value":"value"},"map":{"__type":"Map","value":[["foo",{"bar":"baz"}]]},"object":{"foo":{"bar":"baz"}},"promise":{},"regexp":{},"set":{},"weakmap":{},"weakset":{}}"`, + ) + }) + + it('should handle complex objects with a custom replacer', () => { + const replacer = (_key: string, value: any) => + value && typeof value === 'object' ? value : `primitive-${value}` + + const result = serialize(complexObject, replacer) + + expect(result).toMatchInlineSnapshot( + `"{"boolean":"primitive-true","fn":"primitive-fn() {\\n return \\"foo\\";\\n }","nan":"primitive-NaN","nil":"primitive-null","number":"primitive-123","string":"primitive-foo","undef":"primitive-undefined","array":["primitive-foo",{"bar":"primitive-baz"}],"buffer":{"type":"primitive-Buffer","data":["primitive-116","primitive-104","primitive-105","primitive-115","primitive-32","primitive-105","primitive-115","primitive-32","primitive-97","primitive-32","primitive-116","primitive-101","primitive-115","primitive-116","primitive-32","primitive-98","primitive-117","primitive-102","primitive-102","primitive-101","primitive-114"]},"error":{},"foo":{"value":"primitive-value"},"map":{"__type":"primitive-Map","value":[["primitive-foo",{"bar":"primitive-baz"}]]},"object":{"foo":{"bar":"primitive-baz"}},"promise":{},"regexp":{},"set":{},"weakmap":{},"weakset":{}}"`, + ) + }) + + it('should handle circular objects', () => { + const result = serialize(circularObject) + + expect(result).toEqual( + JSON.stringify( + circularObject, + (() => { + const cache: any[] = [] + + return (_key, value) => { + if (value && typeof value === 'object' && ~cache.indexOf(value)) { + return '[ref=.]' + } + + cache.push(value) + + return value + } + })(), + ), + ) + }) + + it('should handle circular objects with a custom circular replacer', () => { + const result = serialize( + circularObject, + null, + null, + (_key: string, _value: string, referenceKey: string) => referenceKey, + ) + const circularReplacer = (() => { + const cache: any[] = [] + + return (_key: string, value: any) => { + if (value && typeof value === 'object' && ~cache.indexOf(value)) { + return '.' + } + + cache.push(value) + + return value + } + })() + + expect(result).toEqual(JSON.stringify(circularObject, circularReplacer)) + }) + }) + + describe('key references', () => { + it('should point to the top level object when it is referenced', () => { + const object = { + foo: 'bar', + deeply: { + recursive: { + object: {}, + }, + }, + } + + object.deeply.recursive.object = object + + expect(serialize(object)).toEqual( + `{"foo":"bar","deeply":{"recursive":{"object":"[ref=.]"}}}`, + ) + }) + + it('should point to the nested object when it is referenced', () => { + const object = { + foo: 'bar', + deeply: { + recursive: { + object: {}, + }, + }, + } + + object.deeply.recursive.object = object.deeply.recursive + + expect(serialize(object)).toEqual( + `{"foo":"bar","deeply":{"recursive":{"object":"[ref=.deeply.recursive]"}}}`, + ) + }) + }) +}) diff --git a/wagmi-project/packages/core/src/utils/serialize.ts b/wagmi-project/packages/core/src/utils/serialize.ts new file mode 100644 index 000000000..3f538c7b8 --- /dev/null +++ b/wagmi-project/packages/core/src/utils/serialize.ts @@ -0,0 +1,116 @@ +/** + * Get the reference key for the circular value + * + * @param keys the keys to build the reference key from + * @param cutoff the maximum number of keys to include + * @returns the reference key + */ +function getReferenceKey(keys: string[], cutoff: number) { + return keys.slice(0, cutoff).join('.') || '.' +} + +/** + * Faster `Array.prototype.indexOf` implementation build for slicing / splicing + * + * @param array the array to match the value in + * @param value the value to match + * @returns the matching index, or -1 + */ +function getCutoff(array: any[], value: any) { + const { length } = array + + for (let index = 0; index < length; ++index) { + if (array[index] === value) { + return index + 1 + } + } + + return 0 +} + +type StandardReplacer = (key: string, value: any) => any +type CircularReplacer = (key: string, value: any, referenceKey: string) => any + +/** + * Create a replacer method that handles circular values + * + * @param [replacer] a custom replacer to use for non-circular values + * @param [circularReplacer] a custom replacer to use for circular methods + * @returns the value to stringify + */ +function createReplacer( + replacer?: StandardReplacer | null | undefined, + circularReplacer?: CircularReplacer | null | undefined, +): StandardReplacer { + const hasReplacer = typeof replacer === 'function' + const hasCircularReplacer = typeof circularReplacer === 'function' + + const cache: any[] = [] + const keys: string[] = [] + + return function replace(this: any, key: string, value: any) { + if (typeof value === 'object') { + if (cache.length) { + const thisCutoff = getCutoff(cache, this) + + if (thisCutoff === 0) { + cache[cache.length] = this + } else { + cache.splice(thisCutoff) + keys.splice(thisCutoff) + } + + keys[keys.length] = key + + const valueCutoff = getCutoff(cache, value) + + if (valueCutoff !== 0) { + return hasCircularReplacer + ? circularReplacer.call( + this, + key, + value, + getReferenceKey(keys, valueCutoff), + ) + : `[ref=${getReferenceKey(keys, valueCutoff)}]` + } + } else { + cache[0] = value + keys[0] = key + } + } + + return hasReplacer ? replacer.call(this, key, value) : value + } +} + +/** + * Stringifier that handles circular values + * + * Forked from https://github.com/planttheidea/fast-stringify + * + * @param value to stringify + * @param [replacer] a custom replacer function for handling standard values + * @param [indent] the number of spaces to indent the output by + * @param [circularReplacer] a custom replacer function for handling circular values + * @returns the stringified output + */ +export function serialize( + value: any, + replacer?: StandardReplacer | null | undefined, + indent?: number | null | undefined, + circularReplacer?: CircularReplacer | null | undefined, +) { + return JSON.stringify( + value, + createReplacer((key, value_) => { + let value = value_ + if (typeof value === 'bigint') + value = { __type: 'bigint', value: value_.toString() } + if (value instanceof Map) + value = { __type: 'Map', value: Array.from(value_.entries()) } + return replacer?.(key, value) ?? value + }, circularReplacer), + indent ?? undefined, + ) +} diff --git a/wagmi-project/packages/core/src/utils/uid.ts b/wagmi-project/packages/core/src/utils/uid.ts new file mode 100644 index 000000000..dc966beac --- /dev/null +++ b/wagmi-project/packages/core/src/utils/uid.ts @@ -0,0 +1,14 @@ +const size = 256 +let index = size +let buffer: string + +export function uid(length = 11) { + if (!buffer || index + length > size * 2) { + buffer = '' + index = 0 + for (let i = 0; i < size; i++) { + buffer += ((256 + Math.random() * 256) | 0).toString(16).substring(1) + } + } + return buffer.substring(index, index++ + length) +} diff --git a/wagmi-project/packages/core/src/version.ts b/wagmi-project/packages/core/src/version.ts new file mode 100644 index 000000000..e291f4b23 --- /dev/null +++ b/wagmi-project/packages/core/src/version.ts @@ -0,0 +1 @@ +export const version = '2.17.2' diff --git a/wagmi-project/packages/core/test/setup.ts b/wagmi-project/packages/core/test/setup.ts new file mode 100644 index 000000000..f59a0488f --- /dev/null +++ b/wagmi-project/packages/core/test/setup.ts @@ -0,0 +1,5 @@ +import { vi } from 'vitest' + +vi.mock('../src/version.ts', () => { + return { version: 'x.y.z' } +}) diff --git a/wagmi-project/packages/core/tsconfig.build.json b/wagmi-project/packages/core/tsconfig.build.json new file mode 100644 index 000000000..fbed2b103 --- /dev/null +++ b/wagmi-project/packages/core/tsconfig.build.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.base.json", + "include": ["src/**/*.ts"], + "exclude": ["src/**/*.test.ts", "src/**/*.test-d.ts"], + "compilerOptions": { + "sourceMap": true + } +} diff --git a/wagmi-project/packages/core/tsconfig.json b/wagmi-project/packages/core/tsconfig.json new file mode 100644 index 000000000..bacbc9228 --- /dev/null +++ b/wagmi-project/packages/core/tsconfig.json @@ -0,0 +1,5 @@ +{ + "extends": "./tsconfig.build.json", + "include": ["src/**/*.ts", "test/**/*.ts"], + "exclude": [] +} diff --git a/wagmi-project/packages/create-wagmi/CHANGELOG.md b/wagmi-project/packages/create-wagmi/CHANGELOG.md new file mode 100644 index 000000000..7ab58fe7e --- /dev/null +++ b/wagmi-project/packages/create-wagmi/CHANGELOG.md @@ -0,0 +1,278 @@ +# create-wagmi + +## 2.0.14 + +### Patch Changes + +- [#4450](https://github.com/wevm/wagmi/pull/4450) [`7b9a6bb35881b657a00bdd7ccd7edea32660f5bf`](https://github.com/wevm/wagmi/commit/7b9a6bb35881b657a00bdd7ccd7edea32660f5bf) Thanks [@tmm](https://github.com/tmm)! - Removed internal usage of `fs-extra`. + +## 2.0.13 + +### Patch Changes + +- [#4060](https://github.com/wevm/wagmi/pull/4060) [`95965c1f19d480b97f2b297a077a9e607dee32ad`](https://github.com/wevm/wagmi/commit/95965c1f19d480b97f2b297a077a9e607dee32ad) Thanks [@dalechyn](https://github.com/dalechyn)! - Bumped Tanstack Query dependencies to fix typing issues between exported Wagmi query options and TanStack Query suspense query methods (due to [`direction` property in `QueryFunctionContext` being deprecated](https://github.com/TanStack/query/pull/7410)). + +## 2.0.12 + +### Patch Changes + +- [`c00303d0c5909680b3124f92c0a2d2f31ea30405`](https://github.com/wevm/wagmi/commit/c00303d0c5909680b3124f92c0a2d2f31ea30405) Thanks [@tmm](https://github.com/tmm)! - Bumped Next.js version + +## 2.0.11 + +### Patch Changes + +- [#3871](https://github.com/wevm/wagmi/pull/3871) [`0e6bd286`](https://github.com/wevm/wagmi/commit/0e6bd286ca2572d2bfbe206db460528b7c2ebc63) Thanks [@jxom](https://github.com/jxom)! - Added `.npmrc` with `legacy-peer-deps = true` to templates. + +## 2.0.10 + +### Patch Changes + +- [`3f8203bd`](https://github.com/wevm/wagmi/commit/3f8203bd77fcf6b6756640b5971d09741ae3853d) Thanks [@tmm](https://github.com/tmm)! - Set Wagmi-related package versions to latest. + +## 2.0.9 + +### Patch Changes + +- [#3518](https://github.com/wevm/wagmi/pull/3518) [`338e857d`](https://github.com/wevm/wagmi/commit/338e857d8cb2fe85e13d9207bef14cada1c1962d) Thanks [@tmm](https://github.com/tmm)! - Bumped dependencies. + +## 2.0.8 + +### Patch Changes + +- [#3510](https://github.com/wevm/wagmi/pull/3510) [`660ff80d`](https://github.com/wevm/wagmi/commit/660ff80d5b046967a446eba43ee54b8359a37d0d) Thanks [@tmm](https://github.com/tmm)! - Fixed issue where connectors returning multiple addresses didn't checksum correctly. + +## 2.0.7 + +### Patch Changes + +- [#3496](https://github.com/wevm/wagmi/pull/3496) [`ba7f8a75`](https://github.com/wevm/wagmi/commit/ba7f8a758efb07664c6e401b5e7e325e7c62341b) Thanks [@tmm](https://github.com/tmm)! - Bumped dependencies. + +## 2.0.6 + +### Patch Changes + +- [#3427](https://github.com/wevm/wagmi/pull/3427) [`370f1b4a`](https://github.com/wevm/wagmi/commit/370f1b4a3f154d181acf381c31c2e7862e22c0e4) Thanks [@marthendalnunes](https://github.com/marthendalnunes)! - Bumped dependencies. + +## 2.0.5 + +### Patch Changes + +- [#3459](https://github.com/wevm/wagmi/pull/3459) [`d950b666`](https://github.com/wevm/wagmi/commit/d950b666b56700ca039ce16cdfdf34564991e7f5) Thanks [@marthendalnunes](https://github.com/marthendalnunes)! - Bumped dependencies + +## 2.0.4 + +### Patch Changes + +- [#3443](https://github.com/wevm/wagmi/pull/3443) [`007024a6`](https://github.com/wevm/wagmi/commit/007024a684ddbecf924cdc06dd6a8854fc3d5eeb) Thanks [@jmrossy](https://github.com/jmrossy)! - Bumped dependencies. + +- [#3447](https://github.com/wevm/wagmi/pull/3447) [`a02a26ad`](https://github.com/wevm/wagmi/commit/a02a26ad030d3afb78f744377d61b5c60b65d97a) Thanks [@tmm](https://github.com/tmm)! - Bumped dependencies. + +## 2.0.3 + +### Patch Changes + +- [`ec0d8b41`](https://github.com/wevm/wagmi/commit/ec0d8b4112181fefb11025e436a94a6114761d37) Thanks [@tmm](https://github.com/tmm)! - Added note to `metaMask` connector. + +## 2.0.2 + +### Patch Changes + +- [#3384](https://github.com/wevm/wagmi/pull/3384) [`ee868c33`](https://github.com/wevm/wagmi/commit/ee868c3385dae511230b6ddcb5627c1293cc1844) Thanks [@tmm](https://github.com/tmm)! - Fixed connectors not bubbling error when connecting with `chainId` and subsequent user rejection. + +## 2.0.1 + +### Major Changes + +- [#3333](https://github.com/wevm/wagmi/pull/3333) [`b3a0baaa`](https://github.com/wevm/wagmi/commit/b3a0baaaee7decf750d376aab2502cd33ca4825a) Thanks [@tmm](https://github.com/tmm)! - Added support for Wagmi 2.0. + +## 1.0.5 + +### Patch Changes + +- 6ba996f: Fixed optional WalletConnect Cloud Project ID prompt + +## 1.0.4 + +### Patch Changes + +- eb8dd9d: Updated wagmi & viem. Added ConnectKit template back in. + +## 1.0.3 + +### Patch Changes + +- 00d9080: Added RainbowKit & Web3Modal wagmi v1 templates + +## 1.0.2 + +### Patch Changes + +- 3c65f77: Fixed Next.js default template title + +## 1.0.0 + +### Major Changes + +- affc13e: Updated to wagmi v1. + +## 0.1.19 + +### Patch Changes + +- 1282f0e: Updated templates to use WalletConnect v2 by default + +## 0.1.18 + +### Patch Changes + +- 12dcfe0: Updated wagmi to 0.12 in ConnectKit templates. + +## 0.1.17 + +### Patch Changes + +- 6eba01a: Updated wagmi to 0.12. +- 3a0ab8c: Added .env to .gitignore in templates. + +## 0.1.16 + +### Patch Changes + +- 7ad50f1: Upgraded `@wagmi/cli` + +## 0.1.15 + +### Patch Changes + +- 6e30599: Added `test` config to `foundry.toml` on the Foundry templates. + +## 0.1.14 + +### Patch Changes + +- 19f3675: Bumped `wagmi` to `~0.11.0`. + +## 0.1.13 + +### Patch Changes + +- c1ab75c: Bump @wagmi/cli + +## 0.1.12 + +### Patch Changes + +- af6e551: Added templates for `@wagmi/cli`: + + - `@wagmi/cli (Mint NFT Example)` + - `@wagmi/cli + ERC20` + - `@wagmi/cli + Etherscan (Mint NFT Example)` + - `@wagmi/cli + Foundry (Counter.sol Example)` + +## 0.1.11 + +### Patch Changes + +- cc638dd: Fixed an issue where Vite projects used `process.env` instead of `import.meta.env`. +- 75d1c2d: Updated `wagmi` to `~0.10.0`. + +## 0.1.10 + +### Patch Changes + +- 9cd7140: Amend gitignore files for Vite templates + +## 0.1.9 + +### Patch Changes + +- 904a2e1: Fixed import env variables in Vite (React) templates + +## 0.1.8 + +### Patch Changes + +- 65cc841: Update RainbowKit & ConnectKit templates to `wagmi@~0.9.0` + +## 0.1.7 + +### Patch Changes + +- a59d9c5: Upgrade `default` & `web3modal` templates to `wagmi@0.9` + +## 0.1.6 + +### Patch Changes + +- b544457: Updated `connectkit` to `1.1.0` in the ConnectKit templates + +## 0.1.5 + +### Patch Changes + +- 6bd6c74: Updated repo link in package.json + +## 0.1.4 + +### Patch Changes + +- c39666b: Added ability to select providers +- 37708ed: **Added ability to select frameworks.** + + Each directory in `templates/` now mirrors a "framework", where its child directories mirror a "template" for that framework. + + Example: + + ``` + templates/ + next/ + connectkit/ + default/ + rainbowkit/ + web3modal + vite-react/ + connectkit/ + default/ + rainbowkit/ + web3modal/ + ``` + +- 399d2b9: Moved template configuration to the template level + added hooks + +## 0.1.3 + +### Patch Changes + +- 353332a: Added Web3Modal template +- dd95b14: **next-with-connectkit**: Update `connectkit` to `^1.0.0` + +## 0.1.2 + +### Patch Changes + +- 34f666b: Fixed issue where package manager install process would not log error + +## 0.1.1 + +### Patch Changes + +- 900cbdc: Updated `@rainbow-me/rainbowkit` dependency in Next + RainbowKit template + +## 0.1.0 + +### Minor Changes + +- 23993d2: ## 🎉 Initial release 🎉 + + Get up and running quickly with wagmi by using the `create-wagmi` CLI. This tool interactively scaffolds a new wagmi project for you so you can start building instantly without the hassle of setting up `git`, installing packages, worrying about TypeScript configuration, etc. + + To get started, `create-wagmi` can be instantiated with one of your favorite package managers: + + ```bash + npm init wagmi + # or + pnpm create wagmi + # or + yarn create wagmi + ``` diff --git a/wagmi-project/packages/create-wagmi/README.md b/wagmi-project/packages/create-wagmi/README.md new file mode 100644 index 000000000..f923127ca --- /dev/null +++ b/wagmi-project/packages/create-wagmi/README.md @@ -0,0 +1,17 @@ +# create-wagmi + +Get up and running quickly with [Wagmi](https://wagmi.sh) by using the `create-wagmi` CLI. + +## Installation + +```bash +npm create wagmi +# or +pnpm create wagmi +# or +yarn create wagmi +``` + +## Documentation + +For documentation and guides, visit [wagmi.sh](https://wagmi.sh/cli/create-wagmi). diff --git a/wagmi-project/packages/create-wagmi/package.json b/wagmi-project/packages/create-wagmi/package.json new file mode 100644 index 000000000..7b6798c62 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/package.json @@ -0,0 +1,49 @@ +{ + "name": "create-wagmi", + "description": "Create Wagmi apps with one command", + "version": "2.0.14", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/wevm/wagmi.git", + "directory": "packages/create-wagmi" + }, + "scripts": { + "build": "pnpm run clean && pnpm run build:esm+types", + "build:esm+types": "tsc --project tsconfig.build.json --outDir ./dist/esm --declaration --declarationMap --declarationDir ./dist/types", + "check:types": "tsc --noEmit", + "clean": "rm -rf dist tsconfig.tsbuildinfo", + "dev": "bun src/cli.ts", + "test:build": "publint --strict" + }, + "files": [ + "dist/**", + "!dist/**/*.tsbuildinfo", + "src/**/*.ts", + "!src/**/*.test.ts", + "!src/**/*.test-d.ts", + "templates/**" + ], + "bin": { + "wagmi": "./dist/esm/cli.js" + }, + "sideEffects": false, + "type": "module", + "exports": { + "./package.json": "./package.json" + }, + "dependencies": { + "cac": "^6.7.14", + "cross-spawn": "^7.0.5", + "picocolors": "^1.0.0", + "prompts": "^2.4.2" + }, + "devDependencies": { + "@types/cross-spawn": "^6.0.6", + "@types/node": "^20.12.10", + "@types/prompts": "^2.4.9" + }, + "contributors": ["awkweb.eth ", "jxom.eth "], + "funding": "https://github.com/sponsors/wevm", + "keywords": ["wagmi", "eth", "ethereum", "dapps", "wallet", "web3", "cli"] +} diff --git a/wagmi-project/packages/create-wagmi/src/cli.test.ts b/wagmi-project/packages/create-wagmi/src/cli.test.ts new file mode 100644 index 000000000..4d6915a6f --- /dev/null +++ b/wagmi-project/packages/create-wagmi/src/cli.test.ts @@ -0,0 +1,151 @@ +import { + type ExecSyncOptionsWithStringEncoding, + execSync, +} from 'node:child_process' +import { mkdirSync, readdirSync, writeFileSync } from 'node:fs' +import { rm } from 'node:fs/promises' +import { join } from 'node:path' +import pc from 'picocolors' +import { afterEach, beforeAll, expect, test } from 'vitest' + +import { version } from './version.js' + +const cliPath = join(__dirname, '../dist/esm/cli.js') + +const projectName = 'test-app' +const genPath = join(__dirname, projectName) + +function run( + args: string[], + options: ExecSyncOptionsWithStringEncoding = { encoding: 'utf8' }, +): string { + return execSync(`node ${cliPath} ${args.join(' ')}`, options) +} + +function createNonEmptyDir() { + mkdirSync(genPath, { recursive: true }) + const file = join(genPath, 'foo') + writeFileSync(file, 'bar') +} + +beforeAll(async () => { + execSync('pnpm --filter create-wagmi build') + await rm(genPath, { recursive: true, force: true }) +}) +afterEach(async () => { + await rm(genPath, { recursive: true, force: true }) +}) + +test('prompts for the project name if none supplied', () => { + const stdout = run([]) + expect(stdout).toContain('Project name:') +}) + +test('prompts for the framework if none supplied when target dir is current directory', () => { + mkdirSync(genPath) + const stdout = run(['.'], { cwd: genPath, encoding: 'utf8' }) + expect(stdout).toContain('Select a framework:') +}) + +test('prompts for the framework if none supplied', () => { + const stdout = run([projectName]) + expect(stdout).toContain('Select a framework:') +}) + +test('prompts for the framework on not supplying a value for --template', () => { + const stdout = run([projectName, '--template']) + expect(stdout).toContain('Select a framework:') +}) + +test('prompts for the framework on supplying an invalid template', () => { + const stdout = run([projectName, '--template', 'unknown']) + expect(stdout).toContain( + `"unknown" isn't a valid template. Please choose from below:`, + ) +}) + +test('asks to overwrite non-empty target directory', () => { + createNonEmptyDir() + const stdout = run([projectName], { cwd: __dirname, encoding: 'utf8' }) + expect(stdout).toContain(`Target directory "${projectName}" is not empty.`) +}) + +test('asks to overwrite non-empty current directory', () => { + createNonEmptyDir() + const stdout = run(['.'], { cwd: genPath, encoding: 'utf8' }) + expect(stdout).toContain('Current directory is not empty.') +}) + +const templateFiles = readdirSync( + join(cliPath, '../../../templates/vite-react'), +) + .map((filePath) => { + if (filePath === '_gitignore') return '.gitignore' + if (filePath === '_env.local') return '.env.local' + if (filePath === '_npmrc') return '.npmrc' + return filePath + }) + .sort() + +test('successfully scaffolds a project based on vite-react starter template', () => { + mkdirSync(genPath, { recursive: true }) + const stdout = run([projectName, '--template', 'vite-react'], { + cwd: __dirname, + encoding: 'utf8', + }) + const generatedFiles = readdirSync(genPath).sort() + + expect(stdout).toContain(`Scaffolding project in ${genPath}`) + expect(templateFiles).toEqual(generatedFiles) +}) + +test('works with the -t alias', () => { + mkdirSync(genPath, { recursive: true }) + const stdout = run([projectName, '-t', 'vite-react'], { + cwd: __dirname, + encoding: 'utf8', + }) + const generatedFiles = readdirSync(genPath).sort() + + expect(stdout).toContain(`Scaffolding project in ${genPath}`) + expect(templateFiles).toEqual(generatedFiles) +}) + +test('uses different package manager', () => { + mkdirSync(genPath, { recursive: true }) + const stdout = run([projectName, '--bun', '-t', 'vite-react'], { + cwd: __dirname, + encoding: 'utf8', + }) + + expect(stdout).toContain('bun install') +}) + +test('shows help', () => { + const stdout = run(['--help']) + expect( + stdout + .replace(version, 'x.y.z') + .replace(pc.green(''), ''), + ).toMatchInlineSnapshot(` + "create-wagmi/x.y.z + + Usage: + $ create-wagmi [options] + + Options: + -t, --template [name] Template to bootstrap with. Available: vite-react, next, vite-vue, nuxt, vite-vanilla + --bun Use bun as your package manager + --npm Use npm as your package manager + --pnpm Use pnpm as your package manager + --yarn Use yarn as your package manager + -h, --help Display this message + -v, --version Display version number + " + `) +}) + +test('shows version', () => { + const stdout = run(['--version']) + expect(stdout).toContain(`create-wagmi/${version} `) +}) diff --git a/wagmi-project/packages/create-wagmi/src/cli.ts b/wagmi-project/packages/create-wagmi/src/cli.ts new file mode 100644 index 000000000..ecb6a25a4 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/src/cli.ts @@ -0,0 +1,284 @@ +#!/usr/bin/env node +import * as fs from 'node:fs' +import * as path from 'node:path' +import { fileURLToPath } from 'node:url' +import { cac } from 'cac' +import spawn from 'cross-spawn' +import pc from 'picocolors' +import prompts from 'prompts' + +import { type Framework, frameworks } from './frameworks.js' +import { + copy, + emptyDir, + formatTargetDir, + isEmpty, + isValidPackageName, + pkgFromUserAgent, + toValidPackageName, +} from './utils.js' +import { version } from './version.js' + +const templates = frameworks + .map((f) => f.variants?.map((v) => v.name) || [f.name]) + .reduce((a, b) => a.concat(b), []) + +const cli = cac('create-wagmi') + +cli + .usage(`${pc.green('')} [options]`) + .option( + '-t, --template [name]', + `Template to bootstrap with. Available: ${templates + .sort((a, b) => (a && !b ? -1 : 1)) + .join(', ')}`, + ) + .option('--bun', 'Use bun as your package manager') + .option('--npm', 'Use npm as your package manager') + .option('--pnpm', 'Use pnpm as your package manager') + .option('--yarn', 'Use yarn as your package manager') + +cli.help() +cli.version(version) + +const cwd = process.cwd() + +const renameFiles: Record = { + '_env.local': '.env.local', + // https://github.com/npm/npm/issues/1862 + _gitignore: '.gitignore', + _npmrc: '.npmrc', +} + +const defaultTargetDir = 'wagmi-project' + +async function init() { + const { args, options } = cli.parse(process.argv) + if (options.help) return + if (options.version) return + + const argTargetDir = formatTargetDir(args[0]) + const argTemplate = options.template || options.t + + let targetDir = argTargetDir || defaultTargetDir + function getProjectName() { + return targetDir === '.' ? path.basename(path.resolve()) : targetDir + } + + let result: prompts.Answers< + 'framework' | 'overwrite' | 'packageName' | 'projectName' | 'variant' + > + try { + result = await prompts( + [ + { + type: argTargetDir ? null : 'text', + name: 'projectName', + message: pc.reset('Project name:'), + initial: defaultTargetDir, + onState(state) { + targetDir = formatTargetDir(state.value) || defaultTargetDir + }, + }, + { + type() { + return !fs.existsSync(targetDir) || isEmpty(targetDir) + ? null + : 'confirm' + }, + name: 'overwrite', + message() { + return `${ + targetDir === '.' + ? 'Current directory' + : `Target directory "${targetDir}"` + } is not empty. Remove existing files and continue?` + }, + }, + { + type(_, { overwrite }: { overwrite?: boolean }) { + if (overwrite === false) + throw new Error(`${pc.red('✖')} Operation cancelled`) + return null + }, + name: 'overwriteChecker', + }, + { + type() { + return isValidPackageName(getProjectName()) ? null : 'text' + }, + name: 'packageName', + message: pc.reset('Package name:'), + initial() { + return toValidPackageName(getProjectName()) + }, + validate(dir) { + return isValidPackageName(dir) || 'Invalid package.json name' + }, + }, + { + type: + argTemplate && templates.includes(argTemplate) ? null : 'select', + name: 'framework', + message: + typeof argTemplate === 'string' && !templates.includes(argTemplate) + ? pc.reset( + `"${argTemplate}" isn't a valid template. Please choose from below: `, + ) + : pc.reset('Select a framework:'), + initial: 0, + choices: frameworks.map((framework) => { + const frameworkColor = framework.color + return { + title: frameworkColor(framework.display || framework.name), + value: framework, + } + }), + }, + { + type(framework: Framework) { + return framework?.variants?.length > 1 ? 'select' : null + }, + name: 'variant', + message: pc.reset('Select a variant:'), + choices(framework: Framework) { + return framework.variants.map((variant) => { + const variantColor = variant.color + return { + title: variantColor(variant.display || variant.name), + value: variant.name, + } + }) + }, + }, + ], + { + onCancel() { + throw new Error(`${pc.red('✖')} Operation cancelled`) + }, + }, + ) + } catch (error) { + // biome-ignore lint/suspicious/noConsoleLog: + console.log((error as Error).message) + return + } + + // user choice associated with prompts + const { + framework, + overwrite, + packageName, + variant = framework?.variants[0]?.name, + } = result + + const root = path.join(cwd, targetDir) + + if (overwrite) emptyDir(root) + else if (!fs.existsSync(root)) fs.mkdirSync(root, { recursive: true }) + + // determine template + const template: string = variant || framework?.name || argTemplate + + const pkgInfo = pkgFromUserAgent(process.env.npm_config_user_agent) + type PkgManager = 'bun' | 'npm' | 'pnpm' | 'yarn' + let pkgManager: PkgManager + if (options.bun) pkgManager = 'bun' + else if (options.npm) pkgManager = 'npm' + else if (options.pnpm) pkgManager = 'pnpm' + else if (options.yarn) pkgManager = 'yarn' + else pkgManager = pkgInfo ? (pkgInfo.name as PkgManager) : 'npm' + const isYarn1 = pkgManager === 'yarn' && pkgInfo?.version?.startsWith('1.') + + const { customCommand } = + frameworks.flatMap((f) => f.variants).find((v) => v.name === template) ?? {} + + if (customCommand) { + const fullCustomCommand = customCommand + .replace(/^npm create /, () => { + // `bun create` uses it's own set of templates, + // the closest alternative is using `bun x` directly on the package + if (pkgManager === 'bun') return 'bun x create-' + return `${pkgManager} create ` + }) + // Only Yarn 1.x doesn't support `@version` in the `create` command + .replace('@latest', () => (isYarn1 ? '' : '@latest')) + .replace(/^npm exec/, () => { + // Prefer `pnpm dlx`, `yarn dlx`, or `bun x` + if (pkgManager === 'pnpm') return 'pnpm dlx' + if (pkgManager === 'yarn' && !isYarn1) return 'yarn dlx' + if (pkgManager === 'bun') return 'bun x' + // Use `npm exec` in all other cases, + // including Yarn 1.x and other custom npm clients. + return 'npm exec' + }) + + const [command, ...args] = fullCustomCommand.split(' ') + // we replace TARGET_DIR here because targetDir may include a space + const replacedArgs = args.map((arg) => arg.replace('TARGET_DIR', targetDir)) + const { status } = spawn.sync(command!, replacedArgs, { + stdio: 'inherit', + }) + process.exit(status ?? 0) + } + + // biome-ignore lint/suspicious/noConsoleLog: + console.log(`\nScaffolding project in ${root}...`) + + const templateDir = path.resolve( + fileURLToPath(import.meta.url), + '../../../templates', + template, + ) + + function write(file: string, content?: string) { + const targetPath = path.join(root, renameFiles[file] ?? file) + if (content) fs.writeFileSync(targetPath, content) + else copy(path.join(templateDir, file), targetPath) + } + + const files = fs.readdirSync(templateDir) + for (const file of files.filter((f) => f !== 'package.json')) { + write(file) + } + + const pkg = JSON.parse( + fs.readFileSync(path.join(templateDir, 'package.json'), 'utf-8'), + ) + + pkg.name = packageName || getProjectName() + + write('package.json', `${JSON.stringify(pkg, null, 2)}\n`) + + const cdProjectName = path.relative(cwd, root) + // biome-ignore lint/suspicious/noConsoleLog: + console.log('\nDone. Now run:\n') + if (root !== cwd) + // biome-ignore lint/suspicious/noConsoleLog: + console.log( + ` cd ${ + cdProjectName.includes(' ') ? `"${cdProjectName}"` : cdProjectName + }`, + ) + + switch (pkgManager) { + case 'yarn': + // biome-ignore lint/suspicious/noConsoleLog: + console.log(' yarn') + // biome-ignore lint/suspicious/noConsoleLog: + console.log(' yarn dev') + break + default: + // biome-ignore lint/suspicious/noConsoleLog: + console.log(` ${pkgManager} install`) + // biome-ignore lint/suspicious/noConsoleLog: + console.log(` ${pkgManager} run dev`) + break + } + // biome-ignore lint/suspicious/noConsoleLog: + console.log() +} + +init().catch((e) => { + console.error(e) +}) diff --git a/wagmi-project/packages/create-wagmi/src/frameworks.ts b/wagmi-project/packages/create-wagmi/src/frameworks.ts new file mode 100644 index 000000000..1b414bafc --- /dev/null +++ b/wagmi-project/packages/create-wagmi/src/frameworks.ts @@ -0,0 +1,66 @@ +import pc from 'picocolors' + +type ColorFunc = (str: string | number) => string + +type FrameworkVariant = { + name: string + display: string + color: ColorFunc + customCommand?: string +} + +export type Framework = { + name: string + display: string + color: ColorFunc + variants: readonly FrameworkVariant[] +} + +export const frameworks: readonly Framework[] = [ + { + name: 'react', + display: 'React', + color: pc.cyan, + variants: [ + { + name: 'vite-react', + display: 'Vite', + color: pc.blue, + }, + { + name: 'next', + display: 'Next', + color: pc.yellow, + }, + ], + }, + { + name: 'vue', + display: 'Vue', + color: pc.green, + variants: [ + { + name: 'vite-vue', + display: 'Vite', + color: pc.blue, + }, + { + name: 'nuxt', + display: 'Nuxt', + color: pc.yellow, + }, + ], + }, + { + name: 'vanilla', + display: 'Vanilla', + color: pc.magenta, + variants: [ + { + name: 'vite-vanilla', + display: 'Vite', + color: pc.blue, + }, + ], + }, +] diff --git a/wagmi-project/packages/create-wagmi/src/index.test-d.ts b/wagmi-project/packages/create-wagmi/src/index.test-d.ts new file mode 100644 index 000000000..b056d5635 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/src/index.test-d.ts @@ -0,0 +1,4 @@ +import { expectTypeOf } from 'vitest' + +// noop test because vitest typecheck fails unless each workspace project has type test +expectTypeOf(1).toEqualTypeOf() diff --git a/wagmi-project/packages/create-wagmi/src/utils.ts b/wagmi-project/packages/create-wagmi/src/utils.ts new file mode 100644 index 000000000..d04f60ed9 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/src/utils.ts @@ -0,0 +1,79 @@ +import * as fs from 'node:fs' +import * as path from 'node:path' + +export function formatTargetDir(targetDir: string | undefined) { + return targetDir?.trim().replace(/\/+$/g, '') +} + +export function copy(src: string, dest: string) { + const stat = fs.statSync(src) + if (stat.isDirectory()) copyDir(src, dest) + else fs.copyFileSync(src, dest) +} + +function copyDir(srcDir: string, destDir: string) { + fs.mkdirSync(destDir, { recursive: true }) + for (const file of fs.readdirSync(srcDir)) { + const srcFile = path.resolve(srcDir, file) + const destFile = path.resolve(destDir, file) + copy(srcFile, destFile) + } +} + +export function isValidPackageName(projectName: string) { + return /^(?:@[a-z\d\-*~][a-z\d\-*._~]*\/)?[a-z\d\-~][a-z\d\-._~]*$/.test( + projectName, + ) +} + +export function toValidPackageName(projectName: string) { + return projectName + .trim() + .toLowerCase() + .replace(/\s+/g, '-') + .replace(/^[._]/, '') + .replace(/[^a-z\d\-~]+/g, '-') +} + +export function isEmpty(path: string) { + const files = fs.readdirSync(path) + return files.length === 0 || (files.length === 1 && files[0] === '.git') +} + +export function emptyDir(dir: string) { + if (!fs.existsSync(dir)) return + for (const file of fs.readdirSync(dir)) { + if (file === '.git') continue + fs.rmSync(path.resolve(dir, file), { recursive: true, force: true }) + } +} + +export function pkgFromUserAgent(userAgent: string | undefined) { + if (!userAgent) return undefined + const pkgSpec = userAgent.split(' ')[0]! + const pkgSpecArr = pkgSpec.split('/') + return { + name: pkgSpecArr[0], + version: pkgSpecArr[1], + } +} + +// function setupReactSwc(root: string, isTs: boolean) { +// editFile(path.resolve(root, 'package.json'), (content) => { +// return content.replace( +// /"@vitejs\/plugin-react": ".+?"/, +// `"@vitejs/plugin-react-swc": "^3.3.2"`, +// ) +// }) +// editFile( +// path.resolve(root, `vite.config.${isTs ? 'ts' : 'js'}`), +// (content) => { +// return content.replace('@vitejs/plugin-react', '@vitejs/plugin-react-swc') +// }, +// ) +// } + +// function editFile(file: string, callback: (content: string) => string) { +// const content = fs.readFileSync(file, 'utf-8') +// fs.writeFileSync(file, callback(content), 'utf-8') +// } diff --git a/wagmi-project/packages/create-wagmi/src/version.ts b/wagmi-project/packages/create-wagmi/src/version.ts new file mode 100644 index 000000000..5556800c0 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/src/version.ts @@ -0,0 +1 @@ +export const version = '2.0.14' diff --git a/wagmi-project/packages/create-wagmi/templates/next/README.md b/wagmi-project/packages/create-wagmi/templates/next/README.md new file mode 100644 index 000000000..bd3aa7b7f --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/next/README.md @@ -0,0 +1 @@ +This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-wagmi`](https://github.com/wevm/wagmi/tree/main/packages/create-wagmi). diff --git a/wagmi-project/packages/create-wagmi/templates/next/_env.local b/wagmi-project/packages/create-wagmi/templates/next/_env.local new file mode 100644 index 000000000..9a11dba16 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/next/_env.local @@ -0,0 +1,2 @@ +NEXT_PUBLIC_WC_PROJECT_ID= +NEXT_TELEMETRY_DISABLED=1 \ No newline at end of file diff --git a/wagmi-project/packages/create-wagmi/templates/next/_gitignore b/wagmi-project/packages/create-wagmi/templates/next/_gitignore new file mode 100644 index 000000000..8f322f0d8 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/next/_gitignore @@ -0,0 +1,35 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# local env files +.env*.local + +# vercel +.vercel + +# typescript +*.tsbuildinfo +next-env.d.ts diff --git a/wagmi-project/packages/create-wagmi/templates/next/_npmrc b/wagmi-project/packages/create-wagmi/templates/next/_npmrc new file mode 100644 index 000000000..ca1e9d98b --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/next/_npmrc @@ -0,0 +1 @@ +legacy-peer-deps = true \ No newline at end of file diff --git a/wagmi-project/packages/create-wagmi/templates/next/next-env.d.ts b/wagmi-project/packages/create-wagmi/templates/next/next-env.d.ts new file mode 100644 index 000000000..4f11a03dc --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/next/next-env.d.ts @@ -0,0 +1,5 @@ +/// +/// + +// NOTE: This file should not be edited +// see https://nextjs.org/docs/basic-features/typescript for more information. diff --git a/wagmi-project/packages/create-wagmi/templates/next/next.config.js b/wagmi-project/packages/create-wagmi/templates/next/next.config.js new file mode 100644 index 000000000..767719fc4 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/next/next.config.js @@ -0,0 +1,4 @@ +/** @type {import('next').NextConfig} */ +const nextConfig = {} + +module.exports = nextConfig diff --git a/wagmi-project/packages/create-wagmi/templates/next/package.json b/wagmi-project/packages/create-wagmi/templates/next/package.json new file mode 100644 index 000000000..d3867228f --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/next/package.json @@ -0,0 +1,32 @@ +{ + "name": "wagmi-next-starter", + "private": true, + "version": "0.0.0", + "scripts": { + "dev": "next dev", + "build": "next build", + "start": "next start", + "lint": "next lint" + }, + "dependencies": { + "@tanstack/react-query": "5.45.1", + "next": "15.2.4", + "react": "^19.1.0", + "react-dom": "^18.3.1", + "viem": "latest", + "wagmi": "latest" + }, + "devDependencies": { + "@types/node": "^20.12.10", + "@types/react": "^18.3.1", + "@types/react-dom": "^18.3.0", + "@wagmi/cli": "latest", + "bufferutil": "^4.0.8", + "encoding": "^0.1.13", + "lokijs": "^1.5.12", + "pino-pretty": "^10.3.1", + "supports-color": "^9.4.0", + "typescript": "^5.4.5", + "utf-8-validate": "^5.0.2" + } +} diff --git a/wagmi-project/packages/create-wagmi/templates/next/src/app/globals.css b/wagmi-project/packages/create-wagmi/templates/next/src/app/globals.css new file mode 100644 index 000000000..0733a7ee6 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/next/src/app/globals.css @@ -0,0 +1,21 @@ +:root { + background-color: #181818; + color: rgba(255, 255, 255, 0.87); + color-scheme: light dark; + font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; + font-synthesis: none; + font-weight: 400; + line-height: 1.5; + text-rendering: optimizeLegibility; + + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + -webkit-text-size-adjust: 100%; +} + +@media (prefers-color-scheme: light) { + :root { + background-color: #f8f8f8; + color: #181818; + } +} diff --git a/wagmi-project/packages/create-wagmi/templates/next/src/app/layout.tsx b/wagmi-project/packages/create-wagmi/templates/next/src/app/layout.tsx new file mode 100644 index 000000000..da5b293bf --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/next/src/app/layout.tsx @@ -0,0 +1,30 @@ +import './globals.css' +import type { Metadata } from 'next' +import { Inter } from 'next/font/google' +import { headers } from 'next/headers' +import { type ReactNode } from 'react' +import { cookieToInitialState } from 'wagmi' + +import { getConfig } from '../wagmi' +import { Providers } from './providers' + +const inter = Inter({ subsets: ['latin'] }) + +export const metadata: Metadata = { + title: 'Create Wagmi', + description: 'Generated by create-wagmi', +} + +export default async function RootLayout(props: { children: ReactNode }) { + const initialState = cookieToInitialState( + getConfig(), + (await headers()).get('cookie'), + ) + return ( + + + {props.children} + + + ) +} diff --git a/wagmi-project/packages/create-wagmi/templates/next/src/app/page.tsx b/wagmi-project/packages/create-wagmi/templates/next/src/app/page.tsx new file mode 100644 index 000000000..f5dcbdf81 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/next/src/app/page.tsx @@ -0,0 +1,48 @@ +'use client' + +import { useAccount, useConnect, useDisconnect } from 'wagmi' + +function App() { + const account = useAccount() + const { connectors, connect, status, error } = useConnect() + const { disconnect } = useDisconnect() + + return ( + <> +
+

Account

+ +
+ status: {account.status} +
+ addresses: {JSON.stringify(account.addresses)} +
+ chainId: {account.chainId} +
+ + {account.status === 'connected' && ( + + )} +
+ +
+

Connect

+ {connectors.map((connector) => ( + + ))} +
{status}
+
{error?.message}
+
+ + ) +} + +export default App diff --git a/wagmi-project/packages/create-wagmi/templates/next/src/app/providers.tsx b/wagmi-project/packages/create-wagmi/templates/next/src/app/providers.tsx new file mode 100644 index 000000000..b4086cf53 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/next/src/app/providers.tsx @@ -0,0 +1,23 @@ +'use client' + +import { QueryClient, QueryClientProvider } from '@tanstack/react-query' +import { type ReactNode, useState } from 'react' +import { type State, WagmiProvider } from 'wagmi' + +import { getConfig } from '@/wagmi' + +export function Providers(props: { + children: ReactNode + initialState?: State +}) { + const [config] = useState(() => getConfig()) + const [queryClient] = useState(() => new QueryClient()) + + return ( + + + {props.children} + + + ) +} diff --git a/wagmi-project/packages/create-wagmi/templates/next/src/wagmi.ts b/wagmi-project/packages/create-wagmi/templates/next/src/wagmi.ts new file mode 100644 index 000000000..b34f4c007 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/next/src/wagmi.ts @@ -0,0 +1,28 @@ +import { http, cookieStorage, createConfig, createStorage } from 'wagmi' +import { mainnet, sepolia } from 'wagmi/chains' +import { coinbaseWallet, injected, walletConnect } from 'wagmi/connectors' + +export function getConfig() { + return createConfig({ + chains: [mainnet, sepolia], + connectors: [ + injected(), + coinbaseWallet(), + walletConnect({ projectId: process.env.NEXT_PUBLIC_WC_PROJECT_ID }), + ], + storage: createStorage({ + storage: cookieStorage, + }), + ssr: true, + transports: { + [mainnet.id]: http(), + [sepolia.id]: http(), + }, + }) +} + +declare module 'wagmi' { + interface Register { + config: ReturnType + } +} diff --git a/wagmi-project/packages/create-wagmi/templates/next/tsconfig.json b/wagmi-project/packages/create-wagmi/templates/next/tsconfig.json new file mode 100644 index 000000000..e59724b28 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/next/tsconfig.json @@ -0,0 +1,27 @@ +{ + "compilerOptions": { + "target": "es5", + "lib": ["dom", "dom.iterable", "esnext"], + "allowJs": true, + "skipLibCheck": true, + "strict": true, + "noEmit": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "bundler", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "preserve", + "incremental": true, + "plugins": [ + { + "name": "next" + } + ], + "paths": { + "@/*": ["./src/*"] + } + }, + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], + "exclude": ["node_modules"] +} diff --git a/wagmi-project/packages/create-wagmi/templates/nuxt/_env.local b/wagmi-project/packages/create-wagmi/templates/nuxt/_env.local new file mode 100644 index 000000000..437e9e3e7 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/nuxt/_env.local @@ -0,0 +1,3 @@ +NUXT_PUBLIC_WC_PROJECT_ID= +NUXT_TELEMETRY_DISABLED=1 + diff --git a/wagmi-project/packages/create-wagmi/templates/nuxt/_gitignore b/wagmi-project/packages/create-wagmi/templates/nuxt/_gitignore new file mode 100644 index 000000000..4a7f73a2e --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/nuxt/_gitignore @@ -0,0 +1,24 @@ +# Nuxt dev/build outputs +.output +.data +.nuxt +.nitro +.cache +dist + +# Node dependencies +node_modules + +# Logs +logs +*.log + +# Misc +.DS_Store +.fleet +.idea + +# Local env files +.env +.env.* +!.env.example diff --git a/wagmi-project/packages/create-wagmi/templates/nuxt/_npmrc b/wagmi-project/packages/create-wagmi/templates/nuxt/_npmrc new file mode 100644 index 000000000..057cc841f --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/nuxt/_npmrc @@ -0,0 +1,2 @@ +legacy-peer-deps = true + diff --git a/wagmi-project/packages/create-wagmi/templates/nuxt/app.vue b/wagmi-project/packages/create-wagmi/templates/nuxt/app.vue new file mode 100644 index 000000000..98b46bf52 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/nuxt/app.vue @@ -0,0 +1,28 @@ + + + diff --git a/wagmi-project/packages/create-wagmi/templates/nuxt/components/Account.vue b/wagmi-project/packages/create-wagmi/templates/nuxt/components/Account.vue new file mode 100644 index 000000000..33f1491da --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/nuxt/components/Account.vue @@ -0,0 +1,22 @@ + + + diff --git a/wagmi-project/packages/create-wagmi/templates/nuxt/components/Connect.vue b/wagmi-project/packages/create-wagmi/templates/nuxt/components/Connect.vue new file mode 100644 index 000000000..93320448c --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/nuxt/components/Connect.vue @@ -0,0 +1,19 @@ + + + diff --git a/wagmi-project/packages/create-wagmi/templates/nuxt/nuxt.config.ts b/wagmi-project/packages/create-wagmi/templates/nuxt/nuxt.config.ts new file mode 100644 index 000000000..adfe7fd2d --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/nuxt/nuxt.config.ts @@ -0,0 +1,7 @@ +import { defineNuxtConfig } from 'nuxt/config' + +// https://nuxt.com/docs/api/configuration/nuxt-config +export default defineNuxtConfig({ + devtools: { enabled: true }, + modules: ['@wagmi/vue/nuxt'], +}) diff --git a/wagmi-project/packages/create-wagmi/templates/nuxt/package.json b/wagmi-project/packages/create-wagmi/templates/nuxt/package.json new file mode 100644 index 000000000..65ff65752 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/nuxt/package.json @@ -0,0 +1,21 @@ +{ + "name": "nuxt-app", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "build": "nuxt build", + "dev": "nuxt dev", + "generate": "nuxt generate", + "preview": "nuxt preview", + "postinstall": "nuxt prepare" + }, + "dependencies": { + "@tanstack/vue-query": ">=5.45.0", + "@wagmi/vue": "latest", + "nuxt": "^3.11.2", + "viem": "latest", + "vue": ">=3.4.21", + "vue-router": "^4.3.2" + } +} diff --git a/wagmi-project/packages/create-wagmi/templates/nuxt/plugins/wagmi.ts b/wagmi-project/packages/create-wagmi/templates/nuxt/plugins/wagmi.ts new file mode 100644 index 000000000..b6abe5bcd --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/nuxt/plugins/wagmi.ts @@ -0,0 +1,10 @@ +import { VueQueryPlugin } from '@tanstack/vue-query' +import { WagmiPlugin } from '@wagmi/vue' +import { defineNuxtPlugin } from 'nuxt/app' + +import { config } from '../wagmi' + +// TODO: Move to @wagmi/vue/nuxt nitro plugin +export default defineNuxtPlugin((nuxtApp) => { + nuxtApp.vueApp.use(WagmiPlugin, { config }).use(VueQueryPlugin, {}) +}) diff --git a/wagmi-project/packages/create-wagmi/templates/nuxt/server/tsconfig.json b/wagmi-project/packages/create-wagmi/templates/nuxt/server/tsconfig.json new file mode 100644 index 000000000..b9ed69c19 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/nuxt/server/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "../.nuxt/tsconfig.server.json" +} diff --git a/wagmi-project/packages/create-wagmi/templates/nuxt/tsconfig.json b/wagmi-project/packages/create-wagmi/templates/nuxt/tsconfig.json new file mode 100644 index 000000000..a746f2a70 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/nuxt/tsconfig.json @@ -0,0 +1,4 @@ +{ + // https://nuxt.com/docs/guide/concepts/typescript + "extends": "./.nuxt/tsconfig.json" +} diff --git a/wagmi-project/packages/create-wagmi/templates/nuxt/wagmi.ts b/wagmi-project/packages/create-wagmi/templates/nuxt/wagmi.ts new file mode 100644 index 000000000..83e8569ea --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/nuxt/wagmi.ts @@ -0,0 +1,29 @@ +import { http, cookieStorage, createConfig, createStorage } from '@wagmi/vue' +import { mainnet, optimism, sepolia } from '@wagmi/vue/chains' +import { injected, metaMask, walletConnect } from '@wagmi/vue/connectors' + +export const config = createConfig({ + chains: [mainnet, sepolia, optimism], + connectors: [ + injected(), + walletConnect({ + projectId: process.env.NUXT_PUBLIC_WC_PROJECT_ID!, + }), + metaMask(), + ], + storage: createStorage({ + storage: cookieStorage, + }), + ssr: true, + transports: { + [mainnet.id]: http(), + [sepolia.id]: http(), + [optimism.id]: http(), + }, +}) + +declare module '@wagmi/vue' { + interface Register { + config: typeof config + } +} diff --git a/wagmi-project/packages/create-wagmi/templates/vite-react/README.md b/wagmi-project/packages/create-wagmi/templates/vite-react/README.md new file mode 100644 index 000000000..15f6f7954 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-react/README.md @@ -0,0 +1 @@ +This is a [Vite](https://vitejs.dev) project bootstrapped with [`create-wagmi`](https://github.com/wevm/wagmi/tree/main/packages/create-wagmi). diff --git a/wagmi-project/packages/create-wagmi/templates/vite-react/_env.local b/wagmi-project/packages/create-wagmi/templates/vite-react/_env.local new file mode 100644 index 000000000..936f76376 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-react/_env.local @@ -0,0 +1 @@ +VITE_WC_PROJECT_ID= \ No newline at end of file diff --git a/wagmi-project/packages/create-wagmi/templates/vite-react/_gitignore b/wagmi-project/packages/create-wagmi/templates/vite-react/_gitignore new file mode 100644 index 000000000..a547bf36d --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-react/_gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/wagmi-project/packages/create-wagmi/templates/vite-react/_npmrc b/wagmi-project/packages/create-wagmi/templates/vite-react/_npmrc new file mode 100644 index 000000000..ca1e9d98b --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-react/_npmrc @@ -0,0 +1 @@ +legacy-peer-deps = true \ No newline at end of file diff --git a/wagmi-project/packages/create-wagmi/templates/vite-react/biome.json b/wagmi-project/packages/create-wagmi/templates/vite-react/biome.json new file mode 100644 index 000000000..08eb8a26a --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-react/biome.json @@ -0,0 +1,13 @@ +{ + "formatter": { + "enabled": true, + "indentStyle": "space", + "lineWidth": 120 + }, + "linter": { + "enabled": true + }, + "organizeImports": { + "enabled": true + } +} diff --git a/wagmi-project/packages/create-wagmi/templates/vite-react/index.html b/wagmi-project/packages/create-wagmi/templates/vite-react/index.html new file mode 100644 index 000000000..f519ce85a --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-react/index.html @@ -0,0 +1,12 @@ + + + + + + Create Wagmi + + +
+ + + diff --git a/wagmi-project/packages/create-wagmi/templates/vite-react/package.json b/wagmi-project/packages/create-wagmi/templates/vite-react/package.json new file mode 100644 index 000000000..0eeaab9a1 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-react/package.json @@ -0,0 +1,29 @@ +{ + "name": "wagmi-vite-starter", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "tsc && vite build", + "lint": "biome check .", + "preview": "vite preview" + }, + "dependencies": { + "@tanstack/react-query": "5.45.1", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "viem": "latest", + "wagmi": "latest" + }, + "devDependencies": { + "@biomejs/biome": "^1.8.0", + "@types/react": "^18.3.1", + "@types/react-dom": "^18.3.0", + "@vitejs/plugin-react": "^4.2.1", + "@wagmi/cli": "latest", + "buffer": "^6.0.3", + "typescript": "^5.8.3", + "vite": "^5.2.11" + } +} diff --git a/wagmi-project/packages/create-wagmi/templates/vite-react/src/App.tsx b/wagmi-project/packages/create-wagmi/templates/vite-react/src/App.tsx new file mode 100644 index 000000000..faa8ce1c7 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-react/src/App.tsx @@ -0,0 +1,46 @@ +import { useAccount, useConnect, useDisconnect } from 'wagmi' + +function App() { + const account = useAccount() + const { connectors, connect, status, error } = useConnect() + const { disconnect } = useDisconnect() + + return ( + <> +
+

Account

+ +
+ status: {account.status} +
+ addresses: {JSON.stringify(account.addresses)} +
+ chainId: {account.chainId} +
+ + {account.status === 'connected' && ( + + )} +
+ +
+

Connect

+ {connectors.map((connector) => ( + + ))} +
{status}
+
{error?.message}
+
+ + ) +} + +export default App diff --git a/wagmi-project/packages/create-wagmi/templates/vite-react/src/index.css b/wagmi-project/packages/create-wagmi/templates/vite-react/src/index.css new file mode 100644 index 000000000..0733a7ee6 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-react/src/index.css @@ -0,0 +1,21 @@ +:root { + background-color: #181818; + color: rgba(255, 255, 255, 0.87); + color-scheme: light dark; + font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; + font-synthesis: none; + font-weight: 400; + line-height: 1.5; + text-rendering: optimizeLegibility; + + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + -webkit-text-size-adjust: 100%; +} + +@media (prefers-color-scheme: light) { + :root { + background-color: #f8f8f8; + color: #181818; + } +} diff --git a/wagmi-project/packages/create-wagmi/templates/vite-react/src/main.tsx b/wagmi-project/packages/create-wagmi/templates/vite-react/src/main.tsx new file mode 100644 index 000000000..d999e1a93 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-react/src/main.tsx @@ -0,0 +1,24 @@ +import { Buffer } from 'buffer' +import { QueryClient, QueryClientProvider } from '@tanstack/react-query' +import React from 'react' +import ReactDOM from 'react-dom/client' +import { WagmiProvider } from 'wagmi' + +import App from './App.tsx' +import { config } from './wagmi.ts' + +import './index.css' + +globalThis.Buffer = Buffer + +const queryClient = new QueryClient() + +ReactDOM.createRoot(document.getElementById('root')!).render( + + + + + + + , +) diff --git a/wagmi-project/packages/create-wagmi/templates/vite-react/src/vite-env.d.ts b/wagmi-project/packages/create-wagmi/templates/vite-react/src/vite-env.d.ts new file mode 100644 index 000000000..11f02fe2a --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-react/src/vite-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/wagmi-project/packages/create-wagmi/templates/vite-react/src/wagmi.ts b/wagmi-project/packages/create-wagmi/templates/vite-react/src/wagmi.ts new file mode 100644 index 000000000..43cf23193 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-react/src/wagmi.ts @@ -0,0 +1,22 @@ +import { http, createConfig } from 'wagmi' +import { mainnet, sepolia } from 'wagmi/chains' +import { coinbaseWallet, injected, walletConnect } from 'wagmi/connectors' + +export const config = createConfig({ + chains: [mainnet, sepolia], + connectors: [ + injected(), + coinbaseWallet(), + walletConnect({ projectId: import.meta.env.VITE_WC_PROJECT_ID }), + ], + transports: { + [mainnet.id]: http(), + [sepolia.id]: http(), + }, +}) + +declare module 'wagmi' { + interface Register { + config: typeof config + } +} diff --git a/wagmi-project/packages/create-wagmi/templates/vite-react/tsconfig.json b/wagmi-project/packages/create-wagmi/templates/vite-react/tsconfig.json new file mode 100644 index 000000000..a7fc6fbf2 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-react/tsconfig.json @@ -0,0 +1,25 @@ +{ + "compilerOptions": { + "target": "ES2020", + "useDefineForClassFields": true, + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "module": "ESNext", + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "react-jsx", + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true + }, + "include": ["src"], + "references": [{ "path": "./tsconfig.node.json" }] +} diff --git a/wagmi-project/packages/create-wagmi/templates/vite-react/tsconfig.node.json b/wagmi-project/packages/create-wagmi/templates/vite-react/tsconfig.node.json new file mode 100644 index 000000000..42872c59f --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-react/tsconfig.node.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "composite": true, + "skipLibCheck": true, + "module": "ESNext", + "moduleResolution": "bundler", + "allowSyntheticDefaultImports": true + }, + "include": ["vite.config.ts"] +} diff --git a/wagmi-project/packages/create-wagmi/templates/vite-react/vite.config.ts b/wagmi-project/packages/create-wagmi/templates/vite-react/vite.config.ts new file mode 100644 index 000000000..36f7f4e1b --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-react/vite.config.ts @@ -0,0 +1,7 @@ +import react from '@vitejs/plugin-react' +import { defineConfig } from 'vite' + +// https://vitejs.dev/config/ +export default defineConfig({ + plugins: [react()], +}) diff --git a/wagmi-project/packages/create-wagmi/templates/vite-vanilla/_env.local b/wagmi-project/packages/create-wagmi/templates/vite-vanilla/_env.local new file mode 100644 index 000000000..936f76376 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-vanilla/_env.local @@ -0,0 +1 @@ +VITE_WC_PROJECT_ID= \ No newline at end of file diff --git a/wagmi-project/packages/create-wagmi/templates/vite-vanilla/_gitignore b/wagmi-project/packages/create-wagmi/templates/vite-vanilla/_gitignore new file mode 100644 index 000000000..a547bf36d --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-vanilla/_gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/wagmi-project/packages/create-wagmi/templates/vite-vanilla/_npmrc b/wagmi-project/packages/create-wagmi/templates/vite-vanilla/_npmrc new file mode 100644 index 000000000..ca1e9d98b --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-vanilla/_npmrc @@ -0,0 +1 @@ +legacy-peer-deps = true \ No newline at end of file diff --git a/wagmi-project/packages/create-wagmi/templates/vite-vanilla/index.html b/wagmi-project/packages/create-wagmi/templates/vite-vanilla/index.html new file mode 100644 index 000000000..e2028cc12 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-vanilla/index.html @@ -0,0 +1,12 @@ + + + + + + Create Wagmi + + +
+ + + diff --git a/wagmi-project/packages/create-wagmi/templates/vite-vanilla/package.json b/wagmi-project/packages/create-wagmi/templates/vite-vanilla/package.json new file mode 100644 index 000000000..e48954313 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-vanilla/package.json @@ -0,0 +1,24 @@ +{ + "name": "wagmi-core-vanilla-starter", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "tsc && vite build", + "preview": "vite preview" + }, + "dependencies": { + "@wagmi/connectors": "latest", + "@wagmi/core": "latest", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "viem": "latest" + }, + "devDependencies": { + "@wagmi/cli": "latest", + "buffer": "^6.0.3", + "typescript": "^5.8.3", + "vite": "^5.2.11" + } +} diff --git a/wagmi-project/packages/create-wagmi/templates/vite-vanilla/src/main.ts b/wagmi-project/packages/create-wagmi/templates/vite-vanilla/src/main.ts new file mode 100644 index 000000000..f2b80f345 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-vanilla/src/main.ts @@ -0,0 +1,89 @@ +import { Buffer } from 'buffer' +import { connect, disconnect, reconnect, watchAccount } from '@wagmi/core' + +import './style.css' +import { config } from './wagmi' + +globalThis.Buffer = Buffer + +document.querySelector('#app')!.innerHTML = ` +
+
+

Account

+ +
+ status: +
+ addresses: +
+ chainId: +
+
+ +
+

Connect

+ ${config.connectors + .map( + (connector) => + ``, + ) + .join('')} +
+
+` + +setupApp(document.querySelector('#app')!) + +function setupApp(element: HTMLDivElement) { + const connectElement = element.querySelector('#connect') + const buttons = element.querySelectorAll('.connect') + for (const button of buttons) { + const connector = config.connectors.find( + (connector) => connector.uid === button.id, + )! + button.addEventListener('click', async () => { + try { + const errorElement = element.querySelector('#error') + if (errorElement) errorElement.remove() + await connect(config, { connector }) + } catch (error) { + const errorElement = document.createElement('div') + errorElement.id = 'error' + errorElement.innerText = (error as Error).message + connectElement?.appendChild(errorElement) + } + }) + } + + watchAccount(config, { + onChange(account) { + const accountElement = element.querySelector('#account')! + accountElement.innerHTML = ` +

Account

+
+ status: ${account.status} +
+ addresses: ${ + account.addresses ? JSON.stringify(account.addresses) : '' + } +
+ chainId: ${account.chainId ?? ''} +
+ ${ + account.status === 'connected' + ? `` + : '' + } + ` + + const disconnectButton = + element.querySelector('#disconnect') + if (disconnectButton) + disconnectButton.addEventListener('click', () => disconnect(config)) + }, + }) + + reconnect(config) + .then(() => {}) + .catch(() => {}) +} diff --git a/wagmi-project/packages/create-wagmi/templates/vite-vanilla/src/style.css b/wagmi-project/packages/create-wagmi/templates/vite-vanilla/src/style.css new file mode 100644 index 000000000..0733a7ee6 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-vanilla/src/style.css @@ -0,0 +1,21 @@ +:root { + background-color: #181818; + color: rgba(255, 255, 255, 0.87); + color-scheme: light dark; + font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; + font-synthesis: none; + font-weight: 400; + line-height: 1.5; + text-rendering: optimizeLegibility; + + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + -webkit-text-size-adjust: 100%; +} + +@media (prefers-color-scheme: light) { + :root { + background-color: #f8f8f8; + color: #181818; + } +} diff --git a/wagmi-project/packages/create-wagmi/templates/vite-vanilla/src/vite-env.d.ts b/wagmi-project/packages/create-wagmi/templates/vite-vanilla/src/vite-env.d.ts new file mode 100644 index 000000000..11f02fe2a --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-vanilla/src/vite-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/wagmi-project/packages/create-wagmi/templates/vite-vanilla/src/wagmi.ts b/wagmi-project/packages/create-wagmi/templates/vite-vanilla/src/wagmi.ts new file mode 100644 index 000000000..6baeff529 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-vanilla/src/wagmi.ts @@ -0,0 +1,16 @@ +import { coinbaseWallet, injected, walletConnect } from '@wagmi/connectors' +import { http, createConfig } from '@wagmi/core' +import { mainnet, sepolia } from '@wagmi/core/chains' + +export const config = createConfig({ + chains: [mainnet, sepolia], + connectors: [ + injected(), + coinbaseWallet(), + walletConnect({ projectId: import.meta.env.VITE_WC_PROJECT_ID }), + ], + transports: { + [mainnet.id]: http(), + [sepolia.id]: http(), + }, +}) diff --git a/wagmi-project/packages/create-wagmi/templates/vite-vanilla/tsconfig.json b/wagmi-project/packages/create-wagmi/templates/vite-vanilla/tsconfig.json new file mode 100644 index 000000000..75abdef26 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-vanilla/tsconfig.json @@ -0,0 +1,23 @@ +{ + "compilerOptions": { + "target": "ES2020", + "useDefineForClassFields": true, + "module": "ESNext", + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true + }, + "include": ["src"] +} diff --git a/wagmi-project/packages/create-wagmi/templates/vite-vue/README.md b/wagmi-project/packages/create-wagmi/templates/vite-vue/README.md new file mode 100644 index 000000000..15f6f7954 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-vue/README.md @@ -0,0 +1 @@ +This is a [Vite](https://vitejs.dev) project bootstrapped with [`create-wagmi`](https://github.com/wevm/wagmi/tree/main/packages/create-wagmi). diff --git a/wagmi-project/packages/create-wagmi/templates/vite-vue/_env.local b/wagmi-project/packages/create-wagmi/templates/vite-vue/_env.local new file mode 100644 index 000000000..936f76376 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-vue/_env.local @@ -0,0 +1 @@ +VITE_WC_PROJECT_ID= \ No newline at end of file diff --git a/wagmi-project/packages/create-wagmi/templates/vite-vue/_gitignore b/wagmi-project/packages/create-wagmi/templates/vite-vue/_gitignore new file mode 100644 index 000000000..a547bf36d --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-vue/_gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/wagmi-project/packages/create-wagmi/templates/vite-vue/_npmrc b/wagmi-project/packages/create-wagmi/templates/vite-vue/_npmrc new file mode 100644 index 000000000..ca1e9d98b --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-vue/_npmrc @@ -0,0 +1 @@ +legacy-peer-deps = true \ No newline at end of file diff --git a/wagmi-project/packages/create-wagmi/templates/vite-vue/biome.json b/wagmi-project/packages/create-wagmi/templates/vite-vue/biome.json new file mode 100644 index 000000000..08eb8a26a --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-vue/biome.json @@ -0,0 +1,13 @@ +{ + "formatter": { + "enabled": true, + "indentStyle": "space", + "lineWidth": 120 + }, + "linter": { + "enabled": true + }, + "organizeImports": { + "enabled": true + } +} diff --git a/wagmi-project/packages/create-wagmi/templates/vite-vue/index.html b/wagmi-project/packages/create-wagmi/templates/vite-vue/index.html new file mode 100644 index 000000000..e2028cc12 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-vue/index.html @@ -0,0 +1,12 @@ + + + + + + Create Wagmi + + +
+ + + diff --git a/wagmi-project/packages/create-wagmi/templates/vite-vue/package.json b/wagmi-project/packages/create-wagmi/templates/vite-vue/package.json new file mode 100644 index 000000000..8d306e620 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-vue/package.json @@ -0,0 +1,24 @@ +{ + "name": "wagmi-vue-vite-starter", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "vue-tsc && vite build", + "lint": "biome check .", + "preview": "vite preview" + }, + "dependencies": { + "@tanstack/vue-query": ">=5.45.0", + "@wagmi/vue": "latest", + "viem": "latest", + "vue": ">=3.4.21" + }, + "devDependencies": { + "@vitejs/plugin-vue": "^5.0.4", + "buffer": "^6.0.3", + "vite": "^5.2.11", + "vue-tsc": "^2.0.6" + } +} diff --git a/wagmi-project/packages/create-wagmi/templates/vite-vue/src/App.vue b/wagmi-project/packages/create-wagmi/templates/vite-vue/src/App.vue new file mode 100644 index 000000000..421aeb9a7 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-vue/src/App.vue @@ -0,0 +1,19 @@ + + + diff --git a/wagmi-project/packages/create-wagmi/templates/vite-vue/src/components/Account.vue b/wagmi-project/packages/create-wagmi/templates/vite-vue/src/components/Account.vue new file mode 100644 index 000000000..33f1491da --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-vue/src/components/Account.vue @@ -0,0 +1,22 @@ + + + diff --git a/wagmi-project/packages/create-wagmi/templates/vite-vue/src/components/Connect.vue b/wagmi-project/packages/create-wagmi/templates/vite-vue/src/components/Connect.vue new file mode 100644 index 000000000..93320448c --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-vue/src/components/Connect.vue @@ -0,0 +1,19 @@ + + + diff --git a/wagmi-project/packages/create-wagmi/templates/vite-vue/src/main.ts b/wagmi-project/packages/create-wagmi/templates/vite-vue/src/main.ts new file mode 100644 index 000000000..820eed372 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-vue/src/main.ts @@ -0,0 +1,17 @@ +import { Buffer } from 'buffer' +import { VueQueryPlugin } from '@tanstack/vue-query' +import { WagmiPlugin } from '@wagmi/vue' +import { createApp } from 'vue' + +// `@coinbase-wallet/sdk` uses `Buffer` +globalThis.Buffer = Buffer + +import App from './App.vue' +import './style.css' +import { config } from './wagmi' + +const app = createApp(App) + +app.use(WagmiPlugin, { config }).use(VueQueryPlugin, {}) + +app.mount('#app') diff --git a/wagmi-project/packages/create-wagmi/templates/vite-vue/src/style.css b/wagmi-project/packages/create-wagmi/templates/vite-vue/src/style.css new file mode 100644 index 000000000..0733a7ee6 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-vue/src/style.css @@ -0,0 +1,21 @@ +:root { + background-color: #181818; + color: rgba(255, 255, 255, 0.87); + color-scheme: light dark; + font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; + font-synthesis: none; + font-weight: 400; + line-height: 1.5; + text-rendering: optimizeLegibility; + + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + -webkit-text-size-adjust: 100%; +} + +@media (prefers-color-scheme: light) { + :root { + background-color: #f8f8f8; + color: #181818; + } +} diff --git a/wagmi-project/packages/create-wagmi/templates/vite-vue/src/vite-env.d.ts b/wagmi-project/packages/create-wagmi/templates/vite-vue/src/vite-env.d.ts new file mode 100644 index 000000000..11f02fe2a --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-vue/src/vite-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/wagmi-project/packages/create-wagmi/templates/vite-vue/src/wagmi.ts b/wagmi-project/packages/create-wagmi/templates/vite-vue/src/wagmi.ts new file mode 100644 index 000000000..f0282e949 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-vue/src/wagmi.ts @@ -0,0 +1,25 @@ +import { http, createConfig, createStorage } from '@wagmi/vue' +import { mainnet, optimism, sepolia } from '@wagmi/vue/chains' +import { coinbaseWallet, walletConnect } from '@wagmi/vue/connectors' + +export const config = createConfig({ + chains: [mainnet, sepolia, optimism], + connectors: [ + walletConnect({ + projectId: import.meta.env.VITE_WC_PROJECT_ID, + }), + coinbaseWallet({ appName: 'Vite Vue Playground', darkMode: true }), + ], + storage: createStorage({ storage: localStorage, key: 'vite-vue' }), + transports: { + [mainnet.id]: http(), + [sepolia.id]: http(), + [optimism.id]: http(), + }, +}) + +declare module '@wagmi/vue' { + interface Register { + config: typeof config + } +} diff --git a/wagmi-project/packages/create-wagmi/templates/vite-vue/tsconfig.json b/wagmi-project/packages/create-wagmi/templates/vite-vue/tsconfig.json new file mode 100644 index 000000000..9e03e6049 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-vue/tsconfig.json @@ -0,0 +1,25 @@ +{ + "compilerOptions": { + "target": "ES2020", + "useDefineForClassFields": true, + "module": "ESNext", + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "preserve", + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true + }, + "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"], + "references": [{ "path": "./tsconfig.node.json" }] +} diff --git a/wagmi-project/packages/create-wagmi/templates/vite-vue/tsconfig.node.json b/wagmi-project/packages/create-wagmi/templates/vite-vue/tsconfig.node.json new file mode 100644 index 000000000..97ede7ee6 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-vue/tsconfig.node.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "composite": true, + "skipLibCheck": true, + "module": "ESNext", + "moduleResolution": "bundler", + "allowSyntheticDefaultImports": true, + "strict": true + }, + "include": ["vite.config.ts"] +} diff --git a/wagmi-project/packages/create-wagmi/templates/vite-vue/vite.config.ts b/wagmi-project/packages/create-wagmi/templates/vite-vue/vite.config.ts new file mode 100644 index 000000000..c3fa62d86 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-vue/vite.config.ts @@ -0,0 +1,7 @@ +import vue from '@vitejs/plugin-vue' +import { defineConfig } from 'vite' + +// https://vitejs.dev/config/ +export default defineConfig({ + plugins: [vue()], +}) diff --git a/wagmi-project/packages/create-wagmi/tsconfig.build.json b/wagmi-project/packages/create-wagmi/tsconfig.build.json new file mode 100644 index 000000000..45ae2069e --- /dev/null +++ b/wagmi-project/packages/create-wagmi/tsconfig.build.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.base.json", + "include": ["src/**/*.ts"], + "exclude": ["src/**/*.test.ts"], + "compilerOptions": { + "sourceMap": true + } +} diff --git a/wagmi-project/packages/create-wagmi/tsconfig.json b/wagmi-project/packages/create-wagmi/tsconfig.json new file mode 100644 index 000000000..bd33919ac --- /dev/null +++ b/wagmi-project/packages/create-wagmi/tsconfig.json @@ -0,0 +1,5 @@ +{ + "extends": "./tsconfig.build.json", + "include": ["src/**/*.ts"], + "exclude": [] +} diff --git a/wagmi-project/packages/react/CHANGELOG.md b/wagmi-project/packages/react/CHANGELOG.md new file mode 100644 index 000000000..7dfc14098 --- /dev/null +++ b/wagmi-project/packages/react/CHANGELOG.md @@ -0,0 +1,5037 @@ +# wagmi + +## 2.15.4 + +### Patch Changes + +- Updated dependencies [[`42b1fed58e9ac09da0f8ebf3e9271f98a707aaac`](https://github.com/wevm/wagmi/commit/42b1fed58e9ac09da0f8ebf3e9271f98a707aaac)]: + - @wagmi/connectors@5.8.3 + +## 2.15.3 + +### Patch Changes + +- Updated dependencies [[`29297a48af72b537173d948ccd2fe37d39914c66`](https://github.com/wevm/wagmi/commit/29297a48af72b537173d948ccd2fe37d39914c66), [`07370106d5fb6b8fe300992d93abf25b3d0eaf57`](https://github.com/wevm/wagmi/commit/07370106d5fb6b8fe300992d93abf25b3d0eaf57)]: + - @wagmi/core@2.17.2 + - @wagmi/connectors@5.8.2 + +## 2.15.2 + +### Patch Changes + +- [#4649](https://github.com/wevm/wagmi/pull/4649) [`01f64e64fa4f85cdd30023903f972f4f9023681f`](https://github.com/wevm/wagmi/commit/01f64e64fa4f85cdd30023903f972f4f9023681f) Thanks [@jxom](https://github.com/jxom)! - Added `chainId` parameter to `getCapabilities`/`useCapabilities`. + +- Updated dependencies [[`01f64e64fa4f85cdd30023903f972f4f9023681f`](https://github.com/wevm/wagmi/commit/01f64e64fa4f85cdd30023903f972f4f9023681f)]: + - @wagmi/core@2.17.1 + - @wagmi/connectors@5.8.1 + +## 2.15.1 + +### Patch Changes + +- Updated dependencies [[`cc5517ff6880bb630f1b201930acc20dd1a0b451`](https://github.com/wevm/wagmi/commit/cc5517ff6880bb630f1b201930acc20dd1a0b451)]: + - @wagmi/connectors@5.8.0 + +## 2.15.0 + +### Minor Changes + +- [#4638](https://github.com/wevm/wagmi/pull/4638) [`799ee4d4b23c2ecd64e3f3668e67634e81939719`](https://github.com/wevm/wagmi/commit/799ee4d4b23c2ecd64e3f3668e67634e81939719) Thanks [@jxom](https://github.com/jxom)! - Stabilized EIP-5792 Actions & Hooks. + +### Patch Changes + +- Updated dependencies [[`88427b2bcd13ec375ef519e9ad1ccffef9f02a7b`](https://github.com/wevm/wagmi/commit/88427b2bcd13ec375ef519e9ad1ccffef9f02a7b), [`799ee4d4b23c2ecd64e3f3668e67634e81939719`](https://github.com/wevm/wagmi/commit/799ee4d4b23c2ecd64e3f3668e67634e81939719), [`3f8b2edc4f237cccff1009bcef03d51ca27a7324`](https://github.com/wevm/wagmi/commit/3f8b2edc4f237cccff1009bcef03d51ca27a7324)]: + - @wagmi/connectors@6.0.0 + - @wagmi/core@2.17.0 + +## 2.14.16 + +### Patch Changes + +- Updated dependencies [[`b59c024b23c69f5459b17390531207cfdf126ce4`](https://github.com/wevm/wagmi/commit/b59c024b23c69f5459b17390531207cfdf126ce4)]: + - @wagmi/connectors@5.7.12 + +## 2.14.15 + +### Patch Changes + +- [`a4bd0623eed28e3761a27295831a60ad835f0ee0`](https://github.com/wevm/wagmi/commit/a4bd0623eed28e3761a27295831a60ad835f0ee0) Thanks [@jxom](https://github.com/jxom)! - **Experimental (EIP-5792):** Updated `id` parameter to be optional on `useWaitForCallsStatus`. + +- Updated dependencies [[`a4bd0623eed28e3761a27295831a60ad835f0ee0`](https://github.com/wevm/wagmi/commit/a4bd0623eed28e3761a27295831a60ad835f0ee0)]: + - @wagmi/core@2.16.7 + - @wagmi/connectors@5.7.11 + +## 2.14.14 + +### Patch Changes + +- [#4586](https://github.com/wevm/wagmi/pull/4586) [`edf47477b2f6385a1c3ae01d36a8498c47f30a0b`](https://github.com/wevm/wagmi/commit/edf47477b2f6385a1c3ae01d36a8498c47f30a0b) Thanks [@jxom](https://github.com/jxom)! - **Experimental (EIP-5792):** Added `waitForCallsStatus` + `useWaitForCallsStatus`. + +- Updated dependencies [[`edf47477b2f6385a1c3ae01d36a8498c47f30a0b`](https://github.com/wevm/wagmi/commit/edf47477b2f6385a1c3ae01d36a8498c47f30a0b), [`e944812ebc234a72c1417b77cff341166f5e0fef`](https://github.com/wevm/wagmi/commit/e944812ebc234a72c1417b77cff341166f5e0fef)]: + - @wagmi/core@2.16.6 + - @wagmi/connectors@5.7.10 + +## 2.14.13 + +### Patch Changes + +- Updated dependencies [[`5b7101fddb61df56e34b2e02b46bc409e496eaf9`](https://github.com/wevm/wagmi/commit/5b7101fddb61df56e34b2e02b46bc409e496eaf9)]: + - @wagmi/connectors@5.7.9 + +## 2.14.12 + +### Patch Changes + +- [`d0c9a86921a4e939373cc6e763284e53f2a2e93c`](https://github.com/wevm/wagmi/commit/d0c9a86921a4e939373cc6e763284e53f2a2e93c) Thanks [@jxom](https://github.com/jxom)! - **Experimental (ERC-5792)**: Added support for `account: null` in `sendCalls` to cater for sending calls without a connected account (account will be filled by the wallet). + +- Updated dependencies [[`d0c9a86921a4e939373cc6e763284e53f2a2e93c`](https://github.com/wevm/wagmi/commit/d0c9a86921a4e939373cc6e763284e53f2a2e93c)]: + - @wagmi/core@2.16.5 + - @wagmi/connectors@5.7.8 + +## 2.14.11 + +### Patch Changes + +- [`507f864d91238bfd423d0e36d3619eb9f6e52eec`](https://github.com/wevm/wagmi/commit/507f864d91238bfd423d0e36d3619eb9f6e52eec) Thanks [@jxom](https://github.com/jxom)! - Updated `@coinbase/wallet-sdk`. + +- Updated dependencies [[`507f864d91238bfd423d0e36d3619eb9f6e52eec`](https://github.com/wevm/wagmi/commit/507f864d91238bfd423d0e36d3619eb9f6e52eec)]: + - @wagmi/connectors@5.7.7 + - @wagmi/core@2.16.4 + +## 2.14.10 + +### Patch Changes + +- Updated dependencies [[`639952c97f0fe3927106f42d3c9f7f366cdf7f7a`](https://github.com/wevm/wagmi/commit/639952c97f0fe3927106f42d3c9f7f366cdf7f7a), [`5aa2c095f7bfb6dfcf91c6945c3e1f9c9dd05766`](https://github.com/wevm/wagmi/commit/5aa2c095f7bfb6dfcf91c6945c3e1f9c9dd05766)]: + - @wagmi/connectors@5.7.6 + +## 2.14.9 + +### Patch Changes + +- Updated dependencies [[`a257e8d4f97431a4af872cda1817b4ae17c7bbed`](https://github.com/wevm/wagmi/commit/a257e8d4f97431a4af872cda1817b4ae17c7bbed)]: + - @wagmi/connectors@5.7.5 + +## 2.14.8 + +### Patch Changes + +- Updated dependencies [[`c8a257e0f6d2ece013b873895c35769a8a804fdc`](https://github.com/wevm/wagmi/commit/c8a257e0f6d2ece013b873895c35769a8a804fdc)]: + - @wagmi/connectors@5.7.4 + +## 2.14.7 + +### Patch Changes + +- [#4497](https://github.com/wevm/wagmi/pull/4497) [`00c144b21bac3f0797b683d8a4a81f7399c6e042`](https://github.com/wevm/wagmi/commit/00c144b21bac3f0797b683d8a4a81f7399c6e042) Thanks [@tmm](https://github.com/tmm)! - Bumped `use-sync-external-store` version for React 19. + +## 2.14.6 + +### Patch Changes + +- [#4480](https://github.com/wevm/wagmi/pull/4480) [`384a1d91597622eb59e1c05dc13ce25017c5b6d8`](https://github.com/wevm/wagmi/commit/384a1d91597622eb59e1c05dc13ce25017c5b6d8) Thanks [@RodeRickIsWatching](https://github.com/RodeRickIsWatching)! - Fixed invocation of default storage. + +- Updated dependencies [[`384a1d91597622eb59e1c05dc13ce25017c5b6d8`](https://github.com/wevm/wagmi/commit/384a1d91597622eb59e1c05dc13ce25017c5b6d8)]: + - @wagmi/core@2.16.3 + - @wagmi/connectors@5.7.3 + +## 2.14.5 + +### Patch Changes + +- [`012907032b532a438fce48f407470250cbc8f0c6`](https://github.com/wevm/wagmi/commit/012907032b532a438fce48f407470250cbc8f0c6) Thanks [@jxom](https://github.com/jxom)! - Fixed assignment in `getDefaultStorage`. + +- Updated dependencies [[`012907032b532a438fce48f407470250cbc8f0c6`](https://github.com/wevm/wagmi/commit/012907032b532a438fce48f407470250cbc8f0c6)]: + - @wagmi/core@2.16.2 + - @wagmi/connectors@5.7.2 + +## 2.14.4 + +### Patch Changes + +- Updated dependencies [[`9c8c35a3b829f2c58edcd3a29e2dcd99974d7470`](https://github.com/wevm/wagmi/commit/9c8c35a3b829f2c58edcd3a29e2dcd99974d7470), [`3892ebd21c06beef4b28ece4e70d2a38807bce6f`](https://github.com/wevm/wagmi/commit/3892ebd21c06beef4b28ece4e70d2a38807bce6f)]: + - @wagmi/connectors@5.7.1 + - @wagmi/core@2.16.1 + +## 2.14.3 + +### Patch Changes + +- Updated dependencies [[`e3f63a02c1f7d80481804584f262bc98dab0400d`](https://github.com/wevm/wagmi/commit/e3f63a02c1f7d80481804584f262bc98dab0400d)]: + - @wagmi/connectors@5.7.0 + +## 2.14.2 + +### Patch Changes + +- Updated dependencies [[`adf2253b10c6d4fc583e4bc9f01a8ef5ca267c85`](https://github.com/wevm/wagmi/commit/adf2253b10c6d4fc583e4bc9f01a8ef5ca267c85)]: + - @wagmi/connectors@5.6.2 + +## 2.14.1 + +### Patch Changes + +- Updated dependencies [[`987404f590c1d29ebb3cb68928f5e54aa032793d`](https://github.com/wevm/wagmi/commit/987404f590c1d29ebb3cb68928f5e54aa032793d)]: + - @wagmi/connectors@5.6.1 + +## 2.14.0 + +### Minor Changes + +- [#4453](https://github.com/wevm/wagmi/pull/4453) [`070e48480194c8d7f45bda1d7dd1346e6f5d7227`](https://github.com/wevm/wagmi/commit/070e48480194c8d7f45bda1d7dd1346e6f5d7227) Thanks [@tmm](https://github.com/tmm)! - Added support to `useConnect` for custom `connector.connect` parameters. + +### Patch Changes + +- Updated dependencies [[`afea6b67822a7a2b96901ec851441d27ee0f7a52`](https://github.com/wevm/wagmi/commit/afea6b67822a7a2b96901ec851441d27ee0f7a52), [`070e48480194c8d7f45bda1d7dd1346e6f5d7227`](https://github.com/wevm/wagmi/commit/070e48480194c8d7f45bda1d7dd1346e6f5d7227), [`8b0726c1106fce88b782e676498eabf0718b2619`](https://github.com/wevm/wagmi/commit/8b0726c1106fce88b782e676498eabf0718b2619)]: + - @wagmi/connectors@5.6.0 + - @wagmi/core@2.16.0 + +## 2.13.5 + +### Patch Changes + +- [#4447](https://github.com/wevm/wagmi/pull/4447) [`244f7777d9d227b3134d4cb9b9dda64f50cbddd3`](https://github.com/wevm/wagmi/commit/244f7777d9d227b3134d4cb9b9dda64f50cbddd3) Thanks [@Aerilym](https://github.com/Aerilym)! - Fixed config parameter passing in useSimulateContract and useEstimateGas + +## 2.13.4 + +### Patch Changes + +- [`2f79a3da4872d6158569017b1927a07a1ff5e7ba`](https://github.com/wevm/wagmi/commit/2f79a3da4872d6158569017b1927a07a1ff5e7ba) Thanks [@tmm](https://github.com/tmm)! - Exported `injected` and `mock`. + +## 2.13.3 + +### Patch Changes + +- [#4433](https://github.com/wevm/wagmi/pull/4433) [`06e186cd679b27fe195309110e766fcf46d4efbc`](https://github.com/wevm/wagmi/commit/06e186cd679b27fe195309110e766fcf46d4efbc) Thanks [@Aerilym](https://github.com/Aerilym)! - Bumped Metamask SDK version to `0.31.1`. + +- Updated dependencies [[`06e186cd679b27fe195309110e766fcf46d4efbc`](https://github.com/wevm/wagmi/commit/06e186cd679b27fe195309110e766fcf46d4efbc)]: + - @wagmi/connectors@5.5.3 + - @wagmi/core@2.15.2 + +## 2.13.2 + +### Patch Changes + +- Updated dependencies [[`e563ef69130a511fd6f3f72ed4cd4fbe1390541f`](https://github.com/wevm/wagmi/commit/e563ef69130a511fd6f3f72ed4cd4fbe1390541f)]: + - @wagmi/connectors@5.5.2 + +## 2.13.1 + +### Patch Changes + +- [`b8bbb409f4934538e3dd6cac5aaf7346292d0693`](https://github.com/wevm/wagmi/commit/b8bbb409f4934538e3dd6cac5aaf7346292d0693) Thanks [@jxom](https://github.com/jxom)! - Fixed issue where `null` gas would accidentally pass through. + +- Updated dependencies [[`b8bbb409f4934538e3dd6cac5aaf7346292d0693`](https://github.com/wevm/wagmi/commit/b8bbb409f4934538e3dd6cac5aaf7346292d0693)]: + - @wagmi/core@2.15.1 + - @wagmi/connectors@5.5.1 + +## 2.13.0 + +### Minor Changes + +- [#4417](https://github.com/wevm/wagmi/pull/4417) [`42e65ea4fea99c639817088bba915e0933d17141`](https://github.com/wevm/wagmi/commit/42e65ea4fea99c639817088bba915e0933d17141) Thanks [@jxom](https://github.com/jxom)! - Removed simulation in `writeContract` & `sendTransaction`. + +### Patch Changes + +- Updated dependencies [[`42e65ea4fea99c639817088bba915e0933d17141`](https://github.com/wevm/wagmi/commit/42e65ea4fea99c639817088bba915e0933d17141)]: + - @wagmi/connectors@6.0.0 + - @wagmi/core@2.15.0 + +## 2.12.33 + +### Patch Changes + +- Updated dependencies [[`7ca62b44cd997d48f92c2b81343726a5908aa00b`](https://github.com/wevm/wagmi/commit/7ca62b44cd997d48f92c2b81343726a5908aa00b)]: + - @wagmi/connectors@5.4.0 + +## 2.12.32 + +### Patch Changes + +- Updated dependencies [[`a13aa8d7c38eb3cc8171a02d6302e6d12cf6bcb3`](https://github.com/wevm/wagmi/commit/a13aa8d7c38eb3cc8171a02d6302e6d12cf6bcb3), [`a13aa8d7c38eb3cc8171a02d6302e6d12cf6bcb3`](https://github.com/wevm/wagmi/commit/a13aa8d7c38eb3cc8171a02d6302e6d12cf6bcb3)]: + - @wagmi/core@2.14.6 + - @wagmi/connectors@5.3.10 + +## 2.12.31 + +### Patch Changes + +- Updated dependencies [[`b12a04eeec985c48d2feac94b011d41fb29ca23e`](https://github.com/wevm/wagmi/commit/b12a04eeec985c48d2feac94b011d41fb29ca23e)]: + - @wagmi/connectors@5.3.9 + +## 2.12.30 + +### Patch Changes + +- Updated dependencies [[`6b9bbacdc7bffd44fc2165362a5e65fd434e7646`](https://github.com/wevm/wagmi/commit/6b9bbacdc7bffd44fc2165362a5e65fd434e7646), [`dac62dc99a0679fa632a0fae49873d6053d06b35`](https://github.com/wevm/wagmi/commit/dac62dc99a0679fa632a0fae49873d6053d06b35)]: + - @wagmi/core@2.14.5 + - @wagmi/connectors@5.3.8 + +## 2.12.29 + +### Patch Changes + +- Updated dependencies [[`e08681c81fbdf475213e2d0f4c5517d0abf4e743`](https://github.com/wevm/wagmi/commit/e08681c81fbdf475213e2d0f4c5517d0abf4e743)]: + - @wagmi/core@2.14.4 + - @wagmi/connectors@5.3.7 + +## 2.12.28 + +### Patch Changes + +- Updated dependencies [[`7558ff3133c11bc4c49473d08ee9a47eaa12df5b`](https://github.com/wevm/wagmi/commit/7558ff3133c11bc4c49473d08ee9a47eaa12df5b)]: + - @wagmi/connectors@5.3.6 + +## 2.12.27 + +### Patch Changes + +- Updated dependencies [[`cb7dd2ebb871d0be8f1a11a8cd8ce592cd74b7c7`](https://github.com/wevm/wagmi/commit/cb7dd2ebb871d0be8f1a11a8cd8ce592cd74b7c7), [`7fe78f2d09778fc01fd0cffe85ba198e64999275`](https://github.com/wevm/wagmi/commit/7fe78f2d09778fc01fd0cffe85ba198e64999275)]: + - @wagmi/core@2.14.3 + - @wagmi/connectors@5.3.5 + +## 2.12.26 + +### Patch Changes + +- Updated dependencies [[`b6861a4c378dab78d8751ae0ac2aa425f3c24b8f`](https://github.com/wevm/wagmi/commit/b6861a4c378dab78d8751ae0ac2aa425f3c24b8f), [`d0d0963bb5904a15cf0355862d62dd141ce0c31c`](https://github.com/wevm/wagmi/commit/d0d0963bb5904a15cf0355862d62dd141ce0c31c), [`ecac0ba36243d94c9199d0bd21937104c835d9a0`](https://github.com/wevm/wagmi/commit/ecac0ba36243d94c9199d0bd21937104c835d9a0)]: + - @wagmi/connectors@5.3.4 + - @wagmi/core@2.14.2 + +## 2.12.25 + +### Patch Changes + +- Updated dependencies [[`83c6d16b7d6dddfa6bda036e04f00ec313c6248c`](https://github.com/wevm/wagmi/commit/83c6d16b7d6dddfa6bda036e04f00ec313c6248c)]: + - @wagmi/connectors@5.3.3 + +## 2.12.24 + +### Patch Changes + +- [`a4c5389c1a299bd7acf9df4a0d607e2ced709280`](https://github.com/wevm/wagmi/commit/a4c5389c1a299bd7acf9df4a0d607e2ced709280) Thanks [@jxom](https://github.com/jxom)! - Exported `Transport` type (for inference). + +## 2.12.23 + +### Patch Changes + +- Updated dependencies [[`8970cc51398e1ac713435533096215c6d31ffdf9`](https://github.com/wevm/wagmi/commit/8970cc51398e1ac713435533096215c6d31ffdf9)]: + - @wagmi/connectors@5.3.2 + +## 2.12.22 + +### Patch Changes + +- Updated dependencies [[`052e72e1f8c1c14fcbdce04a9f8fa7ec28d83702`](https://github.com/wevm/wagmi/commit/052e72e1f8c1c14fcbdce04a9f8fa7ec28d83702), [`b250fc21ee577b2a75c5a34ff684f62fb4ad771a`](https://github.com/wevm/wagmi/commit/b250fc21ee577b2a75c5a34ff684f62fb4ad771a)]: + - @wagmi/core@2.14.1 + - @wagmi/connectors@5.3.1 + +## 2.12.21 + +### Patch Changes + +- Updated dependencies [[`f43e074f473820b208a6295d7c97f847332f1a1d`](https://github.com/wevm/wagmi/commit/f43e074f473820b208a6295d7c97f847332f1a1d)]: + - @wagmi/connectors@6.0.0 + - @wagmi/core@2.14.0 + +## 2.12.20 + +### Patch Changes + +- Updated dependencies [[`c05caabc20c3ced9682cfc7ba1f3f7dcfece0703`](https://github.com/wevm/wagmi/commit/c05caabc20c3ced9682cfc7ba1f3f7dcfece0703), [`5ae49af590ff168426c9c283d54c34ae5148fcd9`](https://github.com/wevm/wagmi/commit/5ae49af590ff168426c9c283d54c34ae5148fcd9), [`f3182b22e6e454d9bd74f1b940ef34431fd9555d`](https://github.com/wevm/wagmi/commit/f3182b22e6e454d9bd74f1b940ef34431fd9555d)]: + - @wagmi/core@2.13.9 + - @wagmi/connectors@5.2.2 + +## 2.12.19 + +### Patch Changes + +- Updated dependencies [[`91a40f2db08e3a91db421b8732a5511a1e6c88fd`](https://github.com/wevm/wagmi/commit/91a40f2db08e3a91db421b8732a5511a1e6c88fd)]: + - @wagmi/connectors@5.2.1 + +## 2.12.18 + +### Patch Changes + +- Updated dependencies [[`34a0c3b7eea778aee7c27f7ace5e4b2be4e8a0a4`](https://github.com/wevm/wagmi/commit/34a0c3b7eea778aee7c27f7ace5e4b2be4e8a0a4)]: + - @wagmi/connectors@5.2.0 + +## 2.12.17 + +### Patch Changes + +- Updated dependencies [[`3b2123664b7ac66848390739e855c3b9702ab60c`](https://github.com/wevm/wagmi/commit/3b2123664b7ac66848390739e855c3b9702ab60c)]: + - @wagmi/connectors@5.1.15 + +## 2.12.16 + +### Patch Changes + +- Updated dependencies [[`56f2482508f2ba71bd6b0295c70c6abca7101e57`](https://github.com/wevm/wagmi/commit/56f2482508f2ba71bd6b0295c70c6abca7101e57)]: + - @wagmi/connectors@5.1.14 + - @wagmi/core@2.13.8 + +## 2.12.15 + +### Patch Changes + +- [#4229](https://github.com/wevm/wagmi/pull/4229) [`c6b8efd26254c8e692b2b67286ed538fc183b992`](https://github.com/wevm/wagmi/commit/c6b8efd26254c8e692b2b67286ed538fc183b992) Thanks [@weilliao05621](https://github.com/weilliao05621)! - Stabilized `useAccount` return type object reference. + +## 2.12.14 + +### Patch Changes + +- Updated dependencies [[`be75c2d4ef636d7362420ab0a106bfdf63f5d1e6`](https://github.com/wevm/wagmi/commit/be75c2d4ef636d7362420ab0a106bfdf63f5d1e6)]: + - @wagmi/core@2.13.7 + - @wagmi/connectors@5.1.13 + +## 2.12.13 + +### Patch Changes + +- Updated dependencies [[`edcbf5d6fbe92f639bead800502edda9e0aa39f1`](https://github.com/wevm/wagmi/commit/edcbf5d6fbe92f639bead800502edda9e0aa39f1)]: + - @wagmi/core@2.13.6 + - @wagmi/connectors@5.1.12 + +## 2.12.12 + +### Patch Changes + +- Updated dependencies [[`82404c960e04c83e0bae6e1e12459ef9debf9554`](https://github.com/wevm/wagmi/commit/82404c960e04c83e0bae6e1e12459ef9debf9554), [`d07ad7f63a018256908a673d078aaf79e47ac703`](https://github.com/wevm/wagmi/commit/d07ad7f63a018256908a673d078aaf79e47ac703)]: + - @wagmi/connectors@5.1.11 + +## 2.12.11 + +### Patch Changes + +- [#4262](https://github.com/wevm/wagmi/pull/4262) [`8531f83db3a1fbb8202c3e426b7f85679f587a52`](https://github.com/wevm/wagmi/commit/8531f83db3a1fbb8202c3e426b7f85679f587a52) Thanks [@nezouse](https://github.com/nezouse)! - Added experimental actions entrypoint. + +## 2.12.10 + +### Patch Changes + +- [#4260](https://github.com/wevm/wagmi/pull/4260) [`969a208a110b760a13fd7263360320f52440a9b6`](https://github.com/wevm/wagmi/commit/969a208a110b760a13fd7263360320f52440a9b6) Thanks [@tmm](https://github.com/tmm)! - Fixed `useReadContract` deployless reads support. + +- [#4259](https://github.com/wevm/wagmi/pull/4259) [`f47ce8f6d263e49fdff90b8edb3190142d2657bb`](https://github.com/wevm/wagmi/commit/f47ce8f6d263e49fdff90b8edb3190142d2657bb) Thanks [@tmm](https://github.com/tmm)! - Disabled `useConnectorClient` and `useWalletClient` during reconnection if connector is not fully restored. + +- Updated dependencies [[`81de006e66121a18c61945c1f9b8426c83a5713c`](https://github.com/wevm/wagmi/commit/81de006e66121a18c61945c1f9b8426c83a5713c), [`f47ce8f6d263e49fdff90b8edb3190142d2657bb`](https://github.com/wevm/wagmi/commit/f47ce8f6d263e49fdff90b8edb3190142d2657bb)]: + - @wagmi/connectors@5.1.10 + - @wagmi/core@2.13.5 + +## 2.12.9 + +### Patch Changes + +- Updated dependencies [[`21bd0e473d374cbbd7a01bececa6022d529026ba`](https://github.com/wevm/wagmi/commit/21bd0e473d374cbbd7a01bececa6022d529026ba), [`5c89c6853e616437a3be2b019db895451fecfb3c`](https://github.com/wevm/wagmi/commit/5c89c6853e616437a3be2b019db895451fecfb3c)]: + - @wagmi/connectors@5.1.9 + +## 2.12.8 + +### Patch Changes + +- Updated dependencies [[`b580ad4edff1721e0b9d138cf5ae2ec74d2374c7`](https://github.com/wevm/wagmi/commit/b580ad4edff1721e0b9d138cf5ae2ec74d2374c7)]: + - @wagmi/connectors@5.1.8 + +## 2.12.7 + +### Patch Changes + +- Updated dependencies [[`91fd81a068789c5020e891f539bcad8f54a7a52f`](https://github.com/wevm/wagmi/commit/91fd81a068789c5020e891f539bcad8f54a7a52f)]: + - @wagmi/connectors@5.1.7 + +## 2.12.6 + +### Patch Changes + +- Updated dependencies [[`3168616298cbb6135d0ffda771cba4126e83eba8`](https://github.com/wevm/wagmi/commit/3168616298cbb6135d0ffda771cba4126e83eba8), [`d7608ef9a79459465dc8c06a2ab740465c881907`](https://github.com/wevm/wagmi/commit/d7608ef9a79459465dc8c06a2ab740465c881907)]: + - @wagmi/connectors@5.1.6 + +## 2.12.5 + +### Patch Changes + +- Updated dependencies [[`b4c8971788c70b09479946ecfa998cff2f1b3953`](https://github.com/wevm/wagmi/commit/b4c8971788c70b09479946ecfa998cff2f1b3953)]: + - @wagmi/core@2.13.4 + - @wagmi/connectors@5.1.5 + +## 2.12.4 + +### Patch Changes + +- Updated dependencies [[`871dbdbfe59ac8ad01d1ec6150ea7b091b7b7de4`](https://github.com/wevm/wagmi/commit/871dbdbfe59ac8ad01d1ec6150ea7b091b7b7de4)]: + - @wagmi/core@2.13.3 + - @wagmi/connectors@5.1.4 + +## 2.12.3 + +### Patch Changes + +- Updated dependencies [[`1b9b523fa9b9dfe839aecdf4b40caa9547d7e594`](https://github.com/wevm/wagmi/commit/1b9b523fa9b9dfe839aecdf4b40caa9547d7e594)]: + - @wagmi/core@2.13.2 + - @wagmi/connectors@5.1.3 + +## 2.12.2 + +### Patch Changes + +- Updated dependencies [[`abb490dac4f0f02f46cb0878e7ca9a0db6aada56`](https://github.com/wevm/wagmi/commit/abb490dac4f0f02f46cb0878e7ca9a0db6aada56), [`28e0e5c9a4f856583f9d36a807502bd51a0c6ec2`](https://github.com/wevm/wagmi/commit/28e0e5c9a4f856583f9d36a807502bd51a0c6ec2)]: + - @wagmi/connectors@5.1.2 + +## 2.12.1 + +### Patch Changes + +- Updated dependencies [[`07c1227f306d0efb9421d4bb77a774f92f5fcf45`](https://github.com/wevm/wagmi/commit/07c1227f306d0efb9421d4bb77a774f92f5fcf45)]: + - @wagmi/core@2.13.1 + - @wagmi/connectors@5.1.1 + +## 2.12.0 + +### Minor Changes + +- [#4162](https://github.com/wevm/wagmi/pull/4162) [`a73a7737b756886b388f120ae423e72cca53e8a0`](https://github.com/wevm/wagmi/commit/a73a7737b756886b388f120ae423e72cca53e8a0) Thanks [@jxom](https://github.com/jxom)! - Added functionality for consumer-defined RPC URLs (`config.transports`) to be propagated to the WalletConnect & MetaMask Connectors. + +### Patch Changes + +- Updated dependencies [[`a73a7737b756886b388f120ae423e72cca53e8a0`](https://github.com/wevm/wagmi/commit/a73a7737b756886b388f120ae423e72cca53e8a0)]: + - @wagmi/connectors@6.0.0 + - @wagmi/core@2.13.0 + +## 2.11.3 + +### Patch Changes + +- [#4124](https://github.com/wevm/wagmi/pull/4124) [`26616462db2e0140025f22c505c4541cfecb9308`](https://github.com/wevm/wagmi/commit/26616462db2e0140025f22c505c4541cfecb9308) Thanks [@t0rbik](https://github.com/t0rbik)! - Updated `useConnectorClient` to be enabled when status is `'reconnecting'` or `'connected'` (previously was also enabled when status was `'connecting'`). + +## 2.11.2 + +### Patch Changes + +- Updated dependencies [[`5bc8c8877810b2eec24a829df87dce40a51e6f20`](https://github.com/wevm/wagmi/commit/5bc8c8877810b2eec24a829df87dce40a51e6f20), [`8d81df5cc884d0a210dedd3c1ea0e2e9e52b83c5`](https://github.com/wevm/wagmi/commit/8d81df5cc884d0a210dedd3c1ea0e2e9e52b83c5)]: + - @wagmi/core@2.12.2 + - @wagmi/connectors@5.0.26 + +## 2.11.1 + +### Patch Changes + +- [#4146](https://github.com/wevm/wagmi/pull/4146) [`cc996e08e930c9e88cf753a1e874652059e81a3b`](https://github.com/wevm/wagmi/commit/cc996e08e930c9e88cf753a1e874652059e81a3b) Thanks [@jxom](https://github.com/jxom)! - Updated `@safe-global/safe-apps-sdk` + `@safe-global/safe-apps-provider` dependencies. + +- Updated dependencies [[`cc996e08e930c9e88cf753a1e874652059e81a3b`](https://github.com/wevm/wagmi/commit/cc996e08e930c9e88cf753a1e874652059e81a3b)]: + - @wagmi/connectors@5.0.25 + - @wagmi/core@2.12.1 + +## 2.11.0 + +### Minor Changes + +- [#4128](https://github.com/wevm/wagmi/pull/4128) [`5581a810ef70308e99c6f8b630cd4bca59f64afc`](https://github.com/wevm/wagmi/commit/5581a810ef70308e99c6f8b630cd4bca59f64afc) Thanks [@dalechyn](https://github.com/dalechyn)! - Added `useWatchAsset` hook. + +### Patch Changes + +- Updated dependencies [[`5581a810ef70308e99c6f8b630cd4bca59f64afc`](https://github.com/wevm/wagmi/commit/5581a810ef70308e99c6f8b630cd4bca59f64afc)]: + - @wagmi/core@2.12.0 + - @wagmi/connectors@6.0.0 + +## 2.10.11 + +### Patch Changes + +- [`d3814ab4b88f9f0e052b53bc3d458df87b43f01d`](https://github.com/wevm/wagmi/commit/d3814ab4b88f9f0e052b53bc3d458df87b43f01d) Thanks [@jxom](https://github.com/jxom)! - Updated `mipd` dependency. + +- Updated dependencies [[`b08013eaa9ce97c02f8a7128ea400e3da7ef74bb`](https://github.com/wevm/wagmi/commit/b08013eaa9ce97c02f8a7128ea400e3da7ef74bb), [`d3814ab4b88f9f0e052b53bc3d458df87b43f01d`](https://github.com/wevm/wagmi/commit/d3814ab4b88f9f0e052b53bc3d458df87b43f01d)]: + - @wagmi/core@2.11.8 + - @wagmi/connectors@5.0.23 + +## 2.10.10 + +### Patch Changes + +- Updated dependencies [[`0bb8b562ae04ecfeb2d6b2f1b980ebae31dc127e`](https://github.com/wevm/wagmi/commit/0bb8b562ae04ecfeb2d6b2f1b980ebae31dc127e)]: + - @wagmi/connectors@5.0.22 + - @wagmi/core@2.11.7 + +## 2.10.9 + +### Patch Changes + +- [#4060](https://github.com/wevm/wagmi/pull/4060) [`95965c1f19d480b97f2b297a077a9e607dee32ad`](https://github.com/wevm/wagmi/commit/95965c1f19d480b97f2b297a077a9e607dee32ad) Thanks [@dalechyn](https://github.com/dalechyn)! - Bumped Tanstack Query dependencies to fix typing issues between exported Wagmi query options and TanStack Query suspense query methods (due to [`direction` property in `QueryFunctionContext` being deprecated](https://github.com/TanStack/query/pull/7410)). + +- Updated dependencies [[`ff0760b5900114bcfdf420a9fba3cc278ac95afe`](https://github.com/wevm/wagmi/commit/ff0760b5900114bcfdf420a9fba3cc278ac95afe), [`95965c1f19d480b97f2b297a077a9e607dee32ad`](https://github.com/wevm/wagmi/commit/95965c1f19d480b97f2b297a077a9e607dee32ad)]: + - @wagmi/connectors@5.0.21 + - @wagmi/core@2.11.6 + +## 2.10.8 + +### Patch Changes + +- Updated dependencies [[`43fa971d34cac57fa5a2898ad4d839b95d7af37c`](https://github.com/wevm/wagmi/commit/43fa971d34cac57fa5a2898ad4d839b95d7af37c)]: + - @wagmi/connectors@5.0.20 + +## 2.10.7 + +### Patch Changes + +- Updated dependencies [[`b7ad208030d9f2e3f89912ff76b16cdbd848feda`](https://github.com/wevm/wagmi/commit/b7ad208030d9f2e3f89912ff76b16cdbd848feda)]: + - @wagmi/connectors@5.0.19 + +## 2.10.6 + +### Patch Changes + +- Updated dependencies [[`44d24620c9e3957f3245d14d6a042736371df70b`](https://github.com/wevm/wagmi/commit/44d24620c9e3957f3245d14d6a042736371df70b)]: + - @wagmi/connectors@5.0.18 + +## 2.10.5 + +### Patch Changes + +- Updated dependencies [[`04f2b846b113f3d300d82c9fa75212f1805817c5`](https://github.com/wevm/wagmi/commit/04f2b846b113f3d300d82c9fa75212f1805817c5)]: + - @wagmi/core@2.11.5 + - @wagmi/connectors@5.0.17 + +## 2.10.4 + +### Patch Changes + +- Updated dependencies [[`9e8345cd56186b997b5e56deaa2cfc69b30d15f6`](https://github.com/wevm/wagmi/commit/9e8345cd56186b997b5e56deaa2cfc69b30d15f6), [`02c38c28d1aa0ad7a61c33775de603ed974c5c1b`](https://github.com/wevm/wagmi/commit/02c38c28d1aa0ad7a61c33775de603ed974c5c1b)]: + - @wagmi/core@2.11.4 + - @wagmi/connectors@5.0.16 + +## 2.10.3 + +### Patch Changes + +- Updated dependencies [[`8974e6269bb5d7bfaa90db0246bc7d13e8bff798`](https://github.com/wevm/wagmi/commit/8974e6269bb5d7bfaa90db0246bc7d13e8bff798)]: + - @wagmi/core@2.11.3 + - @wagmi/connectors@5.0.15 + +## 2.10.2 + +### Patch Changes + +- Updated dependencies [[`b4d9ef79deb554ee20fed6666a474be5e7cdd522`](https://github.com/wevm/wagmi/commit/b4d9ef79deb554ee20fed6666a474be5e7cdd522)]: + - @wagmi/core@2.11.2 + - @wagmi/connectors@5.0.14 + +## 2.10.1 + +### Patch Changes + +- Updated dependencies [[`9c862d8d63e3d692a22cef2a90782b74a9103f17`](https://github.com/wevm/wagmi/commit/9c862d8d63e3d692a22cef2a90782b74a9103f17)]: + - @wagmi/connectors@5.0.13 + - @wagmi/core@2.11.1 + +## 2.10.0 + +### Minor Changes + +- [#3816](https://github.com/wevm/wagmi/pull/3816) [`06bb598a7f04c7b167f5b7ff6d46bd15886a6a14`](https://github.com/wevm/wagmi/commit/06bb598a7f04c7b167f5b7ff6d46bd15886a6a14) Thanks [@marthendalnunes](https://github.com/marthendalnunes)! - Added `useDeployContract` hook. + +### Patch Changes + +- Updated dependencies [[`06bb598a7f04c7b167f5b7ff6d46bd15886a6a14`](https://github.com/wevm/wagmi/commit/06bb598a7f04c7b167f5b7ff6d46bd15886a6a14), [`24a45b269bd0214a29d6f82a84ac66ef8c3f3822`](https://github.com/wevm/wagmi/commit/24a45b269bd0214a29d6f82a84ac66ef8c3f3822)]: + - @wagmi/core@2.11.0 + - @wagmi/connectors@6.0.0 + +## 2.9.12 + +### Patch Changes + +- Updated dependencies [[`f2a7cefab96691ebed8b8e45ffde071c47b58dbe`](https://github.com/wevm/wagmi/commit/f2a7cefab96691ebed8b8e45ffde071c47b58dbe), [`f0ea0b2a7fe193dadfeb49a4c8031ee451c638b5`](https://github.com/wevm/wagmi/commit/f0ea0b2a7fe193dadfeb49a4c8031ee451c638b5), [`e3b124ce414b8fd1b2214e2c5a28dc72158a13d1`](https://github.com/wevm/wagmi/commit/e3b124ce414b8fd1b2214e2c5a28dc72158a13d1)]: + - @wagmi/core@2.10.6 + - @wagmi/connectors@5.0.11 + +## 2.9.11 + +### Patch Changes + +- Updated dependencies [[`560952acd4bfe33db6c7c07b35c613cef278677c`](https://github.com/wevm/wagmi/commit/560952acd4bfe33db6c7c07b35c613cef278677c)]: + - @wagmi/connectors@5.0.10 + +## 2.9.10 + +### Patch Changes + +- Updated dependencies [[`32cdd7b7dc5aff916c040628519562c3a99d418d`](https://github.com/wevm/wagmi/commit/32cdd7b7dc5aff916c040628519562c3a99d418d)]: + - @wagmi/connectors@5.0.9 + +## 2.9.9 + +### Patch Changes + +- Updated dependencies [[`c1952d1ff7f0a491dc88595a49159451b07b5621`](https://github.com/wevm/wagmi/commit/c1952d1ff7f0a491dc88595a49159451b07b5621)]: + - @wagmi/connectors@5.0.8 + +## 2.9.8 + +### Patch Changes + +- Updated dependencies [[`030c7c2cb380dfd67a2182f62e2aa7a6e1601898`](https://github.com/wevm/wagmi/commit/030c7c2cb380dfd67a2182f62e2aa7a6e1601898)]: + - @wagmi/core@2.10.5 + - @wagmi/connectors@5.0.7 + +## 2.9.7 + +### Patch Changes + +- Updated dependencies [[`51fde8a0433b4fff357c1a8d7e08b41b4c86c968`](https://github.com/wevm/wagmi/commit/51fde8a0433b4fff357c1a8d7e08b41b4c86c968)]: + - @wagmi/core@2.10.4 + - @wagmi/connectors@5.0.6 + +## 2.9.6 + +### Patch Changes + +- Updated dependencies [[`70dd28669dd8d2ce08217cd02e29a8fbba7a08d4`](https://github.com/wevm/wagmi/commit/70dd28669dd8d2ce08217cd02e29a8fbba7a08d4)]: + - @wagmi/connectors@5.0.5 + +## 2.9.5 + +### Patch Changes + +- Updated dependencies [[`be9e1b8a9818b92eb0654a20d9471e9e39329e7e`](https://github.com/wevm/wagmi/commit/be9e1b8a9818b92eb0654a20d9471e9e39329e7e)]: + - @wagmi/connectors@5.0.4 + +## 2.9.4 + +### Patch Changes + +- Updated dependencies [[`2804a8a583b1874271154898b4bae38756ef581c`](https://github.com/wevm/wagmi/commit/2804a8a583b1874271154898b4bae38756ef581c), [`2804a8a583b1874271154898b4bae38756ef581c`](https://github.com/wevm/wagmi/commit/2804a8a583b1874271154898b4bae38756ef581c)]: + - @wagmi/connectors@5.0.3 + - @wagmi/core@2.10.3 + +## 2.9.3 + +### Patch Changes + +- [`ec2f63f106fd468f28b43d3b88ab3e89aaf5e81a`](https://github.com/wevm/wagmi/commit/ec2f63f106fd468f28b43d3b88ab3e89aaf5e81a) Thanks [@tmm](https://github.com/tmm)! - Fixed `useSwitchChain` `chains` typing. + +## 2.9.2 + +### Patch Changes + +- [#3940](https://github.com/wevm/wagmi/pull/3940) [`a5071f581dfdfb961718873643a2fc629101c72a`](https://github.com/wevm/wagmi/commit/a5071f581dfdfb961718873643a2fc629101c72a) Thanks [@jxom](https://github.com/jxom)! - Fixed usage of `metaMask` connector in Vite environments. + +- Updated dependencies [[`a5071f581dfdfb961718873643a2fc629101c72a`](https://github.com/wevm/wagmi/commit/a5071f581dfdfb961718873643a2fc629101c72a)]: + - @wagmi/connectors@5.0.2 + - @wagmi/core@2.10.2 + +## 2.9.1 + +### Patch Changes + +- Bumped versions. + +- Updated dependencies []: + - @wagmi/connectors@5.0.1 + - @wagmi/core@2.10.1 + +## 2.9.0 + +### Minor Changes + +- [#3928](https://github.com/wevm/wagmi/pull/3928) [`3117e71825f9c58a0d718f3d1686f1a191fa9cb1`](https://github.com/wevm/wagmi/commit/3117e71825f9c58a0d718f3d1686f1a191fa9cb1) Thanks [@tmm](https://github.com/tmm)! - Updated the default Coinbase SDK in `coinbaseWallet` Connector to v4.x. + +### Patch Changes + +- Updated dependencies [[`3117e71825f9c58a0d718f3d1686f1a191fa9cb1`](https://github.com/wevm/wagmi/commit/3117e71825f9c58a0d718f3d1686f1a191fa9cb1), [`3117e71825f9c58a0d718f3d1686f1a191fa9cb1`](https://github.com/wevm/wagmi/commit/3117e71825f9c58a0d718f3d1686f1a191fa9cb1)]: + - @wagmi/connectors@5.0.0 + - @wagmi/core@2.10.0 + +## 2.8.8 + +### Patch Changes + +- [#3906](https://github.com/wevm/wagmi/pull/3906) [`32fcb4a31dde6b0206961d8ffe9c651f8a459c67`](https://github.com/wevm/wagmi/commit/32fcb4a31dde6b0206961d8ffe9c651f8a459c67) Thanks [@tmm](https://github.com/tmm)! - Added support for Vue. + +- Updated dependencies [[`32fcb4a31dde6b0206961d8ffe9c651f8a459c67`](https://github.com/wevm/wagmi/commit/32fcb4a31dde6b0206961d8ffe9c651f8a459c67)]: + - @wagmi/connectors@4.3.10 + - @wagmi/core@2.9.8 + +## 2.8.7 + +### Patch Changes + +- [#3924](https://github.com/wevm/wagmi/pull/3924) [`1f58734f88458e0f6adb05c99f0c90f36ab286b8`](https://github.com/wevm/wagmi/commit/1f58734f88458e0f6adb05c99f0c90f36ab286b8) Thanks [@jxom](https://github.com/jxom)! - Refactored `isChainsStale` logic in `walletConnect` connector. + +- Updated dependencies [[`1f58734f88458e0f6adb05c99f0c90f36ab286b8`](https://github.com/wevm/wagmi/commit/1f58734f88458e0f6adb05c99f0c90f36ab286b8)]: + - @wagmi/connectors@4.3.9 + - @wagmi/core@2.9.7 + +## 2.8.6 + +### Patch Changes + +- [#3917](https://github.com/wevm/wagmi/pull/3917) [`05948fdad5bb4a56b08916d45b3dec2cb1e5f55b`](https://github.com/wevm/wagmi/commit/05948fdad5bb4a56b08916d45b3dec2cb1e5f55b) Thanks [@jxom](https://github.com/jxom)! - Updated `@metamask/sdk`. + +- Updated dependencies [[`05948fdad5bb4a56b08916d45b3dec2cb1e5f55b`](https://github.com/wevm/wagmi/commit/05948fdad5bb4a56b08916d45b3dec2cb1e5f55b)]: + - @wagmi/connectors@4.3.8 + - @wagmi/core@2.9.6 + +## 2.8.5 + +### Patch Changes + +- [`4fecbbb66d0aacd03b8c62a6455d11a33cde8f85`](https://github.com/wevm/wagmi/commit/4fecbbb66d0aacd03b8c62a6455d11a33cde8f85) Thanks [@jxom](https://github.com/jxom)! - Fixed address comparison in `getConnectorClient`. + +- Updated dependencies [[`4fecbbb66d0aacd03b8c62a6455d11a33cde8f85`](https://github.com/wevm/wagmi/commit/4fecbbb66d0aacd03b8c62a6455d11a33cde8f85)]: + - @wagmi/core@2.9.5 + - @wagmi/connectors@4.3.7 + +## 2.8.4 + +### Patch Changes + +- Updated dependencies [[`e6139a97c4b8804d734b1547b5e3921ce01fbe24`](https://github.com/wevm/wagmi/commit/e6139a97c4b8804d734b1547b5e3921ce01fbe24)]: + - @wagmi/core@2.9.4 + - @wagmi/connectors@4.3.6 + +## 2.8.3 + +### Patch Changes + +- [#3904](https://github.com/wevm/wagmi/pull/3904) [`addca28ebc20f1a4367c35fe9ef786decff9c87e`](https://github.com/wevm/wagmi/commit/addca28ebc20f1a4367c35fe9ef786decff9c87e) Thanks [@jxom](https://github.com/jxom)! - Updated `@walletconnect/ethereum-provider`. + +- Updated dependencies [[`addca28ebc20f1a4367c35fe9ef786decff9c87e`](https://github.com/wevm/wagmi/commit/addca28ebc20f1a4367c35fe9ef786decff9c87e)]: + - @wagmi/connectors@4.3.5 + - @wagmi/core@2.9.3 + +## 2.8.2 + +### Patch Changes + +- [#3902](https://github.com/wevm/wagmi/pull/3902) [`204b7b624612405500ec098fb9e35facd3f74ca4`](https://github.com/wevm/wagmi/commit/204b7b624612405500ec098fb9e35facd3f74ca4) Thanks [@jxom](https://github.com/jxom)! - Made third-party SDK imports type-only. + +- Updated dependencies [[`204b7b624612405500ec098fb9e35facd3f74ca4`](https://github.com/wevm/wagmi/commit/204b7b624612405500ec098fb9e35facd3f74ca4)]: + - @wagmi/connectors@4.3.4 + - @wagmi/core@2.9.2 + +## 2.8.1 + +### Patch Changes + +- [`cda6a5d5`](https://github.com/wevm/wagmi/commit/cda6a5d56328330fbde050b4ef40b01c58d2519a) Thanks [@jxom](https://github.com/jxom)! - Updated packages. + +- Updated dependencies [[`cda6a5d5`](https://github.com/wevm/wagmi/commit/cda6a5d56328330fbde050b4ef40b01c58d2519a)]: + - @wagmi/core@2.9.1 + - @wagmi/connectors@4.3.3 + +## 2.8.0 + +### Minor Changes + +- [#3878](https://github.com/wevm/wagmi/pull/3878) [`017828fc`](https://github.com/wevm/wagmi/commit/017828fc027c7a84b54ea9d627e9389f4d60d6c2) Thanks [@jxom](https://github.com/jxom)! - Added experimental EIP-5792 Actions & Hooks. + +### Patch Changes + +- Updated dependencies [[`017828fc`](https://github.com/wevm/wagmi/commit/017828fc027c7a84b54ea9d627e9389f4d60d6c2)]: + - @wagmi/core@2.9.0 + - @wagmi/connectors@4.3.2 + +## 2.7.1 + +### Patch Changes + +- [#3869](https://github.com/wevm/wagmi/pull/3869) [`d4a78eb0`](https://github.com/wevm/wagmi/commit/d4a78eb07119d2e5617e52481ac7d6c6d1583ddc) Thanks [@jxom](https://github.com/jxom)! - Fixed issue where `prepareTransactionRequest` would internally call unsupported wallet RPC methods. + +- Updated dependencies [[`d4a78eb0`](https://github.com/wevm/wagmi/commit/d4a78eb07119d2e5617e52481ac7d6c6d1583ddc)]: + - @wagmi/core@2.8.1 + - @wagmi/connectors@4.3.1 + +## 2.7.0 + +### Minor Changes + +- [#3868](https://github.com/wevm/wagmi/pull/3868) [`c2af20b8`](https://github.com/wevm/wagmi/commit/c2af20b88cf16970d087faaec10b463357a5836e) Thanks [@jxom](https://github.com/jxom)! - Added `supportsSimulation` property to connectors that indicates if the connector's wallet supports contract simulation. + +### Patch Changes + +- [#3858](https://github.com/wevm/wagmi/pull/3858) [`0d141f17`](https://github.com/wevm/wagmi/commit/0d141f171d6ec44bcbfc9c876565b5e2fb8af6de) Thanks [@yulafezmesi](https://github.com/yulafezmesi)! - Fixed accessing reverted reason property inside `waitForTransactionReceipt`. + +- Updated dependencies [[`0d141f17`](https://github.com/wevm/wagmi/commit/0d141f171d6ec44bcbfc9c876565b5e2fb8af6de), [`c2af20b8`](https://github.com/wevm/wagmi/commit/c2af20b88cf16970d087faaec10b463357a5836e)]: + - @wagmi/core@2.8.0 + - @wagmi/connectors@5.0.0 + +## 2.6.0 + +### Minor Changes + +- [#3857](https://github.com/wevm/wagmi/pull/3857) [`d4274c03`](https://github.com/wevm/wagmi/commit/d4274c03a6af5f2d26d31432016ebc14950a330e) Thanks [@tmm](https://github.com/tmm)! - Added `addEthereumChainParameter` to `switchChain`-related methods. + +### Patch Changes + +- Updated dependencies [[`d4274c03`](https://github.com/wevm/wagmi/commit/d4274c03a6af5f2d26d31432016ebc14950a330e), [`4781a405`](https://github.com/wevm/wagmi/commit/4781a4056d4ffc2c74f96a75429e9b2cd2417ad8), [`400c960b`](https://github.com/wevm/wagmi/commit/400c960b30d701c134850c695ae903a382c29b5b)]: + - @wagmi/connectors@5.0.0 + - @wagmi/core@2.7.0 + +## 2.5.22 + +### Patch Changes + +- [`e3c832a1`](https://github.com/wevm/wagmi/commit/e3c832a12c301f9b0ee129d877b3101d220ba8b2) Thanks [@jxom](https://github.com/jxom)! - Fixed undefined `navigator` issue in MetaMask connector. + +- Updated dependencies [[`e3c832a1`](https://github.com/wevm/wagmi/commit/e3c832a12c301f9b0ee129d877b3101d220ba8b2)]: + - @wagmi/connectors@4.1.28 + - @wagmi/core@2.6.19 + +## 2.5.21 + +### Patch Changes + +- [#3848](https://github.com/wevm/wagmi/pull/3848) [`dd40a41c`](https://github.com/wevm/wagmi/commit/dd40a41c526ab60a288aff2250ed8dba92a27b16) Thanks [@jxom](https://github.com/jxom)! - Updated MetaMask SDK. + +- Updated dependencies [[`dd40a41c`](https://github.com/wevm/wagmi/commit/dd40a41c526ab60a288aff2250ed8dba92a27b16)]: + - @wagmi/connectors@4.1.27 + - @wagmi/core@2.6.18 + +## 2.5.20 + +### Patch Changes + +- [#3822](https://github.com/wevm/wagmi/pull/3822) [`a97bfbae`](https://github.com/wevm/wagmi/commit/a97bfbaeb615cfef04665e5e7348d85d17f960f0) Thanks [@jxom](https://github.com/jxom)! - Fixed an issue where Wagmi would not correctly rehydrate the active chain when a persisted store was being used. + +- Updated dependencies [[`a97bfbae`](https://github.com/wevm/wagmi/commit/a97bfbaeb615cfef04665e5e7348d85d17f960f0)]: + - @wagmi/core@2.6.17 + - @wagmi/connectors@4.1.26 + +## 2.5.19 + +### Patch Changes + +- [#3793](https://github.com/wevm/wagmi/pull/3793) [`f85b83ae`](https://github.com/wevm/wagmi/commit/f85b83ae95dd0bb73ffbdb49afa174e7c68298e1) Thanks [@tmm](https://github.com/tmm)! - Wired up `config` inside hooks so you can pass it explicitly and not use the `WagmiProvider`. + +- Updated dependencies [[`42ad380d`](https://github.com/wevm/wagmi/commit/42ad380d9a5d8bc0f61d73612142dea9d098de5e)]: + - @wagmi/connectors@4.1.25 + - @wagmi/core@2.6.16 + +## 2.5.18 + +### Patch Changes + +- Updated dependencies [[`b907d5ac`](https://github.com/wevm/wagmi/commit/b907d5ac3a746bcbccc06d1fe78c5bd8f9a7d685)]: + - @wagmi/core@2.6.15 + - @wagmi/connectors@4.1.24 + +## 2.5.17 + +### Patch Changes + +- [#3779](https://github.com/wevm/wagmi/pull/3779) [`3da20bb8`](https://github.com/wevm/wagmi/commit/3da20bb80e7c3efeef8227ced66ad615370fc242) Thanks [@jxom](https://github.com/jxom)! - Fixed an issue where `eth_requestAccounts` would be called upon reconnect instead of `eth_accounts`. + +- [`a3d1858f`](https://github.com/wevm/wagmi/commit/a3d1858fce448d2b70e36ee692ef1589b74e9d3f) Thanks [@jxom](https://github.com/jxom)! - Fixed hydration conditional in `createConfig`. + +- Updated dependencies [[`b3b54ef1`](https://github.com/wevm/wagmi/commit/b3b54ef179c5fa0d1694d38d4b808549a0550409), [`3da20bb8`](https://github.com/wevm/wagmi/commit/3da20bb80e7c3efeef8227ced66ad615370fc242), [`a3d1858f`](https://github.com/wevm/wagmi/commit/a3d1858fce448d2b70e36ee692ef1589b74e9d3f)]: + - @wagmi/core@2.6.14 + - @wagmi/connectors@4.1.23 + +## 2.5.16 + +### Patch Changes + +- [`b80236dc`](https://github.com/wevm/wagmi/commit/b80236dc623095fe8f1e1d10957d7776fb6ab48b) Thanks [@jxom](https://github.com/jxom)! - Removed unneeded `uniqueBy` check on connectors state. + +- Updated dependencies [[`b80236dc`](https://github.com/wevm/wagmi/commit/b80236dc623095fe8f1e1d10957d7776fb6ab48b)]: + - @wagmi/core@2.6.13 + - @wagmi/connectors@4.1.22 + +## 2.5.15 + +### Patch Changes + +- [#3740](https://github.com/wevm/wagmi/pull/3740) [`3373c644`](https://github.com/wevm/wagmi/commit/3373c6444c38ef16532d18cfc351b3fe2bf2d351) Thanks [@BrickheadJohnny](https://github.com/BrickheadJohnny)! - Removed unnecessary re-renders from `useConnectorClient` and `useWalletClient`. + +- Updated dependencies [[`a59069e9`](https://github.com/wevm/wagmi/commit/a59069e9fab45dd606bb89a7f829fe94c51a5494), [`0acd3132`](https://github.com/wevm/wagmi/commit/0acd31320f534993af566be5490c2978b6184f66)]: + - @wagmi/core@2.6.12 + - @wagmi/connectors@4.1.21 + +## 2.5.14 + +### Patch Changes + +- [`e1ca4e63`](https://github.com/wevm/wagmi/commit/e1ca4e637ae6cec7f5902b0a2c0e0efc3b751a1d) Thanks [@tmm](https://github.com/tmm)! - Deprecated `normalizeChainId`. Use `Number` instead. + +- Updated dependencies [[`e1ca4e63`](https://github.com/wevm/wagmi/commit/e1ca4e637ae6cec7f5902b0a2c0e0efc3b751a1d)]: + - @wagmi/connectors@4.1.20 + - @wagmi/core@2.6.11 + +## 2.5.13 + +### Patch Changes + +- [`dbdca8fd`](https://github.com/wevm/wagmi/commit/dbdca8fd14b90c166222a66a373c1b33c06ce019) Thanks [@jxom](https://github.com/jxom)! - Fixed issue where duplicate connectors could be instantiated if injected after page mount. + +- Updated dependencies [[`dbdca8fd`](https://github.com/wevm/wagmi/commit/dbdca8fd14b90c166222a66a373c1b33c06ce019)]: + - @wagmi/core@2.6.10 + - @wagmi/connectors@4.1.19 + +## 2.5.12 + +### Patch Changes + +- [#3612](https://github.com/wevm/wagmi/pull/3612) [`97237bb0`](https://github.com/wevm/wagmi/commit/97237bb05c30860b9b12c094e82a38ce59d9bedf) Thanks [@m1heng](https://github.com/m1heng)! - Added missing `functionName` parameter to `useWriteContract` codegen helper. + +## 2.5.11 + +### Patch Changes + +- [#3714](https://github.com/wevm/wagmi/pull/3714) [`f1628d65`](https://github.com/wevm/wagmi/commit/f1628d65f06e9ef18e6c4e2eb4f6e3ab2e700924) Thanks [@dalechyn](https://github.com/dalechyn)! - Replaced `Omit` with `UnionOmit` for `UseMutationReturnType`. + +- [#3715](https://github.com/wevm/wagmi/pull/3715) [`d56edf4f`](https://github.com/wevm/wagmi/commit/d56edf4f27c52acc7a0f57114454b0d3e22cacd6) Thanks [@jxom](https://github.com/jxom)! - Fixed SSR hydration issues. + +- Updated dependencies [[`d56edf4f`](https://github.com/wevm/wagmi/commit/d56edf4f27c52acc7a0f57114454b0d3e22cacd6)]: + - @wagmi/core@2.6.9 + - @wagmi/connectors@4.1.18 + +## 2.5.10 + +### Patch Changes + +- [#3643](https://github.com/wevm/wagmi/pull/3643) [`e46bcd47`](https://github.com/wevm/wagmi/commit/e46bcd4738a18da15b53f6612b614379c1985374) Thanks [@TateB](https://github.com/TateB)! - Fixed race condition arising from `reconnect`. + +- Updated dependencies [[`e46bcd47`](https://github.com/wevm/wagmi/commit/e46bcd4738a18da15b53f6612b614379c1985374)]: + - @wagmi/core@2.6.8 + - @wagmi/connectors@4.1.17 + +## 2.5.9 + +### Patch Changes + +- [`f5648dd2`](https://github.com/wevm/wagmi/commit/f5648dd28b3576b628f57732b89287f55acbb1c1) Thanks [@jxom](https://github.com/jxom)! - Updated `prepareTransactionRequest` types for `viem@2.8.0`. + +- [`1c1fee6a`](https://github.com/wevm/wagmi/commit/1c1fee6ab8f01f7734ac6ce05093fa8e388beb3e) Thanks [@jxom](https://github.com/jxom)! - Updated `@walletconnect/ethereum-provider`. + +- Updated dependencies [[`b479b5e8`](https://github.com/wevm/wagmi/commit/b479b5e8a5866cba792862f22e6352c4fb566137), [`f5648dd2`](https://github.com/wevm/wagmi/commit/f5648dd28b3576b628f57732b89287f55acbb1c1), [`1c1fee6a`](https://github.com/wevm/wagmi/commit/1c1fee6ab8f01f7734ac6ce05093fa8e388beb3e), [`88a2d744`](https://github.com/wevm/wagmi/commit/88a2d744a1315908c9e54156026df3ad2435ad44)]: + - @wagmi/core@2.6.7 + - @wagmi/connectors@4.1.16 + +## 2.5.8 + +### Patch Changes + +- Updated dependencies [[`a91c0b64`](https://github.com/wevm/wagmi/commit/a91c0b64ba8b3e6537a560e69724eb601f26af27)]: + - @wagmi/core@2.6.6 + - @wagmi/connectors@4.1.15 + +## 2.5.7 + +### Patch Changes + +- [#3580](https://github.com/wevm/wagmi/pull/3580) [`c677dcd2`](https://github.com/wevm/wagmi/commit/c677dcd245dccdf69289a3d66dded237b09570a2) Thanks [@tmm](https://github.com/tmm)! - Made `useSwitchChain().chains` reactive. + +- Updated dependencies [[`ca5decdb`](https://github.com/wevm/wagmi/commit/ca5decdb712f81e3f5dab933a94b967bca5b6af4), [`c677dcd2`](https://github.com/wevm/wagmi/commit/c677dcd245dccdf69289a3d66dded237b09570a2)]: + - @wagmi/connectors@4.1.14 + - @wagmi/core@2.6.5 + +## 2.5.6 + +### Patch Changes + +- Updated dependencies [[`7c6618e6`](https://github.com/wevm/wagmi/commit/7c6618e6a0eb1ff39cf8f66b34d3ddc14be538fe), [`fa25b448`](https://github.com/wevm/wagmi/commit/fa25b4482504b4d9729a5687ea6d6dc959265bc0), [`895f28e8`](https://github.com/wevm/wagmi/commit/895f28e873af7c8eda5ca85734ff67c8979fd950)]: + - @wagmi/core@2.6.4 + - @wagmi/connectors@4.1.13 + +## 2.5.5 + +### Patch Changes + +- Updated dependencies [[`9c3b85dd`](https://github.com/wevm/wagmi/commit/9c3b85dd0a9a4a593e1d7e029345275735330e32), [`2a72214a`](https://github.com/wevm/wagmi/commit/2a72214a2901d6b6ddd39f80238aa0bd4db670a7)]: + - @wagmi/core@2.6.3 + - @wagmi/connectors@4.1.12 + +## 2.5.4 + +### Patch Changes + +- [`3f8203bd`](https://github.com/wevm/wagmi/commit/3f8203bd77fcf6b6756640b5971d09741ae3853d) Thanks [@tmm](https://github.com/tmm)! - Fixed `useBlock` parameters passthrough to Viem. + +## 2.5.3 + +### Patch Changes + +- [#3518](https://github.com/wevm/wagmi/pull/3518) [`338e857d`](https://github.com/wevm/wagmi/commit/338e857d8cb2fe85e13d9207bef14cada1c1962d) Thanks [@tmm](https://github.com/tmm)! - Bumped dependencies. + +- Updated dependencies [[`414eb048`](https://github.com/wevm/wagmi/commit/414eb048af492caac70c0e874dfc87c30702804a), [`338e857d`](https://github.com/wevm/wagmi/commit/338e857d8cb2fe85e13d9207bef14cada1c1962d), [`338e857d`](https://github.com/wevm/wagmi/commit/338e857d8cb2fe85e13d9207bef14cada1c1962d)]: + - @wagmi/core@2.6.2 + - @wagmi/connectors@4.1.11 + +## 2.5.2 + +### Patch Changes + +- [#3433](https://github.com/wevm/wagmi/pull/3433) [`101a7dd1`](https://github.com/wevm/wagmi/commit/101a7dd131b0cae2dc25579ecab9044290efd37b) Thanks [@tmm](https://github.com/tmm)! - Fixed `useClient` and `usePublicClient` throwing when used with unconfigured `chainId`. + +- [#3510](https://github.com/wevm/wagmi/pull/3510) [`660ff80d`](https://github.com/wevm/wagmi/commit/660ff80d5b046967a446eba43ee54b8359a37d0d) Thanks [@tmm](https://github.com/tmm)! - Fixed issue where connectors returning multiple addresses didn't checksum correctly. + +- Updated dependencies [[`660ff80d`](https://github.com/wevm/wagmi/commit/660ff80d5b046967a446eba43ee54b8359a37d0d), [`101a7dd1`](https://github.com/wevm/wagmi/commit/101a7dd131b0cae2dc25579ecab9044290efd37b)]: + - @wagmi/connectors@4.1.10 + - @wagmi/core@2.6.1 + +## 2.5.1 + +### Patch Changes + +- [#3496](https://github.com/wevm/wagmi/pull/3496) [`ba7f8a75`](https://github.com/wevm/wagmi/commit/ba7f8a758efb07664c6e401b5e7e325e7c62341b) Thanks [@tmm](https://github.com/tmm)! - Bumped dependencies. + +- Updated dependencies [[`ba7f8a75`](https://github.com/wevm/wagmi/commit/ba7f8a758efb07664c6e401b5e7e325e7c62341b), [`ba7f8a75`](https://github.com/wevm/wagmi/commit/ba7f8a758efb07664c6e401b5e7e325e7c62341b)]: + - @wagmi/connectors@4.1.9 + - @wagmi/core@2.6.0 + +## 2.5.0 + +### Minor Changes + +- [#3461](https://github.com/wevm/wagmi/pull/3461) [`ca98041d`](https://github.com/wevm/wagmi/commit/ca98041d1b39893d90246929485f4db0d1c6f9f7) Thanks [@marthendalnunes](https://github.com/marthendalnunes)! - Added `useTransactionConfirmations` hook. + +### Patch Changes + +- Updated dependencies [[`ca98041d`](https://github.com/wevm/wagmi/commit/ca98041d1b39893d90246929485f4db0d1c6f9f7)]: + - @wagmi/core@2.5.0 + - @wagmi/connectors@4.1.8 + +## 2.4.0 + +### Minor Changes + +- [#3427](https://github.com/wevm/wagmi/pull/3427) [`370f1b4a`](https://github.com/wevm/wagmi/commit/370f1b4a3f154d181acf381c31c2e7862e22c0e4) Thanks [@marthendalnunes](https://github.com/marthendalnunes)! - Added `usePrepareTransactionRequest` hook. + +### Patch Changes + +- Updated dependencies [[`370f1b4a`](https://github.com/wevm/wagmi/commit/370f1b4a3f154d181acf381c31c2e7862e22c0e4), [`370f1b4a`](https://github.com/wevm/wagmi/commit/370f1b4a3f154d181acf381c31c2e7862e22c0e4)]: + - @wagmi/connectors@4.1.7 + - @wagmi/core@2.4.0 + +## 2.3.1 + +### Patch Changes + +- [#3476](https://github.com/wevm/wagmi/pull/3476) [`3be5bb7b`](https://github.com/wevm/wagmi/commit/3be5bb7b0b38646e12e6da5c762ef74dff66bcc2) Thanks [@jxom](https://github.com/jxom)! - Modified persist strategy to only store "critical" properties that are needed before hydration. + +- Updated dependencies [[`3be5bb7b`](https://github.com/wevm/wagmi/commit/3be5bb7b0b38646e12e6da5c762ef74dff66bcc2)]: + - @wagmi/core@2.3.1 + - @wagmi/connectors@4.1.6 + +## 2.3.0 + +### Minor Changes + +- [#3459](https://github.com/wevm/wagmi/pull/3459) [`d950b666`](https://github.com/wevm/wagmi/commit/d950b666b56700ca039ce16cdfdf34564991e7f5) Thanks [@marthendalnunes](https://github.com/marthendalnunes)! - Added `useEnsText` action. + +### Patch Changes + +- [#3467](https://github.com/wevm/wagmi/pull/3467) [`90ef39bb`](https://github.com/wevm/wagmi/commit/90ef39bb0f4ecb3c914d317875348e35ba0f4524) Thanks [@jxom](https://github.com/jxom)! - Fixed an issue where connectors that share the same provider instance could reconnect when they have never been connected before. + +- [`1cfb6e5a`](https://github.com/wevm/wagmi/commit/1cfb6e5a875e707abcee00dd5739e87da05e8c90) Thanks [@jxom](https://github.com/jxom)! - Bumped listener limit on WalletConnect connector. + +- Updated dependencies [[`d950b666`](https://github.com/wevm/wagmi/commit/d950b666b56700ca039ce16cdfdf34564991e7f5), [`d950b666`](https://github.com/wevm/wagmi/commit/d950b666b56700ca039ce16cdfdf34564991e7f5), [`90ef39bb`](https://github.com/wevm/wagmi/commit/90ef39bb0f4ecb3c914d317875348e35ba0f4524), [`1cfb6e5a`](https://github.com/wevm/wagmi/commit/1cfb6e5a875e707abcee00dd5739e87da05e8c90)]: + - @wagmi/core@2.3.0 + - @wagmi/connectors@5.0.0 + +## 2.2.1 + +### Patch Changes + +- [#3443](https://github.com/wevm/wagmi/pull/3443) [`007024a6`](https://github.com/wevm/wagmi/commit/007024a684ddbecf924cdc06dd6a8854fc3d5eeb) Thanks [@jmrossy](https://github.com/jmrossy)! - Bumped dependencies. + +- [#3447](https://github.com/wevm/wagmi/pull/3447) [`a02a26ad`](https://github.com/wevm/wagmi/commit/a02a26ad030d3afb78f744377d61b5c60b65d97a) Thanks [@tmm](https://github.com/tmm)! - Fixed account typing. + +- Updated dependencies [[`007024a6`](https://github.com/wevm/wagmi/commit/007024a684ddbecf924cdc06dd6a8854fc3d5eeb), [`a02a26ad`](https://github.com/wevm/wagmi/commit/a02a26ad030d3afb78f744377d61b5c60b65d97a), [`a02a26ad`](https://github.com/wevm/wagmi/commit/a02a26ad030d3afb78f744377d61b5c60b65d97a), [`007024a6`](https://github.com/wevm/wagmi/commit/007024a684ddbecf924cdc06dd6a8854fc3d5eeb)]: + - @wagmi/connectors@4.1.4 + - @wagmi/core@2.2.1 + +## 2.2.0 + +### Minor Changes + +- [#3434](https://github.com/wevm/wagmi/pull/3434) [`00bf10a4`](https://github.com/wevm/wagmi/commit/00bf10a428b0d1c5dac35ebf25b19571e033ac26) Thanks [@marthendalnunes](https://github.com/marthendalnunes)! - Added `useBytecode` and `useStorageAt` hooks. + +- [#3408](https://github.com/wevm/wagmi/pull/3408) [`fb6c4148`](https://github.com/wevm/wagmi/commit/fb6c4148d9e9e2fccfbe74c8f343b444dc68dec5) Thanks [@marthendalnunes](https://github.com/marthendalnunes)! - Added `useProof` hook. + +- [#3416](https://github.com/wevm/wagmi/pull/3416) [`64c073f6`](https://github.com/wevm/wagmi/commit/64c073f6c2720961e2d6aff986670b73dbfab9c3) Thanks [@marthendalnunes](https://github.com/marthendalnunes)! - Added `useTransactionReceipt` hook. + +### Patch Changes + +- Updated dependencies [[`00bf10a4`](https://github.com/wevm/wagmi/commit/00bf10a428b0d1c5dac35ebf25b19571e033ac26), [`64c073f6`](https://github.com/wevm/wagmi/commit/64c073f6c2720961e2d6aff986670b73dbfab9c3), [`fb6c4148`](https://github.com/wevm/wagmi/commit/fb6c4148d9e9e2fccfbe74c8f343b444dc68dec5)]: + - @wagmi/core@2.2.0 + - @wagmi/connectors@5.0.0 + +## 2.1.2 + +### Patch Changes + +- [#3407](https://github.com/wevm/wagmi/pull/3407) [`e00b8205`](https://github.com/wevm/wagmi/commit/e00b82058685751637edfa9a6b2d196a12549fe7) Thanks [@jxom](https://github.com/jxom)! - Added a prelude gas estimate check to `sendTransaction`/`useSendTransaction`. + +- Updated dependencies [[`e00b8205`](https://github.com/wevm/wagmi/commit/e00b82058685751637edfa9a6b2d196a12549fe7)]: + - @wagmi/core@2.1.2 + - @wagmi/connectors@4.1.2 + +## 2.1.1 + +### Patch Changes + +- [#3402](https://github.com/wevm/wagmi/pull/3402) [`64b82282`](https://github.com/wevm/wagmi/commit/64b82282c1e57e77c25aa0814673780e4d11edd4) Thanks [@Songkeys](https://github.com/Songkeys)! - Fixed SSR cookie support for cookies that have special characters, e.g. `=`. + +- [`ec0d8b41`](https://github.com/wevm/wagmi/commit/ec0d8b4112181fefb11025e436a94a6114761d37) Thanks [@tmm](https://github.com/tmm)! - Added note to `metaMask` connector. + +- Updated dependencies [[`64b82282`](https://github.com/wevm/wagmi/commit/64b82282c1e57e77c25aa0814673780e4d11edd4), [`ec0d8b41`](https://github.com/wevm/wagmi/commit/ec0d8b4112181fefb11025e436a94a6114761d37)]: + - @wagmi/core@2.1.1 + - @wagmi/connectors@4.1.1 + +## 2.1.0 + +### Minor Changes + +- [#3387](https://github.com/wevm/wagmi/pull/3387) [`c9cd302e`](https://github.com/wevm/wagmi/commit/c9cd302e1c65c980deaee2e12567c2a8ec08b399) Thanks [@marthendalnunes](https://github.com/marthendalnunes)! - Added `useCall` hook. + +### Patch Changes + +- Updated dependencies [[`c9cd302e`](https://github.com/wevm/wagmi/commit/c9cd302e1c65c980deaee2e12567c2a8ec08b399)]: + - @wagmi/core@2.1.0 + - @wagmi/connectors@5.0.0 + +## 2.0.3 + +### Patch Changes + +- [#3384](https://github.com/wevm/wagmi/pull/3384) [`ee868c33`](https://github.com/wevm/wagmi/commit/ee868c3385dae511230b6ddcb5627c1293cc1844) Thanks [@tmm](https://github.com/tmm)! - Fixed connectors not bubbling error when connecting with `chainId` and subsequent user rejection. + +- Updated dependencies [[`ee868c33`](https://github.com/wevm/wagmi/commit/ee868c3385dae511230b6ddcb5627c1293cc1844)]: + - @wagmi/connectors@4.0.2 + - @wagmi/core@2.0.2 + +## 2.0.2 + +### Patch Changes + +- [#3379](https://github.com/wevm/wagmi/pull/3379) [`30a186e5`](https://github.com/wevm/wagmi/commit/30a186e53d1135657d04f72f40d1c27186025370) Thanks [@tmm](https://github.com/tmm)! - Fixed `useConnect` error getting unset. + +## 2.0.1 + +### Major Changes + +- [#3333](https://github.com/wevm/wagmi/pull/3333) [`b3a0baaa`](https://github.com/wevm/wagmi/commit/b3a0baaaee7decf750d376aab2502cd33ca4825a) Thanks [@tmm](https://github.com/tmm)! - Wagmi 2.0 featuring: + + - Full TanStack Query support + queryKeys + - Connect multiple connectors + - Switch chains while disconnected + - EIP-6963 enabled + - Strongly typed chainId and chain properties + - Smaller bundle size + - Miscellaneous improvements and bug fixes + + [Breaking Changes & Migration Guide](https://wagmi.sh/react/guides/migrate-from-v1-to-v2) + +### Patch Changes + +- Updated dependencies [[`b3a0baaa`](https://github.com/wevm/wagmi/commit/b3a0baaaee7decf750d376aab2502cd33ca4825a), [`b3a0baaa`](https://github.com/wevm/wagmi/commit/b3a0baaaee7decf750d376aab2502cd33ca4825a)]: + - @wagmi/connectors@4.0.0 + - @wagmi/core@2.0.0 + +## 1.4.13 + +### Patch Changes + +- Updated dependencies []: + - @wagmi/core@1.4.13 + +## 1.4.12 + +### Patch Changes + +- [`53ca1f7e`](https://github.com/wevm/wagmi/commit/53ca1f7eb411d912e11fcce7e03bd61ed067959c) Thanks [@tmm](https://github.com/tmm)! - Removed LedgerConnector due to security vulnerability + +- Updated dependencies [[`53ca1f7e`](https://github.com/wevm/wagmi/commit/53ca1f7eb411d912e11fcce7e03bd61ed067959c)]: + - @wagmi/core@1.4.12 + +## 1.4.11 + +### Patch Changes + +- [#3299](https://github.com/wevm/wagmi/pull/3299) [`b02020b3`](https://github.com/wevm/wagmi/commit/b02020b3724e0228198f35817611bb063295906e) Thanks [@dasanra](https://github.com/dasanra)! - Fixed issue with [Safe SDK](https://github.com/wevm/viem/issues/579) by bumping `@safe-global/safe-apps-provider@0.18.1` + +- Updated dependencies [[`b02020b3`](https://github.com/wevm/wagmi/commit/b02020b3724e0228198f35817611bb063295906e)]: + - @wagmi/core@1.4.11 + +## 1.4.10 + +### Patch Changes + +- Updated dependencies []: + - @wagmi/core@1.4.10 + +## 1.4.9 + +### Patch Changes + +- [#3276](https://github.com/wevm/wagmi/pull/3276) [`83223a06`](https://github.com/wevm/wagmi/commit/83223a0659e2f675d897a1d3374c7af752c16abf) Thanks [@glitch-txs](https://github.com/glitch-txs)! - Removed required namespaces from WalletConnect connector + +- Updated dependencies [[`83223a06`](https://github.com/wevm/wagmi/commit/83223a0659e2f675d897a1d3374c7af752c16abf)]: + - @wagmi/core@1.4.9 + +## 1.4.8 + +### Patch Changes + +- Updated dependencies []: + - @wagmi/core@1.4.8 + +## 1.4.7 + +### Patch Changes + +- Updated dependencies []: + - @wagmi/core@1.4.7 + +## 1.4.6 + +### Patch Changes + +- Updated dependencies []: + - @wagmi/core@1.4.6 + +## 1.4.5 + +### Patch Changes + +- Updated dependencies []: + - @wagmi/core@1.4.5 + +## 1.4.4 + +### Patch Changes + +- [#3125](https://github.com/wagmi-dev/wagmi/pull/3125) [`725e73fe`](https://github.com/wagmi-dev/wagmi/commit/725e73feb9143dbaa6d540bb76d2009cef29da0b) Thanks [@lukasrosario](https://github.com/lukasrosario)! - Fixed an issue where `dataSuffix` was not being passed down into viem's `simulateContract`, causing the data to be omitted from requests. + +- Updated dependencies [[`725e73fe`](https://github.com/wagmi-dev/wagmi/commit/725e73feb9143dbaa6d540bb76d2009cef29da0b)]: + - @wagmi/core@1.4.4 + +## 1.4.3 + +### Patch Changes + +- [#3076](https://github.com/wagmi-dev/wagmi/pull/3076) [`4c36831b`](https://github.com/wagmi-dev/wagmi/commit/4c36831b7aa44d03b5c0decf64dcd20faae28a67) Thanks [@jxom](https://github.com/jxom)! - Pass `chain` to viem `sendTransaction`/`writeContract`. + +- [#3006](https://github.com/wagmi-dev/wagmi/pull/3006) [`f2ddce23`](https://github.com/wagmi-dev/wagmi/commit/f2ddce23324aff0a91e066100918dac552dc3b4a) Thanks [@jxom](https://github.com/jxom)! - Changed `normalize` to a dynamic import. + +- Updated dependencies [[`4c36831b`](https://github.com/wagmi-dev/wagmi/commit/4c36831b7aa44d03b5c0decf64dcd20faae28a67), [`f2ddce23`](https://github.com/wagmi-dev/wagmi/commit/f2ddce23324aff0a91e066100918dac552dc3b4a)]: + - @wagmi/core@1.4.3 + +## 1.4.2 + +### Patch Changes + +- Updated dependencies []: + - @wagmi/core@1.4.2 + +## 1.4.1 + +### Patch Changes + +- Updated dependencies []: + - @wagmi/core@1.4.1 + +## 1.4.0 + +### Minor Changes + +- [#2956](https://github.com/wagmi-dev/wagmi/pull/2956) [`2abeb285`](https://github.com/wagmi-dev/wagmi/commit/2abeb285674af3e539cc2550b1f5027b1eb0c895) Thanks [@tmm](https://github.com/tmm)! - Replaced `@wagmi/chains` with `viem/chains`. + +### Patch Changes + +- Updated dependencies [[`2abeb285`](https://github.com/wagmi-dev/wagmi/commit/2abeb285674af3e539cc2550b1f5027b1eb0c895)]: + - @wagmi/core@1.4.0 + +## 1.3.11 + +### Patch Changes + +- [`557e6400`](https://github.com/wagmi-dev/wagmi/commit/557e6400b9cef3b2c5131739143956c37d7c934a) Thanks [@jxom](https://github.com/jxom)! - Updated references. + +- Updated dependencies [[`557e6400`](https://github.com/wagmi-dev/wagmi/commit/557e6400b9cef3b2c5131739143956c37d7c934a)]: + - @wagmi/core@1.3.10 + +## 1.3.10 + +### Patch Changes + +- [`247c5d11`](https://github.com/wagmi-dev/wagmi/commit/247c5d113e83acf3a6894264c00d4b125d455107) Thanks [@jxom](https://github.com/jxom)! - Updated references. + +- Updated dependencies [[`247c5d11`](https://github.com/wagmi-dev/wagmi/commit/247c5d113e83acf3a6894264c00d4b125d455107)]: + - @wagmi/core@1.3.9 + +## 1.3.9 + +### Patch Changes + +- [#2741](https://github.com/wagmi-dev/wagmi/pull/2741) [`5b1453d9`](https://github.com/wagmi-dev/wagmi/commit/5b1453d95973ed51f1c235a919fffb707eab9b70) Thanks [@jxom](https://github.com/jxom)! - Updated references + +- Updated dependencies [[`5b1453d9`](https://github.com/wagmi-dev/wagmi/commit/5b1453d95973ed51f1c235a919fffb707eab9b70)]: + - @wagmi/core@1.3.8 + +## 1.3.8 + +### Patch Changes + +- [#2700](https://github.com/wagmi-dev/wagmi/pull/2700) [`30118e97`](https://github.com/wagmi-dev/wagmi/commit/30118e979b1b00302e035f31f58c15d1aed911d5) Thanks [@jxom](https://github.com/jxom)! - Updated references. + +- Updated dependencies [[`30118e97`](https://github.com/wagmi-dev/wagmi/commit/30118e979b1b00302e035f31f58c15d1aed911d5)]: + - @wagmi/core@1.3.7 + +## 1.3.7 + +### Patch Changes + +- [`7ad2fdb8`](https://github.com/wagmi-dev/wagmi/commit/7ad2fdb81c7734d0c8107670800c68390e3bad99) Thanks [@jxom](https://github.com/jxom)! - Updated references. + +- Updated dependencies [[`7ad2fdb8`](https://github.com/wagmi-dev/wagmi/commit/7ad2fdb81c7734d0c8107670800c68390e3bad99)]: + - @wagmi/core@1.3.6 + +## 1.3.6 + +### Patch Changes + +- [`aab63fc1`](https://github.com/wagmi-dev/wagmi/commit/aab63fc1f8949004573978ecd8574fada3360758) Thanks [@jxom](https://github.com/jxom)! - Updated references. + +- Updated dependencies [[`aab63fc1`](https://github.com/wagmi-dev/wagmi/commit/aab63fc1f8949004573978ecd8574fada3360758)]: + - @wagmi/core@1.3.5 + +## 1.3.5 + +### Patch Changes + +- [#2669](https://github.com/wagmi-dev/wagmi/pull/2669) [`db75c459`](https://github.com/wagmi-dev/wagmi/commit/db75c4593b9c46970dc9d3c96d7adafc76878fc3) Thanks [@llllvvuu](https://github.com/llllvvuu)! - Modified `useAccount` and `useNetwork` to be reactive of wagmi Config (`config`). + +## 1.3.4 + +### Patch Changes + +- [`b056f809`](https://github.com/wagmi-dev/wagmi/commit/b056f8095674d4addc6ecd09adf6001fe52e2b15) Thanks [@jxom](https://github.com/jxom)! - Fixed an issue where `onConnect` was not being called when multiple instances of `useAccount` existed. + +- [`22246d98`](https://github.com/wagmi-dev/wagmi/commit/22246d9884277d28ccad6ca2d9529b96b67d47fc) Thanks [@jxom](https://github.com/jxom)! - Updated references. + +- Updated dependencies [[`22246d98`](https://github.com/wagmi-dev/wagmi/commit/22246d9884277d28ccad6ca2d9529b96b67d47fc)]: + - @wagmi/core@1.3.4 + +## 1.3.3 + +### Patch Changes + +- [`1946aa43`](https://github.com/wagmi-dev/wagmi/commit/1946aa43a65b684ef41b7b4c43c67bf29c13e854) Thanks [@jxom](https://github.com/jxom)! - Updated references + +- Updated dependencies [[`1946aa43`](https://github.com/wagmi-dev/wagmi/commit/1946aa43a65b684ef41b7b4c43c67bf29c13e854)]: + - @wagmi/core@1.3.3 + +## 1.3.2 + +### Patch Changes + +- [`e86d0940`](https://github.com/wagmi-dev/wagmi/commit/e86d09409bb20b64d24e1263abcf0291314f03c7) Thanks [@jxom](https://github.com/jxom)! - Updated references + +- Updated dependencies [[`e86d0940`](https://github.com/wagmi-dev/wagmi/commit/e86d09409bb20b64d24e1263abcf0291314f03c7)]: + - @wagmi/core@1.3.2 + +## 1.3.1 + +### Patch Changes + +- [`964042fa`](https://github.com/wagmi-dev/wagmi/commit/964042fa94d682977923c595820c58283fb9244a) Thanks [@jxom](https://github.com/jxom)! - Updated references. + +- Updated dependencies [[`964042fa`](https://github.com/wagmi-dev/wagmi/commit/964042fa94d682977923c595820c58283fb9244a)]: + - @wagmi/core@1.3.1 + +## 1.3.0 + +### Minor Changes + +- [#2619](https://github.com/wagmi-dev/wagmi/pull/2619) [`0d79748c`](https://github.com/wagmi-dev/wagmi/commit/0d79748cec2b6ac2410ad2c9816cc662f2b70962) Thanks [@jxom](https://github.com/jxom)! - Updated references: + - Updated `@safe-global/safe-apps-sdk` to `^8.0.0` (the one with `viem` support) + +### Patch Changes + +- Updated dependencies [[`0d79748c`](https://github.com/wagmi-dev/wagmi/commit/0d79748cec2b6ac2410ad2c9816cc662f2b70962)]: + - @wagmi/core@1.3.0 + +## 1.2.2 + +### Patch Changes + +- [#2611](https://github.com/wagmi-dev/wagmi/pull/2611) [`6d1ed7a1`](https://github.com/wagmi-dev/wagmi/commit/6d1ed7a156729b4df5d66fef3ae9a8b5762a2d34) Thanks [@jxom](https://github.com/jxom)! - Updated references. + +- Updated dependencies [[`6d1ed7a1`](https://github.com/wagmi-dev/wagmi/commit/6d1ed7a156729b4df5d66fef3ae9a8b5762a2d34)]: + - @wagmi/core@1.2.2 + +## 1.2.1 + +### Patch Changes + +- [#2589](https://github.com/wagmi-dev/wagmi/pull/2589) [`9680c347`](https://github.com/wagmi-dev/wagmi/commit/9680c347476500d28ceca20d23eeaed7931cb6e0) Thanks [@jxom](https://github.com/jxom)! - Fixed `writeContract` parameters to be compatible with `prepareWriteContract`. + +- [#2587](https://github.com/wagmi-dev/wagmi/pull/2587) [`cfff9994`](https://github.com/wagmi-dev/wagmi/commit/cfff999459384ac644ff7e62f53a7b787cf37507) Thanks [@jxom](https://github.com/jxom)! - Updated references + +- Updated dependencies [[`9680c347`](https://github.com/wagmi-dev/wagmi/commit/9680c347476500d28ceca20d23eeaed7931cb6e0), [`cfff9994`](https://github.com/wagmi-dev/wagmi/commit/cfff999459384ac644ff7e62f53a7b787cf37507)]: + - @wagmi/core@1.2.1 + +## 1.2.0 + +### Minor Changes + +- [#2536](https://github.com/wagmi-dev/wagmi/pull/2536) [`85e9760a`](https://github.com/wagmi-dev/wagmi/commit/85e9760a140cb169ac6236d9466b96e2105dd193) Thanks [@tmm](https://github.com/tmm)! - Changed `Address` type import from ABIType to viem. + +### Patch Changes + +- [#2539](https://github.com/wagmi-dev/wagmi/pull/2539) [`96319c64`](https://github.com/wagmi-dev/wagmi/commit/96319c640b9d07b375821c08a5c213355d8c290b) Thanks [@jxom](https://github.com/jxom)! - Updated references + +- Updated dependencies [[`85e9760a`](https://github.com/wagmi-dev/wagmi/commit/85e9760a140cb169ac6236d9466b96e2105dd193), [`96319c64`](https://github.com/wagmi-dev/wagmi/commit/96319c640b9d07b375821c08a5c213355d8c290b)]: + - @wagmi/core@1.2.0 + +## 1.1.1 + +### Patch Changes + +- [`02b98a9f`](https://github.com/wagmi-dev/wagmi/commit/02b98a9f9b2c503a47af4a8967e0202b5db21787) Thanks [@jxom](https://github.com/jxom)! - Updated `viem` peer dependency. + +- [`02b98a9f`](https://github.com/wagmi-dev/wagmi/commit/02b98a9f9b2c503a47af4a8967e0202b5db21787) Thanks [@jxom](https://github.com/jxom)! - Updated references. + +- Updated dependencies [[`02b98a9f`](https://github.com/wagmi-dev/wagmi/commit/02b98a9f9b2c503a47af4a8967e0202b5db21787), [`02b98a9f`](https://github.com/wagmi-dev/wagmi/commit/02b98a9f9b2c503a47af4a8967e0202b5db21787)]: + - @wagmi/core@1.1.1 + +## 1.1.0 + +### Minor Changes + +- [#2482](https://github.com/wagmi-dev/wagmi/pull/2482) [`8764b54a`](https://github.com/wagmi-dev/wagmi/commit/8764b54aab68020063946112e8fe52aff650c99c) Thanks [@tmm](https://github.com/tmm)! - Bumped minimum TypeScript version to v5.0.4. + +### Patch Changes + +- [#2471](https://github.com/wagmi-dev/wagmi/pull/2471) [`74099cef`](https://github.com/wagmi-dev/wagmi/commit/74099cefd922317641529f7881a4c8a740d62cbe) Thanks [@iuriiiurevich](https://github.com/iuriiiurevich)! - Added `keepPreviousData` prop to `useContractRead`. + +- [#2484](https://github.com/wagmi-dev/wagmi/pull/2484) [`3adf1f4f`](https://github.com/wagmi-dev/wagmi/commit/3adf1f4feab863cb7b5d52c81ad46f7e4eb56f09) Thanks [@jxom](https://github.com/jxom)! - Updated `abitype` to 0.8.7 + +- [#2484](https://github.com/wagmi-dev/wagmi/pull/2484) [`3adf1f4f`](https://github.com/wagmi-dev/wagmi/commit/3adf1f4feab863cb7b5d52c81ad46f7e4eb56f09) Thanks [@jxom](https://github.com/jxom)! - Updated references. + +- [`01d4a6ed`](https://github.com/wagmi-dev/wagmi/commit/01d4a6ed53110712692599095d94f04dfb5b6e38) Thanks [@jxom](https://github.com/jxom)! - Fixed an issue where `useInvalidateOnBlock`'s `onBlock` was being called on every render. + +- Updated dependencies [[`8764b54a`](https://github.com/wagmi-dev/wagmi/commit/8764b54aab68020063946112e8fe52aff650c99c), [`3adf1f4f`](https://github.com/wagmi-dev/wagmi/commit/3adf1f4feab863cb7b5d52c81ad46f7e4eb56f09), [`3adf1f4f`](https://github.com/wagmi-dev/wagmi/commit/3adf1f4feab863cb7b5d52c81ad46f7e4eb56f09)]: + - @wagmi/core@1.1.0 + +## 1.0.9 + +### Patch Changes + +- [#2446](https://github.com/wagmi-dev/wagmi/pull/2446) [`899d8c06`](https://github.com/wagmi-dev/wagmi/commit/899d8c0698e6cc958ca8ad9ec586883edf20516e) Thanks [@iuriiiurevich](https://github.com/iuriiiurevich)! - Added `cancelRefetch: false` to `useInvalidateOnBlock`. + +## 1.0.8 + +### Patch Changes + +- [#2441](https://github.com/wagmi-dev/wagmi/pull/2441) [`326edee4`](https://github.com/wagmi-dev/wagmi/commit/326edee4bc85db84a7a4e3768e33785849ab8d8e) Thanks [@tmm](https://github.com/tmm)! - Fixed internal type issue + +- Updated dependencies [[`326edee4`](https://github.com/wagmi-dev/wagmi/commit/326edee4bc85db84a7a4e3768e33785849ab8d8e)]: + - @wagmi/core@1.0.8 + +## 1.0.7 + +### Patch Changes + +- [#2433](https://github.com/wagmi-dev/wagmi/pull/2433) [`54fcff5f`](https://github.com/wagmi-dev/wagmi/commit/54fcff5f02f6933bbbe045ee0c83c5a78b6bba49) Thanks [@jxom](https://github.com/jxom)! - Added ability to pass an `account` to `useContractWrite`/`usePrepareContractWrite`. + +- Updated dependencies [[`54fcff5f`](https://github.com/wagmi-dev/wagmi/commit/54fcff5f02f6933bbbe045ee0c83c5a78b6bba49)]: + - @wagmi/core@1.0.7 + +## 1.0.6 + +### Patch Changes + +- [`ca2e1e96`](https://github.com/wagmi-dev/wagmi/commit/ca2e1e96149b87a7dc42c9db07e1f1ad2bb02c4a) Thanks [@jxom](https://github.com/jxom)! - Updated references. + +- [#2401](https://github.com/wagmi-dev/wagmi/pull/2401) [`0f9dc875`](https://github.com/wagmi-dev/wagmi/commit/0f9dc875e90cfdd7a2028e04b7204caf9ea313b2) Thanks [@jxom](https://github.com/jxom)! - Exposed `account` on `readContract`/`useContractRead`. + +- Updated dependencies [[`ca2e1e96`](https://github.com/wagmi-dev/wagmi/commit/ca2e1e96149b87a7dc42c9db07e1f1ad2bb02c4a), [`0f9dc875`](https://github.com/wagmi-dev/wagmi/commit/0f9dc875e90cfdd7a2028e04b7204caf9ea313b2)]: + - @wagmi/core@1.0.6 + +## 1.0.5 + +### Patch Changes + +- [`90e2b3b3`](https://github.com/wagmi-dev/wagmi/commit/90e2b3b39efe0585fe28645ac2264109be17362a) Thanks [@jxom](https://github.com/jxom)! - Updated references. + +- Updated dependencies [[`90e2b3b3`](https://github.com/wagmi-dev/wagmi/commit/90e2b3b39efe0585fe28645ac2264109be17362a)]: + - @wagmi/core@1.0.5 + +## 1.0.4 + +### Patch Changes + +- [#2344](https://github.com/wagmi-dev/wagmi/pull/2344) [`8a725458`](https://github.com/wagmi-dev/wagmi/commit/8a72545853ae1024acd9efd18c06142e8c6c5750) Thanks [@jxom](https://github.com/jxom)! - Added gas estimation back into `prepareSendTransaction`. + +- Updated dependencies [[`8a725458`](https://github.com/wagmi-dev/wagmi/commit/8a72545853ae1024acd9efd18c06142e8c6c5750)]: + - @wagmi/core@1.0.4 + +## 1.0.3 + +### Patch Changes + +- [#2338](https://github.com/wagmi-dev/wagmi/pull/2338) [`92bfdc2c`](https://github.com/wagmi-dev/wagmi/commit/92bfdc2c744539558ba93c95f140b46ad331cee4) Thanks [@jxom](https://github.com/jxom)! - Fixed an issue where synchronous switch chain behavior (WalletConnect v2) would encounter chain id race conditions in `watchWalletClient`. + +- Updated dependencies [[`92bfdc2c`](https://github.com/wagmi-dev/wagmi/commit/92bfdc2c744539558ba93c95f140b46ad331cee4)]: + - @wagmi/core@1.0.3 + +## 1.0.2 + +### Patch Changes + +- Updated dependencies [[`09a4fd38`](https://github.com/wevm/wagmi/commit/09a4fd38f44eb176797925fd85314be17b610cd4)]: + - @wagmi/core@1.0.2 + +## 1.0.1 + +### Patch Changes + +- [`ea651cd7`](https://github.com/wevm/wagmi/commit/ea651cd7fc75b7866272605467db11fd6e1d81af) Thanks [@jxom](https://github.com/jxom)! - Downgraded abitype. + +- Updated dependencies [[`ea651cd7`](https://github.com/wevm/wagmi/commit/ea651cd7fc75b7866272605467db11fd6e1d81af)]: + - @wagmi/core@1.0.1 + +## 1.0.0 + +### Major Changes + +- [#2235](https://github.com/wevm/wagmi/pull/2235) [`5be0655c`](https://github.com/wevm/wagmi/commit/5be0655c8e48b25d38009022461fbf611af54349) Thanks [@jxom](https://github.com/jxom)! - Released v1. Read [Migration Guide](https://next.wagmi.sh/react/migration-guide#1xx-breaking-changes). + +### Patch Changes + +- Updated dependencies [[`5be0655c`](https://github.com/wevm/wagmi/commit/5be0655c8e48b25d38009022461fbf611af54349)]: + - @wagmi/core@1.0.0 + +## 1.0.0-next.9 + +### Patch Changes + +- Fixed `useContractEvent` effect dependencies. + +## 1.0.0-next.8 + +### Patch Changes + +- Added "use client" banner + +## 1.0.0-next.7 + +### Major Changes + +- [#2235](https://github.com/wevm/wagmi/pull/2235) [`708b2ce2`](https://github.com/wevm/wagmi/commit/708b2ce26efa8d3d910806a97cea5171dabc65de) Thanks [@jxom](https://github.com/jxom)! - Added `config.setPublicClient` & `config.setWebSocketPublicClient` + +- Updated references. + +### Patch Changes + +- Updated dependencies [[`708b2ce2`](https://github.com/wevm/wagmi/commit/708b2ce26efa8d3d910806a97cea5171dabc65de)]: + - @wagmi/core@1.0.0-next.7 + +## 1.0.0-next.6 + +### Major Changes + +- Added `config.setConnectors` + +### Patch Changes + +- Updated dependencies [[`708b2ce2`](https://github.com/wevm/wagmi/commit/708b2ce26efa8d3d910806a97cea5171dabc65de)]: + - @wagmi/core@1.0.0-next.6 + +## 1.0.0-next.5 + +### Major Changes + +- [#2235](https://github.com/wevm/wagmi/pull/2235) [`708b2ce2`](https://github.com/wevm/wagmi/commit/708b2ce26efa8d3d910806a97cea5171dabc65de) Thanks [@jxom](https://github.com/jxom)! - Added `config.setPublicClient` & `config.setWebSocketPublicClient` + +### Patch Changes + +- Updated dependencies [[`708b2ce2`](https://github.com/wevm/wagmi/commit/708b2ce26efa8d3d910806a97cea5171dabc65de)]: + - @wagmi/core@1.0.0-next.5 + +## 1.0.0-next.4 + +### Major Changes + +- Updated viem. + Removed `goerli` export from main entrypoint. + +### Patch Changes + +- Updated dependencies []: + - @wagmi/core@1.0.0-next.4 + +## 1.0.0-next.3 + +### Major Changes + +- Updated references. + +### Patch Changes + +- Updated dependencies []: + - @wagmi/core@1.0.0-next.3 + +## 1.0.0-next.2 + +### Major Changes + +- **Breaking:** Renamed `createClient` to `createConfig` +- **Breaking:** Renamed `useClient` to `useConfig` +- **Breaking:** Removed `request` as an argument to `usePrepareSendTransaction` & `useSendTransaction`. Arguments now belong on the root level of the Hook. + +### Patch Changes + +- Updated dependencies []: + - @wagmi/core@1.0.0-next.2 + +## 1.0.0-next.1 + +### Major Changes + +- updated viem + +### Patch Changes + +- Updated dependencies []: + - @wagmi/core@1.0.0-next.1 + +## 1.0.0-next.0 + +### Major Changes + +- [`a7dda00c`](https://github.com/wevm/wagmi/commit/a7dda00c5b546f8b2c42b527e4d9ac1b9e9ab1fb) Thanks [@jxom](https://github.com/jxom)! - Released v1. + +### Patch Changes + +- Updated dependencies [[`a7dda00c`](https://github.com/wevm/wagmi/commit/a7dda00c5b546f8b2c42b527e4d9ac1b9e9ab1fb)]: + - @wagmi/core@1.0.0-next.0 + +## 0.12.13 + +### Patch Changes + +- [#2270](https://github.com/wevm/wagmi/pull/2270) [`6d1fa9df`](https://github.com/wevm/wagmi/commit/6d1fa9df790287729c3b33d4f01fd23c2f8153f1) Thanks [@jxom](https://github.com/jxom)! - Updated references. + +- Updated dependencies [[`6d1fa9df`](https://github.com/wevm/wagmi/commit/6d1fa9df790287729c3b33d4f01fd23c2f8153f1)]: + - @wagmi/core@0.10.11 + +## 0.12.12 + +### Patch Changes + +- [#2208](https://github.com/wevm/wagmi/pull/2208) [`cfc696d8`](https://github.com/wevm/wagmi/commit/cfc696d83c6f768a2e1a29c5197efeed7f1d40a1) Thanks [@bangtoven](https://github.com/bangtoven)! - Bumped references to apply coinbase wallet sdk updates + +- Updated dependencies [[`cfc696d8`](https://github.com/wevm/wagmi/commit/cfc696d83c6f768a2e1a29c5197efeed7f1d40a1)]: + - @wagmi/core@0.10.10 + +## 0.12.11 + +### Patch Changes + +- [#2203](https://github.com/wevm/wagmi/pull/2203) [`a4ca4b05`](https://github.com/wevm/wagmi/commit/a4ca4b05c5bd20c20c5d0741bfb18f2c798b9529) Thanks [@tmm](https://github.com/tmm)! - Downgraded abitype. + +## 0.12.10 + +### Patch Changes + +- [#2143](https://github.com/wevm/wagmi/pull/2143) [`26dc5326`](https://github.com/wevm/wagmi/commit/26dc53260fde1d3278018c0b20a6d48a093d9427) Thanks [@tmm](https://github.com/tmm)! - Exported Sepolia Chain. + +- [#2146](https://github.com/wevm/wagmi/pull/2146) [`21b6842e`](https://github.com/wevm/wagmi/commit/21b6842e8c296a0bbe71ebe0780d898abc4cf4a8) Thanks [@tmm](https://github.com/tmm)! - Bumped references + +- Updated dependencies [[`26dc5326`](https://github.com/wevm/wagmi/commit/26dc53260fde1d3278018c0b20a6d48a093d9427), [`21b6842e`](https://github.com/wevm/wagmi/commit/21b6842e8c296a0bbe71ebe0780d898abc4cf4a8)]: + - @wagmi/core@0.10.9 + +## 0.12.9 + +### Patch Changes + +- [#2120](https://github.com/wevm/wagmi/pull/2120) [`664c2b16`](https://github.com/wevm/wagmi/commit/664c2b1690bdce1ad7a619ac8f673c168dec6529) Thanks [@jxom](https://github.com/jxom)! - Bumped React Query & ABIType dependencies + +## 0.12.8 + +### Patch Changes + +- [#2099](https://github.com/wevm/wagmi/pull/2099) [`f1fee5b3`](https://github.com/wevm/wagmi/commit/f1fee5b30a1bd13b5e66118bf9cdc44b0dc003a1) Thanks [@jxom](https://github.com/jxom)! - Added chains: + + - `nexi` + - `polygonZkEvm` + - `xdc` + - `xdcTestnet` + +- [#2085](https://github.com/wevm/wagmi/pull/2085) [`7d64e3f5`](https://github.com/wevm/wagmi/commit/7d64e3f538a6149777bfa84ea9435769b2a7db58) Thanks [@jxom](https://github.com/jxom)! - Fixed an issue where multicall would not throw if the target chain was not configured on the wagmi client. + +- Updated dependencies [[`f1fee5b3`](https://github.com/wevm/wagmi/commit/f1fee5b30a1bd13b5e66118bf9cdc44b0dc003a1), [`7d64e3f5`](https://github.com/wevm/wagmi/commit/7d64e3f538a6149777bfa84ea9435769b2a7db58)]: + - @wagmi/core@0.10.8 + +## 0.12.7 + +### Patch Changes + +- [#2082](https://github.com/wevm/wagmi/pull/2082) [`2ccc8a25`](https://github.com/wevm/wagmi/commit/2ccc8a255e93f0a2bb7b22101656b3905ec59abd) Thanks [@jxom](https://github.com/jxom)! - Updated references. + +- Updated dependencies [[`2ccc8a25`](https://github.com/wevm/wagmi/commit/2ccc8a255e93f0a2bb7b22101656b3905ec59abd)]: + - @wagmi/core@0.10.7 + +## 0.12.6 + +### Patch Changes + +- [#2056](https://github.com/wevm/wagmi/pull/2056) [`944f6513`](https://github.com/wevm/wagmi/commit/944f6513adf09a6f0b3bd34f591d3bbd1f1ffd2e) Thanks [@tmm](https://github.com/tmm)! - Bumped references. + +- Updated dependencies [[`944f6513`](https://github.com/wevm/wagmi/commit/944f6513adf09a6f0b3bd34f591d3bbd1f1ffd2e)]: + - @wagmi/core@0.10.6 + +## 0.12.5 + +### Patch Changes + +- [#2053](https://github.com/wevm/wagmi/pull/2053) [`665df1bf`](https://github.com/wevm/wagmi/commit/665df1bf2afccb533102069def395e19fb7194dd) Thanks [@tmm](https://github.com/tmm)! - Fixed issue where you add a new chain to MetaMask, but the switch after is rejected. + +- Updated dependencies [[`665df1bf`](https://github.com/wevm/wagmi/commit/665df1bf2afccb533102069def395e19fb7194dd)]: + - @wagmi/core@0.10.5 + +## 0.12.4 + +### Patch Changes + +- [#2046](https://github.com/wevm/wagmi/pull/2046) [`90d8e9b8`](https://github.com/wevm/wagmi/commit/90d8e9b87962b72c54311649537e91a953660f9b) Thanks [@tmm](https://github.com/tmm)! - Exported internal type. + +- Updated dependencies [[`90d8e9b8`](https://github.com/wevm/wagmi/commit/90d8e9b87962b72c54311649537e91a953660f9b)]: + - @wagmi/core@0.10.4 + +## 0.12.3 + +### Patch Changes + +- [#2039](https://github.com/wevm/wagmi/pull/2039) [`bac893ab`](https://github.com/wevm/wagmi/commit/bac893ab26012d4d8741c4f80e8b8813aee26f0c) Thanks [@tmm](https://github.com/tmm)! - Updated references. + +- [#2043](https://github.com/wevm/wagmi/pull/2043) [`49a58320`](https://github.com/wevm/wagmi/commit/49a58320ab5f1f13bc4de25abcc028c8335e98f0) Thanks [@tmm](https://github.com/tmm)! - Removed `InjectedConnector` `shimChainChangedDisconnect` shim (no longer necessary). + +- [#2042](https://github.com/wevm/wagmi/pull/2042) [`e7ac7afc`](https://github.com/wevm/wagmi/commit/e7ac7afccb005e8d208c78d55b1fec979b8522a6) Thanks [@tmm](https://github.com/tmm)! - Fixed exposed types that weren't passed down. + +- Updated dependencies [[`bac893ab`](https://github.com/wevm/wagmi/commit/bac893ab26012d4d8741c4f80e8b8813aee26f0c), [`49a58320`](https://github.com/wevm/wagmi/commit/49a58320ab5f1f13bc4de25abcc028c8335e98f0)]: + - @wagmi/core@0.10.3 + +## 0.12.2 + +### Patch Changes + +- [#2016](https://github.com/wevm/wagmi/pull/2016) [`06bf61de`](https://github.com/wevm/wagmi/commit/06bf61dee6d2920777bd9392491e6b7aedebe7ab) Thanks [@jxom](https://github.com/jxom)! - Added chains: + + - `boba` + - `chronos` + - `crossbell` + - `dfk` + - `dogechain` + - `flare` + - `flareTestnet` + - `klaytn` + - `scrollTestnet` + - `shardeumSphinx` + - `skaleCalypso` + - `skaleCalypsoTestnet` + - `skaleChaosTestnet` + - `skaleCryptoBlades` + - `skaleCryptoColosseum` + - `skaleEuropa` + - `skaleEuropaTestnet` + - `skaleExorde` + - `skaleHumanProtocol` + - `skaleNebula` + - `skaleNebulaTestnet` + - `skaleRazor` + - `skaleTitan` + - `skaleTitanTestnet` + - `songbird` + - `songbirdTestnet` + - `titan` + - `titanTestnet` + - `wanchain` + - `wanchainTestnet` + +- [#2016](https://github.com/wevm/wagmi/pull/2016) [`06bf61de`](https://github.com/wevm/wagmi/commit/06bf61dee6d2920777bd9392491e6b7aedebe7ab) Thanks [@jxom](https://github.com/jxom)! - Updated references/ submodule. + +- Updated dependencies [[`06bf61de`](https://github.com/wevm/wagmi/commit/06bf61dee6d2920777bd9392491e6b7aedebe7ab), [`06bf61de`](https://github.com/wevm/wagmi/commit/06bf61dee6d2920777bd9392491e6b7aedebe7ab)]: + - @wagmi/core@0.10.2 + +## 0.12.0 + +### Minor Changes + +- [#1902](https://github.com/wevm/wagmi/pull/1902) [`0994e896`](https://github.com/wevm/wagmi/commit/0994e8966349b8811db0a5886db3831dafc99245) Thanks [@jxom](https://github.com/jxom)! - **Breaking:** Removed the `version` config option for `WalletConnectConnector`. + + `WalletConnectConnector` now uses WalletConnect v2 by default. WalletConnect v1 is now `WalletConnectLegacyConnector`. + + ### WalletConnect v2 + + ```diff + import { WalletConnectConnector } from 'wagmi/connectors/walletConnect' + + const connector = new WalletConnectConnector({ + options: { + - version: '2', + projectId: 'abc', + }, + }) + ``` + + ### WalletConnect v1 + + ```diff + -import { WalletConnectConnector } from 'wagmi/connectors/walletConnect' + +import { WalletConnectConnector } from 'wagmi/connectors/walletConnectLegacy' + + -const connector = new WalletConnectConnector({ + +const connector = new WalletConnectLegacyConnector({ + options: { + qrcode: true, + }, + }) + ``` + +### Patch Changes + +- Updated dependencies [[`0994e896`](https://github.com/wevm/wagmi/commit/0994e8966349b8811db0a5886db3831dafc99245)]: + - @wagmi/core@0.10.0 + +## 0.11.7 + +### Patch Changes + +- [#1907](https://github.com/wevm/wagmi/pull/1907) [`cc4e74ee`](https://github.com/wevm/wagmi/commit/cc4e74ee19665eccb3767052dab6ab956ff4e676) Thanks [@jxom](https://github.com/jxom)! - Added the following chains to the `wagmi/chains` entrypoint: + + - `baseGoerli` + - `harmonyOne` + - `polygonZkEvmTestnet` + +- Updated dependencies [[`cc4e74ee`](https://github.com/wevm/wagmi/commit/cc4e74ee19665eccb3767052dab6ab956ff4e676)]: + - @wagmi/core@0.9.7 + +## 0.11.6 + +### Patch Changes + +- [#1882](https://github.com/wevm/wagmi/pull/1882) [`282cc1b0`](https://github.com/wevm/wagmi/commit/282cc1b02003684d582cea411b11792a59c26fd0) Thanks [@tmm](https://github.com/tmm)! - Updated references. + +- Updated dependencies [[`282cc1b0`](https://github.com/wevm/wagmi/commit/282cc1b02003684d582cea411b11792a59c26fd0)]: + - @wagmi/core@0.9.6 + +## 0.11.5 + +### Patch Changes + +- [#1812](https://github.com/wevm/wagmi/pull/1812) [`c7fd7fbd`](https://github.com/wevm/wagmi/commit/c7fd7fbde6f6c69a3a9a4f89d948c4dfb1d22679) Thanks [@jxom](https://github.com/jxom)! - Added the following chains to the `wagmi/chains` entrypoint: + + - `filecoinCalibration` + - `moonbaseAlpha` + - `moonbeam` + - `moonriver` + +- Updated dependencies [[`c7fd7fbd`](https://github.com/wevm/wagmi/commit/c7fd7fbde6f6c69a3a9a4f89d948c4dfb1d22679)]: + - @wagmi/core@0.9.5 + +## 0.11.4 + +### Patch Changes + +- [#1679](https://github.com/wevm/wagmi/pull/1679) [`3cef111b`](https://github.com/wevm/wagmi/commit/3cef111b1e30120233d8754b33587cdf94aedd8f) Thanks [@aj-may](https://github.com/aj-may)! - Fixed `useAccount` `onConnect` and `onDisconnect` callbacks for React Strict Mode. + +- [#1786](https://github.com/wevm/wagmi/pull/1786) [`b173a431`](https://github.com/wevm/wagmi/commit/b173a43165c7925a4e56ce1e0327a31917e7edc5) Thanks [@tmm](https://github.com/tmm)! - Locked ethers peer dependency version to >=5.5.1 <6 + +- [#1787](https://github.com/wevm/wagmi/pull/1787) [`f023fd8f`](https://github.com/wevm/wagmi/commit/f023fd8f66befb78b9a4df5ca971ceaa64e37ab4) Thanks [@tmm](https://github.com/tmm)! - Added `SafeConnector` + +- Updated dependencies [[`b173a431`](https://github.com/wevm/wagmi/commit/b173a43165c7925a4e56ce1e0327a31917e7edc5), [`f023fd8f`](https://github.com/wevm/wagmi/commit/f023fd8f66befb78b9a4df5ca971ceaa64e37ab4)]: + - @wagmi/core@0.9.4 + +## 0.11.3 + +### Patch Changes + +- [#1773](https://github.com/wevm/wagmi/pull/1773) [`9aaf1955`](https://github.com/wevm/wagmi/commit/9aaf195514d3b5f4d085c797fc5021d42a9efb6c) Thanks [@jxom](https://github.com/jxom)! - Updated `@walletconnect/universal-provider` on `WalletConnectConnector` v2. + Added more signable methods to `WalletConnectConnector` v2. + +- [#1773](https://github.com/wevm/wagmi/pull/1773) [`9aaf1955`](https://github.com/wevm/wagmi/commit/9aaf195514d3b5f4d085c797fc5021d42a9efb6c) Thanks [@jxom](https://github.com/jxom)! - Added Telos to the `wagmi/chains` entrypoint. Thanks @donnyquixotic! + +- Updated dependencies [[`9aaf1955`](https://github.com/wevm/wagmi/commit/9aaf195514d3b5f4d085c797fc5021d42a9efb6c), [`9aaf1955`](https://github.com/wevm/wagmi/commit/9aaf195514d3b5f4d085c797fc5021d42a9efb6c)]: + - @wagmi/core@0.9.3 + +## 0.11.2 + +### Patch Changes + +- [#1756](https://github.com/wevm/wagmi/pull/1756) [`31d06b8c`](https://github.com/wevm/wagmi/commit/31d06b8ce1e7af5e9d1a7ba57f1743b2dff7a53d) Thanks [@jxom](https://github.com/jxom)! - Added OKC Chain. Thanks @clark-cui! + +- [#1756](https://github.com/wevm/wagmi/pull/1756) [`31d06b8c`](https://github.com/wevm/wagmi/commit/31d06b8ce1e7af5e9d1a7ba57f1743b2dff7a53d) Thanks [@jxom](https://github.com/jxom)! - Fixed race condition between `switchNetwork` and mutation Actions that use `chainId` (e.g. `sendTransaction`). Thanks @DanInTheD4rk! + +- Updated dependencies [[`31d06b8c`](https://github.com/wevm/wagmi/commit/31d06b8ce1e7af5e9d1a7ba57f1743b2dff7a53d), [`31d06b8c`](https://github.com/wevm/wagmi/commit/31d06b8ce1e7af5e9d1a7ba57f1743b2dff7a53d)]: + - @wagmi/core@0.9.2 + +## 0.11.1 + +### Patch Changes + +- [#1752](https://github.com/wevm/wagmi/pull/1752) [`144a0e76`](https://github.com/wevm/wagmi/commit/144a0e76ef4bb9ba0650b5ffb9c63f95329819a4) Thanks [@jxom](https://github.com/jxom)! - Improved `WalletConnectConnector` (v2) initialization & updated dependencies. + +- [#1752](https://github.com/wevm/wagmi/pull/1752) [`144a0e76`](https://github.com/wevm/wagmi/commit/144a0e76ef4bb9ba0650b5ffb9c63f95329819a4) Thanks [@jxom](https://github.com/jxom)! - Added the following chains to the `wagmi/chains` entrypoint: + + - Aurora – thanks @salil-naik + - Bronos – thanks @chedetinaveen + - Canto – thanks @tster + - Celo – thanks @aaronmgdr + +- Updated dependencies [[`144a0e76`](https://github.com/wevm/wagmi/commit/144a0e76ef4bb9ba0650b5ffb9c63f95329819a4), [`144a0e76`](https://github.com/wevm/wagmi/commit/144a0e76ef4bb9ba0650b5ffb9c63f95329819a4)]: + - @wagmi/core@0.9.1 + +## 0.11.0 + +### Minor Changes + +- [#1732](https://github.com/wevm/wagmi/pull/1732) [`01e21897`](https://github.com/wevm/wagmi/commit/01e2189747a5c22dc758c6d719b4145adc2a643c) Thanks [@tmm](https://github.com/tmm)! - Bumped minimum TypeScript version to typescript@>=4.9.4. TypeScript 5.0 is coming soon and has some great features we are excited to bring into wagmi. To prepare for this, update your TypeScript version to 4.9.4 or higher. There are likely no [breaking changes](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-9.html#correctness-fixes-and-breaking-changes) if you are coming from typescript@4.7.x || typescript@4.8.x. + +### Patch Changes + +- Updated dependencies [[`01e21897`](https://github.com/wevm/wagmi/commit/01e2189747a5c22dc758c6d719b4145adc2a643c)]: + - @wagmi/core@0.9.0 + +## 0.10.15 + +### Patch Changes + +- [#1718](https://github.com/wevm/wagmi/pull/1718) [`e62b5ef8`](https://github.com/wevm/wagmi/commit/e62b5ef8aaa8063abb5264790768899ea35bbd31) Thanks [@tmm](https://github.com/tmm)! - Updated references + +- Updated dependencies [[`e62b5ef8`](https://github.com/wevm/wagmi/commit/e62b5ef8aaa8063abb5264790768899ea35bbd31)]: + - @wagmi/core@0.8.19 + +## 0.10.14 + +### Patch Changes + +- [#1708](https://github.com/wevm/wagmi/pull/1708) [`07fc3801`](https://github.com/wevm/wagmi/commit/07fc3801fa13c2cb5f7cf9b86ba8320b05a6a135) Thanks [@jxom](https://github.com/jxom)! - Updated `references/` submodule. + +- Updated dependencies [[`07fc3801`](https://github.com/wevm/wagmi/commit/07fc3801fa13c2cb5f7cf9b86ba8320b05a6a135)]: + - @wagmi/core@0.8.18 + +## 0.10.13 + +### Patch Changes + +- [#1705](https://github.com/wevm/wagmi/pull/1705) [`9ff797dc`](https://github.com/wevm/wagmi/commit/9ff797dcb979dc86b798a432b74c98598165430d) Thanks [@jxom](https://github.com/jxom)! - Added the following chains to the `wagmi/chains` entrypoint: + + - `crossbell` (thanks @Songkeys) + - `filecoin` & `filecoinHyperspace` (thanks @neil0x46dc) + - `gnosisChiado` (thanks @theNvN) + - `metis` & `metisGoerli` (thanks @CookedCookee) + +- Updated dependencies [[`9ff797dc`](https://github.com/wevm/wagmi/commit/9ff797dcb979dc86b798a432b74c98598165430d)]: + - @wagmi/core@0.8.17 + +## 0.10.12 + +### Patch Changes + +- [#1699](https://github.com/wevm/wagmi/pull/1699) [`2f1e7950`](https://github.com/wevm/wagmi/commit/2f1e7950e55550d9b50ef5ccb97cb609f4af39b1) Thanks [@tmm](https://github.com/tmm)! - Added public RPC URL property to Chain + +- Updated dependencies [[`2f1e7950`](https://github.com/wevm/wagmi/commit/2f1e7950e55550d9b50ef5ccb97cb609f4af39b1)]: + - @wagmi/core@0.8.16 + +## 0.10.11 + +### Patch Changes + +- [#1685](https://github.com/wevm/wagmi/pull/1685) [`917f5bc1`](https://github.com/wevm/wagmi/commit/917f5bc1fad578e35a8c6ee787e339bfdc156bab) Thanks [@jxom](https://github.com/jxom)! - Replaced qrcodemodal with web3modal for the WalletConnect v2 Connector. + +- Updated dependencies [[`917f5bc1`](https://github.com/wevm/wagmi/commit/917f5bc1fad578e35a8c6ee787e339bfdc156bab)]: + - @wagmi/core@0.8.15 + +## 0.10.10 + +### Patch Changes + +- [#1648](https://github.com/wevm/wagmi/pull/1648) [`a2db9170`](https://github.com/wevm/wagmi/commit/a2db91709720161cd70eeb5e84dd78433264f0a3) Thanks [@tmm](https://github.com/tmm)! - Exported internal type. + +## 0.10.9 + +### Patch Changes + +- [#1646](https://github.com/wevm/wagmi/pull/1646) [`fcdbe353`](https://github.com/wevm/wagmi/commit/fcdbe3531e6d05cda4a4a511bae1ad4c9e426d88) Thanks [@jxom](https://github.com/jxom)! - Upgraded `zustand` to v4.3.1. + +- Updated dependencies [[`fcdbe353`](https://github.com/wevm/wagmi/commit/fcdbe3531e6d05cda4a4a511bae1ad4c9e426d88)]: + - @wagmi/core@0.8.14 + +## 0.10.8 + +### Patch Changes + +- [#1639](https://github.com/wevm/wagmi/pull/1639) [`c6869f06`](https://github.com/wevm/wagmi/commit/c6869f0604fffb197752a08256f31db77f52e746) Thanks [@jxom](https://github.com/jxom)! - Added `isRainbow` flag to `InjectedConnector`. + +- Updated dependencies [[`c6869f06`](https://github.com/wevm/wagmi/commit/c6869f0604fffb197752a08256f31db77f52e746)]: + - @wagmi/core@0.8.13 + +## 0.10.7 + +### Patch Changes + +- [#1636](https://github.com/wevm/wagmi/pull/1636) [`025f6771`](https://github.com/wevm/wagmi/commit/025f6771b32ff7eed22f527be81c5141ddaf9c3d) Thanks [@DanielSinclair](https://github.com/DanielSinclair)! - Added `isRainbow` flag to injected `window.ethereum` types. + +- Updated dependencies [[`025f6771`](https://github.com/wevm/wagmi/commit/025f6771b32ff7eed22f527be81c5141ddaf9c3d)]: + - @wagmi/core@0.8.12 + +## 0.10.6 + +### Patch Changes + +- [#1623](https://github.com/wevm/wagmi/pull/1623) [`c97a4bc5`](https://github.com/wevm/wagmi/commit/c97a4bc5df422dc9a9d3d8bac0261ec6933ce15b) Thanks [@jxom](https://github.com/jxom)! - Fixed an issue where `useSigner` would not update on account change. + +## 0.10.5 + +### Patch Changes + +- [#1621](https://github.com/wevm/wagmi/pull/1621) [`5812b590`](https://github.com/wevm/wagmi/commit/5812b5909277bf2862cb57a31d52465b47291410) Thanks [@tmm](https://github.com/tmm)! - Bumped @wagmi/connectors + +- Updated dependencies [[`5812b590`](https://github.com/wevm/wagmi/commit/5812b5909277bf2862cb57a31d52465b47291410)]: + - @wagmi/core@0.8.11 + +## 0.10.4 + +### Patch Changes + +- [#1607](https://github.com/wevm/wagmi/pull/1607) [`49a41357`](https://github.com/wevm/wagmi/commit/49a41357f9ca39479bdf759f5998bc169a91ac87) Thanks [@tmm](https://github.com/tmm)! - Exported hook types. + +## 0.10.3 + +### Patch Changes + +- [#1598](https://github.com/wevm/wagmi/pull/1598) [`fc10ebe6`](https://github.com/wevm/wagmi/commit/fc10ebe659dd5f3b7a8e00581f094652280a779b) Thanks [@jxom](https://github.com/jxom)! - Fixed CJS dependency version range + +- Updated dependencies [[`fc10ebe6`](https://github.com/wevm/wagmi/commit/fc10ebe659dd5f3b7a8e00581f094652280a779b)]: + - @wagmi/core@0.8.10 + +## 0.10.2 + +### Patch Changes + +- [#1593](https://github.com/wevm/wagmi/pull/1593) [`216d555c`](https://github.com/wevm/wagmi/commit/216d555c62bd95c3c7c8f8e20f7269f6c8504610) Thanks [@jxom](https://github.com/jxom)! - Added CJS escape hatch bundle under the "cjs" tag. + +- Updated dependencies [[`216d555c`](https://github.com/wevm/wagmi/commit/216d555c62bd95c3c7c8f8e20f7269f6c8504610)]: + - @wagmi/core@0.8.9 + +## 0.10.1 + +### Patch Changes + +- [#1573](https://github.com/wevm/wagmi/pull/1573) [`ef380d9c`](https://github.com/wevm/wagmi/commit/ef380d9c6d51ae0495b9c35925d2843c75d97fd4) Thanks [@tmm](https://github.com/tmm)! - Updated internal types. + +- Updated dependencies [[`ef380d9c`](https://github.com/wevm/wagmi/commit/ef380d9c6d51ae0495b9c35925d2843c75d97fd4)]: + - @wagmi/core@0.8.8 + +## 0.10.0 + +### Minor Changes + +- [#1470](https://github.com/wevm/wagmi/pull/1470) [`3a1a6c9f`](https://github.com/wevm/wagmi/commit/3a1a6c9fe5db5c360adfd116f9a03a1238b5720c) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: The `useSigner` hook now always returns `undefined` when no signer is present. Previously, it returned `null`. + + When no signer is present, the hook will be in an `"idle"` status. + +### Patch Changes + +- [#1470](https://github.com/wevm/wagmi/pull/1470) [`3a1a6c9f`](https://github.com/wevm/wagmi/commit/3a1a6c9fe5db5c360adfd116f9a03a1238b5720c) Thanks [@jxom](https://github.com/jxom)! - Fixed an issue where `useSigner` would broadcast to other `useSigner`s unnecessarily. + +- [#1470](https://github.com/wevm/wagmi/pull/1470) [`3a1a6c9f`](https://github.com/wevm/wagmi/commit/3a1a6c9fe5db5c360adfd116f9a03a1238b5720c) Thanks [@jxom](https://github.com/jxom)! - The `WalletConnectConnector` now supports WalletConnect v2. + + It can be enabled by setting `version` to `'2'` and supplying a [WalletConnect Cloud `projectId`](https://cloud.walletconnect.com/sign-in). + +- [#1570](https://github.com/wevm/wagmi/pull/1570) [`216f585b`](https://github.com/wevm/wagmi/commit/216f585be8a9e3a56e3243f49ccd54d655b5a6dd) Thanks [@jxom](https://github.com/jxom)! - Added `useWatchPendingTransactions` + +- Updated dependencies [[`216f585b`](https://github.com/wevm/wagmi/commit/216f585be8a9e3a56e3243f49ccd54d655b5a6dd), [`3a1a6c9f`](https://github.com/wevm/wagmi/commit/3a1a6c9fe5db5c360adfd116f9a03a1238b5720c)]: + - @wagmi/core@0.8.7 + +## 0.9.6 + +### Patch Changes + +- [#1539](https://github.com/wevm/wagmi/pull/1539) [`732da004`](https://github.com/wevm/wagmi/commit/732da0042c7e28091b2e36a484ea8239971306f5) Thanks [@0xFlicker](https://github.com/0xFlicker)! - All Providers (ie. Alchemy, Infura, Public) now use the ENS Registry address on the wagmi `Chain` object (`chain.contracts.ensRegistry`). + +- [#1574](https://github.com/wevm/wagmi/pull/1574) [`ecde3d10`](https://github.com/wevm/wagmi/commit/ecde3d1029ccdf90e2853ba0e9ae4f5f4ebb9c4c) Thanks [@jxom](https://github.com/jxom)! - Added the following chains: + + - `iotex` + - `iotexTestnet` + - `zkSync` + - `zkSyncTestnet` + +- Updated dependencies [[`732da004`](https://github.com/wevm/wagmi/commit/732da0042c7e28091b2e36a484ea8239971306f5), [`ecde3d10`](https://github.com/wevm/wagmi/commit/ecde3d1029ccdf90e2853ba0e9ae4f5f4ebb9c4c)]: + - @wagmi/core@0.8.6 + +## 0.9.5 + +### Patch Changes + +- [#1542](https://github.com/wevm/wagmi/pull/1542) [`731b3b73`](https://github.com/wevm/wagmi/commit/731b3b733c6a093d1693d49de601705b7c730549) Thanks [@jxom](https://github.com/jxom)! - Added the following chains: + + - `evmos` + - `evmosTestnet` + - `gnosis` + +- [#1542](https://github.com/wevm/wagmi/pull/1542) [`731b3b73`](https://github.com/wevm/wagmi/commit/731b3b733c6a093d1693d49de601705b7c730549) Thanks [@jxom](https://github.com/jxom)! - Updated Goerli symbol to `"ETH"`. + +- [#1542](https://github.com/wevm/wagmi/pull/1542) [`731b3b73`](https://github.com/wevm/wagmi/commit/731b3b733c6a093d1693d49de601705b7c730549) Thanks [@jxom](https://github.com/jxom)! - Updated Arbitrum Goerli RPC and Block Explorer. + +- [#1542](https://github.com/wevm/wagmi/pull/1542) [`731b3b73`](https://github.com/wevm/wagmi/commit/731b3b733c6a093d1693d49de601705b7c730549) Thanks [@jxom](https://github.com/jxom)! - Fixed issue where connecting to MetaMask may return with a stale address. + +- [#1542](https://github.com/wevm/wagmi/pull/1542) [`731b3b73`](https://github.com/wevm/wagmi/commit/731b3b733c6a093d1693d49de601705b7c730549) Thanks [@jxom](https://github.com/jxom)! - Removed ENS registry for Sepolia. + +- Updated dependencies [[`731b3b73`](https://github.com/wevm/wagmi/commit/731b3b733c6a093d1693d49de601705b7c730549), [`731b3b73`](https://github.com/wevm/wagmi/commit/731b3b733c6a093d1693d49de601705b7c730549), [`731b3b73`](https://github.com/wevm/wagmi/commit/731b3b733c6a093d1693d49de601705b7c730549), [`731b3b73`](https://github.com/wevm/wagmi/commit/731b3b733c6a093d1693d49de601705b7c730549), [`731b3b73`](https://github.com/wevm/wagmi/commit/731b3b733c6a093d1693d49de601705b7c730549)]: + - @wagmi/core@0.8.5 + +## 0.9.4 + +### Patch Changes + +- [#1508](https://github.com/wevm/wagmi/pull/1508) [`0b50b62f`](https://github.com/wevm/wagmi/commit/0b50b62f7389619e429509a3e337e451e823b059) Thanks [@jxom](https://github.com/jxom)! - Updated `@wagmi/chains` to `0.1.3`. + +- [#1507](https://github.com/wevm/wagmi/pull/1507) [`7a083bcf`](https://github.com/wevm/wagmi/commit/7a083bcf31d671817a4da2f40fb2160a1ba9d7b7) Thanks [@jxom](https://github.com/jxom)! - Fixed an issue where `useBlockNumber` would return data when `watch` is enabled and `enabled` is falsy. + +- [#1504](https://github.com/wevm/wagmi/pull/1504) [`11b8b794`](https://github.com/wevm/wagmi/commit/11b8b794fbfd4a2b40f39962e2758e9fbf48cb54) Thanks [@tmm](https://github.com/tmm)! - Converted ethers custom "ACTION_REJECTED" error to standard RPC Error. + +- Updated dependencies [[`0b50b62f`](https://github.com/wevm/wagmi/commit/0b50b62f7389619e429509a3e337e451e823b059), [`11b8b794`](https://github.com/wevm/wagmi/commit/11b8b794fbfd4a2b40f39962e2758e9fbf48cb54)]: + - @wagmi/core@0.8.4 + +## 0.9.3 + +### Patch Changes + +- [#1431](https://github.com/wevm/wagmi/pull/1431) [`af28f8f9`](https://github.com/wevm/wagmi/commit/af28f8f9cfc227e7c391927fdb934183edb5c2dc) Thanks [@jxom](https://github.com/jxom)! - Re-export connectors from `@wagmi/connectors` + +- [#1431](https://github.com/wevm/wagmi/pull/1431) [`af28f8f9`](https://github.com/wevm/wagmi/commit/af28f8f9cfc227e7c391927fdb934183edb5c2dc) Thanks [@jxom](https://github.com/jxom)! - Added `LedgerConnector` connector + +- Updated dependencies [[`af28f8f9`](https://github.com/wevm/wagmi/commit/af28f8f9cfc227e7c391927fdb934183edb5c2dc), [`af28f8f9`](https://github.com/wevm/wagmi/commit/af28f8f9cfc227e7c391927fdb934183edb5c2dc)]: + - @wagmi/core@0.8.3 + +## 0.9.2 + +### Patch Changes + +- [#1442](https://github.com/wevm/wagmi/pull/1442) [`cde15289`](https://github.com/wevm/wagmi/commit/cde152899c758dea10787412b0aef669ed7202b2) Thanks [@0xproflupin](https://github.com/0xproflupin)! - Added Phantom wallet support to `InjectedConnector` + +- [#1448](https://github.com/wevm/wagmi/pull/1448) [`c6075f3a`](https://github.com/wevm/wagmi/commit/c6075f3a16885d850ad2656272351f9517c9f67b) Thanks [@tmm](https://github.com/tmm)! - Updated [ABIType](https://github.com/wevm/abitype) version. + +- [#1444](https://github.com/wevm/wagmi/pull/1444) [`310a8bc4`](https://github.com/wevm/wagmi/commit/310a8bc428ce4e7f68377f581b45dcdd64381cce) Thanks [@jxom](https://github.com/jxom)! - Assert that a `connector` exists before invoking the callback in `watchSigner`. + +- [#1434](https://github.com/wevm/wagmi/pull/1434) [`100e2a3b`](https://github.com/wevm/wagmi/commit/100e2a3b22f4602716554487b1d98738e053be76) Thanks [@tmm](https://github.com/tmm)! - Updated `MockConnector` `chainId` behavior to default to first chain from `chains` if not provided in `options`. + +- Updated dependencies [[`cde15289`](https://github.com/wevm/wagmi/commit/cde152899c758dea10787412b0aef669ed7202b2), [`c6075f3a`](https://github.com/wevm/wagmi/commit/c6075f3a16885d850ad2656272351f9517c9f67b), [`310a8bc4`](https://github.com/wevm/wagmi/commit/310a8bc428ce4e7f68377f581b45dcdd64381cce), [`100e2a3b`](https://github.com/wevm/wagmi/commit/100e2a3b22f4602716554487b1d98738e053be76)]: + - @wagmi/core@0.8.2 + +## 0.9.1 + +### Patch Changes + +- [#1437](https://github.com/wevm/wagmi/pull/1437) [`c34a3dc6`](https://github.com/wevm/wagmi/commit/c34a3dc6396e6473d9f0505fad88ec910f8f5275) Thanks [@jxom](https://github.com/jxom)! - Omitted `"EIP712Domain"` type from `signTypedData` `types` arg since ethers throws an [internal error](https://github.com/ethers-io/ethers.js/blob/c80fcddf50a9023486e9f9acb1848aba4c19f7b6/packages/hash/src.ts/typed-data.ts#L466) if you include it. + +- [#1445](https://github.com/wevm/wagmi/pull/1445) [`51dd53cb`](https://github.com/wevm/wagmi/commit/51dd53cba3fe0f79fa1393270b738194577ddf54) Thanks [@jxom](https://github.com/jxom)! - Fixed an issue where the wagmi client wouldn't rehydrate the store in local storage when `autoConnect` is truthy. + +- Updated dependencies [[`c34a3dc6`](https://github.com/wevm/wagmi/commit/c34a3dc6396e6473d9f0505fad88ec910f8f5275), [`51dd53cb`](https://github.com/wevm/wagmi/commit/51dd53cba3fe0f79fa1393270b738194577ddf54)]: + - @wagmi/core@0.8.1 + +## 0.9.0 + +### Minor Changes + +- [#1344](https://github.com/wevm/wagmi/pull/1344) [`57a19374`](https://github.com/wevm/wagmi/commit/57a1937464a4ccf72719fc86c38d1734f6306652) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: With the introduction of the [`wagmi/chains` entrypoint](/react/chains#wagmichains), `wagmi` no longer exports the following: + + - `chain` + - `allChains` + - `defaultChains` + - `defaultL2Chains` + - `chainId` + - `etherscanBlockExplorers` + - `alchemyRpcUrls`, `infuraRpcUrls`, `publicRpcUrls` + + Read below for migration steps. + + #### Removed `chain` + + The `chain` export has been removed. `wagmi` now only exports the `mainnet` & `goerli` chains. If you need to use an alternative chain (`polygon`, `optimism`, etc), you will need to import it from the [`wagmi/chains` entrypoint](/react/chains#wagmichains). + + ```diff + import { + - chain + configureChains + } from 'wagmi' + + import { mainnet, polygon, optimism } from 'wagmi/chains' + + const { ... } = configureChains( + - [chain.mainnet, chain.polygon, chain.optimism], + + [mainnet, polygon, optimism], + { + ... + } + ) + ``` + + #### Removed `allChains` + + The `allChains` export has been removed. If you need a list of all chains, you can utilize [`wagmi/chains` entrypoint](/react/chains#wagmichains). + + ```diff + - import { allChains } from 'wagmi' + + import * as allChains from 'wagmi/chains' + + const { ... } = configureChains(allChains, ...) + ``` + + #### Removed `defaultChains` & `defaultL2Chains` + + The `defaultChains` & `defaultL2Chains` exports have been removed. If you still need the `defaultChains` or `defaultL2Chains` exports, you can build them yourself: + + ```diff + - import { defaultChains } from 'wagmi' + + import { mainnet, goerli } from 'wagmi/chains' + + + const defaultChains = [mainnet, goerli] + ``` + + > The `defaultChains` export was previously populated with `mainnet` & `goerli`. + + ```diff + - import { defaultL2Chains } from 'wagmi' + + import { + + arbitrum, + + arbitrumGoerli, + + polygon, + + polygonMumbai, + + optimism, + + optimismGoerli + + } from 'wagmi/chains' + + + const defaultL2Chains = [ + + arbitrum, + + arbitrumGoerli, + + polygon, + + polygonMumbai, + + optimism + + optimismGoerli + + ] + ``` + + > The `defaultL2Chains` export was previously populated with `arbitrum` & `optimism`. + + #### Removed `chainId` + + The `chainId` export has been removed. You can extract a chain ID from the chain itself. + + ```diff + - import { chainId } from 'wagmi' + + import { mainnet, polygon, optimism } from 'wagmi/chains' + + -const mainnetChainId = chainId.mainnet + -const polygonChainId = chainId.polygon + -const optimismChainId = chainId.optimism + +const mainnetChainId = mainnet.chainId + +const polygonChainId = polygon.chainId + +const optimismChainId = optimism.chainId + ``` + + #### Removed `etherscanBlockExplorers` + + The `etherscanBlockExplorers` export has been removed. You can extract a block explorer from the chain itself. + + ```diff + - import { etherscanBlockExplorers } from 'wagmi' + + import { mainnet, polygon, optimism } from 'wagmi/chains' + + -const mainnetEtherscanBlockExplorer = etherscanBlockExplorers.mainnet + -const polygonEtherscanBlockExplorer = etherscanBlockExplorers.polygon + -const optimismEtherscanBlockExplorer = etherscanBlockExplorers.optimism + +const mainnetEtherscanBlockExplorer = mainnet.blockExplorer + +const polygonEtherscanBlockExplorer = polygon.blockExplorer + +const optimismEtherscanBlockExplorer = optimism.blockExplorer + ``` + + #### Removed `alchemyRpcUrls`, `infuraRpcUrls` & `publicRpcUrls` + + The `alchemyRpcUrls`, `infuraRpcUrls` & `publicRpcUrls` exports have been removed. You can extract a RPC URL from the chain itself. + + ```diff + - import { alchemyRpcUrls, infuraRpcUrls, publicRpcUrls } from 'wagmi' + + import { mainnet } from 'wagmi/chains' + + -const mainnetAlchemyRpcUrl = alchemyRpcUrls.mainnet + -const mainnetInfuraRpcUrl = infuraRpcUrls.mainnet + -const mainnetOptimismRpcUrl = publicRpcUrls.mainnet + +const mainnetAlchemyRpcUrl = mainnet.rpcUrls.alchemy + +const mainnetInfuraRpcUrl = mainnet.rpcUrls.infura + +const mainnetOptimismRpcUrl = mainnet.rpcUrls.optimism + ``` + +- [#1344](https://github.com/wevm/wagmi/pull/1344) [`57a19374`](https://github.com/wevm/wagmi/commit/57a1937464a4ccf72719fc86c38d1734f6306652) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: the shape of the `Chain` type has been modified. + + #### RPC URLs + + The `rpcUrls` shape has changed to include an array of URLs, and also the transport method (`http` or `webSocket`): + + ```diff + type Chain = { + ... + rpcUrls: { + - [key: string]: string + + [key: string]: { + + http: string[] + + webSocket: string[] + + } + } + ... + } + ``` + + Note that you will also need to ensure that usage is migrated: + + ```diff + - const rpcUrl = mainnet.rpcUrls.alchemy + + const rpcUrl = mainnet.rpcUrls.alchemy.http[0] + ``` + + #### Contracts + + The `multicall` and `ens` attributes have been moved into the `contracts` object: + + ```diff + type Contract = { + address: Address + blockCreated?: number + } + + type Chain = { + ... + - multicall: Contract + - ens: Contract + + contracts: { + + multicall3: Contract + + ensRegistry: Contract + + } + ... + } + ``` + + Note that you will also need to ensure that usage is migrated: + + ```diff + - const multicallContract = mainnet.multicall + + const multicallContract = mainnet.contracts.multicall3 + ``` + +- [#1344](https://github.com/wevm/wagmi/pull/1344) [`57a19374`](https://github.com/wevm/wagmi/commit/57a1937464a4ccf72719fc86c38d1734f6306652) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: Removed the `wait` config option on `useWaitForTransaction`. Use the transaction `hash` instead. + + ```diff + const { data } = useWaitForTransaction({ + - wait: transaction.wait + + hash: transaction.hash + }) + ``` + +- [#1344](https://github.com/wevm/wagmi/pull/1344) [`57a19374`](https://github.com/wevm/wagmi/commit/57a1937464a4ccf72719fc86c38d1734f6306652) Thanks [@jxom](https://github.com/jxom)! - Updated errors to use `cause` instead of `internal` + +- [#1344](https://github.com/wevm/wagmi/pull/1344) [`57a19374`](https://github.com/wevm/wagmi/commit/57a1937464a4ccf72719fc86c38d1734f6306652) Thanks [@jxom](https://github.com/jxom)! - `useEnsResolver`'s result is no longer persisted by the query client since it cannot serialize its prototype methods. + +- [#1344](https://github.com/wevm/wagmi/pull/1344) [`57a19374`](https://github.com/wevm/wagmi/commit/57a1937464a4ccf72719fc86c38d1734f6306652) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: Changed `useWaitForTransaction` behavior to return an error if the transaction reverted. + +### Patch Changes + +- [#1344](https://github.com/wevm/wagmi/pull/1344) [`57a19374`](https://github.com/wevm/wagmi/commit/57a1937464a4ccf72719fc86c38d1734f6306652) Thanks [@jxom](https://github.com/jxom)! - `useWaitForTransaction` now throws an error for cancelled or replaced transactions. + +- [#1344](https://github.com/wevm/wagmi/pull/1344) [`57a19374`](https://github.com/wevm/wagmi/commit/57a1937464a4ccf72719fc86c38d1734f6306652) Thanks [@jxom](https://github.com/jxom)! - `useWaitForTransaction` now respects repriced (sped up) transactions. + +- [#1344](https://github.com/wevm/wagmi/pull/1344) [`57a19374`](https://github.com/wevm/wagmi/commit/57a1937464a4ccf72719fc86c38d1734f6306652) Thanks [@jxom](https://github.com/jxom)! - Updated `@coinbase/wallet-sdk` to `^3.6.0`. + +- Updated dependencies [[`57a19374`](https://github.com/wevm/wagmi/commit/57a1937464a4ccf72719fc86c38d1734f6306652), [`57a19374`](https://github.com/wevm/wagmi/commit/57a1937464a4ccf72719fc86c38d1734f6306652), [`57a19374`](https://github.com/wevm/wagmi/commit/57a1937464a4ccf72719fc86c38d1734f6306652), [`57a19374`](https://github.com/wevm/wagmi/commit/57a1937464a4ccf72719fc86c38d1734f6306652), [`57a19374`](https://github.com/wevm/wagmi/commit/57a1937464a4ccf72719fc86c38d1734f6306652), [`57a19374`](https://github.com/wevm/wagmi/commit/57a1937464a4ccf72719fc86c38d1734f6306652), [`57a19374`](https://github.com/wevm/wagmi/commit/57a1937464a4ccf72719fc86c38d1734f6306652), [`57a19374`](https://github.com/wevm/wagmi/commit/57a1937464a4ccf72719fc86c38d1734f6306652), [`57a19374`](https://github.com/wevm/wagmi/commit/57a1937464a4ccf72719fc86c38d1734f6306652)]: + - @wagmi/core@0.8.0 + +## 0.8.10 + +### Patch Changes + +- [#1411](https://github.com/wevm/wagmi/pull/1411) [`659be184`](https://github.com/wevm/wagmi/commit/659be1840c613ce9f7aca9ac96694c4f60da4a66) Thanks [@tmm](https://github.com/tmm)! - Fixed issue where block invalidation was not properly disabled when setting `enabled: false`. + +- [#1409](https://github.com/wevm/wagmi/pull/1409) [`b557b3ee`](https://github.com/wevm/wagmi/commit/b557b3ee4fc58217e61d860fc3d1109d2abc813e) Thanks [@jxom](https://github.com/jxom)! - Ensure that `useSyncExternalStoreWithTracked` rerenders when no values are being tracked. + +- Updated dependencies [[`659be184`](https://github.com/wevm/wagmi/commit/659be1840c613ce9f7aca9ac96694c4f60da4a66)]: + - @wagmi/core@0.7.9 + +## 0.8.9 + +### Patch Changes + +- [#1406](https://github.com/wevm/wagmi/pull/1406) [`4f18c450`](https://github.com/wevm/wagmi/commit/4f18c450a4d7952bfcfa6c533348ffbe55893d3c) Thanks [@tmm](https://github.com/tmm)! - Function for selecting the [EIP-1193](https://eips.ethereum.org/EIPS/eip-1193) Ethereum Provider to target. Defaults to `() => typeof window !== 'undefined' ? window.ethereum : undefined`. + + ```ts + import { InjectedConnector } from "wagmi/connectors/injected"; + + const connector = new InjectedConnector({ + options: { + name: "My Injected Wallet", + getProvider: () => + typeof window !== "undefined" ? window.myInjectedWallet : undefined, + }, + }); + ``` + +- Updated dependencies [[`4f18c450`](https://github.com/wevm/wagmi/commit/4f18c450a4d7952bfcfa6c533348ffbe55893d3c)]: + - @wagmi/core@0.7.8 + +## 0.8.8 + +### Patch Changes + +- [#1386](https://github.com/wevm/wagmi/pull/1386) [`206a2adb`](https://github.com/wevm/wagmi/commit/206a2adbb4ee5149a364543b34612050ccf78c21) Thanks [@jxom](https://github.com/jxom)! - Fixed an issue where `persister` would still use `window.localStorage` instead of the wagmi `storage`. + +- [#1376](https://github.com/wevm/wagmi/pull/1376) [`a70a9528`](https://github.com/wevm/wagmi/commit/a70a9528f93f4d7fea28b7652751dfef2dcacf9b) Thanks [@jxom](https://github.com/jxom)! - Fixed issue where `switchChain` on `WalletConnectConnector` would not resolve. + +- [#1392](https://github.com/wevm/wagmi/pull/1392) [`88afc849`](https://github.com/wevm/wagmi/commit/88afc84978afe9689ab7364633e4422ecd7699ea) Thanks [@tmm](https://github.com/tmm)! - Added check for active connector when connecting + +- Updated dependencies [[`206a2adb`](https://github.com/wevm/wagmi/commit/206a2adbb4ee5149a364543b34612050ccf78c21), [`a70a9528`](https://github.com/wevm/wagmi/commit/a70a9528f93f4d7fea28b7652751dfef2dcacf9b), [`206a2adb`](https://github.com/wevm/wagmi/commit/206a2adbb4ee5149a364543b34612050ccf78c21), [`88afc849`](https://github.com/wevm/wagmi/commit/88afc84978afe9689ab7364633e4422ecd7699ea)]: + - @wagmi/core@0.7.7 + +## 0.8.7 + +### Patch Changes + +- [#1384](https://github.com/wevm/wagmi/pull/1384) [`027e88d6`](https://github.com/wevm/wagmi/commit/027e88d6e5f8d028d46ee78aec8500701e0173d9) Thanks [@tmm](https://github.com/tmm)! - Fixed issue reconnecting after disconnect with `MetaMaskConnector` in MetaMask mobile browser. + +- [#1377](https://github.com/wevm/wagmi/pull/1377) [`089c4f3b`](https://github.com/wevm/wagmi/commit/089c4f3b3b8ce5cf7807f144410e2f64b72e0580) Thanks [@jxom](https://github.com/jxom)! - Fixed an issue where transforming `useContractRead`, `useContractReads` or `useContractInfiniteReads`'s return data via `select` wasn't inferring the type. + +- Updated dependencies [[`027e88d6`](https://github.com/wevm/wagmi/commit/027e88d6e5f8d028d46ee78aec8500701e0173d9)]: + - @wagmi/core@0.7.6 + +## 0.8.6 + +### Patch Changes + +- [`1169914a`](https://github.com/wevm/wagmi/commit/1169914a0f0ad2810ca1c536b1f1bc6c20f2c1be) Thanks [@jxom](https://github.com/jxom)! - Use `get_accounts` for `getSigner` in InjectedConnector + +- Updated dependencies [[`1169914a`](https://github.com/wevm/wagmi/commit/1169914a0f0ad2810ca1c536b1f1bc6c20f2c1be)]: + - @wagmi/core@0.7.5 + +## 0.8.5 + +### Patch Changes + +- [#1282](https://github.com/wevm/wagmi/pull/1282) [`6d286c9e`](https://github.com/wevm/wagmi/commit/6d286c9ed6f64a9872352904d4d171a6bc1c7a96) Thanks [@jxom](https://github.com/jxom)! - Fixed an issue where `useContractRead` would perform an unnecessary rerender if another hook had `watch` enabled. + +## 0.8.4 + +### Patch Changes + +- [#1309](https://github.com/wevm/wagmi/pull/1309) [`1f4a4261`](https://github.com/wevm/wagmi/commit/1f4a4261247b1d3a90e3123157bc851a35d49b9c) Thanks [@tmm](https://github.com/tmm)! - Fixed internal type + +- Updated dependencies [[`1f4a4261`](https://github.com/wevm/wagmi/commit/1f4a4261247b1d3a90e3123157bc851a35d49b9c)]: + - @wagmi/core@0.7.4 + +## 0.8.3 + +### Patch Changes + +- [#1294](https://github.com/wevm/wagmi/pull/1294) [`b2f88949`](https://github.com/wevm/wagmi/commit/b2f88949f32aabaf13f318472648cd51a8b7f2e7) Thanks [@tmm](https://github.com/tmm)! - Set `abi` return type value for `usePrepareContractWrite` as more permissive when not inferrable as `Abi`. + +- Updated dependencies [[`b2f88949`](https://github.com/wevm/wagmi/commit/b2f88949f32aabaf13f318472648cd51a8b7f2e7)]: + - @wagmi/core@0.7.3 + +## 0.8.2 + +### Patch Changes + +- [`e9f806b6`](https://github.com/wevm/wagmi/commit/e9f806b652ba62effb3ddac464815e447fc287f6) Thanks [@tmm](https://github.com/tmm)! - Bumped abitype and zustand versions. + +- [#1290](https://github.com/wevm/wagmi/pull/1290) [`88450052`](https://github.com/wevm/wagmi/commit/88450052b9f070fe53e18d84f72918c410b961f0) Thanks [@tmm](https://github.com/tmm)! - Fixed `useAccount`'s' `onConnect` callback `isReconnected` flag. + +- Updated dependencies [[`e9f806b6`](https://github.com/wevm/wagmi/commit/e9f806b652ba62effb3ddac464815e447fc287f6)]: + - @wagmi/core@0.7.2 + +## 0.8.1 + +### Patch Changes + +- [#1272](https://github.com/wevm/wagmi/pull/1272) [`1f7fc41`](https://github.com/wevm/wagmi/commit/1f7fc419f7960bbdc51dfa85c2f33b89f1ecc1bf) Thanks [@tmm](https://github.com/tmm)! - Fixed ethers import path + +- Updated dependencies [[`1f7fc41`](https://github.com/wevm/wagmi/commit/1f7fc419f7960bbdc51dfa85c2f33b89f1ecc1bf)]: + - @wagmi/core@0.7.1 + +## 0.8.0 + +### Minor Changes + +- [#1202](https://github.com/wevm/wagmi/pull/1202) [`9bf56af`](https://github.com/wevm/wagmi/commit/9bf56af3c30bdb80abb1e785c002e00986fadfb2) Thanks [@tmm](https://github.com/tmm)! - **Breaking**: Removed the following deprecated chains: + + - `ropsten` + - `rinkeby` + - `kovan` + - `optimismKovan` + - `arbitrumRinkeby` + + If you feel you still need to include one of these testnets in your application, you will have to define it manually: + + ```diff + -import { rinkeby } from 'wagmi' + +import { Chain } from 'wagmi' + + +export const rinkeby: Chain = { + + id: 4, + + name: 'Rinkeby', + + network: 'rinkeby', + + nativeCurrency: { name: 'Rinkeby Ether', symbol: 'ETH', decimals: 18 }, + + rpcUrls: { + + alchemy: 'https://eth-rinkeby.alchemyapi.io/v2', + + default: 'https://rpc.ankr.com/eth_rinkeby', + + infura: 'https://rinkeby.infura.io/v3', + + public: 'https://rpc.ankr.com/eth_rinkeby', + + }, + + blockExplorers: { + + etherscan: 'https://rinkeby.etherscan.io', + + default: 'https://rinkeby.etherscan.io', + + }, + + ens: { + + address: '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e', + + }, + + multicall: { + + address: '0xca11bde05977b3631167028862be2a173976ca11', + + blockCreated: 10299530, + + }, + + testnet: true, + } + ``` + + You can reference these removed chains [here](https://github.com/wevm/wagmi/blob/389765f7d9af063ab0df07389a2bbfbc10a41060/packages/core/src/constants/chains.ts). + +- [#1202](https://github.com/wevm/wagmi/pull/1202) [`9bf56af`](https://github.com/wevm/wagmi/commit/9bf56af3c30bdb80abb1e785c002e00986fadfb2) Thanks [@tmm](https://github.com/tmm)! - **Breaking**: Made `apiKey` required on `infuraProvider` and `alchemyProvider`. + + ```diff + import { configureChains } from 'wagmi' + + const config = configureChains(defaultChains, [ + - alchemyProvider(), + + alchemyProvider({ apiKey: process.env.ALCHEMY_API_KEY }) + ]) + ``` + + You can find your Alchemy API key from the [Alchemy Dashboard](https://dashboard.alchemyapi.io/), or your Infura API key from the [Infura Dashboard](https://infura.io/login). + +- [#1202](https://github.com/wevm/wagmi/pull/1202) [`9bf56af`](https://github.com/wevm/wagmi/commit/9bf56af3c30bdb80abb1e785c002e00986fadfb2) Thanks [@tmm](https://github.com/tmm)! - **Breaking**: `addressOrName` renamed to `address` for `useBalance` and `useEnsAvatar`. + + ```diff + const result = useBalance({ + - addressOrName: '0x…', + + address: '0x…', + }) + ``` + + If you were using an ENS name instead of an address, you can resolve the name to an address before passing it to the action. + + ```diff + + const { data: address } = useEnsAddress({ name: 'example.eth' }) + const result = useBalance({ + - addressOrName: 'example.eth', + + address, + }) + ``` + +- [#1202](https://github.com/wevm/wagmi/pull/1202) [`9bf56af`](https://github.com/wevm/wagmi/commit/9bf56af3c30bdb80abb1e785c002e00986fadfb2) Thanks [@tmm](https://github.com/tmm)! - Removed CommonJS support + +### Patch Changes + +- Updated dependencies [[`9bf56af`](https://github.com/wevm/wagmi/commit/9bf56af3c30bdb80abb1e785c002e00986fadfb2), [`9bf56af`](https://github.com/wevm/wagmi/commit/9bf56af3c30bdb80abb1e785c002e00986fadfb2), [`9bf56af`](https://github.com/wevm/wagmi/commit/9bf56af3c30bdb80abb1e785c002e00986fadfb2), [`9bf56af`](https://github.com/wevm/wagmi/commit/9bf56af3c30bdb80abb1e785c002e00986fadfb2)]: + - @wagmi/core@0.7.0 + +## 0.7.15 + +### Patch Changes + +- [#1262](https://github.com/wevm/wagmi/pull/1262) [`45e2ca4`](https://github.com/wevm/wagmi/commit/45e2ca4d1f33a7b1165c387d420b8d47f4f66935) Thanks [@tmm](https://github.com/tmm)! - Added default for `structuralSharing` for `useContractRead`, `useContractReads`, and `useContractInfiniteReads`. + +## 0.7.14 + +### Patch Changes + +- [#1260](https://github.com/wevm/wagmi/pull/1260) [`0e12f03`](https://github.com/wevm/wagmi/commit/0e12f0380442bccca9ed18991e783819778032fe) Thanks [@ilmpc](https://github.com/ilmpc)! - Deprecated `isDataEqual` option from and added `structuralSharing` option to `useContractRead`, `useContractReads`, and `useContractInfiniteReads`. + +## 0.7.13 + +### Patch Changes + +- [#1250](https://github.com/wevm/wagmi/pull/1250) [`ce2e0f4`](https://github.com/wevm/wagmi/commit/ce2e0f4a46b8fd1c509ead552012ef4c072a525b) Thanks [@tmm](https://github.com/tmm)! - Added support for Trust Wallet browser extension. + +- Updated dependencies [[`ce2e0f4`](https://github.com/wevm/wagmi/commit/ce2e0f4a46b8fd1c509ead552012ef4c072a525b)]: + - @wagmi/core@0.6.12 + +## 0.7.12 + +### Patch Changes + +- [#1234](https://github.com/wevm/wagmi/pull/1234) [`3ff9303`](https://github.com/wevm/wagmi/commit/3ff930349250f62137cca4ca3b382522882abf8a) Thanks [@tmm](https://github.com/tmm)! - Fixed issue with adding chain to wallet without block explorer URL. + +- Updated dependencies [[`3ff9303`](https://github.com/wevm/wagmi/commit/3ff930349250f62137cca4ca3b382522882abf8a)]: + - @wagmi/core@0.6.11 + +## 0.7.11 + +### Patch Changes + +- [#1232](https://github.com/wevm/wagmi/pull/1232) [`c0ca509`](https://github.com/wevm/wagmi/commit/c0ca509506dcf6d98b058df549dc761c9a5f3d1c) Thanks [@tmm](https://github.com/tmm)! - Added validation to check that chain is configured for connector when accessing `Signer`. + +- Updated dependencies [[`c0ca509`](https://github.com/wevm/wagmi/commit/c0ca509506dcf6d98b058df549dc761c9a5f3d1c)]: + - @wagmi/core@0.6.10 + +## 0.7.10 + +### Patch Changes + +- [#1206](https://github.com/wevm/wagmi/pull/1206) [`15ff089`](https://github.com/wevm/wagmi/commit/15ff0896216abecf5967294ae5aeb26ea7fb480b) Thanks [@jxom](https://github.com/jxom)! - Added `scopeKey` as a configuration option to the Hooks which scope its cache to a given context. Hooks that have identical scope will share the same cache. + +- [#1207](https://github.com/wevm/wagmi/pull/1207) [`c73d463`](https://github.com/wevm/wagmi/commit/c73d463d65c9dbfcfe709187e47323a769589741) Thanks [@lvshaoping007](https://github.com/lvshaoping007)! - Added Kucoin wallet support to `InjectedConnector` + +- Updated dependencies [[`c73d463`](https://github.com/wevm/wagmi/commit/c73d463d65c9dbfcfe709187e47323a769589741)]: + - @wagmi/core@0.6.9 + +## 0.7.9 + +### Patch Changes + +- [#1201](https://github.com/wevm/wagmi/pull/1201) [`9a07efa`](https://github.com/wevm/wagmi/commit/9a07efaa397d3ba03f2edbe527c359f21e22139a) Thanks [@jxom](https://github.com/jxom)! - Fixed issue where non-checksum addresses did not resolve with an ENS name + +- [#1132](https://github.com/wevm/wagmi/pull/1132) [`d41c0d6`](https://github.com/wevm/wagmi/commit/d41c0d650f8c0e54145758685b7604b8909d7ae0) Thanks [@toniocodo](https://github.com/toniocodo)! - Added ERC-4626 ABI + +- Updated dependencies [[`d41c0d6`](https://github.com/wevm/wagmi/commit/d41c0d650f8c0e54145758685b7604b8909d7ae0), [`9a07efa`](https://github.com/wevm/wagmi/commit/9a07efaa397d3ba03f2edbe527c359f21e22139a)]: + - @wagmi/core@0.6.8 + +## 0.7.8 + +### Patch Changes + +- [#1174](https://github.com/wevm/wagmi/pull/1174) [`196a458`](https://github.com/wevm/wagmi/commit/196a458f64141e8a9f39c1b1e1af5937f692cb39) Thanks [@jxom](https://github.com/jxom)! - Fixed an issue where `client.chains` (active connector chains) would be populated when there is no active connector (disconnected user). + +- [#1176](https://github.com/wevm/wagmi/pull/1176) [`389765f`](https://github.com/wevm/wagmi/commit/389765f7d9af063ab0df07389a2bbfbc10a41060) Thanks [@jxom](https://github.com/jxom)! - Migrate away from Alchemy RPC URLs in the public RPC URL list + +- Updated dependencies [[`196a458`](https://github.com/wevm/wagmi/commit/196a458f64141e8a9f39c1b1e1af5937f692cb39), [`389765f`](https://github.com/wevm/wagmi/commit/389765f7d9af063ab0df07389a2bbfbc10a41060)]: + - @wagmi/core@0.6.7 + +## 0.7.7 + +### Patch Changes + +- [#1166](https://github.com/wevm/wagmi/pull/1166) [`6fbe910`](https://github.com/wevm/wagmi/commit/6fbe91080b54e33e8543e9638ff5089e749ada3f) Thanks [@jxom](https://github.com/jxom)! - Export the React entrypoint `Client` type instead of `@wagmi/core`'s `Client`. + +- [`81ce9e6`](https://github.com/wevm/wagmi/commit/81ce9e64d85f7d01370324c1a529988a0919894f) Thanks [@jxom](https://github.com/jxom)! - Add `isPortal` to injected MetaMask flags. + +- [`c2c0109`](https://github.com/wevm/wagmi/commit/c2c01096ef4cd0ffadbb49062969c208604c6194) Thanks [@jxom](https://github.com/jxom)! - Add etherscan block explorer to Optimism Goerli + +- Updated dependencies [[`81ce9e6`](https://github.com/wevm/wagmi/commit/81ce9e64d85f7d01370324c1a529988a0919894f), [`c2c0109`](https://github.com/wevm/wagmi/commit/c2c01096ef4cd0ffadbb49062969c208604c6194)]: + - @wagmi/core@0.6.6 + +## 0.7.6 + +### Patch Changes + +- [#1162](https://github.com/wevm/wagmi/pull/1162) [`30335b3`](https://github.com/wevm/wagmi/commit/30335b3199fb425e398e9c492b50c68d5e2ade7e) Thanks [@tmm](https://github.com/tmm)! - Fixed issue where non-indexed event parameter types were set to `null`. + +- [#1162](https://github.com/wevm/wagmi/pull/1162) [`30335b3`](https://github.com/wevm/wagmi/commit/30335b3199fb425e398e9c492b50c68d5e2ade7e) Thanks [@tmm](https://github.com/tmm)! - Fixed issue where `useContractReads` and `useContractInfiniteReads` types were slowing down TypeScript compiler. + +- Updated dependencies [[`30335b3`](https://github.com/wevm/wagmi/commit/30335b3199fb425e398e9c492b50c68d5e2ade7e), [`30335b3`](https://github.com/wevm/wagmi/commit/30335b3199fb425e398e9c492b50c68d5e2ade7e)]: + - @wagmi/core@0.6.5 + +## 0.7.5 + +### Patch Changes + +- [#1103](https://github.com/wevm/wagmi/pull/1103) [`651eda0`](https://github.com/wevm/wagmi/commit/651eda06384bd0955268427f898e9337b2dc5a31) Thanks [@tmm](https://github.com/tmm)! - Bumped `abitype` dependency. + +- Updated dependencies [[`651eda0`](https://github.com/wevm/wagmi/commit/651eda06384bd0955268427f898e9337b2dc5a31)]: + - @wagmi/core@0.6.4 + +## 0.7.4 + +### Patch Changes + +- [#1099](https://github.com/wevm/wagmi/pull/1099) [`748e617`](https://github.com/wevm/wagmi/commit/748e61719ad706acae057be903321ebe0c2e817e) Thanks [@jxom](https://github.com/jxom)! - Added `isFetchedAfterMount` to the return value of hooks. + + The `isFetchedAfterMount` will be truthy if the hook has fetched after the component has been mounted. This value can be utilized to not show the result if it has previously been cached. + +- [#1091](https://github.com/wevm/wagmi/pull/1091) [`a3aaf59`](https://github.com/wevm/wagmi/commit/a3aaf590e8e993017baa9a1ac50ecd63dd287caf) Thanks [@tmm](https://github.com/tmm)! - Fixed `useAccount` `onConnect`/`onDisconnect` from not firing when the account was already connected/disconnected. + +## 0.7.3 + +### Patch Changes + +- [#1086](https://github.com/wevm/wagmi/pull/1086) [`4e28d2a`](https://github.com/wevm/wagmi/commit/4e28d2ad4c2e6b3479b728563040b9529463cbcf) Thanks [@tmm](https://github.com/tmm)! - Exposed module types. + +- Updated dependencies [[`4e28d2a`](https://github.com/wevm/wagmi/commit/4e28d2ad4c2e6b3479b728563040b9529463cbcf)]: + - @wagmi/core@0.6.3 + +## 0.7.2 + +### Patch Changes + +- [#1080](https://github.com/wevm/wagmi/pull/1080) [`3be5e8b`](https://github.com/wevm/wagmi/commit/3be5e8b01e58ed40cc9dab7ef9533c0197cb74d0) Thanks [@tmm](https://github.com/tmm)! - Added `abitype` to `dependencies` so types ship correctly. + +- Updated dependencies [[`3be5e8b`](https://github.com/wevm/wagmi/commit/3be5e8b01e58ed40cc9dab7ef9533c0197cb74d0)]: + - @wagmi/core@0.6.2 + +## 0.7.1 + +### Patch Changes + +- [#1074](https://github.com/wevm/wagmi/pull/1074) [`8db807f`](https://github.com/wevm/wagmi/commit/8db807f16149aa278c2a7db9ee5245431db12173) Thanks [@IljaDaderko](https://github.com/IljaDaderko)! - Exported `EventListener` type + +- Updated dependencies [[`8db807f`](https://github.com/wevm/wagmi/commit/8db807f16149aa278c2a7db9ee5245431db12173)]: + - @wagmi/core@0.6.1 + +## 0.7.0 + +### Minor Changes + +- [#940](https://github.com/wevm/wagmi/pull/940) [`b6cb8f4`](https://github.com/wevm/wagmi/commit/b6cb8f4cd15eb13073bc7e9ecb4bfa2c261c0663) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: `usePrepareContractWrite` now throws when a `chainId` is specified and the end-user is on a different chain id (the wrong network). + + If you wish to defer this check until the click handler is pressed, you can place `chainId` in `useContractWrite` instead: + + ```diff + import { usePrepareContractWrite, useContractWrite } from 'wagmi' + import { optimism } from 'wagmi/chains' + + // ... + + const { config } = usePrepareContractWrite({ + addressOrName: '0xaf0326d92b97df1221759476b072abfd8084f9be', + contractInterface: ['function mint()'], + functionName: 'mint', + }) + const { write } = useContractWrite({ + ...config, + + chainId: optimism.id + }) + + ``` + +- [#940](https://github.com/wevm/wagmi/pull/940) [`b6cb8f4`](https://github.com/wevm/wagmi/commit/b6cb8f4cd15eb13073bc7e9ecb4bfa2c261c0663) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: The `usePrepareSendTransaction` hook will now only run when the end-user is connected to their wallet. + + This is to reach parity with `usePrepareContractWrite`. + + If the end-user is not connected, then the `usePrepareSendTransaction` hook will remain idle. + +- [#940](https://github.com/wevm/wagmi/pull/940) [`b6cb8f4`](https://github.com/wevm/wagmi/commit/b6cb8f4cd15eb13073bc7e9ecb4bfa2c261c0663) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: `usePrepareSendTransaction` now throws when a `chainId` is specified and the end-user is on a different chain id (the wrong network). + + If you wish to defer this check until the click handler is pressed, you can place `chainId` in `useContractWrite` instead: + + ```diff + import { usePrepareSendTransaction, useContractWrite } from 'wagmi' + import { optimism } from 'wagmi/chains' + + // ... + + const { config } = usePrepareSendTransaction({ + request: { + to: 'moxey.eth', + value: parseEther('1'), + }, + }) + const { sendTransaction } = useSendTransaction({ + ...config, + + chainId: optimism.id + }) + + ``` + +- [#941](https://github.com/wevm/wagmi/pull/941) [`0c96009`](https://github.com/wevm/wagmi/commit/0c96009398647a515a57f72ef25c32724f7c978c) Thanks [@tmm](https://github.com/tmm)! - **Breaking**: `useContractEvent` no longer accepts a `signerOrProvider` configuration option. + +- [#941](https://github.com/wevm/wagmi/pull/941) [`0c96009`](https://github.com/wevm/wagmi/commit/0c96009398647a515a57f72ef25c32724f7c978c) Thanks [@tmm](https://github.com/tmm)! - **Breaking**: `addressOrName` and `contractInterface` renamed to `address` and `abi` respectively for contract hooks: `useContract`, `useContractEvent`, `useContractRead`, `useContractReads`, `useContractInfiniteReads`, `useContractWrite`, `usePrepareContractWrite`. + + ```diff + import { useContractRead } from 'wagmi' + + const result = useContractRead({ + - addressOrName: '0x…', + + address: '0x…', + - contractInterface: […] as const, + + abi: […] as const, + functionName: 'balanceOf', + args: ['0x…'], + }) + ``` + + If you were using an ENS name instead of an address, you can resolve the name to an address before passing it to the action. + + ```diff + - import { useContractRead } from 'wagmi' + + import { useContractRead, useEnsAddress } from 'wagmi' + + + const { data: address} = useEnsAddress({ name: 'example.eth'}) + const result = useContractRead({ + - addressOrName: 'example.eth', + + address, + abi: […], + functionName: 'balanceOf', + args: ['0x…'], + }) + ``` + +- [#941](https://github.com/wevm/wagmi/pull/941) [`0c96009`](https://github.com/wevm/wagmi/commit/0c96009398647a515a57f72ef25c32724f7c978c) Thanks [@tmm](https://github.com/tmm)! - **Breaking**: Updated TypeScript generics for contract and typed data hooks. + + Adding a [const assertion](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-4.html#const-assertions) to `abi` allows TypeScript to infer `functionName`, `args`, `overrides`, and return types for functions, and `eventName` and `listener` types for events. + + ```diff + import { useContractRead } from 'wagmi' + + const result = useContractRead({ + address: '0x…', + - abi: […], + + abi: […] as const, + functionName: 'balanceOf', // will autocomplete and catch typos + args: ['0x…'], // inferred based on `abi`, `functionName`, `args` + }) + result.data // inferred based on `functionName` + ``` + + This works for the following actions: `useContractRead`, `useContractWrite`, `usePrepareContractWrite`, `useContractReads`, `useContractInfiniteReads`, and `useContractEvent`. + + Adding a [const assertion](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-4.html#const-assertions) to `useSignTypedData`'s config option, `types`, allows TypeScript to infer `value`. + + ```diff + import { useSignTypedData } from 'wagmi' + + const result = useSignTypedData({ + domain: { + name: 'Ether Mail', + version: '1', + chainId: 1, + verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC', + }, + types: { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], + - }, + + } as const, + value: { // `value` is inferred based on `types` + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, + }) + ``` + +- [#941](https://github.com/wevm/wagmi/pull/941) [`0c96009`](https://github.com/wevm/wagmi/commit/0c96009398647a515a57f72ef25c32724f7c978c) Thanks [@tmm](https://github.com/tmm)! - **Breaking**: Updated TypeScript version to `typescript@>=4.7.4`. + + `@wagmi/core` can now infer types based on [ABI](https://docs.soliditylang.org/en/v0.8.15/abi-spec.html#json) and [EIP-712](https://eips.ethereum.org/EIPS/eip-712) Typed Data definitions, giving you full end-to-end type-safety from your contracts to your frontend and incredible developer experience (e.g. autocomplete contract function names and catch misspellings, type contract function arguments, etc.). + + For this to work, you must upgrade to `typescript@>=4.7.4`. Why is TypeScript v4.7.4 or greater necessary? TypeScript 4.7.4 introduced the ability to [extend constraints on inferred type variables](https://devblogs.microsoft.com/typescript/announcing-typescript-4-7/#extends-constraints-on-infer-type-variables), which is used extensively to help narrow types for ABIs. Good news! When upgrading TypeScript from 4.6 to 4.7 there are likely no [breaking changes](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-7.html#breaking-changes) for your set up. + +- [#941](https://github.com/wevm/wagmi/pull/941) [`0c96009`](https://github.com/wevm/wagmi/commit/0c96009398647a515a57f72ef25c32724f7c978c) Thanks [@tmm](https://github.com/tmm)! - **Breaking**: Updated `paginatedIndexesConfig` `fn` parameter return type. `fn` now returns an array instead of a single object. + + ```diff + import { BigNumber } from 'ethers' + import { paginatedIndexesConfig, useContractInfiniteReads } from 'wagmi' + + useContractInfiniteReads({ + cacheKey: 'contracts', + ...paginatedIndexesConfig( + - (index) => ({ + + (index) => [{ + ...mlootContractConfig, + functionName: 'tokenURI', + args: [BigNumber.from(index)] as const, + - }), + + }], + { start: 0, perPage: 10, direction: 'increment' }, + ), + }) + ``` + +- [#941](https://github.com/wevm/wagmi/pull/941) [`0c96009`](https://github.com/wevm/wagmi/commit/0c96009398647a515a57f72ef25c32724f7c978c) Thanks [@tmm](https://github.com/tmm)! - **Breaking**: `args` config option must now be an array for the following hooks: `useContractRead`, `useContractWrite`, `usePrepareContractWrite`, `useContractReads`, and `useContractInfiniteReads`. + + ```diff + import { useContractRead } from 'wagmi' + + const { data } = useContractRead({ + address: '0x…', + abi: […], + functionName: 'balanceOf', + - args: '0x…', + + args: ['0x…'], + }) + ``` + +### Patch Changes + +- [#940](https://github.com/wevm/wagmi/pull/940) [`b6cb8f4`](https://github.com/wevm/wagmi/commit/b6cb8f4cd15eb13073bc7e9ecb4bfa2c261c0663) Thanks [@jxom](https://github.com/jxom)! - The `useSigner` hook now accepts an optional `chainId` to use for signer initialization as an argument. + + ```tsx + import { useSigner } from "wagmi"; + import { optimism } from "wagmi/core"; + + // ... + + useSigner({ chainId: optimism.id }); + ``` + +- [#1061](https://github.com/wevm/wagmi/pull/1061) [`a4ffe8b`](https://github.com/wevm/wagmi/commit/a4ffe8b25516d5504685ae94579da4cd8c409329) Thanks [@alecananian](https://github.com/alecananian)! - Added Arbitrum Goerli Arbiscan block explorer + +- [#1050](https://github.com/wevm/wagmi/pull/1050) [`73d4d47`](https://github.com/wevm/wagmi/commit/73d4d47bc679f4f9a1cf46010fe2bf858c9d0b5c) Thanks [@jxom](https://github.com/jxom)! - update dependencies + + - `@coinbase/wallet-sdk@3.5.3` + - `@tanstack/query-sync-storage-persister@4.10.1` + - `@tanstack/react-query@4.10.1` + - `@tanstack/react-query-persist-client@4.10.1` + - `@walletconnect/ethereum-provider@1.8.0` + +- [#1048](https://github.com/wevm/wagmi/pull/1048) [`ed13074`](https://github.com/wevm/wagmi/commit/ed130747c0f28c1d9980a1328883e4000a60455e) Thanks [@Max-3-7](https://github.com/Max-3-7)! - Added support for Avalanche core wallet + +- [#1046](https://github.com/wevm/wagmi/pull/1046) [`ab9ecaa`](https://github.com/wevm/wagmi/commit/ab9ecaa74dfa4324279e167dd7e348319ef7d35d) Thanks [@jxom](https://github.com/jxom)! - make ethers block format validator compatible with Celo + +- Updated dependencies [[`b6cb8f4`](https://github.com/wevm/wagmi/commit/b6cb8f4cd15eb13073bc7e9ecb4bfa2c261c0663), [`b6cb8f4`](https://github.com/wevm/wagmi/commit/b6cb8f4cd15eb13073bc7e9ecb4bfa2c261c0663), [`a4ffe8b`](https://github.com/wevm/wagmi/commit/a4ffe8b25516d5504685ae94579da4cd8c409329), [`b6cb8f4`](https://github.com/wevm/wagmi/commit/b6cb8f4cd15eb13073bc7e9ecb4bfa2c261c0663), [`0c96009`](https://github.com/wevm/wagmi/commit/0c96009398647a515a57f72ef25c32724f7c978c), [`b6cb8f4`](https://github.com/wevm/wagmi/commit/b6cb8f4cd15eb13073bc7e9ecb4bfa2c261c0663), [`ed13074`](https://github.com/wevm/wagmi/commit/ed130747c0f28c1d9980a1328883e4000a60455e), [`b6cb8f4`](https://github.com/wevm/wagmi/commit/b6cb8f4cd15eb13073bc7e9ecb4bfa2c261c0663), [`ab9ecaa`](https://github.com/wevm/wagmi/commit/ab9ecaa74dfa4324279e167dd7e348319ef7d35d), [`0c96009`](https://github.com/wevm/wagmi/commit/0c96009398647a515a57f72ef25c32724f7c978c), [`0c96009`](https://github.com/wevm/wagmi/commit/0c96009398647a515a57f72ef25c32724f7c978c), [`73d4d47`](https://github.com/wevm/wagmi/commit/73d4d47bc679f4f9a1cf46010fe2bf858c9d0b5c), [`0c96009`](https://github.com/wevm/wagmi/commit/0c96009398647a515a57f72ef25c32724f7c978c), [`0c96009`](https://github.com/wevm/wagmi/commit/0c96009398647a515a57f72ef25c32724f7c978c)]: + - @wagmi/core@0.6.0 + +## 0.6.8 + +### Patch Changes + +- [`0b77286b`](https://github.com/wevm/wagmi/commit/0b77286b89cb8603426cf5081872416c291a6531) Thanks [@jxom](https://github.com/jxom)! - Isolate wagmi's React Query `queryClient` instance. + +* [`8cb07462`](https://github.com/wevm/wagmi/commit/8cb07462acc3c5637398d11d2451f8b8e330d553) Thanks [@jxom](https://github.com/jxom)! - Added `chainId` as an argument to `watchBlockNumber`. + +- [`53c1a474`](https://github.com/wevm/wagmi/commit/53c1a4747d03b685e8cfbf55361fc2a56777fb06) Thanks [@tmm](https://github.com/tmm)! - Added missing `decimals` option to `Connector` `watchAsset` + +* [`4d74dd4f`](https://github.com/wevm/wagmi/commit/4d74dd4ff827ba5c43c3546a218f38cee45ea76a) Thanks [@jxom](https://github.com/jxom)! - Support ERC20 contracts that represent strings as bytes32 + +* Updated dependencies [[`8cb07462`](https://github.com/wevm/wagmi/commit/8cb07462acc3c5637398d11d2451f8b8e330d553), [`53c1a474`](https://github.com/wevm/wagmi/commit/53c1a4747d03b685e8cfbf55361fc2a56777fb06), [`4d74dd4f`](https://github.com/wevm/wagmi/commit/4d74dd4ff827ba5c43c3546a218f38cee45ea76a)]: + - @wagmi/core@0.5.8 + +## 0.6.7 + +### Patch Changes + +- [`aa51bc4d`](https://github.com/wevm/wagmi/commit/aa51bc4dc5683bf0178597d2fdb8f2e9d82e7970) Thanks [@jxom](https://github.com/jxom)! - Fixed an issue in `CoinbaseWalletConnector` where the browser extension would unintendedly reset the network when the browser is refreshed. + +* [#955](https://github.com/wevm/wagmi/pull/955) [`e326cd80`](https://github.com/wevm/wagmi/commit/e326cd80fe65267db623eb6c80ccdd75572914cf) Thanks [@0xFlicker](https://github.com/0xFlicker)! - Added Infura RPC URL for Sepolia + +- [`cec14089`](https://github.com/wevm/wagmi/commit/cec14089500c86687226ab272b4c3fcb85ae3d69) Thanks [@jxom](https://github.com/jxom)! - Fixed an issue where `useProvider` & `getProvider` were not returning referentially equal providers. + +* [`cec14089`](https://github.com/wevm/wagmi/commit/cec14089500c86687226ab272b4c3fcb85ae3d69) Thanks [@jxom](https://github.com/jxom)! - Fixed an issue where the `watch` option was not respecting the neighboring `chainId` option in `useBlockNumber`. + +- [`cec14089`](https://github.com/wevm/wagmi/commit/cec14089500c86687226ab272b4c3fcb85ae3d69) Thanks [@jxom](https://github.com/jxom)! - Fixed an issue where block listeners (via `watch`) were firing excessively on L2 chains. + +- Updated dependencies [[`aa51bc4d`](https://github.com/wevm/wagmi/commit/aa51bc4dc5683bf0178597d2fdb8f2e9d82e7970), [`e326cd80`](https://github.com/wevm/wagmi/commit/e326cd80fe65267db623eb6c80ccdd75572914cf), [`cec14089`](https://github.com/wevm/wagmi/commit/cec14089500c86687226ab272b4c3fcb85ae3d69), [`cec14089`](https://github.com/wevm/wagmi/commit/cec14089500c86687226ab272b4c3fcb85ae3d69), [`cec14089`](https://github.com/wevm/wagmi/commit/cec14089500c86687226ab272b4c3fcb85ae3d69)]: + - @wagmi/core@0.5.7 + +## 0.6.6 + +### Patch Changes + +- [#936](https://github.com/wevm/wagmi/pull/936) [`3329d1f`](https://github.com/wevm/wagmi/commit/3329d1f5880431566e14ac1640f48d0975aec4c2) Thanks [@jxom](https://github.com/jxom)! - Added the ability to provide a custom logger to override how logs are broadcasted to the consumer in wagmi. + + A custom logger can be provided to the wagmi client via `logger`. + + ### API + + ```tsx + logger?: { + warn: typeof console.warn | null + } + ``` + + ### Examples + + **Passing in a custom logger** + + You can pass in a function to define your own custom logger. + + ```diff + + import { logWarn } from './logger'; + + const client = createClient({ + ... + + logger: { + + warn: message => logWarn(message) + + } + ... + }) + ``` + + **Disabling a logger** + + You can disable a logger by passing `null` as the value. + + ```diff + const client = createClient({ + ... + + logger: { + + warn: null + + } + ... + }) + ``` + +* [#889](https://github.com/wevm/wagmi/pull/889) [`27788ed`](https://github.com/wevm/wagmi/commit/27788ed989b5dc26849c7945fb91a92e56766018) Thanks [@jxom](https://github.com/jxom)! - Make multicall & readContracts more error robust + +* Updated dependencies [[`3329d1f`](https://github.com/wevm/wagmi/commit/3329d1f5880431566e14ac1640f48d0975aec4c2), [`27788ed`](https://github.com/wevm/wagmi/commit/27788ed989b5dc26849c7945fb91a92e56766018)]: + - @wagmi/core@0.5.6 + +## 0.6.5 + +### Patch Changes + +- [#912](https://github.com/wevm/wagmi/pull/912) [`e529e12`](https://github.com/wevm/wagmi/commit/e529e125c713ed3ef24a59c6bf226fe4deee7ac9) Thanks [@zouhangwithsweet](https://github.com/zouhangwithsweet)! - Added BitKeep to injected flags + +- [#912](https://github.com/wevm/wagmi/pull/910) Thanks [@mytangying](https://github.com/zouhangwithsweet)! - Added MathWallet to injected flags + +- [#904](https://github.com/wevm/wagmi/pull/904) [`c231058`](https://github.com/wevm/wagmi/commit/c23105850f335f8798031e14c7098b7dee8c2975) Thanks [@jxom](https://github.com/jxom)! - Removed `contractInterface` & `signer` from persisted query keys. + +- Updated dependencies [[`e529e12`](https://github.com/wevm/wagmi/commit/e529e125c713ed3ef24a59c6bf226fe4deee7ac9), [`c231058`](https://github.com/wevm/wagmi/commit/c23105850f335f8798031e14c7098b7dee8c2975)]: + - @wagmi/core@0.5.5 + +## 0.6.4 + +### Patch Changes + +- [#852](https://github.com/wevm/wagmi/pull/852) [`c3192d0`](https://github.com/wevm/wagmi/commit/c3192d0663aa332ae9edfd9dd49b333454013ab7) Thanks [@skeithc](https://github.com/skeithc)! - Added support for the Sepolia testnet + +- Updated dependencies [[`c3192d0`](https://github.com/wevm/wagmi/commit/c3192d0663aa332ae9edfd9dd49b333454013ab7)]: + - @wagmi/core@0.5.4 + +## 0.6.3 + +### Patch Changes + +- [#835](https://github.com/wevm/wagmi/pull/835) [`1b85e54`](https://github.com/wevm/wagmi/commit/1b85e54ae654e2564cf5bc2dae6411fe0a25875c) Thanks [@jxom](https://github.com/jxom)! - Update `@coinbase/wallet-sdk` to `3.4.1` + +* [#843](https://github.com/wevm/wagmi/pull/843) [`e77dee6`](https://github.com/wevm/wagmi/commit/e77dee6a606b8aac4279569c54cec8902476fee9) Thanks [@tmm](https://github.com/tmm)! - Fix `MockConnector` entrypoint path + +- [#834](https://github.com/wevm/wagmi/pull/834) [`9655879`](https://github.com/wevm/wagmi/commit/96558793b0319df47aefafa6b7b9c959068d491b) Thanks [@jxom](https://github.com/jxom)! - Update zustand to `4.0.0` + +* [#833](https://github.com/wevm/wagmi/pull/833) [`3ae6d0f`](https://github.com/wevm/wagmi/commit/3ae6d0f5e2d65432024272b43afe68a8f63bb7ea) Thanks [@jxom](https://github.com/jxom)! - Updated `react-query@4.0.0-beta.23` to `@tanstack/react-query@^4.0.10` + +* Updated dependencies [[`1b85e54`](https://github.com/wevm/wagmi/commit/1b85e54ae654e2564cf5bc2dae6411fe0a25875c), [`9655879`](https://github.com/wevm/wagmi/commit/96558793b0319df47aefafa6b7b9c959068d491b)]: + - @wagmi/core@0.5.3 + +## 0.6.2 + +### Patch Changes + +- [#823](https://github.com/wevm/wagmi/pull/823) [`10b8b78`](https://github.com/wevm/wagmi/commit/10b8b78605b7246b2c55b8d69f96663906e5cd20) Thanks [@tmm](https://github.com/tmm)! - Add Optimism Goerli to `chain` lookup. + +- Updated dependencies [[`10b8b78`](https://github.com/wevm/wagmi/commit/10b8b78605b7246b2c55b8d69f96663906e5cd20)]: + - @wagmi/core@0.5.2 + +## 0.6.1 + +### Patch Changes + +- [#767](https://github.com/wevm/wagmi/pull/767) [`e9392f3`](https://github.com/wevm/wagmi/commit/e9392f396e48e928bd9d2522e3ad671c589f08cb) Thanks [@klyap](https://github.com/klyap)! - Add Optimism Goerli chain ahead of [Kovan deprecation](https://dev.optimism.io/kovan-to-goerli). + +* [#817](https://github.com/wevm/wagmi/pull/817) [`7e5cac7`](https://github.com/wevm/wagmi/commit/7e5cac75815dcd8aa563462342a4853fc5207735) Thanks [@alecananian](https://github.com/alecananian)! - Added custom name mapping for 1inch Wallet injected provider + +- [#806](https://github.com/wevm/wagmi/pull/806) [`0b34e56`](https://github.com/wevm/wagmi/commit/0b34e56db97e6dcdb71088e0149b2d55ebc604a5) Thanks [@vmichalik](https://github.com/vmichalik)! - Fix canonical testnet native asset symbols by changing them to ETH + +* [#778](https://github.com/wevm/wagmi/pull/778) [`0892908`](https://github.com/wevm/wagmi/commit/08929084eeeba1a3a55aa098fa9d92a243685ad5) Thanks [@0xcadams](https://github.com/0xcadams)! - Add Arbitrum Goerli chain. + +* Updated dependencies [[`e9392f3`](https://github.com/wevm/wagmi/commit/e9392f396e48e928bd9d2522e3ad671c589f08cb), [`7e5cac7`](https://github.com/wevm/wagmi/commit/7e5cac75815dcd8aa563462342a4853fc5207735), [`0b34e56`](https://github.com/wevm/wagmi/commit/0b34e56db97e6dcdb71088e0149b2d55ebc604a5), [`0892908`](https://github.com/wevm/wagmi/commit/08929084eeeba1a3a55aa098fa9d92a243685ad5)]: + - @wagmi/core@0.5.1 + +## 0.6.0 + +### Minor Changes + +- [#658](https://github.com/wevm/wagmi/pull/658) [`d70c115`](https://github.com/wevm/wagmi/commit/d70c115131f299fb61f87867b6ac4218e0bcf432) Thanks [@jxom](https://github.com/jxom)! - **Breaking:** The `useSendTransaction` hook's `data` now returns an object only consisting of `hash` & `wait`, and not the full [`TransactionResponse`](https://docs.ethers.io/v5/api/providers/types/#providers-TransactionResponse). + + If you require the full `TransactionResponse`, you can use `useTransaction`: + + ```diff + import { useSendTransaction, useTransaction } from 'wagmi' + + const { + data: { + hash, + wait, + - ...transaction + } + } = useSendTransaction(...) + + +const { data: transaction } = useTransaction({ hash }) + ``` + + > Why? The old implementation of `useSendTransaction` created a long-running async task, causing [UX pitfalls](https://wagmi.sh/docs/prepare-hooks#ux-pitfalls-without-prepare-hooks) when invoked in a click handler. + +* [#658](https://github.com/wevm/wagmi/pull/658) [`d70c115`](https://github.com/wevm/wagmi/commit/d70c115131f299fb61f87867b6ac4218e0bcf432) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: The configuration passed to the `useSendTransaction` hook now needs to be either: + + - prepared with the `usePrepareSendTransaction` hook **(new)**, or + - recklessly unprepared **(previous functionality)** + + > Why? [Read here](https://wagmi.sh/docs/prepare-hooks) + + ### Prepared usage + + ```diff + import { usePrepareSendTransaction, useSendTransaction } from 'wagmi' + + +const { config } = usePrepareSendTransaction({ + + request: { + + to: 'moxey.eth', + + value: parseEther('1'), + + } + +}) + + const { data } = useSendTransaction({ + - request: { + - to: 'moxey.eth', + - value: parseEther('1') + - } + + ...config + }) + ``` + + ### Recklessly unprepared usage + + If you are not ready to upgrade to `usePrepareSendTransaction`, it is possible to use `useSendTransaction` without preparing the configuration first by passing `mode: 'recklesslyUnprepared'`. + + ```diff + import { useSendTransaction } from 'wagmi' + + const { data } = useSendTransaction({ + + mode: 'recklesslyUnprepared', + request: { + to: 'moxey.eth', + value: parseEther('1'), + } + }) + ``` + +- [#658](https://github.com/wevm/wagmi/pull/658) [`d70c115`](https://github.com/wevm/wagmi/commit/d70c115131f299fb61f87867b6ac4218e0bcf432) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: If a `chainId` is passed to `useContractWrite` or `useSendTransaction`, it will no longer attempt to switch chain before sending the transaction. Instead, it will throw an error if the user is on the wrong chain. + + > Why? Eagerly prompting to switch chain in these actions created a long-running async task that that makes [iOS App Links](https://wagmi.sh/docs/prepare-hooks#ios-app-link-constraints) vulnerable. + +* [#760](https://github.com/wevm/wagmi/pull/760) [`d8af6bf`](https://github.com/wevm/wagmi/commit/d8af6bf50885aec110ae4d64716642453aa27896) Thanks [@tmm](https://github.com/tmm)! - **Breaking:** `alchemyProvider` and `infuraProvider` now use a generic `apiKey` configuration option instead of `alchemyId` and `infuraId`. + + ```diff + import { alchemyProvider } from '@wagmi/core/providers/alchemy' + import { infuraProvider } from '@wagmi/core/providers/infura' + + alchemyProvider({ + - alchemyId: 'yourAlchemyApiKey', + + apiKey: 'yourAlchemyApiKey', + }) + + infuraProvider({ + - infuraId: 'yourInfuraApiKey', + + apiKey: 'yourInfuraApiKey', + }) + ``` + +- [#658](https://github.com/wevm/wagmi/pull/658) [`d70c115`](https://github.com/wevm/wagmi/commit/d70c115131f299fb61f87867b6ac4218e0bcf432) Thanks [@jxom](https://github.com/jxom)! - Added the `usePrepareContractWrite` hook that eagerly fetches the parameters required for sending a contract write transaction such as the gas estimate. + + It returns config to be passed through to `useContractWrite`. + + ```ts + const { config } = usePrepareContractWrite({ + addressOrName: "0xecb504d39723b0be0e3a9aa33d646642d1051ee1", + contractInterface: wagmigotchiABI, + functionName: "feed", + }); + const { write } = useContractWrite(config); + ``` + +* [#658](https://github.com/wevm/wagmi/pull/658) [`d70c115`](https://github.com/wevm/wagmi/commit/d70c115131f299fb61f87867b6ac4218e0bcf432) Thanks [@jxom](https://github.com/jxom)! - **Breaking:** When `useSendTransaction` is in "prepare mode" (used with `usePrepareSendTransaction`), `sendTransaction`/`sendTransactionAsync` will be `undefined` until the configuration has been prepared. Ensure that your usage reflects this. + + ```tsx + const { config } = usePrepareSendTransaction({ ... }) + const { sendTransaction } = useSendTransaction(config) + + + ``` + +- [#658](https://github.com/wevm/wagmi/pull/658) [`d70c115`](https://github.com/wevm/wagmi/commit/d70c115131f299fb61f87867b6ac4218e0bcf432) Thanks [@jxom](https://github.com/jxom)! - Added the `usePrepareSendTransaction` hook that eagerly fetches the parameters required for sending a transaction such as the gas estimate and resolving an ENS address (if required). + + It returns config to be passed through to `useSendTransaction`. + + ```ts + import { usePrepareSendTransaction, useSendTransaction } from "@wagmi/core"; + + const { config } = usePrepareSendTransaction({ + request: { + to: "moxey.eth", + value: parseEther("1"), + }, + }); + const { sendTransaction } = useSendTransaction(config); + ``` + +* [#658](https://github.com/wevm/wagmi/pull/658) [`d70c115`](https://github.com/wevm/wagmi/commit/d70c115131f299fb61f87867b6ac4218e0bcf432) Thanks [@jxom](https://github.com/jxom)! - **Breaking:** The `sendTransaction`/`sendTransactionAsync` configuration object has now been altered to only accept "reckless" configuration. If one or more of these values are set, it can lead to [UX pitfalls](https://wagmi.sh/docs/prepare-hooks#ux-pitfalls-without-prepare-hooks). + + ```diff + + ``` + +- [#727](https://github.com/wevm/wagmi/pull/727) [`ac3b9b8`](https://github.com/wevm/wagmi/commit/ac3b9b87f80cb45b65d003f09d916d7d1427a62e) Thanks [@tmm](https://github.com/tmm)! - **Breaking**: Moved the `pollingInterval` config option from the chain provider config to `configureChains` config. + + ```diff + const { chains, provider } = configureChains( + [chain.mainnet, chain.polygon], + [ + - alchemyProvider({ apiKey, pollingInterval: 5000 }), + - publicProvider({ pollingInterval: 5000 }) + + alchemyProvider({ apiKey }), + + publicProvider() + ], + + { pollingInterval: 5000 } + ) + ``` + +* [#658](https://github.com/wevm/wagmi/pull/658) [`d70c115`](https://github.com/wevm/wagmi/commit/d70c115131f299fb61f87867b6ac4218e0bcf432) Thanks [@jxom](https://github.com/jxom)! - **Breaking:** When `useContractWrite` is in "prepare mode" (used with `usePrepareContractWrite`), `write`/`writeAsync` will be `undefined` until the configuration has been prepared. Ensure that your usage reflects this. + + ```tsx + const { config } = usePrepareContractWrite({ ... }) + const { write } = useContractWrite(config) + + + ``` + +- [#658](https://github.com/wevm/wagmi/pull/658) [`d70c115`](https://github.com/wevm/wagmi/commit/d70c115131f299fb61f87867b6ac4218e0bcf432) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: The configuration passed to the `useContractWrite` hook now needs to be either: + + - prepared with the `usePrepareContractWrite` hook **(new)**, or + - recklessly unprepared **(previous functionality)** + + > Why? [Read here](https://wagmi.sh/docs/prepare-hooks) + + ### Prepared usage + + ```diff + import { usePrepareContractWrite, useContractWrite } from 'wagmi' + + +const { config } = usePrepareContractWrite({ + + addressOrName: '0x...', + + contractInterface: wagmiAbi, + + functionName: 'mint', + + args: [tokenId] + +}) + + const { data } = useContractWrite({ + - addressOrName: '0x...', + - contractInterface: wagmiAbi, + - functionName: 'mint', + - args: [tokenId], + + ...config + }) + ``` + + ### Recklessly unprepared usage + + If you are not ready to upgrade to `usePrepareContractWrite`, it is possible to use `useContractWrite` without preparing the configuration first by passing `mode: 'recklesslyUnprepared'`. + + ```diff + import { useContractWrite } from 'wagmi' + + const { data } = useContractWrite({ + + mode: 'recklesslyUnprepared', + addressOrName: '0x...', + contractInterface: wagmiAbi, + functionName: 'mint', + args: [tokenId], + }) + ``` + +### Patch Changes + +- [#733](https://github.com/wevm/wagmi/pull/733) [`6232487`](https://github.com/wevm/wagmi/commit/623248703bc728d539e28bf8a89b8ab22f0a5703) Thanks [@tmm](https://github.com/tmm)! - Add mock connector entrypoint + +* [#762](https://github.com/wevm/wagmi/pull/762) [`ccaeed5`](https://github.com/wevm/wagmi/commit/ccaeed53d731f51879e0cdd5648797a32f7d7a31) Thanks [@jxom](https://github.com/jxom)! - Fix `useContractRead` return value unexpectedly returning null for falsy values + +- [#734](https://github.com/wevm/wagmi/pull/734) [`7c2fa04`](https://github.com/wevm/wagmi/commit/7c2fa04e9b695840d6fa088e1f8d069f3c916551) Thanks [@jxom](https://github.com/jxom)! - Fix issue where `useProvider` & `useWebSocketProvider` would not update when `chainId` config changes + +* [#739](https://github.com/wevm/wagmi/pull/739) [`c2295a5`](https://github.com/wevm/wagmi/commit/c2295a56cc86d02cc6602e2b4557b8ab9a091a3f) Thanks [@tmm](https://github.com/tmm)! - Fix balance formatting for tokens that do not have 18 decimals. + +- [#759](https://github.com/wevm/wagmi/pull/759) [`959953d`](https://github.com/wevm/wagmi/commit/959953d1f5b3e8189bac56de245c62333470d18e) Thanks [@tmm](https://github.com/tmm)! - Added `useTransaction` hook: + + ```ts + import { useTransaction } from "wagmi"; + + const result = useTransaction({ + hash: "0x5c504ed432cb51138bcf09aa5e8a410dd4a1e204ef84bfed1be16dfba1b22060", + }); + ``` + +- Updated dependencies [[`d70c115`](https://github.com/wevm/wagmi/commit/d70c115131f299fb61f87867b6ac4218e0bcf432), [`d70c115`](https://github.com/wevm/wagmi/commit/d70c115131f299fb61f87867b6ac4218e0bcf432), [`d70c115`](https://github.com/wevm/wagmi/commit/d70c115131f299fb61f87867b6ac4218e0bcf432), [`d8af6bf`](https://github.com/wevm/wagmi/commit/d8af6bf50885aec110ae4d64716642453aa27896), [`d70c115`](https://github.com/wevm/wagmi/commit/d70c115131f299fb61f87867b6ac4218e0bcf432), [`c2295a5`](https://github.com/wevm/wagmi/commit/c2295a56cc86d02cc6602e2b4557b8ab9a091a3f), [`ac3b9b8`](https://github.com/wevm/wagmi/commit/ac3b9b87f80cb45b65d003f09d916d7d1427a62e), [`d70c115`](https://github.com/wevm/wagmi/commit/d70c115131f299fb61f87867b6ac4218e0bcf432), [`d70c115`](https://github.com/wevm/wagmi/commit/d70c115131f299fb61f87867b6ac4218e0bcf432), [`959953d`](https://github.com/wevm/wagmi/commit/959953d1f5b3e8189bac56de245c62333470d18e)]: + - @wagmi/core@0.5.0 + +## 0.5.11 + +### Patch Changes + +- [`4c7d123`](https://github.com/wevm/wagmi/commit/4c7d123c8e74f93e770096857eb8c40ce0a47681) Thanks [@jxom](https://github.com/jxom)! - Fix issue where `useProvider` & `useWebSocketProvider` would not update when `chainId` config changes + +## 0.5.10 + +### Patch Changes + +- [#713](https://github.com/tmm/wagmi/pull/713) [`08b0113`](https://github.com/tmm/wagmi/commit/08b0113bef9f32dceab2ecd823b1ee00f9bdc45d) Thanks [@jxom](https://github.com/jxom)! - Fix an issue where the `useContractRead` query function could return `undefined` instead of a serializable `null`. + +* [#725](https://github.com/tmm/wagmi/pull/725) [`b976920`](https://github.com/tmm/wagmi/commit/b97692051d778d7e112872663832c97963a8029a) Thanks [@tmm](https://github.com/tmm)! - Lock `react-query` version + +- [#721](https://github.com/tmm/wagmi/pull/721) [`abea25f`](https://github.com/tmm/wagmi/commit/abea25fd15d81d1ecaec9d3fbd687042ab29b1e6) Thanks [@tmm](https://github.com/tmm)! - Add `name` to `useToken` `data` value. + +- Updated dependencies [[`abea25f`](https://github.com/tmm/wagmi/commit/abea25fd15d81d1ecaec9d3fbd687042ab29b1e6), [`abea25f`](https://github.com/tmm/wagmi/commit/abea25fd15d81d1ecaec9d3fbd687042ab29b1e6)]: + - @wagmi/core@0.4.9 + +## 0.5.9 + +### Patch Changes + +- [#677](https://github.com/tmm/wagmi/pull/677) [`35e4219`](https://github.com/tmm/wagmi/commit/35e42199af9dd346549c1718e144728f55b8d7dd) Thanks [@jxom](https://github.com/jxom)! - Move `parseContractResult` to `@wagmi/core` + +* [#677](https://github.com/tmm/wagmi/pull/677) [`35e4219`](https://github.com/tmm/wagmi/commit/35e42199af9dd346549c1718e144728f55b8d7dd) Thanks [@jxom](https://github.com/jxom)! - Parse tuples correctly in `parseContractResult` + +* Updated dependencies [[`35e4219`](https://github.com/tmm/wagmi/commit/35e42199af9dd346549c1718e144728f55b8d7dd)]: + - @wagmi/core@0.4.7 + +## 0.5.8 + +### Patch Changes + +- [#670](https://github.com/tmm/wagmi/pull/670) [`29a0d21`](https://github.com/tmm/wagmi/commit/29a0d21ee83995559f63542778dfa805f15e7441) Thanks [@tmm](https://github.com/tmm)! - Fix broken release not containing `deepEqual` from `@wagmi/core`. + +- Updated dependencies [[`29a0d21`](https://github.com/tmm/wagmi/commit/29a0d21ee83995559f63542778dfa805f15e7441)]: + - @wagmi/core@0.4.6 + +## 0.5.7 + +### Patch Changes + +- [#659](https://github.com/tmm/wagmi/pull/659) [`be76586`](https://github.com/tmm/wagmi/commit/be76586431238dc5a0970a6f10a3dff9faa8ca2d) Thanks [@jxom](https://github.com/jxom)! - Added an `isDataEqual` config option to `useContractRead`, `useContractReads` & `useContractInfiniteReads` to define whether or not that data has changed. Defaults to `deepEqual`. + +* [#659](https://github.com/tmm/wagmi/pull/659) [`be76586`](https://github.com/tmm/wagmi/commit/be76586431238dc5a0970a6f10a3dff9faa8ca2d) Thanks [@jxom](https://github.com/jxom)! - Added `onBlock` config to `useBlockNumber` + +- [#659](https://github.com/tmm/wagmi/pull/659) [`be76586`](https://github.com/tmm/wagmi/commit/be76586431238dc5a0970a6f10a3dff9faa8ca2d) Thanks [@jxom](https://github.com/jxom)! - Fixed an issue where `useContractRead` & `useContractReads` would return unstable data. + +## 0.5.6 + +### Patch Changes + +- [#654](https://github.com/tmm/wagmi/pull/654) [`e66530b`](https://github.com/tmm/wagmi/commit/e66530bf4881b3533c528f8c5a5f41be0eab0a64) Thanks [@jxom](https://github.com/jxom)! - omit `contractInterface` from `useContractRead` & `useContractReads` query key hash + +* [#654](https://github.com/tmm/wagmi/pull/654) [`e66530b`](https://github.com/tmm/wagmi/commit/e66530bf4881b3533c528f8c5a5f41be0eab0a64) Thanks [@jxom](https://github.com/jxom)! - fix `multicall` returning nullish data for all calls unexpectedly + +* Updated dependencies [[`e66530b`](https://github.com/tmm/wagmi/commit/e66530bf4881b3533c528f8c5a5f41be0eab0a64)]: + - @wagmi/core@0.4.5 + +## 0.5.5 + +### Patch Changes + +- [#629](https://github.com/tmm/wagmi/pull/629) [`199db71`](https://github.com/tmm/wagmi/commit/199db7165eed43d36cb882d373f95e7c49212f23) Thanks [@jxom](https://github.com/jxom)! - Add `wagmi/actions` entrypoint that exports imperative `@wagmi/core` actions + +* [#616](https://github.com/tmm/wagmi/pull/616) [`7a7a17a`](https://github.com/tmm/wagmi/commit/7a7a17a46d4c9e6465cc46a111b5fe8a56109f1b) Thanks [@tmm](https://github.com/tmm)! - Adds `UNSTABLE_shimOnConnectSelectAccount` flag. With this flag and "disconnected" with `shimDisconnect` enabled, the user is prompted to select a different MetaMask account (than the currently connected account) when trying to connect (e.g. `useConnect`/`connect` action). + +* Updated dependencies [[`7a7a17a`](https://github.com/tmm/wagmi/commit/7a7a17a46d4c9e6465cc46a111b5fe8a56109f1b)]: + - @wagmi/core@0.4.4 + +## 0.5.4 + +### Patch Changes + +- [#631](https://github.com/tmm/wagmi/pull/631) [`a780e32`](https://github.com/tmm/wagmi/commit/a780e32e91a0072c795fa0b5a6111302768e2a01) Thanks [@tmm](https://github.com/tmm)! - Fix WalletConnect stale session + +- Updated dependencies [[`a780e32`](https://github.com/tmm/wagmi/commit/a780e32e91a0072c795fa0b5a6111302768e2a01)]: + - @wagmi/core@0.4.3 + +## 0.5.3 + +### Patch Changes + +- [#627](https://github.com/tmm/wagmi/pull/627) [`5985530`](https://github.com/tmm/wagmi/commit/59855301d138313e83a607b3f05053e9f46a78a8) Thanks [@jxom](https://github.com/jxom)! - equalityFn in `useSyncExternalStoreWithTracked` should return truthy when there are no tracked keys. + +## 0.5.2 + +### Patch Changes + +- [#624](https://github.com/tmm/wagmi/pull/624) [`416fa7e`](https://github.com/tmm/wagmi/commit/416fa7ee1f8019ab86e33fb93783ffddecc02c49) Thanks [@jxom](https://github.com/jxom)! - Fix broken `WebSocketProvider` type defs + +- Updated dependencies [[`416fa7e`](https://github.com/tmm/wagmi/commit/416fa7ee1f8019ab86e33fb93783ffddecc02c49)]: + - @wagmi/core@0.4.2 + +## 0.5.1 + +### Patch Changes + +- [#622](https://github.com/tmm/wagmi/pull/622) [`d171581`](https://github.com/tmm/wagmi/commit/d171581464891dd870d97b6232205da0cb152d9b) Thanks [@tmm](https://github.com/tmm)! - Use `domain.chainId` to validate and switch chain before signing in `useSignTypedData`. + +* [#618](https://github.com/tmm/wagmi/pull/618) [`a5138e8`](https://github.com/tmm/wagmi/commit/a5138e82a00e4d9469ad78c97b2d34200d7f1fbe) Thanks [@tmm](https://github.com/tmm)! - Fix adding chains when using MetaMask mobile app, add `publicRpcUrls` constant, and default to public endpoint when adding chain. + +* Updated dependencies [[`d171581`](https://github.com/tmm/wagmi/commit/d171581464891dd870d97b6232205da0cb152d9b), [`a5138e8`](https://github.com/tmm/wagmi/commit/a5138e82a00e4d9469ad78c97b2d34200d7f1fbe)]: + - @wagmi/core@0.4.1 + +## 0.5.0 + +### Minor Changes + +- [`fc94210`](https://github.com/tmm/wagmi/commit/fc94210b67daa91aa164625dfe189d5b6c2f92d4) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: The `useContractWrite` hook parameters have been consolidated into a singular config parameter. + + Before: + + ```tsx + useContractWrite( + { + addressOrName: mlootContractAddress, + contractInterface: mlootABI, + }, + "claim", + ); + ``` + + After: + + ```tsx + useContractWrite({ + addressOrName: mlootContractAddress, + contractInterface: mlootABI, + functionName: "claim", + }); + ``` + +* [`fc94210`](https://github.com/tmm/wagmi/commit/fc94210b67daa91aa164625dfe189d5b6c2f92d4) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: The `useContractEvent` hook parameters have been consolidated into a singular config parameter. + + Before: + + ```tsx + useContractEvent( + { + addressOrName: uniContractAddress, + contractInterface: erc20ABI, + }, + 'Transfer', + listener, + ), + ``` + + After: + + ```tsx + useContractEvent({ + addressOrName: uniContractAddress, + contractInterface: erc20ABI, + eventName: "Transfer", + listener, + }); + ``` + +- [`fc94210`](https://github.com/tmm/wagmi/commit/fc94210b67daa91aa164625dfe189d5b6c2f92d4) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: The `client` prop is now required on `WagmiConfig`. + + ````diff + ```tsx + import { + createClient, + + configureChains, + + defaultChains + } from 'wagmi' + +import { publicProvider } from 'wagmi/providers/public' + + +const { provider, webSocketProvider } = configureChains(defaultChains, [ + + publicProvider(), + +]) + + +const client = createClient({ + + provider, + + webSocketProvider, + +}) + + function App() { + return ( + + + + ) + } + ```` + +* [`fc94210`](https://github.com/tmm/wagmi/commit/fc94210b67daa91aa164625dfe189d5b6c2f92d4) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: The `provider` config option is now required on `createClient`. It is recommended to pass the [`provider` given from `configureChains`](https://wagmi.sh/docs/providers/configuring-chains). + + ```diff + import { + createClient, + + defaultChains, + + configureChains + } from 'wagmi' + +import { publicProvider } from 'wagmi/providers/publicProvider' + + +const { provider } = configureChains(defaultChains, [ + + publicProvider + +]) + + const client = createClient({ + + provider + }) + ``` + + If you previously used an ethers.js Provider, you now need to provide your `chains` on the Provider instance: + + ```diff + import { + createClient, + + defaultChains + } from 'wagmi' + import ethers from 'ethers' + + const client = createClient({ + - provider: getDefaultProvider() + + provider: Object.assign(getDefaultProvider(), { chains: defaultChains }) + }) + ``` + +- [`4f8f3c0`](https://github.com/tmm/wagmi/commit/4f8f3c0d65383bd8bbdfc3f1033adfdb11d80ebb) Thanks [@nachoiacovino](https://github.com/nachoiacovino)! - Use ethereum-lists chains symbols + +* [#582](https://github.com/tmm/wagmi/pull/582) [`b03830a`](https://github.com/tmm/wagmi/commit/b03830a54465215c2526f9509543fe2c978bfe70) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: The following changes were made to the `useAccount` return value: + + ### The `data` value is now `address` & `connector` + + ```diff + { + - data?: { + - address: string + - connector: Connector + - } + + address?: string + + connector?: Connector + } + ``` + + ### Global connection status values have been added + + The following global connection status values have been added: + + ```diff + { + + isConnecting: boolean + + isReconnecting: boolean + + isConnected: boolean + + isDisconnected: boolean + + status: 'connecting' | 'reconnecting' | 'connected' | 'disconnected' + } + ``` + + The `useAccount` hook is now aware of any connection event in your application, so now you can use these connection status values to determine if your user is connected, disconnected or connecting to a wallet on a global scope. + + ### `error`, states & `refetch` values have been removed + + Since the `useAccount` hook never dealt with asynchronous data, all of these values were + redundant & unused. + + ```diff + { + - error?: Error + - isIdle: boolean + - isLoading: boolean + - isFetching: boolean + - isSuccess: boolean + - isError: boolean + - isFetched: boolean + - isRefetching: boolean + - refetch: (options: { + - throwOnError: boolean + - cancelRefetch: boolean + - }) => Promise<{ + - address: string + - connector: Connector + - }> + - status: 'idle' | 'error' | 'loading' | 'success' + } + ``` + + ### Summary of changes + + Below is the whole diff of changes to the `useAccount` return value. + + ```diff + { + - data?: { + - address: string + - connector: Connector + - } + + address?: string + + connector?: Connector + - error?: Error + - isIdle: boolean + - isLoading: boolean + - isFetching: boolean + - isSuccess: boolean + - isError: boolean + - isFetched: boolean + - isRefetching: boolean + + isConnecting: boolean + + isReconnecting: boolean + + isConnected: boolean + + isDisconnected: boolean + - refetch: (options: { + - throwOnError: boolean + - cancelRefetch: boolean + - }) => Promise<{ + - address: string + - connector: Connector + - }> + - status: 'idle' | 'error' | 'loading' | 'success' + + status: 'connecting' | 'reconnecting' | 'connected' | 'disconnected' + } + ``` + +- [`fc94210`](https://github.com/tmm/wagmi/commit/fc94210b67daa91aa164625dfe189d5b6c2f92d4) Thanks [@jxom](https://github.com/jxom)! - **Breaking:** Removed the `chainId` parameter from `connectors` function on `createClient`. + + ```diff + const client = createClient({ + - connectors({ chainId }) { + + connectors() { + ... + } + }) + ``` + + If you previously derived RPC URLs from the `chainId` on `connectors`, you can now remove that logic as `wagmi` now handles RPC URLs internally when used with `configureChains`. + + ```diff + import { + chain, + + configureChains, + createClient + } from 'wagmi'; + + +import { publicProvider } from 'wagmi/providers/public' + + import { CoinbaseWalletConnector } from 'wagmi/connectors/coinbaseWallet' + import { InjectedConnector } from 'wagmi/connectors/injected' + import { MetaMaskConnector } from 'wagmi/connectors/metaMask' + import { WalletConnectConnector } from 'wagmi/connectors/walletConnect' + + +const { chains } = configureChains( + + [chain.mainnet], + + [publicProvider()] + +); + + const client = createClient({ + - connectors({ chainId }) { + - const chain = chains.find((x) => x.id === chainId) ?? defaultChain + - const rpcUrl = chain.rpcUrls.alchemy + - ? `${chain.rpcUrls.alchemy}/${alchemyId}` + - : chain.rpcUrls.default + - return [ + + connectors: [ + new MetaMaskConnector({ chains }), + new CoinbaseWalletConnector({ + chains, + options: { + appName: 'wagmi', + - chainId: chain.id, + - jsonRpcUrl: rpcUrl, + }, + }), + new WalletConnectConnector({ + chains, + options: { + qrcode: true, + - rpc: { [chain.id]: rpcUrl }, + }, + }), + new InjectedConnector({ + chains, + options: { name: 'Injected' }, + }), + ] + - }, + }) + ``` + +* [#596](https://github.com/tmm/wagmi/pull/596) [`a770af7`](https://github.com/tmm/wagmi/commit/a770af7d2cb214b6620d5341115f1e938e1e77ff) Thanks [@tmm](https://github.com/tmm)! - **Breaking**: `TypedDataDomain` and `TypedDataField` types were removed and incorporated into `SignTypedDataArgs`. + +- [#582](https://github.com/tmm/wagmi/pull/582) [`b03830a`](https://github.com/tmm/wagmi/commit/b03830a54465215c2526f9509543fe2c978bfe70) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: The following changes were made to the `useAccount` configuration: + + ## `onConnect` has been added + + The `onConnect` callback is invoked when the account connects. + + It provides the connected address & connector, as well as a `isReconnected` flag for if the user reconnected via `autoConnect`. + + ```tsx + const account = useAccount({ + onConnect({ address, connector, isReconnected }) { + console.log("Connected"); + }, + }); + ``` + + ## `onDisconnect` has been added + + The `onDisconnect` callback is invoked when the account disconnected. + + ```tsx + const account = useAccount({ + onDisconnect() { + console.log("Disconnected"); + }, + }); + ``` + + ## `suspense` has been removed + + The `useAccount` hook is a synchronous hook – so `suspense` never worked. + + ```diff + const account = useAccount({ + - suspense: true, + }) + ``` + + ## `onError` has been removed + + The `useAccount` hook never had any error definitions – so `onError` was never invoked. + + ```diff + const account = useAccount({ + - onError(error) { + - console.log('Error', error) + - }, + }) + ``` + + ## `onSettled` has been removed + + The `useAccount` hook is a synchronous hook. `onSettled` was always invoked immediately. + + ```diff + const account = useAccount({ + - onSettled(data) { + - console.log('Settled', data) + - }, + }) + ``` + + If you used `onSettled`, you can move the code beneath the `useAccount` hook: + + ```diff + const account = useAccount({ + - onSettled(data) { + - console.log('Address:', data.address) + - }, + }) + + console.log('Address:', account.address) + ``` + + ## `onSuccess` has been removed + + The `useAccount` hook is a synchronous hook. `onSuccess` was always invoked immediately. + + ```diff + const account = useAccount({ + - onSuccess(data) { + - console.log('Success', data) + - }, + }) + ``` + + If you used `onSuccess`, you can move the code beneath the `useAccount` hook: + + ```diff + const account = useAccount({ + - onSuccess(data) { + - console.log('Address:', data.address) + - }, + }) + + console.log('Address:', account.address) + ``` + +* [#582](https://github.com/tmm/wagmi/pull/582) [`b03830a`](https://github.com/tmm/wagmi/commit/b03830a54465215c2526f9509543fe2c978bfe70) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: The following changes were made to the `useConnect` return value: + + ### Connection status flags have been moved + + The `isConnected`, `isConnecting`, `isReconnecting` & `isDisconnected` flags have been moved to the `useAccount` hook. + + ```diff + -import { useConnect } from 'wagmi' + +import { useAccount } from 'wagmi' + + function App() { + const { + isConnected, + isConnecting, + isConnecting, + isDisconnected + - } = useConnect() + + } = useAccount() + } + ``` + + ### New `connect` mutation status flags have been added + + The `isLoading`, `isSuccess` and `isError` flags have been added to `useConnect`. + + These flags represent the **local** async state of `useConnect`. + + ### `activeConnector` has been removed + + The `activeConnector` value has been removed. You can find the active connector on `useAccount`. + + ```diff + -import { useConnect } from 'wagmi' + +import { useAccount } from 'wagmi' + + function App() { + - const { activeConnector } = useConnect() + + const { connector } = useAccount() + } + ``` + +- [#582](https://github.com/tmm/wagmi/pull/582) [`b03830a`](https://github.com/tmm/wagmi/commit/b03830a54465215c2526f9509543fe2c978bfe70) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: The following changes were made to the `useConnect` configuration: + + ### `onBeforeConnect` has been renamed + + The `onBeforeConnect` callback has been renamed to `onMutate` + + ### `onConnect` has been renamed + + The `onConnect` callback has been renamed to `onSuccess` + +* [#582](https://github.com/tmm/wagmi/pull/582) [`b03830a`](https://github.com/tmm/wagmi/commit/b03830a54465215c2526f9509543fe2c978bfe70) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: The `connector` parameter to `connect` & `connectAsync` now has to be in the config object parameter shape. + + ```diff + import { useConnect } from 'wagmi' + + function App() { + const { connect, connectors } = useConnect() + + return ( + + ) + } + ``` + +- [#582](https://github.com/tmm/wagmi/pull/582) [`b03830a`](https://github.com/tmm/wagmi/commit/b03830a54465215c2526f9509543fe2c978bfe70) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: The "switch network" functionality has been moved out of `useNetwork` into a new `useSwitchNetwork` hook. + + The `useNetwork` hook now accepts no configuration and only returns `chain` (renamed from `activeChain`) and `chains`. + + ```diff + import { + useNetwork + + useSwitchNetwork + } from 'wagmi' + + const { + - activeChain + + chain, + chains, + - data, + - error, + - isError, + - isIdle, + - isLoading, + - isSuccess, + - pendingChainId, + - switchNetwork, + - switchNetworkAsync, + - status, + - reset, + -} = useNetwork({ + - chainId: 69, + - onError(error) {}, + - onMutate(args) {}, + - onSettled(data, error) {}, + - onSuccess(data) {} + -}) + +} = useNetwork() + + +const { + + data, + + error, + + isError, + + isIdle, + + isLoading, + + isSuccess, + + pendingChainId, + + switchNetwork, + + switchNetworkAsync, + + status, + + reset, + +} = useSwitchNetwork({ + + chainId: 69, + + onError(error) {}, + + onMutate(args) {}, + + onSettled(data, error) {}, + + onSuccess(data) {} + +}) + ``` + +* [`fc94210`](https://github.com/tmm/wagmi/commit/fc94210b67daa91aa164625dfe189d5b6c2f92d4) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: The `useContractRead` hook parameters have been consolidated into a singular config parameter. + + Before: + + ```tsx + useContractRead( + { + addressOrName: wagmigotchiContractAddress, + contractInterface: wagmigotchiABI, + }, + "love", + { args: "0x27a69ffba1e939ddcfecc8c7e0f967b872bac65c" }, + ); + ``` + + After: + + ```tsx + useContractRead({ + addressOrName: wagmigotchiContractAddress, + contractInterface: wagmigotchiABI, + functionName: "love", + args: "0x27a69ffba1e939ddcfecc8c7e0f967b872bac65c", + }); + ``` + +### Patch Changes + +- [`fc94210`](https://github.com/tmm/wagmi/commit/fc94210b67daa91aa164625dfe189d5b6c2f92d4) Thanks [@jxom](https://github.com/jxom)! - Added a `useContractInfiniteReads` hook that provides the ability to call multiple ethers Contract read-only methods with "infinite scrolling" ("fetch more") support. Useful for rendering a dynamic list of contract data. + + [Learn more](https://wagmi.sh/docs/hooks/useContractInfiniteReads) + +* [`fc94210`](https://github.com/tmm/wagmi/commit/fc94210b67daa91aa164625dfe189d5b6c2f92d4) Thanks [@jxom](https://github.com/jxom)! - Added a `useContractReads` hook that provides the ability to batch up multiple ethers Contract read-only methods. + + [Learn more](https://wagmi.sh/docs/hooks/useContractReads) + +- [#598](https://github.com/tmm/wagmi/pull/598) [`fef26bf`](https://github.com/tmm/wagmi/commit/fef26bf8aef76fc9621e3cd54d4e0ca8f69abb38) Thanks [@markdalgleish](https://github.com/markdalgleish)! - Update `@coinbase/wallet-sdk` to fix errors when connecting with older versions of the Coinbase Wallet extension and mobile app. + +* [#611](https://github.com/tmm/wagmi/pull/611) [`3089c34`](https://github.com/tmm/wagmi/commit/3089c34196d4034acabac031e0a2f7ee63ae30cc) Thanks [@tmm](https://github.com/tmm)! - Added `chainId` config parameter for `useContractWrite` and `useSendTransaction`. + + If `chainId` is provided, the connector will validate that `chainId` is the active chain before sending a transaction (and switch to `chainId` if necessary). + +* Updated dependencies [[`fc94210`](https://github.com/tmm/wagmi/commit/fc94210b67daa91aa164625dfe189d5b6c2f92d4), [`fc94210`](https://github.com/tmm/wagmi/commit/fc94210b67daa91aa164625dfe189d5b6c2f92d4), [`4f8f3c0`](https://github.com/tmm/wagmi/commit/4f8f3c0d65383bd8bbdfc3f1033adfdb11d80ebb), [`fc94210`](https://github.com/tmm/wagmi/commit/fc94210b67daa91aa164625dfe189d5b6c2f92d4), [`3089c34`](https://github.com/tmm/wagmi/commit/3089c34196d4034acabac031e0a2f7ee63ae30cc), [`a770af7`](https://github.com/tmm/wagmi/commit/a770af7d2cb214b6620d5341115f1e938e1e77ff), [`4f8f3c0`](https://github.com/tmm/wagmi/commit/4f8f3c0d65383bd8bbdfc3f1033adfdb11d80ebb), [`fef26bf`](https://github.com/tmm/wagmi/commit/fef26bf8aef76fc9621e3cd54d4e0ca8f69abb38), [`fc94210`](https://github.com/tmm/wagmi/commit/fc94210b67daa91aa164625dfe189d5b6c2f92d4), [`3089c34`](https://github.com/tmm/wagmi/commit/3089c34196d4034acabac031e0a2f7ee63ae30cc), [`b03830a`](https://github.com/tmm/wagmi/commit/b03830a54465215c2526f9509543fe2c978bfe70), [`fc94210`](https://github.com/tmm/wagmi/commit/fc94210b67daa91aa164625dfe189d5b6c2f92d4), [`fc94210`](https://github.com/tmm/wagmi/commit/fc94210b67daa91aa164625dfe189d5b6c2f92d4)]: + - @wagmi/core@0.4.0 + +## 0.4.12 + +### Patch Changes + +- [#570](https://github.com/tmm/wagmi/pull/570) [`0e3fe15`](https://github.com/tmm/wagmi/commit/0e3fe15445377f35d6f4142b49bf1c96bfeb62cd) Thanks [@tmm](https://github.com/tmm)! - adds chain for [Foundry](https://github.com/foundry-rs) + +- Updated dependencies [[`0e3fe15`](https://github.com/tmm/wagmi/commit/0e3fe15445377f35d6f4142b49bf1c96bfeb62cd)]: + - @wagmi/core@0.3.8 + +## 0.4.11 + +### Patch Changes + +- [#566](https://github.com/tmm/wagmi/pull/566) [`8713c00`](https://github.com/tmm/wagmi/commit/8713c00f70fcac3afef4ba183e3c87c6d3cbbf65) Thanks [@jxom](https://github.com/jxom)! - Fixed `parseContractResult` breaking `useContractRead` for more complex contract types + +## 0.4.10 + +### Patch Changes + +- [`20a1ab7`](https://github.com/tmm/wagmi/commit/20a1ab7bd02a24c4f1ea02be1bc3ecfbe4abc584) Thanks [@jxom](https://github.com/jxom)! - Updated to `react-query@4.0.0-beta.23` + +* [`20a1ab7`](https://github.com/tmm/wagmi/commit/20a1ab7bd02a24c4f1ea02be1bc3ecfbe4abc584) Thanks [@jxom](https://github.com/jxom)! - Fixed an issue in `useContractRead` where contract structs wouldn't be parsed back to an ethers `Result` correctly. + +## 0.4.9 + +### Patch Changes + +- [#555](https://github.com/tmm/wagmi/pull/555) [`8bf014d`](https://github.com/tmm/wagmi/commit/8bf014d8167e9f9feb1fd91488aab42dd51c92af) Thanks [@tmm](https://github.com/tmm)! - wire up `useEnsName` `chainId` + +## 0.4.8 + +### Patch Changes + +- [#550](https://github.com/tmm/wagmi/pull/550) [`2a5313e`](https://github.com/tmm/wagmi/commit/2a5313e8cbc9ba6335e8e4b85e43862c9b711bd3) Thanks [@tmm](https://github.com/tmm)! - fix `CoinbaseWalletConnector` possible type error + +* [#548](https://github.com/tmm/wagmi/pull/548) [`0c48719`](https://github.com/tmm/wagmi/commit/0c487199f2421f042abc1f1d139468ccbbc5646a) Thanks [@dohaki](https://github.com/dohaki)! - add ensAddress to Chain type + +- [#549](https://github.com/tmm/wagmi/pull/549) [`89b3a74`](https://github.com/tmm/wagmi/commit/89b3a74ead4234daacd0dcf8506659887ebf0553) Thanks [@tmm](https://github.com/tmm)! - Turns on [`noUncheckedIndexedAccess`](https://www.typescriptlang.org/tsconfig#noUncheckedIndexedAccess=) and [`strictNullChecks`](https://www.typescriptlang.org/tsconfig#strictNullChecks=) for better runtime safety. + +- Updated dependencies [[`2a5313e`](https://github.com/tmm/wagmi/commit/2a5313e8cbc9ba6335e8e4b85e43862c9b711bd3), [`0c48719`](https://github.com/tmm/wagmi/commit/0c487199f2421f042abc1f1d139468ccbbc5646a), [`89b3a74`](https://github.com/tmm/wagmi/commit/89b3a74ead4234daacd0dcf8506659887ebf0553)]: + - @wagmi/core@0.3.7 + +## 0.4.7 + +### Patch Changes + +- [#526](https://github.com/tmm/wagmi/pull/526) [`e95c5f9`](https://github.com/tmm/wagmi/commit/e95c5f91859e57d079b962a72d06b93dce004d2f) Thanks [@jxom](https://github.com/jxom)! - Added `shimChainChangedDisconnect` option to `InjectedConnector`. Defaults to `true` for `MetaMaskConnector`. + +* [#526](https://github.com/tmm/wagmi/pull/526) [`e95c5f9`](https://github.com/tmm/wagmi/commit/e95c5f91859e57d079b962a72d06b93dce004d2f) Thanks [@jxom](https://github.com/jxom)! - Added `chainId` config option to `useConnect()` & `connect()`. Consumers can now pick what chain they want their user to be connected to. + + Examples: + + ```tsx + import { useConnect, chain } from "wagmi"; + import { InjectedConnector } from "wagmi/connectors/injected"; + + function App() { + const connect = useConnect({ + chainId: chain.polygon.id, + }); + } + ``` + + ```tsx + import { useConnect, chain } from "wagmi"; + import { InjectedConnector } from "wagmi/connectors/injected"; + + function App() { + const connect = useConnect(); + + return ( + + ); + } + ``` + +* Updated dependencies [[`e95c5f9`](https://github.com/tmm/wagmi/commit/e95c5f91859e57d079b962a72d06b93dce004d2f), [`e95c5f9`](https://github.com/tmm/wagmi/commit/e95c5f91859e57d079b962a72d06b93dce004d2f), [`e95c5f9`](https://github.com/tmm/wagmi/commit/e95c5f91859e57d079b962a72d06b93dce004d2f)]: + - @wagmi/core@0.3.6 + +## 0.4.6 + +### Patch Changes + +- [#543](https://github.com/tmm/wagmi/pull/543) [`4d489fd`](https://github.com/tmm/wagmi/commit/4d489fd630dd8c00440bdaf4d646de662c41ff52) Thanks [@tmm](https://github.com/tmm)! - fix fee data formatting for null values + +- Updated dependencies [[`4d489fd`](https://github.com/tmm/wagmi/commit/4d489fd630dd8c00440bdaf4d646de662c41ff52)]: + - @wagmi/core@0.3.5 + +## 0.4.5 + +### Patch Changes + +- [`01cc47b`](https://github.com/tmm/wagmi/commit/01cc47b2385c78d82bc799c2dedacb2a42457e2f) Thanks [@jxom](https://github.com/jxom)! - Update `react-query` to `4.0.0-beta.19` + +## 0.4.4 + +### Patch Changes + +- [`c4deb66`](https://github.com/tmm/wagmi/commit/c4deb6655a52e4cc4e5b3fd82202db11d6106848) Thanks [@jxom](https://github.com/jxom)! - infer `options.chainId` config from `chains` on WalletConnectConnector + +- Updated dependencies [[`c4deb66`](https://github.com/tmm/wagmi/commit/c4deb6655a52e4cc4e5b3fd82202db11d6106848)]: + - @wagmi/core@0.3.4 + +## 0.4.3 + +### Patch Changes + +- [#486](https://github.com/tmm/wagmi/pull/486) [`dbfe3dd`](https://github.com/tmm/wagmi/commit/dbfe3dd320d178d6854a8096101200c1508786bb) Thanks [@tmm](https://github.com/tmm)! - add chains entrypoint + +- Updated dependencies [[`dbfe3dd`](https://github.com/tmm/wagmi/commit/dbfe3dd320d178d6854a8096101200c1508786bb)]: + - @wagmi/core@0.3.3 + +## 0.4.2 + +### Patch Changes + +- [`b1a2e58`](https://github.com/tmm/wagmi/commit/b1a2e5830e325be448bf865aeccda60217fc8d75) Thanks [@jxom](https://github.com/jxom)! - Made the `defaultChains` type generic in `configureChains`. + +## 0.4.1 + +### Patch Changes + +- [#484](https://github.com/tmm/wagmi/pull/484) [`1b9a503`](https://github.com/tmm/wagmi/commit/1b9a5033d51c6655b4f6570c490da6e0e9a29da9) Thanks [@tmm](https://github.com/tmm)! - export React Context + +- Updated dependencies [[`1b9a503`](https://github.com/tmm/wagmi/commit/1b9a5033d51c6655b4f6570c490da6e0e9a29da9)]: + - @wagmi/core@0.3.1 + +## 0.4.0 + +### Minor Changes + +- [#468](https://github.com/tmm/wagmi/pull/468) [`44a884b`](https://github.com/tmm/wagmi/commit/44a884b84171c418f57701e80ef8de972948ef0b) Thanks [@tmm](https://github.com/tmm)! - **Breaking:** Duplicate exports with different names and the same functionality were removed to simplify the public API. In addition, confusing exports were renamed to be more descriptive. + + - `createWagmiClient` alias was removed. Use `createClient` instead. + - `useWagmiClient` alias was removed. Use `useClient` instead. + - `WagmiClient` alias was removed. Use `Client` instead. + - `createWagmiStorage` alias was removed. Use `createStorage` instead. + - `Provider` was renamed and `WagmiProvider` alias was removed. Use `WagmiConfig` instead. + +* [#408](https://github.com/tmm/wagmi/pull/408) [`bfcc3a5`](https://github.com/tmm/wagmi/commit/bfcc3a51bbb1551753e3ccde6af134e9fd4fec9a) Thanks [@jxom](https://github.com/jxom)! - Add `configureChains` API. + + The `configureChains` function allows you to configure your chains with a selected provider (Alchemy, Infura, JSON RPC, Public RPC URLs). This means you don't have to worry about deriving your own RPC URLs for each chain, or instantiating a Ethereum Provider. + + `configureChains` accepts 3 parameters: an array of chains, and an array of providers, and a config object. + + [Learn more about configuring chains & providers.](https://wagmi.sh/docs/providers/configuring-chains) + + ### Before + + ```tsx + import { providers } from "ethers"; + import { chain, createClient, defaultChains } from "wagmi"; + import { CoinbaseWalletConnector } from "wagmi/connectors/coinbaseWallet"; + import { InjectedConnector } from "wagmi/connectors/injected"; + import { MetaMaskConnector } from "wagmi/connectors/metaMask"; + import { WalletConnectConnector } from "wagmi/connectors/walletConnect"; + + const alchemyId = process.env.ALCHEMY_ID; + + const chains = defaultChains; + const defaultChain = chain.mainnet; + + const client = createClient({ + autoConnect: true, + connectors({ chainId }) { + const chain = chains.find((x) => x.id === chainId) ?? defaultChain; + const rpcUrl = chain.rpcUrls.alchemy + ? `${chain.rpcUrls.alchemy}/${alchemyId}` + : chain.rpcUrls.default; + return [ + new MetaMaskConnector({ chains }), + new CoinbaseWalletConnector({ + chains, + options: { + appName: "wagmi", + chainId: chain.id, + jsonRpcUrl: rpcUrl, + }, + }), + new WalletConnectConnector({ + chains, + options: { + qrcode: true, + rpc: { [chain.id]: rpcUrl }, + }, + }), + new InjectedConnector({ + chains, + options: { + name: "Injected", + shimDisconnect: true, + }, + }), + ]; + }, + provider: ({ chainId }) => + new providers.AlchemyProvider(chainId, alchemyId), + }); + ``` + + ### After + + ```tsx + import { chain, createClient, defaultChains } from "wagmi"; + + import { alchemyProvider } from "wagmi/providers/alchemy"; + import { publicProvider } from "wagmi/providers/public"; + + import { CoinbaseWalletConnector } from "wagmi/connectors/coinbaseWallet"; + import { InjectedConnector } from "wagmi/connectors/injected"; + import { MetaMaskConnector } from "wagmi/connectors/metaMask"; + import { WalletConnectConnector } from "wagmi/connectors/walletConnect"; + + const alchemyId = process.env.ALCHEMY_ID; + + const { chains, provider, webSocketProvider } = configureChains( + defaultChains, + [alchemyProvider({ alchemyId }), publicProvider()], + ); + + const client = createClient({ + autoConnect: true, + connectors: [ + new MetaMaskConnector({ chains }), + new CoinbaseWalletConnector({ + chains, + options: { + appName: "wagmi", + }, + }), + new WalletConnectConnector({ + chains, + options: { + qrcode: true, + }, + }), + new InjectedConnector({ + chains, + options: { + name: "Injected", + shimDisconnect: true, + }, + }), + ], + provider, + webSocketProvider, + }); + ``` + +### Patch Changes + +- [#404](https://github.com/tmm/wagmi/pull/404) [`f81c156`](https://github.com/tmm/wagmi/commit/f81c15665e2e71534f84ada3fa705f2d78627472) Thanks [@holic](https://github.com/holic)! - Add `ProviderRpcError` and `RpcError` error classes. + + Certain wagmi-standardized errors may wrap `ProviderRpcError` or `RpcError`. For these cases, you can access the original provider rpc or rpc error value using the `internal` property. + +* [#459](https://github.com/tmm/wagmi/pull/459) [`72dcf7c`](https://github.com/tmm/wagmi/commit/72dcf7c09e814261b2e43a8fa364c57675c472de) Thanks [@tmm](https://github.com/tmm)! - update dependencies + +- [#447](https://github.com/tmm/wagmi/pull/447) [`b9ebf78`](https://github.com/tmm/wagmi/commit/b9ebf782e0900725bcb76483686b30f09d357ebd) Thanks [@tmm](https://github.com/tmm)! - Fix case where connector disconnected while app was closed and stale data was returned when autoconnecting. For example, [MetaMask was locked](https://github.com/tmm/wagmi/issues/444) when page was closed. + +- Updated dependencies [[`f81c156`](https://github.com/tmm/wagmi/commit/f81c15665e2e71534f84ada3fa705f2d78627472), [`bfcc3a5`](https://github.com/tmm/wagmi/commit/bfcc3a51bbb1551753e3ccde6af134e9fd4fec9a), [`44a884b`](https://github.com/tmm/wagmi/commit/44a884b84171c418f57701e80ef8de972948ef0b), [`72dcf7c`](https://github.com/tmm/wagmi/commit/72dcf7c09e814261b2e43a8fa364c57675c472de), [`a54f3e2`](https://github.com/tmm/wagmi/commit/a54f3e23ea385ed8aa4ad188128d7089ba20f83e), [`b9ebf78`](https://github.com/tmm/wagmi/commit/b9ebf782e0900725bcb76483686b30f09d357ebd), [`bfcc3a5`](https://github.com/tmm/wagmi/commit/bfcc3a51bbb1551753e3ccde6af134e9fd4fec9a)]: + - @wagmi/core@0.3.0 + +## 0.3.5 + +### Patch Changes + +- [`4e03666`](https://github.com/tmm/wagmi/commit/4e03666428d42fc9186c617001b5eb356229677e) Thanks [@tmm](https://github.com/tmm)! - bump dependencies #429 + add imToken support for WC switch chains #432 + fix MetaMask and Brave Wallet collision #436 +- Updated dependencies [[`4e03666`](https://github.com/tmm/wagmi/commit/4e03666428d42fc9186c617001b5eb356229677e)]: + - @wagmi/core@0.2.5 + +## 0.3.4 + +### Patch Changes + +- [#421](https://github.com/tmm/wagmi/pull/421) [`a232b3f`](https://github.com/tmm/wagmi/commit/a232b3ff5cc41e882c4d2a34c599a8cb670edd2b) Thanks [@tmm](https://github.com/tmm)! - fix erc721 abi + +- Updated dependencies [[`a232b3f`](https://github.com/tmm/wagmi/commit/a232b3ff5cc41e882c4d2a34c599a8cb670edd2b)]: + - @wagmi/core@0.2.4 + +## 0.3.3 + +### Patch Changes + +- [#412](https://github.com/tmm/wagmi/pull/412) [`80bef4f`](https://github.com/tmm/wagmi/commit/80bef4ff3f714b0b8f896f1b4b658acc7266299b) Thanks [@markdalgleish](https://github.com/markdalgleish)! - Import providers from `ethers` peer dependency rather than `@ethersproject/providers` to avoid multiple conflicting versions being installed + +- Updated dependencies [[`80bef4f`](https://github.com/tmm/wagmi/commit/80bef4ff3f714b0b8f896f1b4b658acc7266299b)]: + - @wagmi/core@0.2.3 + +## 0.3.2 + +### Patch Changes + +- [`018c2a1`](https://github.com/tmm/wagmi/commit/018c2a11b22ee513571cc7f83fd63f7eb169ee70) Thanks [@tmm](https://github.com/tmm)! - - warn and fallback to default client #380 + + - remove signerOrProvider option from read contract #390 + + - MetaMaskConnector #391 + +- Updated dependencies [[`018c2a1`](https://github.com/tmm/wagmi/commit/018c2a11b22ee513571cc7f83fd63f7eb169ee70)]: + - @wagmi/core@0.2.2 + +## 0.3.1 + +### Patch Changes + +- [`afc4607`](https://github.com/tmm/wagmi/commit/afc46071e91601ab8a2b465524da796cd60b6ad4) Thanks [@tmm](https://github.com/tmm)! - - Fix time scaling e9593df + - Use fully-specified path for use-sync-external-store import 7b235c1 + - Update serialize 236fc17 +- Updated dependencies [[`afc4607`](https://github.com/tmm/wagmi/commit/afc46071e91601ab8a2b465524da796cd60b6ad4)]: + - @wagmi/core@0.2.1 + +## 0.3.0 + +### Minor Changes + +- [#311](https://github.com/tmm/wagmi/pull/311) [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d) Thanks [@tmm](https://github.com/tmm)! - don't persist account data when `autoConnect` is falsy + +* [#311](https://github.com/tmm/wagmi/pull/311) [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d) Thanks [@tmm](https://github.com/tmm)! - - fix(@wagmi/core): persist connector chains to local storage + +- [#311](https://github.com/tmm/wagmi/pull/311) [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d) Thanks [@tmm](https://github.com/tmm)! - - Favour `message` event over `connecting` event to conform to EIP-1193 + - Export `useWaitForTransaction` + +* [#311](https://github.com/tmm/wagmi/pull/311) [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d) Thanks [@tmm](https://github.com/tmm)! - force address to be required in `useAccount` + +- [#311](https://github.com/tmm/wagmi/pull/311) [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d) Thanks [@tmm](https://github.com/tmm)! - Initial 0.3.0 release + +* [#311](https://github.com/tmm/wagmi/pull/311) [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d) Thanks [@tmm](https://github.com/tmm)! - Add `cacheOnBlock` config for `useContractRead` + Update `react-query` to v4 + Fix `watchBlockNumber` listener leak + +- [#311](https://github.com/tmm/wagmi/pull/311) [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d) Thanks [@tmm](https://github.com/tmm)! - - fix `useContractWrite` mutation fn arguments + +* [#311](https://github.com/tmm/wagmi/pull/311) [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d) Thanks [@tmm](https://github.com/tmm)! - Update react-query to 4.0.0-beta.5 + +### Patch Changes + +- [#311](https://github.com/tmm/wagmi/pull/311) [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d) Thanks [@tmm](https://github.com/tmm)! - add chainId to actions and hooks + +* [#311](https://github.com/tmm/wagmi/pull/311) [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d) Thanks [@tmm](https://github.com/tmm)! - showtime + +- [#311](https://github.com/tmm/wagmi/pull/311) [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d) Thanks [@tmm](https://github.com/tmm)! - improve type support for ethers providers + +* [#311](https://github.com/tmm/wagmi/pull/311) [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d) Thanks [@tmm](https://github.com/tmm)! - update zustand + +- [#311](https://github.com/tmm/wagmi/pull/311) [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d) Thanks [@tmm](https://github.com/tmm)! - update babel target + +* [#311](https://github.com/tmm/wagmi/pull/311) [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d) Thanks [@tmm](https://github.com/tmm)! - update block explorers and rpc urls structure + +- [#311](https://github.com/tmm/wagmi/pull/311) [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d) Thanks [@tmm](https://github.com/tmm)! - keep previous data when watching + +* [#311](https://github.com/tmm/wagmi/pull/311) [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d) Thanks [@tmm](https://github.com/tmm)! - republish + +- [#311](https://github.com/tmm/wagmi/pull/311) [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d) Thanks [@tmm](https://github.com/tmm)! - fix stale connectors when switching chains + +* [#311](https://github.com/tmm/wagmi/pull/311) [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d) Thanks [@tmm](https://github.com/tmm)! - last beta + +* Updated dependencies [[`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d), [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d), [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d), [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d), [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d), [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d), [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d), [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d), [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d), [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d), [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d), [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d), [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d), [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d), [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d), [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d), [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d), [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d)]: + - @wagmi/core@0.2.0 + +## 0.3.0-next.21 + +### Patch Changes + +- showtime + +- Updated dependencies []: + - @wagmi/core@0.2.0-next.18 + +## 0.3.0-next.20 + +### Patch Changes + +- update block explorers and rpc urls structure + +- Updated dependencies []: + - @wagmi/core@0.2.0-next.17 + +## 0.3.0-next.19 + +### Minor Changes + +- Update react-query to 4.0.0-beta.5 + +## 0.3.0-next.18 + +### Patch Changes + +- last beta + +- Updated dependencies []: + - @wagmi/core@0.2.0-next.16 + +## 0.3.0-next.17 + +### Patch Changes + +- update zustand + +- Updated dependencies []: + - @wagmi/core@0.2.0-next.15 + +## 0.3.0-next.16 + +### Minor Changes + +- Add `cacheOnBlock` config for `useContractRead` +- Update `react-query` to v4 +- Fix `watchBlockNumber` listener leak + +### Patch Changes + +- Updated dependencies []: + - @wagmi/core@0.2.0-next.14 + +## 0.3.0-next.15 + +### Patch Changes + +- keep previous data when watching + +- Updated dependencies []: + - @wagmi/core@0.2.0-next.13 + +## 0.3.0-next.14 + +### Patch Changes + +- add chainId to actions and hooks + +- Updated dependencies []: + - @wagmi/core@0.2.0-next.12 + +## 0.3.0-next.13 + +### Patch Changes + +- fix stale connectors when switching chains + +- Updated dependencies []: + - @wagmi/core@0.2.0-next.11 + +## 0.3.0-next.12 + +### Patch Changes + +- republish + +- Updated dependencies []: + - @wagmi/core@0.2.0-next.10 + +## 0.3.0-next.11 + +### Patch Changes + +- improve type support for ethers providers + +- Updated dependencies []: + - @wagmi/core@0.2.0-next.9 + +## 0.3.0-next.10 + +### Patch Changes + +- update babel target + +- Updated dependencies []: + - @wagmi/core@0.2.0-next.8 + +## 0.3.0-next.9 + +### Minor Changes + +- - Favour `message` event over `connecting` event to conform to EIP-1193 + - Export `useWaitForTransaction` + +### Patch Changes + +- Updated dependencies []: + - @wagmi/core@0.2.0-next.7 + +## 0.3.0-next.8 + +### Patch Changes + +- Updated dependencies []: + - @wagmi/core@0.2.0-next.6 + +## 0.3.0-next.7 + +### Minor Changes + +- don't persist account data when `autoConnect` is falsy + +### Patch Changes + +- Updated dependencies []: + - @wagmi/core@0.2.0-next.5 + +## 0.3.0-next.6 + +### Minor Changes + +- fix `useContractWrite` mutation fn arguments + +### Patch Changes + +- Updated dependencies []: + - @wagmi/core@0.2.0-next.4 + +## 0.3.0-next.5 + +### Patch Changes + +- Updated dependencies []: + - @wagmi/core@0.2.0-next.3 + +## 0.3.0-next.4 + +### Minor Changes + +- force address to be required in `useAccount` + +## 0.3.0-next.3 + +### Patch Changes + +- Updated dependencies []: + - @wagmi/core@0.2.0-next.2 + +## 0.3.0-next.2 + +### Minor Changes + +- Initial 0.3.0 release + +### Patch Changes + +- Updated dependencies []: + - @wagmi/core@0.2.0-next.1 + +## 0.2.28 + +### Patch Changes + +- [`747d895`](https://github.com/tmm/wagmi/commit/747d895a54b562958afde34b1d34e81ab5039e2c) Thanks [@tmm](https://github.com/tmm)! - add warning to WalletLinkConnector + +- Updated dependencies [[`747d895`](https://github.com/tmm/wagmi/commit/747d895a54b562958afde34b1d34e81ab5039e2c)]: + - wagmi-core@0.1.22 + +## 0.2.27 + +### Patch Changes + +- [`c858c51`](https://github.com/tmm/wagmi/commit/c858c51b44d9039f1d0db5bcf016639f47d1931f) Thanks [@tmm](https://github.com/tmm)! - update coinbase connector + +- Updated dependencies [[`c858c51`](https://github.com/tmm/wagmi/commit/c858c51b44d9039f1d0db5bcf016639f47d1931f)]: + - wagmi-core@0.1.21 + +## 0.2.26 + +### Patch Changes + +- Updated dependencies [[`36e6989`](https://github.com/tmm/wagmi/commit/36e69894f4c27aaad7fb6d678476c8bb870244bb)]: + - wagmi-core@0.1.20 + +## 0.2.25 + +### Patch Changes + +- [`d467df6`](https://github.com/tmm/wagmi/commit/d467df6374210dbc4b016788b4beb4fded54cb4d) Thanks [@tmm](https://github.com/tmm)! - fix global type leaking + +- Updated dependencies [[`d467df6`](https://github.com/tmm/wagmi/commit/d467df6374210dbc4b016788b4beb4fded54cb4d)]: + - wagmi-core@0.1.19 + +## 0.2.24 + +### Patch Changes + +- [#294](https://github.com/tmm/wagmi/pull/294) [`1d253f3`](https://github.com/tmm/wagmi/commit/1d253f3a59b61d24c88d25c99decd84a6c734e5d) Thanks [@tmm](https://github.com/tmm)! - change babel target + +- Updated dependencies [[`1d253f3`](https://github.com/tmm/wagmi/commit/1d253f3a59b61d24c88d25c99decd84a6c734e5d)]: + - wagmi-core@0.1.18 + +## 0.2.23 + +### Patch Changes + +- [#292](https://github.com/tmm/wagmi/pull/292) [`53c9be1`](https://github.com/tmm/wagmi/commit/53c9be17ee0c2ae6b8f34f2351b8858257b3f5f2) Thanks [@tmm](https://github.com/tmm)! - fix private fields + +- Updated dependencies [[`53c9be1`](https://github.com/tmm/wagmi/commit/53c9be17ee0c2ae6b8f34f2351b8858257b3f5f2)]: + - wagmi-core@0.1.17 + +## 0.2.22 + +### Patch Changes + +- [`79a2499`](https://github.com/tmm/wagmi/commit/79a249989029f818c32c0e84c0dd2c75e8aa990a) Thanks [@tmm](https://github.com/tmm)! - update build target to es2021 + +- Updated dependencies [[`79a2499`](https://github.com/tmm/wagmi/commit/79a249989029f818c32c0e84c0dd2c75e8aa990a)]: + - wagmi-core@0.1.16 + +## 0.2.21 + +### Patch Changes + +- [`f9790b5`](https://github.com/tmm/wagmi/commit/f9790b55600df09c77bb8ca349c5a3457df1b07c) Thanks [@tmm](https://github.com/tmm)! - fix WalletConnect issue + +- Updated dependencies [[`f9790b5`](https://github.com/tmm/wagmi/commit/f9790b55600df09c77bb8ca349c5a3457df1b07c)]: + - wagmi-core@0.1.15 + +## 0.2.20 + +### Patch Changes + +- [`fed29fb`](https://github.com/tmm/wagmi/commit/fed29fb4714abe234e2dabb63782cfc4439a10cf) Thanks [@tmm](https://github.com/tmm)! - export useSignTypedData + +## 0.2.19 + +### Patch Changes + +- [`6987278`](https://github.com/tmm/wagmi/commit/69872786e0b54b89a20945cc5471c1f4675b0a68) Thanks [@tmm](https://github.com/tmm)! - add useSignedTypeData + +## 0.2.18 + +### Patch Changes + +- [#236](https://github.com/tmm/wagmi/pull/236) [`53bad61`](https://github.com/tmm/wagmi/commit/53bad615788764e31121678083c382c1bd042fe8) Thanks [@markdalgleish](https://github.com/markdalgleish)! - Updated `@walletconnect/ethereum-provider` to [v1.7.4](https://github.com/WalletConnect/walletconnect-monorepo/releases/tag/1.7.4) + +- Updated dependencies [[`53bad61`](https://github.com/tmm/wagmi/commit/53bad615788764e31121678083c382c1bd042fe8)]: + - wagmi-core@0.1.14 + +## 0.2.17 + +### Patch Changes + +- [`8e9412a`](https://github.com/tmm/wagmi/commit/8e9412af71958301ae2f9748febb936e79900aa0) Thanks [@tmm](https://github.com/tmm)! - bump walletlink + +- Updated dependencies [[`8e9412a`](https://github.com/tmm/wagmi/commit/8e9412af71958301ae2f9748febb936e79900aa0)]: + - wagmi-core@0.1.13 + +## 0.2.16 + +### Patch Changes + +- [#210](https://github.com/tmm/wagmi/pull/210) [`684468a`](https://github.com/tmm/wagmi/commit/684468aee3e42a1ce2b4b599f3f17d1819213de8) Thanks [@tmm](https://github.com/tmm)! - update chains to match chainslist.org + +- Updated dependencies [[`684468a`](https://github.com/tmm/wagmi/commit/684468aee3e42a1ce2b4b599f3f17d1819213de8)]: + - wagmi-core@0.1.12 + +## 0.2.15 + +### Patch Changes + +- [#195](https://github.com/tmm/wagmi/pull/195) [`25b6083`](https://github.com/tmm/wagmi/commit/25b6083a662a0236794d1765343467691421c14b) Thanks [@tmm](https://github.com/tmm)! - rename wagmi-private to wagmi-core + +- Updated dependencies [[`25b6083`](https://github.com/tmm/wagmi/commit/25b6083a662a0236794d1765343467691421c14b)]: + - wagmi-core@0.1.11 + +## 0.2.14 + +### Patch Changes + +- [#192](https://github.com/tmm/wagmi/pull/192) [`428cedb`](https://github.com/tmm/wagmi/commit/428cedb3dec4e3e4b9f4559c8e65932e05f94e05) Thanks [@tmm](https://github.com/tmm)! - rename core and testing packages + +- Updated dependencies [[`428cedb`](https://github.com/tmm/wagmi/commit/428cedb3dec4e3e4b9f4559c8e65932e05f94e05)]: + - wagmi-core@0.1.10 + +## 0.2.13 + +### Patch Changes + +- [#190](https://github.com/tmm/wagmi/pull/190) [`7034bb8`](https://github.com/tmm/wagmi/commit/7034bb868412b9f481b206371280e84c2d52706d) Thanks [@tmm](https://github.com/tmm)! - add shim for metamask chain changed to prevent disconnect + +- Updated dependencies [[`7034bb8`](https://github.com/tmm/wagmi/commit/7034bb868412b9f481b206371280e84c2d52706d)]: + - wagmi-private@0.1.9 + +## 0.2.12 + +### Patch Changes + +- [`566b47f`](https://github.com/tmm/wagmi/commit/566b47f53c80e1cdcc368d43c53b1772eeb5be20) Thanks [@tmm](https://github.com/tmm)! - fix contract read skip option + +## 0.2.11 + +### Patch Changes + +- [`09f0719`](https://github.com/tmm/wagmi/commit/09f071947012e3133362a7eb80c0f39356899190) Thanks [@tmm](https://github.com/tmm)! - - safe state updates h/t @bpierre + - add useEnsResolveName hook h/t @shunkakinoki + +## 0.2.10 + +### Patch Changes + +- [#159](https://github.com/tmm/wagmi/pull/159) [`981438d`](https://github.com/tmm/wagmi/commit/981438d527fb6b5f025dd9bb405fa9e7a2751597) Thanks [@markdalgleish](https://github.com/markdalgleish)! - add `WagmiProvider` alias for `Provider` + +## 0.2.9 + +### Patch Changes + +- [#137](https://github.com/tmm/wagmi/pull/137) [`dceeb43`](https://github.com/tmm/wagmi/commit/dceeb430d9021fbf98366859cb1cd0149e80c55c) Thanks [@tmm](https://github.com/tmm)! - add siwe guide + +- Updated dependencies [[`dceeb43`](https://github.com/tmm/wagmi/commit/dceeb430d9021fbf98366859cb1cd0149e80c55c)]: + - wagmi-private@0.1.8 + +## 0.2.8 + +### Patch Changes + +- [`b49cb89`](https://github.com/tmm/wagmi/commit/b49cb89ef59289ee1185eafab427d3ab55c17c25) Thanks [@tmm](https://github.com/tmm)! - refactor contract read/write hook state + +## 0.2.7 + +### Patch Changes + +- [`7132631`](https://github.com/tmm/wagmi/commit/713263159899feb257c11614716f0af4f6b06a14) Thanks [@tmm](https://github.com/tmm)! - update contract read and write state + +## 0.2.6 + +### Patch Changes + +- [#127](https://github.com/tmm/wagmi/pull/127) [`f05b031`](https://github.com/tmm/wagmi/commit/f05b0310f7f7e6447e9b6c81cedbb27dcf2f3649) Thanks [@tmm](https://github.com/tmm)! - update switch chain return type + +- Updated dependencies [[`f05b031`](https://github.com/tmm/wagmi/commit/f05b0310f7f7e6447e9b6c81cedbb27dcf2f3649)]: + - wagmi-private@0.1.7 + +## 0.2.5 + +### Patch Changes + +- [`1412eed`](https://github.com/tmm/wagmi/commit/1412eed0d1494bb4f8c6845a0e890f79e4e68e03) Thanks [@tmm](https://github.com/tmm)! - add frame to injected + +- Updated dependencies [[`1412eed`](https://github.com/tmm/wagmi/commit/1412eed0d1494bb4f8c6845a0e890f79e4e68e03)]: + - wagmi-private@0.1.6 + +## 0.2.4 + +### Patch Changes + +- [#122](https://github.com/tmm/wagmi/pull/122) [`94f599c`](https://github.com/tmm/wagmi/commit/94f599cc1de74a977956d4118d85ab0d36915471) Thanks [@tmm](https://github.com/tmm)! - add decimals to useBalance + +## 0.2.3 + +### Patch Changes + +- [`e338c3b`](https://github.com/tmm/wagmi/commit/e338c3b6cc255742be6a67593aa5da6c17e90fbd) Thanks [@tmm](https://github.com/tmm)! - checksum connector address on change events + + add shim to injected connector for simulating disconnect + +- Updated dependencies [[`e338c3b`](https://github.com/tmm/wagmi/commit/e338c3b6cc255742be6a67593aa5da6c17e90fbd)]: + - wagmi-private@0.1.5 + +## 0.2.2 + +### Patch Changes + +- [`0176c4e`](https://github.com/tmm/wagmi/commit/0176c4e83fb0c5f159c3c802a1da3d6deb2184ae) Thanks [@tmm](https://github.com/tmm)! - added switchChain to WalletConnect and WalletLink connectors + +- Updated dependencies [[`0176c4e`](https://github.com/tmm/wagmi/commit/0176c4e83fb0c5f159c3c802a1da3d6deb2184ae)]: + - wagmi-private@0.1.4 + +## 0.2.1 + +### Patch Changes + +- [`f12d9cc`](https://github.com/tmm/wagmi/commit/f12d9ccfdf87a2f75299b53a7dd6b1ad046a49d8) Thanks [@tmm](https://github.com/tmm)! - fixes overrides type + +## 0.2.0 + +### Minor Changes + +- [#98](https://github.com/tmm/wagmi/pull/98) [`b2ec758`](https://github.com/tmm/wagmi/commit/b2ec7580436f52fd35005c6dd3f4472650a14d02) Thanks [@oveddan](https://github.com/oveddan)! - Exported Context + +## 0.1.7 + +### Patch Changes + +- [`d965757`](https://github.com/tmm/wagmi/commit/d9657578bc17648716c4671b8cc35ad295bc71d2) Thanks [@tmm](https://github.com/tmm)! - use balance eth symbol + +## 0.1.6 + +### Patch Changes + +- [`071d7fb`](https://github.com/tmm/wagmi/commit/071d7fbca35ec4832700b5343661ceb2dae20598) Thanks [@tmm](https://github.com/tmm)! - add hardhat chain + +- Updated dependencies [[`071d7fb`](https://github.com/tmm/wagmi/commit/071d7fbca35ec4832700b5343661ceb2dae20598)]: + - wagmi-private@0.1.3 + +## 0.1.5 + +### Patch Changes + +- [`db4d869`](https://github.com/tmm/wagmi/commit/db4d869fd9380b26a1f3f96ab34abd14ca73d068) Thanks [@tmm](https://github.com/tmm)! - - add global connecting property for `Provider` `autoConnect` (h/t @sammdec) + - fix `useContractEvent` error (h/t @math-marcellino) + +## 0.1.4 + +### Patch Changes + +- [#73](https://github.com/tmm/wagmi/pull/73) [`0c78ccc`](https://github.com/tmm/wagmi/commit/0c78ccc4e7f311525d4ea712b79cf532899e2006) Thanks [@tmm](https://github.com/tmm)! - fix module exports + +## 0.1.3 + +### Patch Changes + +- [`78bade9`](https://github.com/tmm/wagmi/commit/78bade9d0da97ab38a7e6594c34e3841ec1c8fe6) Thanks [@tmm](https://github.com/tmm)! - add type definitions + +- Updated dependencies [[`78bade9`](https://github.com/tmm/wagmi/commit/78bade9d0da97ab38a7e6594c34e3841ec1c8fe6)]: + - wagmi-private@0.1.2 + +## 0.1.2 + +### Patch Changes + +- [#56](https://github.com/tmm/wagmi/pull/56) [`2ebfd8e`](https://github.com/tmm/wagmi/commit/2ebfd8e85b560f25cd46cff04619c84643cab297) Thanks [@tmm](https://github.com/tmm)! - add chain support status + +- Updated dependencies [[`2ebfd8e`](https://github.com/tmm/wagmi/commit/2ebfd8e85b560f25cd46cff04619c84643cab297)]: + - wagmi-private@0.1.1 + +## 0.1.1 + +### Patch Changes + +- [#54](https://github.com/tmm/wagmi/pull/54) [`25acd3d`](https://github.com/tmm/wagmi/commit/25acd3dfbb4498af5e1139ae9c892f5013404cbc) Thanks [@tmm](https://github.com/tmm)! - Stale contract object when useContract hook arguments change @zakangelle + +## 0.1.0 + +### Minor Changes + +- [#52](https://github.com/tmm/wagmi/pull/52) [`da7a3a6`](https://github.com/tmm/wagmi/commit/da7a3a615def2443f65c041999100ce35e9774cc) Thanks [@tmm](https://github.com/tmm)! - Moves connectors to their own entrypoints to reduce bundle size. + + ```ts + // old - WalletLinkConnector unused, but still in final bundle + import { InjectedConnector, WalletConnectConnector } from "wagmi"; + + // new - WalletLinkConnector not in final bundle + import { InjectedConnector } from "wagmi/connectors/injected"; + import { WalletConnectConnector } from "wagmi/connectors/walletConnect"; + ``` + +### Patch Changes + +- Updated dependencies [[`da7a3a6`](https://github.com/tmm/wagmi/commit/da7a3a615def2443f65c041999100ce35e9774cc)]: + - wagmi-private@0.1.0 + +## 0.0.17 + +### Patch Changes + +- [#25](https://github.com/tmm/wagmi/pull/25) [`9a7dab7`](https://github.com/tmm/wagmi/commit/9a7dab78b3518658bc7d85dc397990f0d28da175) Thanks [@tmm](https://github.com/tmm)! - update response types + +- Updated dependencies [[`9a7dab7`](https://github.com/tmm/wagmi/commit/9a7dab78b3518658bc7d85dc397990f0d28da175)]: + - wagmi-private@0.0.17 + +## 0.0.16 + +### Patch Changes + +- [`d1574cf`](https://github.com/tmm/wagmi/commit/d1574cf5f7a578ccd480889c2e375134145a4aba) Thanks [@tmm](https://github.com/tmm)! - add better type information for contract results + +- Updated dependencies [[`d1574cf`](https://github.com/tmm/wagmi/commit/d1574cf5f7a578ccd480889c2e375134145a4aba)]: + - wagmi-private@0.0.16 + +## 0.0.15 + +### Patch Changes + +- [`3909624`](https://github.com/tmm/wagmi/commit/39096249c1fa9516beabb11735beb67c94032879) Thanks [@tmm](https://github.com/tmm)! - make contract read and write execute overrides param optional + +- Updated dependencies [[`3909624`](https://github.com/tmm/wagmi/commit/39096249c1fa9516beabb11735beb67c94032879)]: + - wagmi-private@0.0.15 + +## 0.0.14 + +### Patch Changes + +- [`63312e2`](https://github.com/tmm/wagmi/commit/63312e2b06b8d835abc2908cba399d941ca79408) Thanks [@tmm](https://github.com/tmm)! - add once to contract event + +- Updated dependencies [[`63312e2`](https://github.com/tmm/wagmi/commit/63312e2b06b8d835abc2908cba399d941ca79408)]: + - wagmi-private@0.0.14 + +## 0.0.13 + +### Patch Changes + +- [`6f890b0`](https://github.com/tmm/wagmi/commit/6f890b0dabbdbea913ec91cb8bfc970c05ed0a93) Thanks [@tmm](https://github.com/tmm)! - update readme + +- Updated dependencies [[`6f890b0`](https://github.com/tmm/wagmi/commit/6f890b0dabbdbea913ec91cb8bfc970c05ed0a93)]: + - wagmi-private@0.0.13 + +## 0.0.12 + +### Patch Changes + +- [#19](https://github.com/tmm/wagmi/pull/19) [`7bc1c47`](https://github.com/tmm/wagmi/commit/7bc1c47875e9ef24e9c79cfafc6b23e7a838b5bc) Thanks [@tmm](https://github.com/tmm)! - remove console log from walletlink connector + +- Updated dependencies [[`7bc1c47`](https://github.com/tmm/wagmi/commit/7bc1c47875e9ef24e9c79cfafc6b23e7a838b5bc)]: + - wagmi-private@0.0.12 + +## 0.0.11 + +### Patch Changes + +- [#17](https://github.com/tmm/wagmi/pull/17) [`571648b`](https://github.com/tmm/wagmi/commit/571648b754f7f538536bafc9387bd3104657ea49) Thanks [@tmm](https://github.com/tmm)! - standardize connector provider + +- Updated dependencies [[`571648b`](https://github.com/tmm/wagmi/commit/571648b754f7f538536bafc9387bd3104657ea49)]: + - wagmi-private@0.0.11 + +## 0.0.10 + +### Patch Changes + +- [#15](https://github.com/tmm/wagmi/pull/15) [`5f7675c`](https://github.com/tmm/wagmi/commit/5f7675c3ffd848522d4117c07c1f62b17dfc6616) Thanks [@tmm](https://github.com/tmm)! - read and write contract functions + +- Updated dependencies [[`5f7675c`](https://github.com/tmm/wagmi/commit/5f7675c3ffd848522d4117c07c1f62b17dfc6616)]: + - wagmi-private@0.0.10 + +## 0.0.9 + +### Patch Changes + +- [#13](https://github.com/tmm/wagmi/pull/13) [`e5545f5`](https://github.com/tmm/wagmi/commit/e5545f5565cf0bbf5e62ec7ccab3051705b1d313) Thanks [@tmm](https://github.com/tmm)! - add testing package + +- Updated dependencies [[`e5545f5`](https://github.com/tmm/wagmi/commit/e5545f5565cf0bbf5e62ec7ccab3051705b1d313)]: + - wagmi-private@0.0.9 + +## 0.0.8 + +### Patch Changes + +- [`5332500`](https://github.com/tmm/wagmi/commit/5332500918ac240d29ffe4d2aed8566a8ac001e4) Thanks [@tmm](https://github.com/tmm)! - update signing + +- Updated dependencies [[`5332500`](https://github.com/tmm/wagmi/commit/5332500918ac240d29ffe4d2aed8566a8ac001e4)]: + - wagmi-private@0.0.8 + +## 0.0.7 + +### Patch Changes + +- [`0bff89a`](https://github.com/tmm/wagmi/commit/0bff89ab2ad28b2cb9b346d1ac870e859d9278bc) Thanks [@tmm](https://github.com/tmm)! - update injected connector + +- Updated dependencies [[`0bff89a`](https://github.com/tmm/wagmi/commit/0bff89ab2ad28b2cb9b346d1ac870e859d9278bc)]: + - wagmi-private@0.0.7 + +## 0.0.6 + +### Patch Changes + +- [`37d39d1`](https://github.com/tmm/wagmi/commit/37d39d174ddfa122462bbe2d02141cd61eb9db4a) Thanks [@tmm](https://github.com/tmm)! - add message signing + +- Updated dependencies [[`37d39d1`](https://github.com/tmm/wagmi/commit/37d39d174ddfa122462bbe2d02141cd61eb9db4a)]: + - wagmi-private@0.0.6 + +## 0.0.5 + +### Patch Changes + +- [`d7d94f0`](https://github.com/tmm/wagmi/commit/d7d94f06f7d30468e5e39d64db63124c6315cf82) Thanks [@tmm](https://github.com/tmm)! - fix injected connector name + +- Updated dependencies [[`d7d94f0`](https://github.com/tmm/wagmi/commit/d7d94f06f7d30468e5e39d64db63124c6315cf82)]: + - wagmi-private@0.0.5 + +## 0.0.4 + +### Patch Changes + +- [`29fbe29`](https://github.com/tmm/wagmi/commit/29fbe2920046b9e87a34faa04500ccf3c4f83748) Thanks [@tmm](https://github.com/tmm)! - fix external deps + +- Updated dependencies [[`29fbe29`](https://github.com/tmm/wagmi/commit/29fbe2920046b9e87a34faa04500ccf3c4f83748)]: + - wagmi-private@0.0.4 + +## 0.0.3 + +### Patch Changes + +- [#6](https://github.com/tmm/wagmi/pull/6) [`8dc3a5d`](https://github.com/tmm/wagmi/commit/8dc3a5d5f418813b09663534fe585d9bcf94dbeb) Thanks [@tmm](https://github.com/tmm)! - clean up deps + +- Updated dependencies [[`8dc3a5d`](https://github.com/tmm/wagmi/commit/8dc3a5d5f418813b09663534fe585d9bcf94dbeb)]: + - wagmi-private@0.0.3 + +## 0.0.2 + +### Patch Changes + +- [#4](https://github.com/tmm/wagmi/pull/4) [`2fbd821`](https://github.com/tmm/wagmi/commit/2fbd8216379bd03c9cc5c06b10b75637e75cb7d8) Thanks [@tmm](https://github.com/tmm)! - init changesets + +- Updated dependencies [[`2fbd821`](https://github.com/tmm/wagmi/commit/2fbd8216379bd03c9cc5c06b10b75637e75cb7d8)]: + - wagmi-private@0.0.2 diff --git a/wagmi-project/packages/react/README.md b/wagmi-project/packages/react/README.md new file mode 100644 index 000000000..4c87fd5e6 --- /dev/null +++ b/wagmi-project/packages/react/README.md @@ -0,0 +1,13 @@ +# wagmi + +React Hooks for Ethereum + +## Installation + +```bash +pnpm add wagmi viem @tanstack/react-query +``` + +## Documentation + +For documentation and guides, visit [wagmi.sh](https://wagmi.sh). diff --git a/wagmi-project/packages/react/package.json b/wagmi-project/packages/react/package.json new file mode 100644 index 000000000..79311aa5c --- /dev/null +++ b/wagmi-project/packages/react/package.json @@ -0,0 +1,119 @@ +{ + "name": "wagmi", + "description": "React Hooks for Ethereum", + "version": "2.15.4", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/wevm/wagmi.git", + "directory": "packages/react" + }, + "scripts": { + "build": "pnpm run clean && pnpm run build:esm+types", + "build:esm+types": "tsc --project tsconfig.build.json --outDir ./dist/esm --declaration --declarationMap --declarationDir ./dist/types", + "check:types": "tsc --noEmit", + "clean": "rm -rf dist tsconfig.tsbuildinfo actions chains codegen connectors experimental query", + "test:build": "publint --strict && attw --pack --ignore-rules cjs-resolves-to-esm" + }, + "files": [ + "dist/**", + "!dist/**/*.tsbuildinfo", + "src/**/*.ts", + "!src/**/*.test.ts", + "!src/**/*.test-d.ts", + "/actions", + "/chains", + "/codegen", + "/connectors", + "/experimental", + "/query" + ], + "sideEffects": false, + "type": "module", + "main": "./dist/esm/exports/index.js", + "types": "./dist/types/exports/index.d.ts", + "typings": "./dist/types/exports/index.d.ts", + "exports": { + ".": { + "types": "./dist/types/exports/index.d.ts", + "default": "./dist/esm/exports/index.js" + }, + "./actions": { + "types": "./dist/types/exports/actions.d.ts", + "default": "./dist/esm/exports/actions.js" + }, + "./actions/experimental": { + "types": "./dist/types/exports/actions/experimental.d.ts", + "default": "./dist/esm/exports/actions/experimental.js" + }, + "./chains": { + "types": "./dist/types/exports/chains.d.ts", + "default": "./dist/esm/exports/chains.js" + }, + "./codegen": { + "types": "./dist/types/exports/codegen.d.ts", + "default": "./dist/esm/exports/codegen.js" + }, + "./connectors": { + "types": "./dist/types/exports/connectors.d.ts", + "default": "./dist/esm/exports/connectors.js" + }, + "./experimental": { + "types": "./dist/types/exports/experimental.d.ts", + "default": "./dist/esm/exports/experimental.js" + }, + "./query": { + "types": "./dist/types/exports/query.d.ts", + "default": "./dist/esm/exports/query.js" + }, + "./package.json": "./package.json" + }, + "typesVersions": { + "*": { + "actions": ["./dist/types/exports/actions.d.ts"], + "chains": ["./dist/types/exports/chains.d.ts"], + "codegen": ["./dist/types/exports/codegen.d.ts"], + "connectors": ["./dist/types/exports/connectors.d.ts"], + "experimental": ["./dist/types/exports/experimental.d.ts"], + "query": ["./dist/types/exports/query.d.ts"] + } + }, + "peerDependencies": { + "@tanstack/react-query": ">=5.0.0", + "react": ">=18", + "typescript": ">=5.0.4", + "viem": "2.x" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + }, + "dependencies": { + "@wagmi/connectors": "workspace:*", + "@wagmi/core": "workspace:*", + "use-sync-external-store": "1.4.0" + }, + "devDependencies": { + "@tanstack/react-query": "catalog:", + "@testing-library/dom": "catalog:", + "@testing-library/react": "catalog:", + "@types/react": "catalog:", + "@types/react-dom": "catalog:", + "@types/use-sync-external-store": "^0.0.6", + "react": "catalog:", + "react-dom": "catalog:" + }, + "contributors": ["awkweb.eth ", "jxom.eth "], + "funding": "https://github.com/sponsors/wevm", + "keywords": [ + "wagmi", + "react", + "hooks", + "eth", + "ethereum", + "dapps", + "wallet", + "web3" + ] +} diff --git a/wagmi-project/packages/react/src/context.test.tsx b/wagmi-project/packages/react/src/context.test.tsx new file mode 100644 index 000000000..7a716ac68 --- /dev/null +++ b/wagmi-project/packages/react/src/context.test.tsx @@ -0,0 +1,101 @@ +import { QueryClient, QueryClientProvider } from '@tanstack/react-query' +import { render, waitFor } from '@testing-library/react' +import { http, connect, createConfig, mock } from '@wagmi/core' +import { accounts, addressRegex, config, mainnet } from '@wagmi/test' +import React from 'react' +import { expect, test } from 'vitest' + +import { WagmiProvider } from './context.js' +import { useAccount } from './hooks/useAccount.js' +import { useConnectorClient } from './hooks/useConnectorClient.js' + +test('default', () => { + function Component() { + const { address } = useAccount() + const { data } = useConnectorClient() + return ( +
+

wevm

+
useAccount: {address}
+
useConnectorClient: {data?.account?.address}
+
+ ) + } + + const queryClient = new QueryClient() + const result = render( + + + + + , + ) + expect(result.getByRole('heading').innerText).toMatchInlineSnapshot(`"wevm"`) + result.unmount() +}) + +test('fake ssr config', () => { + const config = createConfig({ + chains: [mainnet], + pollingInterval: 100, + ssr: true, + transports: { + [mainnet.id]: http(), + }, + }) + const queryClient = new QueryClient() + + const result = render( + + +

wevm

+
+
, + ) + expect(result.getAllByRole('heading')).toMatchInlineSnapshot(` + [ +

+ wevm +

, + ] + `) + result.unmount() +}) + +test('mock reconnect', async () => { + function Component() { + const { address } = useAccount() + return ( +
+

{address}

+
+ ) + } + + const connector = mock({ + accounts, + features: { reconnect: true }, + }) + const config = createConfig({ + chains: [mainnet], + connectors: [connector], + storage: null, + transports: { + [mainnet.id]: http(), + }, + }) + await connect(config, { connector }) + + const queryClient = new QueryClient() + const result = render( + + + + + , + ) + await waitFor(() => + expect(result.getByRole('heading').innerText).toMatch(addressRegex), + ) + result.unmount() +}) diff --git a/wagmi-project/packages/react/src/context.ts b/wagmi-project/packages/react/src/context.ts new file mode 100644 index 000000000..ec484ccd7 --- /dev/null +++ b/wagmi-project/packages/react/src/context.ts @@ -0,0 +1,28 @@ +'use client' + +import type { ResolvedRegister, State } from '@wagmi/core' +import { createContext, createElement } from 'react' +import { Hydrate } from './hydrate.js' + +export const WagmiContext = createContext< + ResolvedRegister['config'] | undefined +>(undefined) + +export type WagmiProviderProps = { + config: ResolvedRegister['config'] + initialState?: State | undefined + reconnectOnMount?: boolean | undefined +} + +export function WagmiProvider( + parameters: React.PropsWithChildren, +) { + const { children, config } = parameters + + const props = { value: config } + return createElement( + Hydrate, + parameters, + createElement(WagmiContext.Provider, props, children), + ) +} diff --git a/wagmi-project/packages/react/src/errors/base.test.ts b/wagmi-project/packages/react/src/errors/base.test.ts new file mode 100644 index 000000000..2980541ed --- /dev/null +++ b/wagmi-project/packages/react/src/errors/base.test.ts @@ -0,0 +1,155 @@ +import { expect, test } from 'vitest' + +import { BaseError } from './base.js' + +test('BaseError', () => { + expect(new BaseError('An error occurred.')).toMatchInlineSnapshot(` + [WagmiError: An error occurred. + + Version: wagmi@x.y.z] + `) + + expect( + new BaseError('An error occurred.', { details: 'details' }), + ).toMatchInlineSnapshot(` + [WagmiError: An error occurred. + + Details: details + Version: wagmi@x.y.z] + `) + + expect(new BaseError('', { details: 'details' })).toMatchInlineSnapshot(` + [WagmiError: An error occurred. + + Details: details + Version: wagmi@x.y.z] + `) +}) + +test('BaseError (w/ docsPath)', () => { + expect( + new BaseError('An error occurred.', { + details: 'details', + docsPath: '/lol', + }), + ).toMatchInlineSnapshot(` + [WagmiError: An error occurred. + + Docs: https://wagmi.sh/react/lol.html + Details: details + Version: wagmi@x.y.z] + `) + expect( + new BaseError('An error occurred.', { + cause: new BaseError('error', { docsPath: '/docs' }), + }), + ).toMatchInlineSnapshot(` + [WagmiError: An error occurred. + + Docs: https://wagmi.sh/react/docs.html + Version: wagmi@x.y.z] + `) + expect( + new BaseError('An error occurred.', { + cause: new BaseError('error'), + docsPath: '/lol', + }), + ).toMatchInlineSnapshot(` + [WagmiError: An error occurred. + + Docs: https://wagmi.sh/react/lol.html + Version: wagmi@x.y.z] + `) + expect( + new BaseError('An error occurred.', { + details: 'details', + docsPath: '/lol', + docsSlug: 'test', + }), + ).toMatchInlineSnapshot(` + [WagmiError: An error occurred. + + Docs: https://wagmi.sh/react/lol.html#test + Details: details + Version: wagmi@x.y.z] + `) +}) + +test('BaseError (w/ metaMessages)', () => { + expect( + new BaseError('An error occurred.', { + details: 'details', + metaMessages: ['Reason: idk', 'Cause: lol'], + }), + ).toMatchInlineSnapshot(` + [WagmiError: An error occurred. + + Reason: idk + Cause: lol + + Details: details + Version: wagmi@x.y.z] + `) +}) + +test('inherited BaseError', () => { + const err = new BaseError('An error occurred.', { + details: 'details', + docsPath: '/lol', + }) + expect( + new BaseError('An internal error occurred.', { + cause: err, + }), + ).toMatchInlineSnapshot(` + [WagmiError: An internal error occurred. + + Docs: https://wagmi.sh/react/lol.html + Details: details + Version: wagmi@x.y.z] + `) +}) + +test('inherited Error', () => { + const err = new Error('details') + expect( + new BaseError('An internal error occurred.', { + cause: err, + docsPath: '/lol', + }), + ).toMatchInlineSnapshot(` + [WagmiError: An internal error occurred. + + Docs: https://wagmi.sh/react/lol.html + Details: details + Version: wagmi@x.y.z] + `) +}) + +test('walk: no predicate fn (walks to leaf)', () => { + class FooError extends BaseError {} + class BarError extends BaseError {} + + const err = new BaseError('test1', { + cause: new FooError('test2', { cause: new BarError('test3') }), + }) + expect(err.walk()).toMatchInlineSnapshot(` + [WagmiError: test3 + + Version: wagmi@x.y.z] + `) +}) + +test('walk: predicate fn', () => { + class FooError extends BaseError {} + class BarError extends BaseError {} + + const err = new BaseError('test1', { + cause: new FooError('test2', { cause: new BarError('test3') }), + }) + expect(err.walk((err) => err instanceof FooError)).toMatchInlineSnapshot(` + [WagmiError: test2 + + Version: wagmi@x.y.z] + `) +}) diff --git a/wagmi-project/packages/react/src/errors/base.ts b/wagmi-project/packages/react/src/errors/base.ts new file mode 100644 index 000000000..b2ee83c86 --- /dev/null +++ b/wagmi-project/packages/react/src/errors/base.ts @@ -0,0 +1,14 @@ +import { BaseError as CoreError } from '@wagmi/core' + +import { getVersion } from '../utils/getVersion.js' + +export type BaseErrorType = BaseError & { name: 'WagmiError' } +export class BaseError extends CoreError { + override name = 'WagmiError' + override get docsBaseUrl() { + return 'https://wagmi.sh/react' + } + override get version() { + return getVersion() + } +} diff --git a/wagmi-project/packages/react/src/errors/context.test.ts b/wagmi-project/packages/react/src/errors/context.test.ts new file mode 100644 index 000000000..8dc5a16c4 --- /dev/null +++ b/wagmi-project/packages/react/src/errors/context.test.ts @@ -0,0 +1,12 @@ +import { expect, test } from 'vitest' + +import { WagmiProviderNotFoundError } from './context.js' + +test('WagmiProviderNotFoundError', () => { + expect(new WagmiProviderNotFoundError()).toMatchInlineSnapshot(` + [WagmiProviderNotFoundError: \`useConfig\` must be used within \`WagmiProvider\`. + + Docs: https://wagmi.sh/react/api/WagmiProvider.html + Version: wagmi@x.y.z] + `) +}) diff --git a/wagmi-project/packages/react/src/errors/context.ts b/wagmi-project/packages/react/src/errors/context.ts new file mode 100644 index 000000000..0ea5cadaa --- /dev/null +++ b/wagmi-project/packages/react/src/errors/context.ts @@ -0,0 +1,13 @@ +import { BaseError } from './base.js' + +export type WagmiProviderNotFoundErrorType = WagmiProviderNotFoundError & { + name: 'WagmiProviderNotFoundError' +} +export class WagmiProviderNotFoundError extends BaseError { + override name = 'WagmiProviderNotFoundError' + constructor() { + super('`useConfig` must be used within `WagmiProvider`.', { + docsPath: '/api/WagmiProvider', + }) + } +} diff --git a/wagmi-project/packages/react/src/experimental/hooks/useWriteContracts.test.ts b/wagmi-project/packages/react/src/experimental/hooks/useWriteContracts.test.ts new file mode 100644 index 000000000..ea6d4815d --- /dev/null +++ b/wagmi-project/packages/react/src/experimental/hooks/useWriteContracts.test.ts @@ -0,0 +1,45 @@ +import { connect, disconnect } from '@wagmi/core' +import { abi, address, config } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { expect, test } from 'vitest' + +import { useWriteContracts } from './useWriteContracts.js' + +const connector = config.connectors[0]! + +test('default', async () => { + await connect(config, { connector }) + + const { result } = renderHook(() => useWriteContracts()) + + result.current.writeContracts({ + contracts: [ + { + abi: abi.wagmiMintExample, + address: address.wagmiMintExample, + functionName: 'mint', + }, + { + abi: abi.wagmiMintExample, + address: address.wagmiMintExample, + functionName: 'mint', + }, + { + abi: abi.wagmiMintExample, + address: address.wagmiMintExample, + functionName: 'mint', + }, + ], + }) + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current.data).toMatchInlineSnapshot( + ` + { + "id": "0x8913636bd97cf4bcc0a6343c730905a27ead0f7480ff82190072e916439eb212", + } + `, + ) + + await disconnect(config, { connector }) +}) diff --git a/wagmi-project/packages/react/src/experimental/hooks/useWriteContracts.ts b/wagmi-project/packages/react/src/experimental/hooks/useWriteContracts.ts new file mode 100644 index 000000000..8d0d32aef --- /dev/null +++ b/wagmi-project/packages/react/src/experimental/hooks/useWriteContracts.ts @@ -0,0 +1,85 @@ +'use client' + +import { useMutation } from '@tanstack/react-query' +import type { Config, ResolvedRegister } from '@wagmi/core' +import { + type WriteContractsData, + type WriteContractsErrorType, + type WriteContractsMutate, + type WriteContractsMutateAsync, + type WriteContractsVariables, + writeContractsMutationOptions, +} from '@wagmi/core/experimental' +import type { Compute } from '@wagmi/core/internal' +import type { ContractFunctionParameters } from 'viem' + +import { useConfig } from '../../hooks/useConfig.js' +import type { ConfigParameter } from '../../types/properties.js' +import type { + UseMutationParameters, + UseMutationReturnType, +} from '../../utils/query.js' + +export type UseWriteContractsParameters< + contracts extends readonly unknown[] = readonly ContractFunctionParameters[], + config extends Config = Config, + context = unknown, +> = Compute< + ConfigParameter & { + mutation?: + | UseMutationParameters< + WriteContractsData, + WriteContractsErrorType, + WriteContractsVariables< + contracts, + config, + config['chains'][number]['id'] + >, + context + > + | undefined + } +> + +export type UseWriteContractsReturnType< + contracts extends readonly unknown[] = readonly ContractFunctionParameters[], + config extends Config = Config, + context = unknown, +> = Compute< + UseMutationReturnType< + WriteContractsData, + WriteContractsErrorType, + WriteContractsVariables, + context + > & { + writeContracts: WriteContractsMutate + writeContractsAsync: WriteContractsMutateAsync + } +> + +/** https://wagmi.sh/react/api/hooks/useWriteContracts */ +export function useWriteContracts< + const contracts extends + readonly unknown[] = readonly ContractFunctionParameters[], + config extends Config = ResolvedRegister['config'], + context = unknown, +>( + parameters: UseWriteContractsParameters = {}, +): UseWriteContractsReturnType { + const { mutation } = parameters + + const config = useConfig(parameters) + + const mutationOptions = writeContractsMutationOptions(config) + const { mutate, mutateAsync, ...result } = useMutation({ + ...mutation, + ...mutationOptions, + }) + + type Return = UseWriteContractsReturnType + return { + ...result, + writeContracts: mutate as Return['writeContracts'], + writeContractsAsync: mutateAsync as Return['writeContractsAsync'], + } +} diff --git a/wagmi-project/packages/react/src/exports/actions.test.ts b/wagmi-project/packages/react/src/exports/actions.test.ts new file mode 100644 index 000000000..eaaedba14 --- /dev/null +++ b/wagmi-project/packages/react/src/exports/actions.test.ts @@ -0,0 +1,86 @@ +import { expect, test } from 'vitest' + +import * as actions from './actions.js' + +test('exports', () => { + expect(Object.keys(actions)).toMatchInlineSnapshot(` + [ + "call", + "connect", + "deployContract", + "disconnect", + "estimateGas", + "estimateFeesPerGas", + "estimateMaxPriorityFeePerGas", + "getAccount", + "getBalance", + "fetchBalance", + "getBlock", + "getBlockNumber", + "fetchBlockNumber", + "getBlockTransactionCount", + "getBytecode", + "getCallsStatus", + "getCapabilities", + "getChainId", + "getChains", + "getClient", + "getConnections", + "getConnectors", + "getConnectorClient", + "getEnsAddress", + "fetchEnsAddress", + "getEnsAvatar", + "fetchEnsAvatar", + "getEnsName", + "fetchEnsName", + "getEnsResolver", + "fetchEnsResolver", + "getEnsText", + "getFeeHistory", + "getGasPrice", + "getProof", + "getPublicClient", + "getStorageAt", + "getToken", + "fetchToken", + "getTransaction", + "fetchTransaction", + "getTransactionConfirmations", + "getTransactionCount", + "getTransactionReceipt", + "getWalletClient", + "multicall", + "prepareTransactionRequest", + "readContract", + "readContracts", + "reconnect", + "sendCalls", + "sendTransaction", + "showCallsStatus", + "signMessage", + "signTypedData", + "simulateContract", + "switchAccount", + "switchChain", + "switchNetwork", + "verifyMessage", + "verifyTypedData", + "waitForCallsStatus", + "watchAccount", + "watchAsset", + "watchBlocks", + "watchBlockNumber", + "watchChainId", + "watchClient", + "watchConnections", + "watchConnectors", + "watchContractEvent", + "watchPendingTransactions", + "watchPublicClient", + "waitForTransactionReceipt", + "waitForTransaction", + "writeContract", + ] + `) +}) diff --git a/wagmi-project/packages/react/src/exports/actions.ts b/wagmi-project/packages/react/src/exports/actions.ts new file mode 100644 index 000000000..3ff9c743c --- /dev/null +++ b/wagmi-project/packages/react/src/exports/actions.ts @@ -0,0 +1,7 @@ +//////////////////////////////////////////////////////////////////////////////// +// @wagmi/core/actions +//////////////////////////////////////////////////////////////////////////////// + +// biome-ignore lint/performance/noBarrelFile: entrypoint module +// biome-ignore lint/performance/noReExportAll: entrypoint module +export * from '@wagmi/core/actions' diff --git a/wagmi-project/packages/react/src/exports/actions/experimental.test.ts b/wagmi-project/packages/react/src/exports/actions/experimental.test.ts new file mode 100644 index 000000000..7c4b92df8 --- /dev/null +++ b/wagmi-project/packages/react/src/exports/actions/experimental.test.ts @@ -0,0 +1,25 @@ +import { expect, test } from 'vitest' + +import * as experimentalActions from './experimental.js' + +test('exports', () => { + expect(Object.keys(experimentalActions)).toMatchInlineSnapshot(` + [ + "getCallsStatus", + "getCapabilities", + "sendCalls", + "showCallsStatus", + "waitForCallsStatus", + "writeContracts", + "getCallsStatusQueryOptions", + "getCallsStatusQueryKey", + "getCapabilitiesQueryOptions", + "getCapabilitiesQueryKey", + "sendCallsMutationOptions", + "showCallsStatusMutationOptions", + "waitForCallsStatusQueryKey", + "waitForCallsStatusQueryOptions", + "writeContractsMutationOptions", + ] + `) +}) diff --git a/wagmi-project/packages/react/src/exports/actions/experimental.ts b/wagmi-project/packages/react/src/exports/actions/experimental.ts new file mode 100644 index 000000000..6ee0334af --- /dev/null +++ b/wagmi-project/packages/react/src/exports/actions/experimental.ts @@ -0,0 +1,7 @@ +//////////////////////////////////////////////////////////////////////////////// +// @wagmi/core/experimental +//////////////////////////////////////////////////////////////////////////////// + +// biome-ignore lint/performance/noBarrelFile: entrypoint module +// biome-ignore lint/performance/noReExportAll: entrypoint module +export * from '@wagmi/core/experimental' diff --git a/wagmi-project/packages/react/src/exports/chains.ts b/wagmi-project/packages/react/src/exports/chains.ts new file mode 100644 index 000000000..1fca7f537 --- /dev/null +++ b/wagmi-project/packages/react/src/exports/chains.ts @@ -0,0 +1,7 @@ +//////////////////////////////////////////////////////////////////////////////// +// viem/chains +//////////////////////////////////////////////////////////////////////////////// + +// biome-ignore lint/performance/noBarrelFile: entrypoint module +// biome-ignore lint/performance/noReExportAll: entrypoint module +export * from 'viem/chains' diff --git a/wagmi-project/packages/react/src/exports/codegen.test.ts b/wagmi-project/packages/react/src/exports/codegen.test.ts new file mode 100644 index 000000000..19697cc9a --- /dev/null +++ b/wagmi-project/packages/react/src/exports/codegen.test.ts @@ -0,0 +1,18 @@ +import { expect, test } from 'vitest' + +import * as codegen from './codegen.js' + +test('exports', () => { + expect(Object.keys(codegen)).toMatchInlineSnapshot(` + [ + "createSimulateContract", + "createReadContract", + "createWatchContractEvent", + "createWriteContract", + "createUseSimulateContract", + "createUseReadContract", + "createUseWatchContractEvent", + "createUseWriteContract", + ] + `) +}) diff --git a/wagmi-project/packages/react/src/exports/codegen.ts b/wagmi-project/packages/react/src/exports/codegen.ts new file mode 100644 index 000000000..c642f63bc --- /dev/null +++ b/wagmi-project/packages/react/src/exports/codegen.ts @@ -0,0 +1,35 @@ +//////////////////////////////////////////////////////////////////////////////// +// @wagmi/core/codegen +//////////////////////////////////////////////////////////////////////////////// + +// biome-ignore lint/performance/noBarrelFile: entrypoint module +// biome-ignore lint/performance/noReExportAll: entrypoint module +export * from '@wagmi/core/codegen' + +//////////////////////////////////////////////////////////////////////////////// +// Hooks +//////////////////////////////////////////////////////////////////////////////// + +export { + type CreateUseSimulateContractParameters, + type CreateUseSimulateContractReturnType, + createUseSimulateContract, +} from '../hooks/codegen/createUseSimulateContract.js' + +export { + type CreateUseReadContractParameters, + type CreateUseReadContractReturnType, + createUseReadContract, +} from '../hooks/codegen/createUseReadContract.js' + +export { + type CreateUseWatchContractEventParameters, + type CreateUseWatchContractEventReturnType, + createUseWatchContractEvent, +} from '../hooks/codegen/createUseWatchContractEvent.js' + +export { + type CreateUseWriteContractParameters, + type CreateUseWriteContractReturnType, + createUseWriteContract, +} from '../hooks/codegen/createUseWriteContract.js' diff --git a/wagmi-project/packages/react/src/exports/connectors.test.ts b/wagmi-project/packages/react/src/exports/connectors.test.ts new file mode 100644 index 000000000..068db8227 --- /dev/null +++ b/wagmi-project/packages/react/src/exports/connectors.test.ts @@ -0,0 +1,17 @@ +import { expect, test } from 'vitest' + +import * as connectors from './connectors.js' + +test('exports', () => { + expect(Object.keys(connectors)).toMatchInlineSnapshot(` + [ + "injected", + "mock", + "coinbaseWallet", + "metaMask", + "safe", + "walletConnect", + "version", + ] + `) +}) diff --git a/wagmi-project/packages/react/src/exports/connectors.ts b/wagmi-project/packages/react/src/exports/connectors.ts new file mode 100644 index 000000000..e10367e31 --- /dev/null +++ b/wagmi-project/packages/react/src/exports/connectors.ts @@ -0,0 +1,7 @@ +//////////////////////////////////////////////////////////////////////////////// +// @wagmi/connectors +//////////////////////////////////////////////////////////////////////////////// + +// biome-ignore lint/performance/noBarrelFile: entrypoint module +// biome-ignore lint/performance/noReExportAll: entrypoint module +export * from '@wagmi/connectors' diff --git a/wagmi-project/packages/react/src/exports/experimental.ts b/wagmi-project/packages/react/src/exports/experimental.ts new file mode 100644 index 000000000..996eb56a7 --- /dev/null +++ b/wagmi-project/packages/react/src/exports/experimental.ts @@ -0,0 +1,58 @@ +//////////////////////////////////////////////////////////////////////////////// +// Hooks +//////////////////////////////////////////////////////////////////////////////// + +// biome-ignore lint/performance/noBarrelFile: entrypoint module +export { + /** @deprecated This is no longer experimental – use `import type { UseCallsStatusParameters } from 'wagmi'` instead. */ + type UseCallsStatusParameters, + /** @deprecated This is no longer experimental – use `import type { UseCallsStatusReturnType } from 'wagmi'` instead. */ + type UseCallsStatusReturnType, + /** @deprecated This is no longer experimental – use `import { useCallsStatus } from 'wagmi'` instead. */ + useCallsStatus, +} from '../hooks/useCallsStatus.js' + +export { + /** @deprecated This is no longer experimental – use `import type { UseCapabilitiesParameters } from 'wagmi'` instead. */ + type UseCapabilitiesParameters, + /** @deprecated This is no longer experimental – use `import type { UseCapabilitiesReturnType } from 'wagmi'` instead. */ + type UseCapabilitiesReturnType, + /** @deprecated This is no longer experimental – use `import { useCapabilities } from 'wagmi'` instead. */ + useCapabilities, +} from '../hooks/useCapabilities.js' + +export { + /** @deprecated This is no longer experimental – use `import type { UseSendCallsParameters } from 'wagmi'` instead. */ + type UseSendCallsParameters, + /** @deprecated This is no longer experimental – use `import type { UseSendCallsReturnType } from 'wagmi'` instead. */ + type UseSendCallsReturnType, + /** @deprecated This is no longer experimental – use `import { useSendCalls } from 'wagmi'` instead. */ + useSendCalls, +} from '../hooks/useSendCalls.js' + +export { + /** @deprecated This is no longer experimental – use `import type { UseShowCallsStatusParameters } from 'wagmi'` instead. */ + type UseShowCallsStatusParameters, + /** @deprecated This is no longer experimental – use `import type { UseShowCallsStatusReturnType } from 'wagmi'` instead. */ + type UseShowCallsStatusReturnType, + /** @deprecated This is no longer experimental – use `import { useShowCallsStatus } from 'wagmi'` instead. */ + useShowCallsStatus, +} from '../hooks/useShowCallsStatus.js' + +export { + /** @deprecated This is no longer experimental – use `import type { UseWaitForCallsStatusParameters } from 'wagmi'` instead. */ + type UseWaitForCallsStatusParameters, + /** @deprecated This is no longer experimental – use `import type { UseWaitForCallsStatusReturnType } from 'wagmi'` instead. */ + type UseWaitForCallsStatusReturnType, + /** @deprecated This is no longer experimental – use `import { useWaitForCallsStatus } from 'wagmi'` instead. */ + useWaitForCallsStatus, +} from '../hooks/useWaitForCallsStatus.js' + +export { + /** @deprecated Use `UseSendCallsParameters` instead. */ + type UseWriteContractsParameters, + /** @deprecated Use `UseSendCallsReturnType` instead. */ + type UseWriteContractsReturnType, + /** @deprecated Use `useSendCalls` instead. */ + useWriteContracts, +} from '../experimental/hooks/useWriteContracts.js' diff --git a/wagmi-project/packages/react/src/exports/index.test.ts b/wagmi-project/packages/react/src/exports/index.test.ts new file mode 100644 index 000000000..d8d6f7c6d --- /dev/null +++ b/wagmi-project/packages/react/src/exports/index.test.ts @@ -0,0 +1,111 @@ +import { expect, test } from 'vitest' + +import * as react from './index.js' + +test('exports', () => { + expect(Object.keys(react)).toMatchInlineSnapshot(` + [ + "WagmiContext", + "WagmiProvider", + "Context", + "WagmiConfig", + "BaseError", + "WagmiProviderNotFoundError", + "useAccount", + "useAccountEffect", + "useBalance", + "useBlock", + "useBlockNumber", + "useBlockTransactionCount", + "useBytecode", + "useCallsStatus", + "useCapabilities", + "useCall", + "useChainId", + "useChains", + "useClient", + "useConfig", + "useConnect", + "useConnections", + "useConnectors", + "useConnectorClient", + "useDeployContract", + "useDisconnect", + "useEnsAddress", + "useEnsAvatar", + "useEnsName", + "useEnsResolver", + "useEnsText", + "useEstimateFeesPerGas", + "useFeeData", + "useEstimateGas", + "useEstimateMaxPriorityFeePerGas", + "useFeeHistory", + "useGasPrice", + "useInfiniteReadContracts", + "useContractInfiniteReads", + "usePrepareTransactionRequest", + "useProof", + "usePublicClient", + "useReadContract", + "useContractRead", + "useReadContracts", + "useContractReads", + "useReconnect", + "useSendCalls", + "useSendTransaction", + "useShowCallsStatus", + "useSignMessage", + "useSignTypedData", + "useSimulateContract", + "useStorageAt", + "useSwitchAccount", + "useSwitchChain", + "useToken", + "useTransaction", + "useTransactionConfirmations", + "useTransactionCount", + "useTransactionReceipt", + "useVerifyMessage", + "useVerifyTypedData", + "useWalletClient", + "useWaitForCallsStatus", + "useWaitForTransactionReceipt", + "useWatchAsset", + "useWatchBlocks", + "useWatchBlockNumber", + "useWatchContractEvent", + "useWatchPendingTransactions", + "useWriteContract", + "useContractWrite", + "Hydrate", + "createConfig", + "createConnector", + "injected", + "mock", + "ChainNotConfiguredError", + "ConnectorAlreadyConnectedError", + "ConnectorNotFoundError", + "ConnectorAccountNotFoundError", + "ConnectorChainMismatchError", + "ConnectorUnavailableReconnectingError", + "ProviderNotFoundError", + "SwitchChainNotSupportedError", + "createStorage", + "noopStorage", + "custom", + "fallback", + "http", + "webSocket", + "unstable_connector", + "cookieStorage", + "cookieToInitialState", + "deepEqual", + "deserialize", + "normalizeChainId", + "parseCookie", + "serialize", + "version", + ] + `) +}) diff --git a/wagmi-project/packages/react/src/exports/index.ts b/wagmi-project/packages/react/src/exports/index.ts new file mode 100644 index 000000000..a4b850298 --- /dev/null +++ b/wagmi-project/packages/react/src/exports/index.ts @@ -0,0 +1,487 @@ +//////////////////////////////////////////////////////////////////////////////// +// Context +//////////////////////////////////////////////////////////////////////////////// + +// biome-ignore lint/performance/noBarrelFile: entrypoint module +export { + type WagmiProviderProps, + WagmiContext, + WagmiProvider, + /** @deprecated Use `WagmiContext` instead */ + WagmiContext as Context, + /** @deprecated Use `WagmiProvider` instead */ + WagmiProvider as WagmiConfig, +} from '../context.js' + +//////////////////////////////////////////////////////////////////////////////// +// Errors +//////////////////////////////////////////////////////////////////////////////// + +export { type BaseErrorType, BaseError } from '../errors/base.js' + +export { + type WagmiProviderNotFoundErrorType, + WagmiProviderNotFoundError, +} from '../errors/context.js' + +//////////////////////////////////////////////////////////////////////////////// +// Hooks +//////////////////////////////////////////////////////////////////////////////// + +export { + type UseAccountParameters, + type UseAccountReturnType, + useAccount, +} from '../hooks/useAccount.js' + +export { + type UseAccountEffectParameters, + useAccountEffect, +} from '../hooks/useAccountEffect.js' + +export { + type UseBalanceParameters, + type UseBalanceReturnType, + useBalance, +} from '../hooks/useBalance.js' + +export { + type UseBlockParameters, + type UseBlockReturnType, + useBlock, +} from '../hooks/useBlock.js' + +export { + type UseBlockNumberParameters, + type UseBlockNumberReturnType, + useBlockNumber, +} from '../hooks/useBlockNumber.js' + +export { + type UseBlockTransactionCountParameters, + type UseBlockTransactionCountReturnType, + useBlockTransactionCount, +} from '../hooks/useBlockTransactionCount.js' + +export { + type UseBytecodeParameters, + type UseBytecodeReturnType, + useBytecode, +} from '../hooks/useBytecode.js' + +export { + type UseCallsStatusParameters, + type UseCallsStatusReturnType, + useCallsStatus, +} from '../hooks/useCallsStatus.js' + +export { + type UseCapabilitiesParameters, + type UseCapabilitiesReturnType, + useCapabilities, +} from '../hooks/useCapabilities.js' + +export { + type UseCallParameters, + type UseCallReturnType, + useCall, +} from '../hooks/useCall.js' + +export { + type UseChainIdParameters, + type UseChainIdReturnType, + useChainId, +} from '../hooks/useChainId.js' + +export { + type UseChainsParameters, + type UseChainsReturnType, + useChains, +} from '../hooks/useChains.js' + +export { + type UseClientParameters, + type UseClientReturnType, + useClient, +} from '../hooks/useClient.js' + +export { + type UseConfigParameters, + type UseConfigReturnType, + useConfig, +} from '../hooks/useConfig.js' + +export { + type UseConnectParameters, + type UseConnectReturnType, + useConnect, +} from '../hooks/useConnect.js' + +export { + type UseConnectionsParameters, + type UseConnectionsReturnType, + useConnections, +} from '../hooks/useConnections.js' + +export { + type UseConnectorsParameters, + type UseConnectorsReturnType, + useConnectors, +} from '../hooks/useConnectors.js' + +export { + type UseConnectorClientParameters, + type UseConnectorClientReturnType, + useConnectorClient, +} from '../hooks/useConnectorClient.js' + +export { + type UseDeployContractParameters, + type UseDeployContractReturnType, + useDeployContract, +} from '../hooks/useDeployContract.js' + +export { + type UseDisconnectParameters, + type UseDisconnectReturnType, + useDisconnect, +} from '../hooks/useDisconnect.js' + +export { + type UseEnsAddressParameters, + type UseEnsAddressReturnType, + useEnsAddress, +} from '../hooks/useEnsAddress.js' + +export { + type UseEnsAvatarParameters, + type UseEnsAvatarReturnType, + useEnsAvatar, +} from '../hooks/useEnsAvatar.js' + +export { + type UseEnsNameParameters, + type UseEnsNameReturnType, + useEnsName, +} from '../hooks/useEnsName.js' + +export { + type UseEnsResolverParameters, + type UseEnsResolverReturnType, + useEnsResolver, +} from '../hooks/useEnsResolver.js' + +export { + type UseEnsTextParameters, + type UseEnsTextReturnType, + useEnsText, +} from '../hooks/useEnsText.js' + +export { + type UseEstimateFeesPerGasParameters, + type UseEstimateFeesPerGasReturnType, + useEstimateFeesPerGas, + /** @deprecated Use `useEstimateFeesPerGas` instead */ + useEstimateFeesPerGas as useFeeData, +} from '../hooks/useEstimateFeesPerGas.js' + +export { + type UseEstimateGasParameters, + type UseEstimateGasReturnType, + useEstimateGas, +} from '../hooks/useEstimateGas.js' + +export { + type UseEstimateMaxPriorityFeePerGasParameters, + type UseEstimateMaxPriorityFeePerGasReturnType, + useEstimateMaxPriorityFeePerGas, +} from '../hooks/useEstimateMaxPriorityFeePerGas.js' + +export { + type UseFeeHistoryParameters, + type UseFeeHistoryReturnType, + useFeeHistory, +} from '../hooks/useFeeHistory.js' + +export { + type UseGasPriceParameters, + type UseGasPriceReturnType, + useGasPrice, +} from '../hooks/useGasPrice.js' + +export { + type UseInfiniteContractReadsParameters, + type UseInfiniteContractReadsReturnType, + useInfiniteReadContracts, + /** @deprecated Use `useInfiniteReadContracts` instead */ + useInfiniteReadContracts as useContractInfiniteReads, +} from '../hooks/useInfiniteReadContracts.js' + +export { + type UsePrepareTransactionRequestParameters, + type UsePrepareTransactionRequestReturnType, + usePrepareTransactionRequest, +} from '../hooks/usePrepareTransactionRequest.js' + +export { + type UseProofParameters, + type UseProofReturnType, + useProof, +} from '../hooks/useProof.js' + +export { + type UsePublicClientParameters, + type UsePublicClientReturnType, + usePublicClient, +} from '../hooks/usePublicClient.js' + +export { + type UseReadContractParameters, + type UseReadContractReturnType, + useReadContract, + /** @deprecated Use `useWriteContract` instead */ + useReadContract as useContractRead, +} from '../hooks/useReadContract.js' + +export { + type UseReadContractsParameters, + type UseReadContractsReturnType, + useReadContracts, + /** @deprecated Use `useWriteContract` instead */ + useReadContracts as useContractReads, +} from '../hooks/useReadContracts.js' + +export { + type UseReconnectParameters, + type UseReconnectReturnType, + useReconnect, +} from '../hooks/useReconnect.js' + +export { + type UseSendCallsParameters, + type UseSendCallsReturnType, + useSendCalls, +} from '../hooks/useSendCalls.js' + +export { + type UseSendTransactionParameters, + type UseSendTransactionReturnType, + useSendTransaction, +} from '../hooks/useSendTransaction.js' + +export { + type UseShowCallsStatusParameters, + type UseShowCallsStatusReturnType, + useShowCallsStatus, +} from '../hooks/useShowCallsStatus.js' + +export { + type UseSignMessageParameters, + type UseSignMessageReturnType, + useSignMessage, +} from '../hooks/useSignMessage.js' + +export { + type UseSignTypedDataParameters, + type UseSignTypedDataReturnType, + useSignTypedData, +} from '../hooks/useSignTypedData.js' + +export { + type UseSimulateContractParameters, + type UseSimulateContractReturnType, + useSimulateContract, +} from '../hooks/useSimulateContract.js' + +export { + type UseStorageAtParameters, + type UseStorageAtReturnType, + useStorageAt, +} from '../hooks/useStorageAt.js' + +export { + type UseSwitchAccountParameters, + type UseSwitchAccountReturnType, + useSwitchAccount, +} from '../hooks/useSwitchAccount.js' + +export { + type UseSwitchChainParameters, + type UseSwitchChainReturnType, + useSwitchChain, +} from '../hooks/useSwitchChain.js' + +export { + type UseTokenParameters, + type UseTokenReturnType, + /** @deprecated Use `useReadContracts` instead */ + useToken, +} from '../hooks/useToken.js' + +export { + type UseTransactionParameters, + type UseTransactionReturnType, + useTransaction, +} from '../hooks/useTransaction.js' + +export { + type UseTransactionConfirmationsParameters, + type UseTransactionConfirmationsReturnType, + useTransactionConfirmations, +} from '../hooks/useTransactionConfirmations.js' + +export { + type UseTransactionCountParameters, + type UseTransactionCountReturnType, + useTransactionCount, +} from '../hooks/useTransactionCount.js' + +export { + type UseTransactionReceiptParameters, + type UseTransactionReceiptReturnType, + useTransactionReceipt, +} from '../hooks/useTransactionReceipt.js' + +export { + type UseVerifyMessageParameters, + type UseVerifyMessageReturnType, + useVerifyMessage, +} from '../hooks/useVerifyMessage.js' + +export { + type UseVerifyTypedDataParameters, + type UseVerifyTypedDataReturnType, + useVerifyTypedData, +} from '../hooks/useVerifyTypedData.js' + +export { + type UseWalletClientParameters, + type UseWalletClientReturnType, + useWalletClient, +} from '../hooks/useWalletClient.js' + +export { + type UseWaitForCallsStatusParameters, + type UseWaitForCallsStatusReturnType, + useWaitForCallsStatus, +} from '../hooks/useWaitForCallsStatus.js' + +export { + type UseWaitForTransactionReceiptParameters, + type UseWaitForTransactionReceiptReturnType, + useWaitForTransactionReceipt, +} from '../hooks/useWaitForTransactionReceipt.js' + +export { + type UseWatchAssetParameters, + type UseWatchAssetReturnType, + useWatchAsset, +} from '../hooks/useWatchAsset.js' + +export { + type UseWatchBlocksParameters, + type UseWatchBlocksReturnType, + useWatchBlocks, +} from '../hooks/useWatchBlocks.js' + +export { + type UseWatchBlockNumberParameters, + type UseWatchBlockNumberReturnType, + useWatchBlockNumber, +} from '../hooks/useWatchBlockNumber.js' + +export { + type UseWatchContractEventParameters, + type UseWatchContractEventReturnType, + useWatchContractEvent, +} from '../hooks/useWatchContractEvent.js' + +export { + type UseWatchPendingTransactionsParameters, + type UseWatchPendingTransactionsReturnType, + useWatchPendingTransactions, +} from '../hooks/useWatchPendingTransactions.js' + +export { + type UseWriteContractParameters, + type UseWriteContractReturnType, + useWriteContract, + /** @deprecated Use `useWriteContract` instead */ + useWriteContract as useContractWrite, +} from '../hooks/useWriteContract.js' + +//////////////////////////////////////////////////////////////////////////////// +// Hydrate +//////////////////////////////////////////////////////////////////////////////// + +export { + type HydrateProps, + Hydrate, +} from '../hydrate.js' + +//////////////////////////////////////////////////////////////////////////////// +// @wagmi/core +//////////////////////////////////////////////////////////////////////////////// + +export { + // Config + type Connection, + type Connector, + type Config, + type CreateConfigParameters, + type PartializedState, + type State, + createConfig, + // Connector + type ConnectorEventMap, + type CreateConnectorFn, + createConnector, + injected, + mock, + // Errors + type ChainNotConfiguredErrorType, + ChainNotConfiguredError, + type ConnectorAlreadyConnectedErrorType, + ConnectorAlreadyConnectedError, + type ConnectorNotFoundErrorType, + ConnectorNotFoundError, + type ConnectorAccountNotFoundErrorType, + ConnectorAccountNotFoundError, + type ConnectorChainMismatchErrorType, + ConnectorChainMismatchError, + type ConnectorUnavailableReconnectingErrorType, + ConnectorUnavailableReconnectingError, + type ProviderNotFoundErrorType, + ProviderNotFoundError, + type SwitchChainNotSupportedErrorType, + SwitchChainNotSupportedError, + // Storage + type CreateStorageParameters, + type Storage, + createStorage, + noopStorage, + // Transports + custom, + fallback, + http, + webSocket, + unstable_connector, + type Transport, + // Types + type Register, + type ResolvedRegister, + // Utilities + cookieStorage, + cookieToInitialState, + deepEqual, + deserialize, + normalizeChainId, + parseCookie, + serialize, +} from '@wagmi/core' + +//////////////////////////////////////////////////////////////////////////////// +// Version +//////////////////////////////////////////////////////////////////////////////// + +export { version } from '../version.js' diff --git a/wagmi-project/packages/react/src/exports/query.test.ts b/wagmi-project/packages/react/src/exports/query.test.ts new file mode 100644 index 000000000..002b6abaa --- /dev/null +++ b/wagmi-project/packages/react/src/exports/query.test.ts @@ -0,0 +1,100 @@ +import { expect, test } from 'vitest' + +import * as query from './query.js' + +test('exports', () => { + expect(Object.keys(query)).toMatchInlineSnapshot(` + [ + "callQueryKey", + "callQueryOptions", + "connectMutationOptions", + "deployContractMutationOptions", + "disconnectMutationOptions", + "estimateFeesPerGasQueryKey", + "estimateFeesPerGasQueryOptions", + "estimateGasQueryKey", + "estimateGasQueryOptions", + "estimateMaxPriorityFeePerGasQueryKey", + "estimateMaxPriorityFeePerGasQueryOptions", + "getBalanceQueryKey", + "getBalanceQueryOptions", + "getBlockQueryKey", + "getBlockQueryOptions", + "getBlockNumberQueryKey", + "getBlockNumberQueryOptions", + "getBlockTransactionCountQueryKey", + "getBlockTransactionCountQueryOptions", + "getBytecodeQueryKey", + "getBytecodeQueryOptions", + "getCallsStatusQueryKey", + "getCallsStatusQueryOptions", + "getCapabilitiesQueryKey", + "getCapabilitiesQueryOptions", + "getConnectorClientQueryKey", + "getConnectorClientQueryOptions", + "getEnsAddressQueryKey", + "getEnsAddressQueryOptions", + "getEnsAvatarQueryKey", + "getEnsAvatarQueryOptions", + "getEnsNameQueryKey", + "getEnsNameQueryOptions", + "getEnsResolverQueryKey", + "getEnsResolverQueryOptions", + "getEnsTextQueryKey", + "getEnsTextQueryOptions", + "getFeeHistoryQueryKey", + "getFeeHistoryQueryOptions", + "getGasPriceQueryKey", + "getGasPriceQueryOptions", + "getProofQueryKey", + "getProofQueryOptions", + "getStorageAtQueryKey", + "getStorageAtQueryOptions", + "getTokenQueryKey", + "getTokenQueryOptions", + "getTransactionQueryKey", + "getTransactionQueryOptions", + "getTransactionConfirmationsQueryKey", + "getTransactionConfirmationsQueryOptions", + "getTransactionCountQueryKey", + "getTransactionCountQueryOptions", + "getTransactionReceiptQueryKey", + "getTransactionReceiptQueryOptions", + "getWalletClientQueryKey", + "getWalletClientQueryOptions", + "infiniteReadContractsQueryKey", + "infiniteReadContractsQueryOptions", + "prepareTransactionRequestQueryKey", + "prepareTransactionRequestQueryOptions", + "readContractQueryKey", + "readContractQueryOptions", + "readContractsQueryKey", + "readContractsQueryOptions", + "reconnectMutationOptions", + "sendCallsMutationOptions", + "showCallsStatusMutationOptions", + "sendTransactionMutationOptions", + "signMessageMutationOptions", + "signTypedDataMutationOptions", + "switchAccountMutationOptions", + "simulateContractQueryKey", + "simulateContractQueryOptions", + "switchChainMutationOptions", + "verifyMessageQueryKey", + "verifyMessageQueryOptions", + "verifyTypedDataQueryKey", + "verifyTypedDataQueryOptions", + "waitForCallsStatusQueryKey", + "waitForCallsStatusQueryOptions", + "waitForTransactionReceiptQueryKey", + "waitForTransactionReceiptQueryOptions", + "watchAssetMutationOptions", + "writeContractMutationOptions", + "hashFn", + "structuralSharing", + "useInfiniteQuery", + "useMutation", + "useQuery", + ] + `) +}) diff --git a/wagmi-project/packages/react/src/exports/query.ts b/wagmi-project/packages/react/src/exports/query.ts new file mode 100644 index 000000000..ff91fee2d --- /dev/null +++ b/wagmi-project/packages/react/src/exports/query.ts @@ -0,0 +1,19 @@ +//////////////////////////////////////////////////////////////////////////////// +// @wagmi/core/query +//////////////////////////////////////////////////////////////////////////////// + +// biome-ignore lint/performance/noBarrelFile: entrypoint module +// biome-ignore lint/performance/noReExportAll: entrypoint module +export * from '@wagmi/core/query' + +export { + type UseInfiniteQueryParameters, + type UseInfiniteQueryReturnType, + type UseMutationParameters, + type UseMutationReturnType, + type UseQueryParameters, + type UseQueryReturnType, + useInfiniteQuery, + useMutation, + useQuery, +} from '../utils/query.js' diff --git a/wagmi-project/packages/react/src/hooks/codegen/createUseReadContract.test-d.ts b/wagmi-project/packages/react/src/hooks/codegen/createUseReadContract.test-d.ts new file mode 100644 index 000000000..f0331efed --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/codegen/createUseReadContract.test-d.ts @@ -0,0 +1,152 @@ +import { abi, mainnet, optimism } from '@wagmi/test' +import { assertType, expectTypeOf, test } from 'vitest' + +import { createUseReadContract } from './createUseReadContract.js' + +test('default', () => { + const useReadErc20 = createUseReadContract({ + abi: abi.erc20, + }) + + const result = useReadErc20({ + functionName: 'balanceOf', + args: ['0x'], + chainId: 123, + }) + expectTypeOf(result.data).toEqualTypeOf() +}) + +test('select data', () => { + const useReadErc20 = createUseReadContract({ + abi: abi.erc20, + }) + + const result = useReadErc20({ + address: '0x', + functionName: 'balanceOf', + args: ['0x'], + query: { + select(data) { + expectTypeOf(data).toEqualTypeOf() + return data?.toString() + }, + }, + }) + expectTypeOf(result.data).toEqualTypeOf() +}) + +test('multichain address', () => { + const useReadErc20 = createUseReadContract({ + abi: abi.erc20, + address: { + [mainnet.id]: '0x', + [optimism.id]: '0x', + }, + }) + + const result = useReadErc20({ + functionName: 'balanceOf', + args: ['0x'], + chainId: mainnet.id, + // ^? + }) + assertType(result.data) + + useReadErc20({ + functionName: 'balanceOf', + args: ['0x'], + // @ts-expect-error chain id must match address keys + chainId: 420, + }) + + useReadErc20({ + functionName: 'balanceOf', + args: ['0x'], + // @ts-expect-error address not allowed + address: '0x', + }) +}) + +test('overloads', () => { + const useReadViewOverloads = createUseReadContract({ + abi: abi.viewOverloads, + }) + + const result1 = useReadViewOverloads({ + functionName: 'foo', + }) + assertType(result1.data) + + const result2 = useReadViewOverloads({ + functionName: 'foo', + args: [], + }) + assertType(result2.data) + + const result3 = useReadViewOverloads({ + functionName: 'foo', + args: ['0x'], + }) + // @ts-ignore – TODO: Fix https://github.com/wevm/viem/issues/1916 + assertType(result3.data) + + const result4 = useReadViewOverloads({ + functionName: 'foo', + args: ['0x', '0x'], + }) + assertType< + | { + foo: `0x${string}` + bar: `0x${string}` + } + | undefined + // @ts-ignore – TODO: Fix https://github.com/wevm/viem/issues/1916 + >(result4.data) +}) + +test('functionName', () => { + const useReadErc20BalanceOf = createUseReadContract({ + abi: abi.erc20, + address: '0x', + functionName: 'balanceOf', + }) + + const result = useReadErc20BalanceOf({ + args: ['0x'], + chainId: 1, + }) + expectTypeOf(result.data).toEqualTypeOf() +}) + +test('functionName with overloads', () => { + const useReadViewOverloads = createUseReadContract({ + abi: abi.viewOverloads, + functionName: 'foo', + }) + + const result1 = useReadViewOverloads() + assertType(result1.data) + + const result2 = useReadViewOverloads({ + args: [], + }) + assertType(result2.data) + + const result3 = useReadViewOverloads({ + args: ['0x'], + }) + // @ts-ignore – TODO: Fix https://github.com/wevm/viem/issues/1916 + assertType(result3.data) + + const result4 = useReadViewOverloads({ + args: ['0x', '0x'], + }) + assertType< + | { + foo: `0x${string}` + bar: `0x${string}` + } + | undefined + // @ts-ignore – TODO: Fix https://github.com/wevm/viem/issues/1916 + >(result4.data) +}) diff --git a/wagmi-project/packages/react/src/hooks/codegen/createUseReadContract.test.ts b/wagmi-project/packages/react/src/hooks/codegen/createUseReadContract.test.ts new file mode 100644 index 000000000..4419c030c --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/codegen/createUseReadContract.test.ts @@ -0,0 +1,177 @@ +import { abi, address, chain } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { expect, test } from 'vitest' + +import { createUseReadContract } from './createUseReadContract.js' + +test('default', async () => { + const useReadWagmiMintExample = createUseReadContract({ + address: address.wagmiMintExample, + abi: abi.wagmiMintExample, + }) + + const { result } = renderHook(() => + useReadWagmiMintExample({ + functionName: 'balanceOf', + args: ['0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC'], + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": 4n, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "readContract", + { + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "args": [ + "0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC", + ], + "chainId": 1, + "functionName": "balanceOf", + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('multichain', async () => { + const useReadWagmiMintExample = createUseReadContract({ + address: { + [chain.mainnet.id]: address.wagmiMintExample, + [chain.mainnet2.id]: address.wagmiMintExample, + }, + abi: abi.wagmiMintExample, + }) + + const { result } = renderHook(() => + useReadWagmiMintExample({ + functionName: 'balanceOf', + args: ['0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC'], + chainId: chain.mainnet2.id, + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": 4n, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "readContract", + { + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "args": [ + "0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC", + ], + "chainId": 456, + "functionName": "balanceOf", + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('functionName', async () => { + const useReadWagmiMintExampleBalanceOf = createUseReadContract({ + address: address.wagmiMintExample, + abi: abi.wagmiMintExample, + functionName: 'balanceOf', + }) + + const { result } = renderHook(() => + useReadWagmiMintExampleBalanceOf({ + args: ['0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC'], + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": 4n, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "readContract", + { + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "args": [ + "0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC", + ], + "chainId": 1, + "functionName": "balanceOf", + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) diff --git a/wagmi-project/packages/react/src/hooks/codegen/createUseReadContract.ts b/wagmi-project/packages/react/src/hooks/codegen/createUseReadContract.ts new file mode 100644 index 000000000..1c5f509e5 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/codegen/createUseReadContract.ts @@ -0,0 +1,127 @@ +import type { + Config, + ReadContractErrorType, + ReadContractParameters, + ResolvedRegister, +} from '@wagmi/core' +import type { + ScopeKeyParameter, + UnionCompute, + UnionExactPartial, + UnionStrictOmit, +} from '@wagmi/core/internal' +import type { + ReadContractData, + ReadContractQueryFnData, + ReadContractQueryKey, +} from '@wagmi/core/query' +import type { + Abi, + Address, + ContractFunctionArgs, + ContractFunctionName, +} from 'viem' + +import type { ConfigParameter, QueryParameter } from '../../types/properties.js' +import { useAccount } from '../useAccount.js' +import { useChainId } from '../useChainId.js' +import { useConfig } from '../useConfig.js' +import { + type UseReadContractReturnType, + useReadContract, +} from '../useReadContract.js' + +type stateMutability = 'pure' | 'view' + +export type CreateUseReadContractParameters< + abi extends Abi | readonly unknown[], + address extends Address | Record | undefined = undefined, + functionName extends + | ContractFunctionName + | undefined = undefined, +> = { + abi: abi | Abi | readonly unknown[] + address?: address | Address | Record | undefined + functionName?: + | functionName + | ContractFunctionName + | undefined +} + +export type CreateUseReadContractReturnType< + abi extends Abi | readonly unknown[], + address extends Address | Record | undefined, + functionName extends ContractFunctionName | undefined, + /// + omittedProperties extends 'abi' | 'address' | 'chainId' | 'functionName' = + | 'abi' + | (address extends undefined ? never : 'address') + | (address extends Record ? 'chainId' : never) + | (functionName extends undefined ? never : 'functionName'), +> = < + name extends functionName extends ContractFunctionName + ? functionName + : ContractFunctionName, + args extends ContractFunctionArgs, + config extends Config = ResolvedRegister['config'], + selectData = ReadContractData, +>( + parameters?: UnionCompute< + UnionExactPartial< + UnionStrictOmit< + ReadContractParameters, + omittedProperties + > + > & + ScopeKeyParameter & + ConfigParameter & + QueryParameter< + ReadContractQueryFnData, + ReadContractErrorType, + selectData, + ReadContractQueryKey + > + > & + (address extends Record + ? { chainId?: keyof address | undefined } + : unknown), +) => UseReadContractReturnType + +export function createUseReadContract< + const abi extends Abi | readonly unknown[], + const address extends + | Address + | Record + | undefined = undefined, + functionName extends + | ContractFunctionName + | undefined = undefined, +>( + props: CreateUseReadContractParameters, +): CreateUseReadContractReturnType { + if (props.address !== undefined && typeof props.address === 'object') + return (parameters) => { + const config = useConfig(parameters) + const configChainId = useChainId({ config }) + const account = useAccount({ config }) + const chainId = + (parameters as { chainId?: number })?.chainId ?? + account.chainId ?? + configChainId + return useReadContract({ + ...(parameters as any), + ...(props.functionName ? { functionName: props.functionName } : {}), + address: props.address?.[chainId], + abi: props.abi, + }) + } + + return (parameters) => { + return useReadContract({ + ...(parameters as any), + ...(props.address ? { address: props.address } : {}), + ...(props.functionName ? { functionName: props.functionName } : {}), + abi: props.abi, + }) + } +} diff --git a/wagmi-project/packages/react/src/hooks/codegen/createUseSimulateContract.test-d.ts b/wagmi-project/packages/react/src/hooks/codegen/createUseSimulateContract.test-d.ts new file mode 100644 index 000000000..5388e6910 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/codegen/createUseSimulateContract.test-d.ts @@ -0,0 +1,199 @@ +import { abi, mainnet, optimism } from '@wagmi/test' +import type { Address } from 'viem' +import { assertType, expectTypeOf, test } from 'vitest' + +import { createUseSimulateContract } from './createUseSimulateContract.js' + +test('default', () => { + const useSimulateErc20 = createUseSimulateContract({ + abi: abi.erc20, + }) + + const result = useSimulateErc20({ + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + chainId: 123, + }) + result.data?.request.chainId + expectTypeOf(result.data).toMatchTypeOf< + | { + result: boolean + request: { + chainId: 123 + abi: readonly [ + { + readonly name: 'transferFrom' + readonly type: 'function' + readonly stateMutability: 'nonpayable' + readonly inputs: readonly [ + { readonly type: 'address'; readonly name: 'sender' }, + { readonly type: 'address'; readonly name: 'recipient' }, + { readonly type: 'uint256'; readonly name: 'amount' }, + ] + readonly outputs: readonly [{ type: 'bool' }] + }, + ] + functionName: 'transferFrom' + args: readonly [Address, Address, bigint] + } + } + | undefined + >() +}) + +test('select data', () => { + const useSimulateErc20 = createUseSimulateContract({ + abi: abi.erc20, + }) + + const result = useSimulateErc20({ + address: '0x', + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + query: { + select(data) { + expectTypeOf(data.result).toEqualTypeOf() + return data?.toString() + }, + }, + }) + expectTypeOf(result.data).toEqualTypeOf() +}) + +test('multichain address', () => { + const useSimulateErc20 = createUseSimulateContract({ + abi: abi.erc20, + address: { + [mainnet.id]: '0x', + [optimism.id]: '0x', + }, + }) + + const result = useSimulateErc20({ + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + chainId: optimism.id, + }) + expectTypeOf(result.data?.result).toEqualTypeOf() + + useSimulateErc20({ + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + // @ts-expect-error chain id must match address keys + chainId: 420, + }) + + useSimulateErc20({ + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + // @ts-expect-error address not allowed + address: '0x', + }) +}) + +test('overloads', () => { + const useSimulateWriteOverloads = createUseSimulateContract({ + abi: abi.writeOverloads, + }) + + const result1 = useSimulateWriteOverloads({ + functionName: 'foo', + }) + assertType(result1.data?.result) + + const result2 = useSimulateWriteOverloads({ + functionName: 'foo', + args: [], + }) + assertType(result2.data?.result) + + const result3 = useSimulateWriteOverloads({ + functionName: 'foo', + args: ['0x'], + }) + // @ts-ignore – TODO: Fix https://github.com/wevm/viem/issues/1916 + assertType(result3.data?.result) + + const result4 = useSimulateWriteOverloads({ + functionName: 'foo', + args: ['0x', '0x'], + }) + assertType< + | { + foo: `0x${string}` + bar: `0x${string}` + } + | undefined + // @ts-ignore – TODO: Fix https://github.com/wevm/viem/issues/1916 + >(result4.data?.result) +}) + +test('functionName', () => { + const useSimulateErc20 = createUseSimulateContract({ + abi: abi.erc20, + functionName: 'transferFrom', + }) + + const result = useSimulateErc20({ + args: ['0x', '0x', 123n], + chainId: 123, + }) + result.data?.request.chainId + expectTypeOf(result.data).toMatchTypeOf< + | { + result: boolean + request: { + chainId: 123 + abi: readonly [ + { + readonly name: 'transferFrom' + readonly type: 'function' + readonly stateMutability: 'nonpayable' + readonly inputs: readonly [ + { readonly type: 'address'; readonly name: 'sender' }, + { readonly type: 'address'; readonly name: 'recipient' }, + { readonly type: 'uint256'; readonly name: 'amount' }, + ] + readonly outputs: readonly [{ type: 'bool' }] + }, + ] + functionName: 'transferFrom' + args: readonly [Address, Address, bigint] + } + } + | undefined + >() +}) + +test('functionName with overloads', () => { + const useSimulateWriteOverloads = createUseSimulateContract({ + abi: abi.writeOverloads, + functionName: 'foo', + }) + + const result1 = useSimulateWriteOverloads({}) + assertType(result1.data?.result) + + const result2 = useSimulateWriteOverloads({ + args: [], + }) + assertType(result2.data?.result) + + const result3 = useSimulateWriteOverloads({ + args: ['0x'], + }) + // @ts-ignore – TODO: Fix https://github.com/wevm/viem/issues/1916 + assertType(result3.data?.result) + + const result4 = useSimulateWriteOverloads({ + args: ['0x', '0x'], + }) + assertType< + | { + foo: `0x${string}` + bar: `0x${string}` + } + | undefined + // @ts-ignore – TODO: Fix https://github.com/wevm/viem/issues/1916 + >(result4.data?.result) +}) diff --git a/wagmi-project/packages/react/src/hooks/codegen/createUseSimulateContract.test.ts b/wagmi-project/packages/react/src/hooks/codegen/createUseSimulateContract.test.ts new file mode 100644 index 000000000..c6e70b90c --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/codegen/createUseSimulateContract.test.ts @@ -0,0 +1,258 @@ +import { connect, disconnect } from '@wagmi/core' +import { abi, address, chain, config } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { expect, test } from 'vitest' + +import { createUseSimulateContract } from './createUseSimulateContract.js' + +const connector = config.connectors[0]! + +test('default', async () => { + await connect(config, { connector }) + + const useSimulateWagmiMintExample = createUseSimulateContract({ + address: address.wagmiMintExample, + abi: abi.wagmiMintExample, + }) + + const { result } = renderHook(() => + useSimulateWagmiMintExample({ + functionName: 'mint', + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": { + "chainId": 1, + "request": { + "abi": [ + { + "inputs": [], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + ], + "account": { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "type": "json-rpc", + }, + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "args": undefined, + "chainId": 1, + "dataSuffix": undefined, + "functionName": "mint", + }, + "result": undefined, + }, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "simulateContract", + { + "account": { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "type": "json-rpc", + }, + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "chainId": 1, + "functionName": "mint", + }, + ], + "refetch": [Function], + "status": "success", + } + `) + + await disconnect(config, { connector }) +}) + +test('multichain', async () => { + await connect(config, { connector }) + + const useReadWagmiMintExample = createUseSimulateContract({ + address: { + [chain.mainnet.id]: address.wagmiMintExample, + [chain.mainnet2.id]: address.wagmiMintExample, + }, + abi: abi.wagmiMintExample, + }) + + const { result } = renderHook(() => + useReadWagmiMintExample({ + functionName: 'mint', + chainId: chain.mainnet2.id, + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": { + "chainId": 456, + "request": { + "abi": [ + { + "inputs": [], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + ], + "account": { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "type": "json-rpc", + }, + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "args": undefined, + "chainId": 456, + "dataSuffix": undefined, + "functionName": "mint", + }, + "result": undefined, + }, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "simulateContract", + { + "account": { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "type": "json-rpc", + }, + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "chainId": 456, + "functionName": "mint", + }, + ], + "refetch": [Function], + "status": "success", + } + `) + + await disconnect(config, { connector }) +}) + +test('functionName', async () => { + await connect(config, { connector }) + + const useSimulateWagmiMintExample = createUseSimulateContract({ + address: address.wagmiMintExample, + abi: abi.wagmiMintExample, + functionName: 'mint', + }) + + const { result } = renderHook(() => useSimulateWagmiMintExample({})) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": { + "chainId": 1, + "request": { + "abi": [ + { + "inputs": [], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + ], + "account": { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "type": "json-rpc", + }, + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "args": undefined, + "chainId": 1, + "dataSuffix": undefined, + "functionName": "mint", + }, + "result": undefined, + }, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "simulateContract", + { + "account": { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "type": "json-rpc", + }, + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "chainId": 1, + "functionName": "mint", + }, + ], + "refetch": [Function], + "status": "success", + } + `) + + await disconnect(config, { connector }) +}) diff --git a/wagmi-project/packages/react/src/hooks/codegen/createUseSimulateContract.ts b/wagmi-project/packages/react/src/hooks/codegen/createUseSimulateContract.ts new file mode 100644 index 000000000..51758b995 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/codegen/createUseSimulateContract.ts @@ -0,0 +1,120 @@ +import type { + Config, + ResolvedRegister, + SimulateContractErrorType, + SimulateContractParameters, +} from '@wagmi/core' +import type { ScopeKeyParameter, UnionExactPartial } from '@wagmi/core/internal' +import type { + SimulateContractData, + SimulateContractQueryFnData, + SimulateContractQueryKey, +} from '@wagmi/core/query' +import type { + Abi, + Address, + ContractFunctionArgs, + ContractFunctionName, +} from 'viem' + +import type { ConfigParameter, QueryParameter } from '../../types/properties.js' +import { useAccount } from '../useAccount.js' +import { useChainId } from '../useChainId.js' +import { useConfig } from '../useConfig.js' +import { + type UseSimulateContractReturnType, + useSimulateContract, +} from '../useSimulateContract.js' + +type stateMutability = 'nonpayable' | 'payable' + +export type CreateUseSimulateContractParameters< + abi extends Abi | readonly unknown[], + address extends Address | Record | undefined = undefined, + functionName extends + | ContractFunctionName + | undefined = undefined, +> = { + abi: abi | Abi | readonly unknown[] + address?: address | Address | Record | undefined + functionName?: + | functionName + | ContractFunctionName + | undefined +} + +export type CreateUseSimulateContractReturnType< + abi extends Abi | readonly unknown[], + address extends Address | Record | undefined, + functionName extends ContractFunctionName | undefined, +> = < + name extends functionName extends ContractFunctionName + ? functionName + : ContractFunctionName, + args extends ContractFunctionArgs, + config extends Config = ResolvedRegister['config'], + chainId extends config['chains'][number]['id'] | undefined = undefined, + selectData = SimulateContractData, +>( + parameters?: { + abi?: undefined + address?: address extends undefined ? Address : undefined + functionName?: functionName extends undefined ? name : undefined + chainId?: address extends Record + ? + | keyof address + | (chainId extends keyof address ? chainId : never) + | undefined + : chainId | number | undefined + } & UnionExactPartial< + // TODO: Take `abi` and `address` from above and omit from below (currently breaks inference) + SimulateContractParameters + > & + ScopeKeyParameter & + ConfigParameter & + QueryParameter< + SimulateContractQueryFnData, + SimulateContractErrorType, + selectData, + SimulateContractQueryKey + >, +) => UseSimulateContractReturnType + +export function createUseSimulateContract< + const abi extends Abi | readonly unknown[], + const address extends + | Address + | Record + | undefined = undefined, + functionName extends + | ContractFunctionName + | undefined = undefined, +>( + props: CreateUseSimulateContractParameters, +): CreateUseSimulateContractReturnType { + if (props.address !== undefined && typeof props.address === 'object') + return (parameters) => { + const config = useConfig(parameters) + const configChainId = useChainId({ config }) + const account = useAccount({ config }) + const chainId = + (parameters as { chainId?: number })?.chainId ?? + account.chainId ?? + configChainId + return useSimulateContract({ + ...(parameters as any), + ...(props.functionName ? { functionName: props.functionName } : {}), + address: props.address?.[chainId], + abi: props.abi, + }) + } + + return (parameters) => { + return useSimulateContract({ + ...(parameters as any), + ...(props.address ? { address: props.address } : {}), + ...(props.functionName ? { functionName: props.functionName } : {}), + abi: props.abi, + }) + } +} diff --git a/wagmi-project/packages/react/src/hooks/codegen/createUseWatchContractEvent.test-d.ts b/wagmi-project/packages/react/src/hooks/codegen/createUseWatchContractEvent.test-d.ts new file mode 100644 index 000000000..b3a69775b --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/codegen/createUseWatchContractEvent.test-d.ts @@ -0,0 +1,123 @@ +import { http, createConfig, webSocket } from '@wagmi/core' +import { abi, mainnet, optimism } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' + +import { createUseWatchContractEvent } from './createUseWatchContractEvent.js' + +test('default', () => { + const useWatchErc20Event = createUseWatchContractEvent({ + abi: abi.erc20, + }) + + useWatchErc20Event({ + eventName: 'Transfer', + chainId: 123, + onLogs(logs) { + expectTypeOf(logs[0]!.eventName).toEqualTypeOf<'Transfer'>() + expectTypeOf(logs[0]!.args).toEqualTypeOf<{ + from?: `0x${string}` | undefined + to?: `0x${string}` | undefined + value?: bigint | undefined + }>() + }, + }) +}) + +test('multichain address', () => { + const useWatchErc20Event = createUseWatchContractEvent({ + abi: abi.erc20, + address: { + [mainnet.id]: '0x', + [optimism.id]: '0x', + }, + }) + + useWatchErc20Event({ + eventName: 'Transfer', + chainId: mainnet.id, + // ^? + }) + + useWatchErc20Event({ + eventName: 'Transfer', + // @ts-expect-error chain id must match address keys + chainId: 420, + }) + + useWatchErc20Event({ + eventName: 'Transfer', + // @ts-expect-error chain id must match address keys + address: '0x', + }) +}) + +test('differing transports', () => { + const useWatchErc20Event = createUseWatchContractEvent({ + abi: abi.erc20, + }) + + const config = createConfig({ + chains: [mainnet, optimism], + transports: { + [mainnet.id]: http(), + [optimism.id]: webSocket(), + }, + }) + + useWatchErc20Event({ + config, + poll: false, + address: '0x', + onLogs() {}, + }) + + useWatchErc20Event({ + config, + chainId: mainnet.id, + poll: true, + address: '0x', + onLogs() {}, + }) + useWatchErc20Event({ + config, + chainId: mainnet.id, + // @ts-expect-error poll required since http transport + poll: false, + address: '0x', + onLogs() {}, + }) + + useWatchErc20Event({ + config, + chainId: optimism.id, + poll: true, + address: '0x', + onLogs() {}, + }) + useWatchErc20Event({ + config, + chainId: optimism.id, + poll: false, + address: '0x', + onLogs() {}, + }) +}) + +test('eventName', () => { + const useWatchErc20Event = createUseWatchContractEvent({ + abi: abi.erc20, + eventName: 'Transfer', + }) + + useWatchErc20Event({ + chainId: 123, + onLogs(logs) { + expectTypeOf(logs[0]!.eventName).toEqualTypeOf<'Transfer'>() + expectTypeOf(logs[0]!.args).toEqualTypeOf<{ + from?: `0x${string}` | undefined + to?: `0x${string}` | undefined + value?: bigint | undefined + }>() + }, + }) +}) diff --git a/wagmi-project/packages/react/src/hooks/codegen/createUseWatchContractEvent.test.ts b/wagmi-project/packages/react/src/hooks/codegen/createUseWatchContractEvent.test.ts new file mode 100644 index 000000000..61464fe3d --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/codegen/createUseWatchContractEvent.test.ts @@ -0,0 +1,44 @@ +import { abi, address, chain } from '@wagmi/test' +import { renderHook } from '@wagmi/test/react' +import type { WatchEventOnLogsParameter } from 'viem' +import { test } from 'vitest' + +import { createUseWatchContractEvent } from './createUseWatchContractEvent.js' + +test('default', async () => { + const useWatchErc20Event = createUseWatchContractEvent({ + address: address.usdc, + abi: abi.wagmiMintExample, + }) + + let logs: WatchEventOnLogsParameter = [] + renderHook(() => + useWatchErc20Event({ + eventName: 'Transfer', + onLogs(next) { + logs = logs.concat(next) + }, + }), + ) +}) + +test('multichain', async () => { + const useWatchErc20Event = createUseWatchContractEvent({ + address: { + [chain.mainnet.id]: address.usdc, + [chain.mainnet2.id]: address.usdc, + }, + abi: abi.wagmiMintExample, + }) + + let logs: WatchEventOnLogsParameter = [] + renderHook(() => + useWatchErc20Event({ + eventName: 'Transfer', + chainId: chain.mainnet2.id, + onLogs(next) { + logs = logs.concat(next) + }, + }), + ) +}) diff --git a/wagmi-project/packages/react/src/hooks/codegen/createUseWatchContractEvent.ts b/wagmi-project/packages/react/src/hooks/codegen/createUseWatchContractEvent.ts new file mode 100644 index 000000000..e453b9442 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/codegen/createUseWatchContractEvent.ts @@ -0,0 +1,101 @@ +import type { + Config, + ResolvedRegister, + WatchContractEventParameters, +} from '@wagmi/core' +import type { + UnionCompute, + UnionExactPartial, + UnionStrictOmit, +} from '@wagmi/core/internal' +import type { Abi, Address, ContractEventName } from 'viem' + +import type { + ConfigParameter, + EnabledParameter, +} from '../../types/properties.js' +import { useAccount } from '../useAccount.js' +import { useChainId } from '../useChainId.js' +import { useConfig } from '../useConfig.js' +import { useWatchContractEvent } from '../useWatchContractEvent.js' + +export type CreateUseWatchContractEventParameters< + abi extends Abi | readonly unknown[], + address extends Address | Record | undefined = undefined, + eventName extends ContractEventName | undefined = undefined, +> = { + abi: abi | Abi | readonly unknown[] + address?: address | Address | Record | undefined + eventName?: eventName | ContractEventName | undefined +} + +export type CreateUseWatchContractEventReturnType< + abi extends Abi | readonly unknown[], + address extends Address | Record | undefined, + eventName extends ContractEventName | undefined, + /// + omittedProperties extends 'abi' | 'address' | 'chainId' | 'eventName' = + | 'abi' + | (address extends undefined ? never : 'address') + | (address extends Record ? 'chainId' : never) + | (eventName extends undefined ? never : 'eventName'), +> = < + name extends eventName extends ContractEventName + ? eventName + : ContractEventName, + strict extends boolean | undefined = undefined, + config extends Config = ResolvedRegister['config'], + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +>( + parameters?: UnionCompute< + UnionExactPartial< + UnionStrictOmit< + WatchContractEventParameters, + omittedProperties + > + > & + ConfigParameter & + EnabledParameter + > & + (address extends Record + ? { chainId?: keyof address | undefined } + : unknown), +) => void + +export function createUseWatchContractEvent< + const abi extends Abi | readonly unknown[], + const address extends + | Address + | Record + | undefined = undefined, + eventName extends ContractEventName | undefined = undefined, +>( + props: CreateUseWatchContractEventParameters, +): CreateUseWatchContractEventReturnType { + if (props.address !== undefined && typeof props.address === 'object') + return (parameters) => { + const config = useConfig(parameters) + const configChainId = useChainId({ config }) + const account = useAccount({ config }) + const chainId = + (parameters as { chainId?: number })?.chainId ?? + account.chainId ?? + configChainId + return useWatchContractEvent({ + ...(parameters as any), + ...(props.eventName ? { eventName: props.eventName } : {}), + address: props.address?.[chainId], + abi: props.abi, + }) + } + + return (parameters) => { + return useWatchContractEvent({ + ...(parameters as any), + ...(props.address ? { address: props.address } : {}), + ...(props.eventName ? { eventName: props.eventName } : {}), + abi: props.abi, + }) + } +} diff --git a/wagmi-project/packages/react/src/hooks/codegen/createUseWriteContract.test-d.ts b/wagmi-project/packages/react/src/hooks/codegen/createUseWriteContract.test-d.ts new file mode 100644 index 000000000..14906fda4 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/codegen/createUseWriteContract.test-d.ts @@ -0,0 +1,153 @@ +import { abi } from '@wagmi/test' +import type { Address, Hash } from 'viem' +import { mainnet, optimism } from 'viem/chains' +import { expectTypeOf, test } from 'vitest' + +import { useSimulateContract } from '../useSimulateContract.js' +import { createUseWriteContract } from './createUseWriteContract.js' + +const contextValue = { foo: 'bar' } as const + +test('default', () => { + const useWriteErc20 = createUseWriteContract({ + abi: abi.erc20, + }) + + const { writeContract } = useWriteErc20() + writeContract({ + address: '0x', + functionName: 'transfer', + args: ['0x', 123n], + }) +}) + +test('context', () => { + const useWriteErc20 = createUseWriteContract({ + abi: abi.erc20, + }) + + const { writeContract } = useWriteErc20({ + mutation: { + onMutate() { + return contextValue + }, + onSuccess(data, variables, context) { + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(variables.functionName).toEqualTypeOf() + expectTypeOf(variables.args).toEqualTypeOf< + readonly unknown[] | undefined + >() + expectTypeOf(context).toEqualTypeOf() + }, + }, + }) + + writeContract( + { + address: '0x', + functionName: 'transfer', + args: ['0x', 123n], + }, + { + onSuccess(data, variables, context) { + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(variables.functionName).toEqualTypeOf<'transfer'>() + expectTypeOf(variables.args).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + }, + ) +}) + +test('multichain address', () => { + const useWriteErc20 = createUseWriteContract({ + abi: abi.erc20, + address: { + [mainnet.id]: '0x', + [optimism.id]: '0x', + }, + }) + + const { writeContract } = useWriteErc20() + writeContract({ + functionName: 'transfer', + args: ['0x', 123n], + chainId: mainnet.id, + // ^? + }) + + writeContract({ + functionName: 'transfer', + args: ['0x', 123n], + // @ts-expect-error chain id must match address keys + chainId: 420, + }) + + writeContract({ + // @ts-expect-error address not allowed + address: '0x', + functionName: 'transfer', + args: ['0x', 123n], + }) +}) + +test('overloads', () => { + const useWriteOverloads = createUseWriteContract({ + abi: abi.writeOverloads, + address: { + [mainnet.id]: '0x', + [optimism.id]: '0x', + }, + }) + + const { writeContract } = useWriteOverloads() + writeContract({ + functionName: 'foo', + args: [], + }) + + writeContract({ + functionName: 'foo', + args: ['0x'], + }) + + writeContract({ + functionName: 'foo', + args: ['0x', '0x'], + }) +}) + +test('useSimulateContract', () => { + const useWriteErc20 = createUseWriteContract({ + abi: abi.erc20, + address: { + [mainnet.id]: '0x', + [optimism.id]: '0x', + }, + }) + + const { data } = useSimulateContract({ + address: '0x', + abi: abi.erc20, + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + chainId: 1, + }) + const { writeContract } = useWriteErc20() + + const request = data?.request + if (request) writeContract(request) +}) + +test('functionName', () => { + const useWriteErc20 = createUseWriteContract({ + abi: abi.erc20, + functionName: 'transfer', + }) + + const { writeContract } = useWriteErc20() + writeContract({ + address: '0x', + args: ['0x', 123n], + }) +}) diff --git a/wagmi-project/packages/react/src/hooks/codegen/createUseWriteContract.test.ts b/wagmi-project/packages/react/src/hooks/codegen/createUseWriteContract.test.ts new file mode 100644 index 000000000..e89dc6214 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/codegen/createUseWriteContract.test.ts @@ -0,0 +1,13 @@ +import { abi } from '@wagmi/test' +import { renderHook } from '@wagmi/test/react' +import { test } from 'vitest' + +import { createUseWriteContract } from './createUseWriteContract.js' + +test('default', () => { + const useWriteErc20 = createUseWriteContract({ + abi: abi.erc20, + }) + + renderHook(() => useWriteErc20()) +}) diff --git a/wagmi-project/packages/react/src/hooks/codegen/createUseWriteContract.ts b/wagmi-project/packages/react/src/hooks/codegen/createUseWriteContract.ts new file mode 100644 index 000000000..9e58fd973 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/codegen/createUseWriteContract.ts @@ -0,0 +1,297 @@ +import type { MutateOptions } from '@tanstack/react-query' +import type { + Config, + ResolvedRegister, + WriteContractErrorType, +} from '@wagmi/core' +import type { + ChainIdParameter, + Compute, + ConnectorParameter, + SelectChains, + UnionCompute, + UnionStrictOmit, +} from '@wagmi/core/internal' +import type { + WriteContractData, + WriteContractVariables, +} from '@wagmi/core/query' +import { useCallback } from 'react' +import type { + Abi, + Account, + Address, + Chain, + ContractFunctionArgs, + ContractFunctionName, +} from 'viem' +import type { WriteContractParameters as viem_WriteContractParameters } from 'viem/actions' + +import { useAccount } from '../useAccount.js' +import { useChainId } from '../useChainId.js' +import { useConfig } from '../useConfig.js' +import { + type UseWriteContractParameters, + useWriteContract, + type UseWriteContractReturnType as wagmi_UseWriteContractReturnType, +} from '../useWriteContract.js' + +type stateMutability = 'nonpayable' | 'payable' + +export type CreateUseWriteContractParameters< + abi extends Abi | readonly unknown[], + address extends Address | Record | undefined = undefined, + functionName extends + | ContractFunctionName + | undefined = undefined, +> = { + abi: abi | Abi | readonly unknown[] + address?: address | Address | Record | undefined + functionName?: + | functionName + | ContractFunctionName + | undefined +} + +export type CreateUseWriteContractReturnType< + abi extends Abi | readonly unknown[], + address extends Address | Record | undefined, + functionName extends ContractFunctionName | undefined, +> = ( + parameters?: UseWriteContractParameters, +) => Compute< + Omit< + wagmi_UseWriteContractReturnType, + 'writeContract' | 'writeContractAsync' + > & { + writeContract: < + const abi2 extends abi, + name extends functionName extends ContractFunctionName< + abi, + stateMutability + > + ? functionName + : ContractFunctionName, + args extends ContractFunctionArgs, + chainId extends config['chains'][number]['id'], + >( + variables: Variables< + abi2, + functionName, + name, + args, + config, + chainId, + address + >, + options?: + | MutateOptions< + WriteContractData, + WriteContractErrorType, + WriteContractVariables< + abi2, + name, + args, + config, + chainId, + // use `functionName` to make sure it's not union of all possible function names + name + >, + context + > + | undefined, + ) => void + writeContractAsync: < + const abi2 extends abi, + name extends functionName extends ContractFunctionName< + abi, + stateMutability + > + ? functionName + : ContractFunctionName, + args extends ContractFunctionArgs, + chainId extends config['chains'][number]['id'], + >( + variables: Variables< + abi2, + functionName, + name, + args, + config, + chainId, + address + >, + options?: + | MutateOptions< + WriteContractData, + WriteContractErrorType, + WriteContractVariables< + abi2, + name, + args, + config, + chainId, + // use `functionName` to make sure it's not union of all possible function names + name + >, + context + > + | undefined, + ) => Promise + } +> + +export function createUseWriteContract< + const abi extends Abi | readonly unknown[], + const address extends + | Address + | Record + | undefined = undefined, + functionName extends + | ContractFunctionName + | undefined = undefined, +>( + props: CreateUseWriteContractParameters, +): CreateUseWriteContractReturnType { + if (props.address !== undefined && typeof props.address === 'object') + return (parameters) => { + const config = useConfig(parameters) + const result = useWriteContract(parameters) + const configChainId = useChainId({ config }) + const account = useAccount({ config }) + type Args = Parameters + return { + ...(result as any), + writeContract: useCallback( + (...args: Args) => { + let chainId: number | undefined + if (args[0].chainId) chainId = args[0].chainId + else if (args[0].account && args[0].account === account.address) + chainId = account.chainId + else if (args[0].account === undefined) chainId = account.chainId + else chainId = configChainId + + const variables = { + ...(args[0] as any), + address: chainId ? props.address?.[chainId] : undefined, + ...(props.functionName + ? { functionName: props.functionName } + : {}), + abi: props.abi, + } + result.writeContract(variables, args[1] as any) + }, + [ + account.address, + account.chainId, + props, + configChainId, + result.writeContract, + ], + ), + writeContractAsync: useCallback( + (...args: Args) => { + let chainId: number | undefined + if (args[0].chainId) chainId = args[0].chainId + else if (args[0].account && args[0].account === account.address) + chainId = account.chainId + else if (args[0].account === undefined) chainId = account.chainId + else chainId = configChainId + + const variables = { + ...(args[0] as any), + address: chainId ? props.address?.[chainId] : undefined, + ...(props.functionName + ? { functionName: props.functionName } + : {}), + abi: props.abi, + } + return result.writeContractAsync(variables, args[1] as any) + }, + [ + account.address, + account.chainId, + props, + configChainId, + result.writeContractAsync, + ], + ), + } + } + + return (parameters) => { + const result = useWriteContract(parameters) + type Args = Parameters + return { + ...(result as any), + writeContract: useCallback( + (...args: Args) => { + const variables = { + ...(args[0] as any), + ...(props.address ? { address: props.address } : {}), + ...(props.functionName ? { functionName: props.functionName } : {}), + abi: props.abi, + } + result.writeContract(variables, args[1] as any) + }, + [props, result.writeContract], + ), + writeContractAsync: useCallback( + (...args: Args) => { + const variables = { + ...(args[0] as any), + ...(props.address ? { address: props.address } : {}), + ...(props.functionName ? { functionName: props.functionName } : {}), + abi: props.abi, + } + return result.writeContractAsync(variables, args[1] as any) + }, + [props, result.writeContractAsync], + ), + } + } +} + +type Variables< + abi extends Abi | readonly unknown[], + functionName extends ContractFunctionName | undefined, + name extends ContractFunctionName, + args extends ContractFunctionArgs, + config extends Config, + chainId extends config['chains'][number]['id'], + address extends Address | Record | undefined, + /// + allFunctionNames = ContractFunctionName, + chains extends readonly Chain[] = SelectChains, + omittedProperties extends 'abi' | 'address' | 'functionName' = + | 'abi' + | (address extends undefined ? never : 'address') + | (functionName extends undefined ? never : 'functionName'), +> = UnionCompute< + { + [key in keyof chains]: UnionStrictOmit< + viem_WriteContractParameters< + abi, + name, + args, + chains[key], + Account, + chains[key], + allFunctionNames + >, + omittedProperties | 'chain' + > + }[number] & + (address extends Record + ? { + chainId?: + | keyof address + | (chainId extends keyof address ? chainId : never) + | undefined + } + : Compute>) & + ConnectorParameter & { + /** @deprecated */ + __mode?: 'prepared' + } +> diff --git a/wagmi-project/packages/react/src/hooks/useAccount.test-d.ts b/wagmi-project/packages/react/src/hooks/useAccount.test-d.ts new file mode 100644 index 000000000..a22d816d6 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useAccount.test-d.ts @@ -0,0 +1,68 @@ +import type { Connector } from '@wagmi/core' +import type { Address, Chain } from 'viem' +import { expectTypeOf, test } from 'vitest' + +import { useAccount } from './useAccount.js' + +test('states', () => { + const result = useAccount() + + switch (result.status) { + case 'reconnecting': { + expectTypeOf(result).toMatchTypeOf<{ + address: Address | undefined + chain: Chain | undefined + chainId: number | undefined + connector: Connector | undefined + isConnected: boolean + isConnecting: false + isDisconnected: false + isReconnecting: true + status: 'reconnecting' + }>() + break + } + case 'connecting': { + expectTypeOf(result).toMatchTypeOf<{ + address: Address | undefined + chain: Chain | undefined + chainId: number | undefined + connector: Connector | undefined + isConnected: false + isReconnecting: false + isConnecting: true + isDisconnected: false + status: 'connecting' + }>() + break + } + case 'connected': { + expectTypeOf(result).toMatchTypeOf<{ + address: Address + chain: Chain | undefined + chainId: number + connector: Connector + isConnected: true + isConnecting: false + isDisconnected: false + isReconnecting: false + status: 'connected' + }>() + break + } + case 'disconnected': { + expectTypeOf(result).toMatchTypeOf<{ + address: undefined + chain: undefined + chainId: undefined + connector: undefined + isConnected: false + isReconnecting: false + isConnecting: false + isDisconnected: true + status: 'disconnected' + }>() + break + } + } +}) diff --git a/wagmi-project/packages/react/src/hooks/useAccount.test.ts b/wagmi-project/packages/react/src/hooks/useAccount.test.ts new file mode 100644 index 000000000..3c4af3c3f --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useAccount.test.ts @@ -0,0 +1,29 @@ +import { connect, disconnect } from '@wagmi/core' +import { config } from '@wagmi/test' +import { renderHook } from '@wagmi/test/react' +import { Fragment, createElement } from 'react' +import { expect, test } from 'vitest' + +import { useAccount } from './useAccount.js' + +test('default', async () => { + const { result, rerender } = renderHook(() => useAccount()) + + expect(result.current.address).not.toBeDefined() + expect(result.current.status).toEqual('disconnected') + + await connect(config, { connector: config.connectors[0]! }) + rerender() + + expect(result.current.address).toBeDefined() + expect(result.current.status).toEqual('connected') + + await disconnect(config) +}) + +test('parameters: config', () => { + const { result } = renderHook(() => useAccount({ config }), { + wrapper: ({ children }) => createElement(Fragment, { children }), + }) + expect(result.current).toBeDefined() +}) diff --git a/wagmi-project/packages/react/src/hooks/useAccount.ts b/wagmi-project/packages/react/src/hooks/useAccount.ts new file mode 100644 index 000000000..c7c177946 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useAccount.ts @@ -0,0 +1,31 @@ +'use client' + +import { + type Config, + type GetAccountReturnType, + type ResolvedRegister, + getAccount, + watchAccount, +} from '@wagmi/core' + +import type { ConfigParameter } from '../types/properties.js' +import { useConfig } from './useConfig.js' +import { useSyncExternalStoreWithTracked } from './useSyncExternalStoreWithTracked.js' + +export type UseAccountParameters = + ConfigParameter + +export type UseAccountReturnType = + GetAccountReturnType + +/** https://wagmi.sh/react/api/hooks/useAccount */ +export function useAccount( + parameters: UseAccountParameters = {}, +): UseAccountReturnType { + const config = useConfig(parameters) + + return useSyncExternalStoreWithTracked( + (onChange) => watchAccount(config, { onChange }), + () => getAccount(config), + ) +} diff --git a/wagmi-project/packages/react/src/hooks/useAccountEffect.test.ts b/wagmi-project/packages/react/src/hooks/useAccountEffect.test.ts new file mode 100644 index 000000000..b252ee0f9 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useAccountEffect.test.ts @@ -0,0 +1,77 @@ +import { mock } from '@wagmi/connectors' +import { http, connect, createConfig, disconnect } from '@wagmi/core' +import { accounts, chain, config } from '@wagmi/test' +import { createWrapper, renderHook, waitFor } from '@wagmi/test/react' +import { Fragment, createElement } from 'react' +import { expect, test, vi } from 'vitest' + +import { WagmiProvider } from '../context.js' +import { useAccountEffect } from './useAccountEffect.js' +import { useConnect } from './useConnect.js' +import { useDisconnect } from './useDisconnect.js' + +test('parameters: config', () => { + const { result } = renderHook(() => useAccountEffect({ config }), { + wrapper: ({ children }) => createElement(Fragment, { children }), + }) + expect(result.current).toBeUndefined() +}) + +test('behavior: connect and disconnect called once', async () => { + const onConnect = vi.fn() + const onDisconnect = vi.fn() + + const { result } = renderHook(() => ({ + useAccountEffect: useAccountEffect({ onConnect, onDisconnect }), + useConnect: useConnect(), + useDisconnect: useDisconnect(), + })) + + result.current.useConnect.connect({ + connector: result.current.useConnect.connectors[0]!, + }) + await waitFor(() => expect(result.current.useConnect.isSuccess).toBeTruthy()) + + result.current.useConnect.connect({ + connector: result.current.useConnect.connectors[0]!, + }) + await waitFor(() => expect(result.current.useConnect.isSuccess).toBeTruthy()) + + result.current.useDisconnect.disconnect() + await waitFor(() => + expect(result.current.useDisconnect.isSuccess).toBeTruthy(), + ) + result.current.useDisconnect.disconnect() + await waitFor(() => + expect(result.current.useDisconnect.isSuccess).toBeTruthy(), + ) + + expect(onConnect).toBeCalledTimes(1) + expect(onDisconnect).toBeCalledTimes(1) +}) + +test('behavior: connect called on reconnect', async () => { + const config = createConfig({ + chains: [chain.mainnet], + connectors: [ + mock({ + accounts, + features: { reconnect: true }, + }), + ], + transports: { [chain.mainnet.id]: http() }, + }) + + await connect(config, { connector: config.connectors[0]! }) + const onConnect = vi.fn((data) => { + expect(data.isReconnected).toBeTruthy() + }) + + renderHook(() => useAccountEffect({ onConnect }), { + wrapper: createWrapper(WagmiProvider, { config, reconnectOnMount: true }), + }) + + await waitFor(() => expect(onConnect).toBeCalledTimes(1)) + + await disconnect(config) +}) diff --git a/wagmi-project/packages/react/src/hooks/useAccountEffect.ts b/wagmi-project/packages/react/src/hooks/useAccountEffect.ts new file mode 100644 index 000000000..5c77585e3 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useAccountEffect.ts @@ -0,0 +1,62 @@ +'use client' + +import { type GetAccountReturnType, watchAccount } from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { useEffect } from 'react' + +import type { ConfigParameter } from '../types/properties.js' +import { useConfig } from './useConfig.js' + +export type UseAccountEffectParameters = Compute< + { + onConnect?( + data: Compute< + Pick< + Extract, + 'address' | 'addresses' | 'chain' | 'chainId' | 'connector' + > & { + isReconnected: boolean + } + >, + ): void + onDisconnect?(): void + } & ConfigParameter +> + +/** https://wagmi.sh/react/api/hooks/useAccountEffect */ +export function useAccountEffect(parameters: UseAccountEffectParameters = {}) { + const { onConnect, onDisconnect } = parameters + + const config = useConfig(parameters) + + useEffect(() => { + return watchAccount(config, { + onChange(data, prevData) { + if ( + (prevData.status === 'reconnecting' || + (prevData.status === 'connecting' && + prevData.address === undefined)) && + data.status === 'connected' + ) { + const { address, addresses, chain, chainId, connector } = data + const isReconnected = + prevData.status === 'reconnecting' || + // if `previousAccount.status` is `undefined`, the connector connected immediately. + prevData.status === undefined + onConnect?.({ + address, + addresses, + chain, + chainId, + connector, + isReconnected, + }) + } else if ( + prevData.status === 'connected' && + data.status === 'disconnected' + ) + onDisconnect?.() + }, + }) + }, [config, onConnect, onDisconnect]) +} diff --git a/wagmi-project/packages/react/src/hooks/useBalance.test-d.ts b/wagmi-project/packages/react/src/hooks/useBalance.test-d.ts new file mode 100644 index 000000000..74630d50c --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useBalance.test-d.ts @@ -0,0 +1,14 @@ +import { expectTypeOf, test } from 'vitest' + +import { useBalance } from './useBalance.js' + +test('select data', () => { + const result = useBalance({ + query: { + select(data) { + return data?.value + }, + }, + }) + expectTypeOf(result.data).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/react/src/hooks/useBalance.test.ts b/wagmi-project/packages/react/src/hooks/useBalance.test.ts new file mode 100644 index 000000000..ba7f85780 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useBalance.test.ts @@ -0,0 +1,312 @@ +import { accounts, chain, testClient, wait } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { type Address, parseEther } from 'viem' +import { beforeEach, expect, test } from 'vitest' + +import { useBalance } from './useBalance.js' + +const address = accounts[0] + +beforeEach(async () => { + await testClient.mainnet.setBalance({ address, value: parseEther('10000') }) + await testClient.mainnet.mine({ blocks: 1 }) + await testClient.mainnet2.setBalance({ address, value: parseEther('69') }) + await testClient.mainnet2.mine({ blocks: 1 }) +}) + +test('default', async () => { + const { result } = renderHook(() => useBalance({ address })) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + const { data, ...rest } = result.current + expect(data).toMatchObject( + expect.objectContaining({ + decimals: expect.any(Number), + formatted: expect.any(String), + symbol: expect.any(String), + value: expect.any(BigInt), + }), + ) + expect(rest).toMatchInlineSnapshot(` + { + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "balance", + { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "chainId": 1, + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('parameters: chainId', async () => { + const { result } = renderHook(() => + useBalance({ address, chainId: chain.mainnet2.id }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": { + "decimals": 18, + "formatted": "69", + "symbol": "WAG", + "value": 69000000000000000000n, + }, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "balance", + { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "chainId": 456, + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('parameters: token', async () => { + const { result } = renderHook(() => + useBalance({ + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', + token: '0x6B175474E89094C44Da98b954EedeAC495271d0F', + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": { + "decimals": 18, + "formatted": "0.559062564299199392", + "symbol": "DAI", + "value": 559062564299199392n, + }, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "balance", + { + "address": "0x4557B18E779944BFE9d78A672452331C186a9f48", + "chainId": 1, + "token": "0x6B175474E89094C44Da98b954EedeAC495271d0F", + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('parameters: unit', async () => { + const { result } = renderHook(() => + useBalance({ address, chainId: chain.mainnet2.id, unit: 'wei' }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": { + "decimals": 18, + "formatted": "69000000000000000000", + "symbol": "WAG", + "value": 69000000000000000000n, + }, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "balance", + { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "chainId": 456, + "unit": "wei", + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('behavior: address: undefined -> defined', async () => { + let address: Address | undefined = undefined + + const { result, rerender } = renderHook(() => useBalance({ address })) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": undefined, + "dataUpdatedAt": 0, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": false, + "isFetchedAfterMount": false, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": true, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": false, + "isSuccess": false, + "queryKey": [ + "balance", + { + "address": undefined, + "chainId": 1, + }, + ], + "refetch": [Function], + "status": "pending", + } + `) + + address = accounts[0] + rerender() + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": { + "decimals": 18, + "formatted": "10000", + "symbol": "ETH", + "value": 10000000000000000000000n, + }, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "balance", + { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "chainId": 1, + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('behavior: disabled when properties missing', async () => { + const { result } = renderHook(() => useBalance()) + + await wait(100) + await waitFor(() => expect(result.current.isPending).toBeTruthy()) +}) diff --git a/wagmi-project/packages/react/src/hooks/useBalance.ts b/wagmi-project/packages/react/src/hooks/useBalance.ts new file mode 100644 index 000000000..93568089f --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useBalance.ts @@ -0,0 +1,54 @@ +'use client' + +import type { Config, GetBalanceErrorType, ResolvedRegister } from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type GetBalanceData, + type GetBalanceOptions, + type GetBalanceQueryKey, + getBalanceQueryOptions, +} from '@wagmi/core/query' +import type { GetBalanceQueryFnData } from '@wagmi/core/query' + +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseBalanceParameters< + config extends Config = Config, + selectData = GetBalanceData, +> = Compute< + GetBalanceOptions & + ConfigParameter & + QueryParameter< + GetBalanceQueryFnData, + GetBalanceErrorType, + selectData, + GetBalanceQueryKey + > +> + +export type UseBalanceReturnType = + UseQueryReturnType + +/** https://wagmi.sh/react/api/hooks/useBalance */ +export function useBalance< + config extends Config = ResolvedRegister['config'], + selectData = GetBalanceData, +>( + parameters: UseBalanceParameters = {}, +): UseBalanceReturnType { + const { address, query = {} } = parameters + + const config = useConfig(parameters) + const chainId = useChainId({ config }) + + const options = getBalanceQueryOptions(config, { + ...parameters, + chainId: parameters.chainId ?? chainId, + }) + const enabled = Boolean(address && (query.enabled ?? true)) + + return useQuery({ ...query, ...options, enabled }) +} diff --git a/wagmi-project/packages/react/src/hooks/useBlock.test-d.ts b/wagmi-project/packages/react/src/hooks/useBlock.test-d.ts new file mode 100644 index 000000000..04aae7507 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useBlock.test-d.ts @@ -0,0 +1,64 @@ +import { http, createConfig, webSocket } from '@wagmi/core' +import { mainnet, optimism } from '@wagmi/core/chains' +import { expectTypeOf, test } from 'vitest' + +import { useBlock } from './useBlock.js' + +test('select data', () => { + const result = useBlock({ + query: { + select(data) { + return data?.number + }, + }, + }) + expectTypeOf(result.data).toEqualTypeOf() +}) + +test('differing transports', () => { + const config = createConfig({ + chains: [mainnet, optimism], + transports: { + [mainnet.id]: http(), + [optimism.id]: webSocket(), + }, + }) + + useBlock({ + config, + watch: { + poll: false, + }, + }) + + useBlock({ + config, + chainId: mainnet.id, + watch: { + poll: true, + }, + }) + useBlock({ + config, + chainId: mainnet.id, + watch: { + // @ts-expect-error + poll: false, + }, + }) + + useBlock({ + config, + chainId: optimism.id, + watch: { + poll: true, + }, + }) + useBlock({ + config, + chainId: optimism.id, + watch: { + poll: false, + }, + }) +}) diff --git a/wagmi-project/packages/react/src/hooks/useBlock.test.ts b/wagmi-project/packages/react/src/hooks/useBlock.test.ts new file mode 100644 index 000000000..0d2095ec6 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useBlock.test.ts @@ -0,0 +1,67 @@ +import { testClient } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { expect, test } from 'vitest' + +import { useBlock } from './useBlock.js' + +test('mounts', async () => { + const { result } = renderHook(() => useBlock()) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + const { data, ...rest } = result.current + expect(data).toBeDefined() + expect(rest).toMatchInlineSnapshot(` + { + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "block", + { + "chainId": 1, + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('parameters: watch', async () => { + await testClient.mainnet.restart() + + const { result } = renderHook(() => useBlock({ watch: true })) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + const block = result.current.data! + expect(block).toBeDefined() + + await testClient.mainnet.mine({ blocks: 1 }) + await waitFor(() => { + expect(result.current.data?.number).toEqual(block.number + 1n) + }) + + await testClient.mainnet.mine({ blocks: 1 }) + await waitFor(() => { + expect(result.current.data?.number).toEqual(block.number + 2n) + }) +}) diff --git a/wagmi-project/packages/react/src/hooks/useBlock.ts b/wagmi-project/packages/react/src/hooks/useBlock.ts new file mode 100644 index 000000000..1a16a5bd9 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useBlock.ts @@ -0,0 +1,131 @@ +'use client' + +import { useQueryClient } from '@tanstack/react-query' +import type { Config, GetBlockErrorType, ResolvedRegister } from '@wagmi/core' +import type { + Compute, + UnionCompute, + UnionStrictOmit, +} from '@wagmi/core/internal' +import { + type GetBlockData, + type GetBlockOptions, + type GetBlockQueryFnData, + type GetBlockQueryKey, + getBlockQueryOptions, +} from '@wagmi/core/query' +import type { BlockTag } from 'viem' + +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' +import { + type UseWatchBlocksParameters, + useWatchBlocks, +} from './useWatchBlocks.js' + +export type UseBlockParameters< + includeTransactions extends boolean = false, + blockTag extends BlockTag = 'latest', + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = GetBlockData, +> = Compute< + GetBlockOptions & + ConfigParameter & + QueryParameter< + GetBlockQueryFnData, + GetBlockErrorType, + selectData, + GetBlockQueryKey + > & { + watch?: + | boolean + | UnionCompute< + UnionStrictOmit< + UseWatchBlocksParameters< + includeTransactions, + blockTag, + config, + chainId + >, + 'chainId' | 'config' | 'onBlock' | 'onError' + > + > + | undefined + } +> + +export type UseBlockReturnType< + includeTransactions extends boolean = false, + blockTag extends BlockTag = 'latest', + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = GetBlockData, +> = UseQueryReturnType + +/** https://wagmi.sh/react/hooks/useBlock */ +export function useBlock< + includeTransactions extends boolean = false, + blockTag extends BlockTag = 'latest', + config extends Config = ResolvedRegister['config'], + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = GetBlockData, +>( + parameters: UseBlockParameters< + includeTransactions, + blockTag, + config, + chainId, + selectData + > = {}, +): UseBlockReturnType< + includeTransactions, + blockTag, + config, + chainId, + selectData +> { + const { query = {}, watch } = parameters + + const config = useConfig(parameters) + const queryClient = useQueryClient() + const configChainId = useChainId({ config }) + const chainId = parameters.chainId ?? configChainId + + const options = getBlockQueryOptions(config, { + ...parameters, + chainId, + }) + const enabled = Boolean(query.enabled ?? true) + + useWatchBlocks({ + ...({ + config: parameters.config, + chainId: parameters.chainId!, + ...(typeof watch === 'object' ? watch : {}), + } as UseWatchBlocksParameters), + enabled: Boolean( + enabled && (typeof watch === 'object' ? watch.enabled : watch), + ), + onBlock(block) { + queryClient.setQueryData(options.queryKey, block) + }, + }) + + return useQuery({ + ...(query as any), + ...options, + enabled, + }) as UseBlockReturnType< + includeTransactions, + blockTag, + config, + chainId, + selectData + > +} diff --git a/wagmi-project/packages/react/src/hooks/useBlockNumber.test-d.ts b/wagmi-project/packages/react/src/hooks/useBlockNumber.test-d.ts new file mode 100644 index 000000000..dfb4ca4db --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useBlockNumber.test-d.ts @@ -0,0 +1,65 @@ +import { http, createConfig, webSocket } from '@wagmi/core' +import { mainnet, optimism } from '@wagmi/core/chains' +import { expectTypeOf, test } from 'vitest' + +import { useBlockNumber } from './useBlockNumber.js' + +test('select data', () => { + const result = useBlockNumber({ + query: { + select(data) { + expectTypeOf(data).toEqualTypeOf() + return data?.toString() + }, + }, + }) + expectTypeOf(result.data).toEqualTypeOf() +}) + +test('differing transports', () => { + const config = createConfig({ + chains: [mainnet, optimism], + transports: { + [mainnet.id]: http(), + [optimism.id]: webSocket(), + }, + }) + + useBlockNumber({ + config, + watch: { + poll: false, + }, + }) + + useBlockNumber({ + config, + chainId: mainnet.id, + watch: { + poll: true, + }, + }) + useBlockNumber({ + config, + chainId: mainnet.id, + watch: { + // @ts-expect-error + poll: false, + }, + }) + + useBlockNumber({ + config, + chainId: optimism.id, + watch: { + poll: true, + }, + }) + useBlockNumber({ + config, + chainId: optimism.id, + watch: { + poll: false, + }, + }) +}) diff --git a/wagmi-project/packages/react/src/hooks/useBlockNumber.test.ts b/wagmi-project/packages/react/src/hooks/useBlockNumber.test.ts new file mode 100644 index 000000000..93006a666 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useBlockNumber.test.ts @@ -0,0 +1,68 @@ +import { testClient } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { expect, test } from 'vitest' + +import { useBlockNumber } from './useBlockNumber.js' + +test('mounts', async () => { + await testClient.mainnet.resetFork() + + const { result } = renderHook(() => useBlockNumber()) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": 19258213n, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "blockNumber", + { + "chainId": 1, + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('parameters: watch', async () => { + await testClient.mainnet.restart() + + const { result } = renderHook(() => useBlockNumber({ watch: true })) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + const blockNumber = result.current.data! + expect(result.current.data).toMatchInlineSnapshot('19258213n') + + await testClient.mainnet.mine({ blocks: 1 }) + await waitFor(() => { + expect(result.current.data).toEqual(blockNumber + 1n) + }) + + await testClient.mainnet.mine({ blocks: 1 }) + await waitFor(() => { + expect(result.current.data).toEqual(blockNumber + 2n) + }) +}) diff --git a/wagmi-project/packages/react/src/hooks/useBlockNumber.ts b/wagmi-project/packages/react/src/hooks/useBlockNumber.ts new file mode 100644 index 000000000..f91d8466e --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useBlockNumber.ts @@ -0,0 +1,97 @@ +'use client' + +import { useQueryClient } from '@tanstack/react-query' +import type { + Config, + GetBlockNumberErrorType, + ResolvedRegister, +} from '@wagmi/core' +import type { + Compute, + UnionCompute, + UnionStrictOmit, +} from '@wagmi/core/internal' +import { + type GetBlockNumberData, + type GetBlockNumberOptions, + type GetBlockNumberQueryFnData, + type GetBlockNumberQueryKey, + getBlockNumberQueryOptions, +} from '@wagmi/core/query' + +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' +import { + type UseWatchBlockNumberParameters, + useWatchBlockNumber, +} from './useWatchBlockNumber.js' + +export type UseBlockNumberParameters< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = GetBlockNumberData, +> = Compute< + GetBlockNumberOptions & + ConfigParameter & + QueryParameter< + GetBlockNumberQueryFnData, + GetBlockNumberErrorType, + selectData, + GetBlockNumberQueryKey + > & { + watch?: + | boolean + | UnionCompute< + UnionStrictOmit< + UseWatchBlockNumberParameters, + 'chainId' | 'config' | 'onBlockNumber' | 'onError' + > + > + | undefined + } +> + +export type UseBlockNumberReturnType = + UseQueryReturnType + +/** https://wagmi.sh/react/api/hooks/useBlockNumber */ +export function useBlockNumber< + config extends Config = ResolvedRegister['config'], + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = GetBlockNumberData, +>( + parameters: UseBlockNumberParameters = {}, +): UseBlockNumberReturnType { + const { query = {}, watch } = parameters + + const config = useConfig(parameters) + const queryClient = useQueryClient() + const configChainId = useChainId({ config }) + const chainId = parameters.chainId ?? configChainId + + const options = getBlockNumberQueryOptions(config, { + ...parameters, + chainId, + }) + + useWatchBlockNumber({ + ...({ + config: parameters.config, + chainId: parameters.chainId, + ...(typeof watch === 'object' ? watch : {}), + } as UseWatchBlockNumberParameters), + enabled: Boolean( + (query.enabled ?? true) && + (typeof watch === 'object' ? watch.enabled : watch), + ), + onBlockNumber(blockNumber) { + queryClient.setQueryData(options.queryKey, blockNumber) + }, + }) + + return useQuery({ ...query, ...options }) +} diff --git a/wagmi-project/packages/react/src/hooks/useBlockTransactionCount.test-d.ts b/wagmi-project/packages/react/src/hooks/useBlockTransactionCount.test-d.ts new file mode 100644 index 000000000..ff23fcfe9 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useBlockTransactionCount.test-d.ts @@ -0,0 +1,14 @@ +import { expectTypeOf, test } from 'vitest' + +import { useBlockTransactionCount } from './useBlockTransactionCount.js' + +test('select data', () => { + const result = useBlockTransactionCount({ + query: { + select(data) { + return data + }, + }, + }) + expectTypeOf(result.data).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/react/src/hooks/useBlockTransactionCount.test.ts b/wagmi-project/packages/react/src/hooks/useBlockTransactionCount.test.ts new file mode 100644 index 000000000..dad6c9550 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useBlockTransactionCount.test.ts @@ -0,0 +1,231 @@ +import { chain } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { expect, test } from 'vitest' + +import { useBlockTransactionCount } from './useBlockTransactionCount.js' + +test('default', async () => { + const { result } = renderHook(() => useBlockTransactionCount({})) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + const { data, ...rest } = result.current + expect(data).toBeTypeOf('number') + expect(rest).toMatchInlineSnapshot(` + { + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "blockTransactionCount", + { + "chainId": 1, + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('parameters: chainId', async () => { + const { result } = renderHook(() => + useBlockTransactionCount({ chainId: chain.mainnet2.id }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + const { data, ...rest } = result.current + expect(data).toBeTypeOf('number') + expect(rest).toMatchInlineSnapshot(` + { + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "blockTransactionCount", + { + "chainId": 456, + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('parameters: blockNumber', async () => { + const { result } = renderHook(() => + useBlockTransactionCount({ blockNumber: 13677382n }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + const { data, ...rest } = result.current + expect(data).toBeTypeOf('number') + expect(rest).toMatchInlineSnapshot(` + { + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "blockTransactionCount", + { + "blockNumber": 13677382n, + "chainId": 1, + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('parameters: blockHash', async () => { + const { result } = renderHook(() => + useBlockTransactionCount({ + blockHash: + '0x6201f37a245850d1f11e4be3ac45bc51bd9d43ee4a127192cad550f351cfa575', + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + const { data, ...rest } = result.current + expect(data).toBeTypeOf('number') + expect(rest).toMatchInlineSnapshot(` + { + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "blockTransactionCount", + { + "blockHash": "0x6201f37a245850d1f11e4be3ac45bc51bd9d43ee4a127192cad550f351cfa575", + "chainId": 1, + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('parameters: blockTag', async () => { + const { result } = renderHook(() => + useBlockTransactionCount({ + blockTag: 'safe', + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + const { data, ...rest } = result.current + expect(data).toBeTypeOf('number') + expect(rest).toMatchInlineSnapshot(` + { + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "blockTransactionCount", + { + "blockTag": "safe", + "chainId": 1, + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) diff --git a/wagmi-project/packages/react/src/hooks/useBlockTransactionCount.ts b/wagmi-project/packages/react/src/hooks/useBlockTransactionCount.ts new file mode 100644 index 000000000..edbd6e8dd --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useBlockTransactionCount.ts @@ -0,0 +1,67 @@ +'use client' + +import type { + Config, + GetBlockTransactionCountErrorType, + ResolvedRegister, +} from '@wagmi/core' +import type { UnionCompute } from '@wagmi/core/internal' +import { + type GetBlockTransactionCountData, + type GetBlockTransactionCountOptions, + type GetBlockTransactionCountQueryFnData, + type GetBlockTransactionCountQueryKey, + getBlockTransactionCountQueryOptions, +} from '@wagmi/core/query' + +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseBlockTransactionCountParameters< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = GetBlockTransactionCountData, +> = UnionCompute< + GetBlockTransactionCountOptions & + ConfigParameter & + QueryParameter< + GetBlockTransactionCountQueryFnData, + GetBlockTransactionCountErrorType, + selectData, + GetBlockTransactionCountQueryKey + > +> + +export type UseBlockTransactionCountReturnType< + selectData = GetBlockTransactionCountData, +> = UseQueryReturnType + +/** https://wagmi.sh/react/api/hooks/useBlockTransactionCount */ +export function useBlockTransactionCount< + config extends Config = ResolvedRegister['config'], + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = GetBlockTransactionCountData, +>( + parameters: UseBlockTransactionCountParameters< + config, + chainId, + selectData + > = {}, +): UseBlockTransactionCountReturnType { + const { query = {} } = parameters + + const config = useConfig(parameters) + const configChainId = useChainId({ config }) + const chainId = parameters.chainId ?? configChainId + + const options = getBlockTransactionCountQueryOptions(config, { + ...parameters, + chainId, + }) + + return useQuery({ ...query, ...options }) +} diff --git a/wagmi-project/packages/react/src/hooks/useBytecode.test-d.ts b/wagmi-project/packages/react/src/hooks/useBytecode.test-d.ts new file mode 100644 index 000000000..eff094e71 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useBytecode.test-d.ts @@ -0,0 +1,15 @@ +import { expectTypeOf, test } from 'vitest' + +import type { Hex } from 'viem' +import { useBytecode } from './useBytecode.js' + +test('select data', () => { + const result = useBytecode({ + query: { + select(data) { + return data + }, + }, + }) + expectTypeOf(result.data).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/react/src/hooks/useBytecode.test.ts b/wagmi-project/packages/react/src/hooks/useBytecode.test.ts new file mode 100644 index 000000000..4c25fa955 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useBytecode.test.ts @@ -0,0 +1,291 @@ +import { address, chain, wait } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { expect, test } from 'vitest' + +import type { Address } from 'viem' +import { useBytecode } from './useBytecode.js' + +test('default', async () => { + const { result } = renderHook(() => + useBytecode({ + address: address.wagmiMintExample, + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + const { data, ...rest } = result.current + expect(rest).toMatchInlineSnapshot(` + { + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "getBytecode", + { + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "chainId": 1, + }, + ], + "refetch": [Function], + "status": "success", + } + `) + expect(data).toMatch(/^0x.*/) +}) + +test('parameters: blockNumber', async () => { + const { result } = renderHook(() => + useBytecode({ + address: address.wagmiMintExample, + blockNumber: 15564163n, + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": null, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "getBytecode", + { + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "blockNumber": 15564163n, + "chainId": 1, + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('parameters: blockTag', async () => { + const { result } = renderHook(() => + useBytecode({ + address: address.wagmiMintExample, + blockTag: 'earliest', + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": null, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "getBytecode", + { + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "blockTag": "earliest", + "chainId": 1, + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('parameters: chainId', async () => { + const { result } = renderHook(() => + useBytecode({ + address: address.wagmiMintExample, + chainId: chain.optimism.id, + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": null, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "getBytecode", + { + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "chainId": 10, + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('behavior: address: undefined -> defined', async () => { + let contractAddress: Address | undefined = undefined + + const { result, rerender } = renderHook(() => + useBytecode({ + address: contractAddress, + }), + ) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": undefined, + "dataUpdatedAt": 0, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": false, + "isFetchedAfterMount": false, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": true, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": false, + "isSuccess": false, + "queryKey": [ + "getBytecode", + { + "address": undefined, + "chainId": 1, + }, + ], + "refetch": [Function], + "status": "pending", + } + `) + + contractAddress = address.wagmiMintExample + rerender() + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + const { data, ...rest } = result.current + expect(rest).toMatchInlineSnapshot(` + { + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "getBytecode", + { + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "chainId": 1, + }, + ], + "refetch": [Function], + "status": "success", + } + `) + expect(data).toMatch(/^0x.*/) +}) + +test('behavior: disabled when properties missing', async () => { + const { result } = renderHook(() => useBytecode()) + + await wait(100) + await waitFor(() => expect(result.current.isPending).toBeTruthy()) +}) diff --git a/wagmi-project/packages/react/src/hooks/useBytecode.ts b/wagmi-project/packages/react/src/hooks/useBytecode.ts new file mode 100644 index 000000000..3dd01d438 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useBytecode.ts @@ -0,0 +1,57 @@ +'use client' + +import type { + Config, + GetBytecodeErrorType, + ResolvedRegister, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type GetBytecodeData, + type GetBytecodeOptions, + type GetBytecodeQueryKey, + getBytecodeQueryOptions, +} from '@wagmi/core/query' +import type { GetBytecodeQueryFnData } from '@wagmi/core/query' +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseBytecodeParameters< + config extends Config = Config, + selectData = GetBytecodeData, +> = Compute< + GetBytecodeOptions & + ConfigParameter & + QueryParameter< + GetBytecodeQueryFnData, + GetBytecodeErrorType, + selectData, + GetBytecodeQueryKey + > +> + +export type UseBytecodeReturnType = + UseQueryReturnType + +/** https://wagmi.sh/react/api/hooks/useBytecode */ +export function useBytecode< + config extends Config = ResolvedRegister['config'], + selectData = GetBytecodeData, +>( + parameters: UseBytecodeParameters = {}, +): UseBytecodeReturnType { + const { address, query = {} } = parameters + + const config = useConfig(parameters) + const chainId = useChainId({ config }) + + const options = getBytecodeQueryOptions(config, { + ...parameters, + chainId: parameters.chainId ?? chainId, + }) + const enabled = Boolean(address && (query.enabled ?? true)) + + return useQuery({ ...query, ...options, enabled }) +} diff --git a/wagmi-project/packages/react/src/hooks/useCall.test-d.ts b/wagmi-project/packages/react/src/hooks/useCall.test-d.ts new file mode 100644 index 000000000..5c47b096c --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useCall.test-d.ts @@ -0,0 +1,14 @@ +import type { CallReturnType } from 'viem' +import { expectTypeOf, test } from 'vitest' +import { useCall } from './useCall.js' + +test('select data', () => { + const result = useCall({ + query: { + select(data) { + return data + }, + }, + }) + expectTypeOf(result.data).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/react/src/hooks/useCall.test.ts b/wagmi-project/packages/react/src/hooks/useCall.test.ts new file mode 100644 index 000000000..ee8ce813c --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useCall.test.ts @@ -0,0 +1,224 @@ +import { accounts, address, chain } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { expect, test } from 'vitest' + +import { useCall } from './useCall.js' + +const name4bytes = '0x06fdde03' + +const account = accounts[0] + +test('default', async () => { + const { result } = renderHook(() => + useCall({ + account, + data: name4bytes, + to: address.wagmiMintExample, + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": { + "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000057761676d69000000000000000000000000000000000000000000000000000000", + }, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "call", + { + "account": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "chainId": 1, + "data": "0x06fdde03", + "to": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +// TODO: Re-enable +test.skip('parameters: blockTag', async () => { + const { result } = renderHook(() => + useCall({ + account, + data: name4bytes, + to: address.wagmiMintExample, + blockTag: 'safe', + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": { + "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000057761676d69000000000000000000000000000000000000000000000000000000", + }, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "call", + { + "account": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "blockTag": "safe", + "chainId": 1, + "data": "0x06fdde03", + "to": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +// TODO: Re-enable +test.skip('parameters: blockNumber', async () => { + const { result } = renderHook(() => + useCall({ + account, + data: name4bytes, + to: address.wagmiMintExample, + blockNumber: 16280770n, + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": { + "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000057761676d69000000000000000000000000000000000000000000000000000000", + }, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "call", + { + "account": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "blockNumber": 16280770n, + "chainId": 1, + "data": "0x06fdde03", + "to": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('parameters: chainId', async () => { + const { result } = renderHook(() => + useCall({ + account, + data: name4bytes, + to: address.wagmiMintExample, + chainId: chain.mainnet2.id, + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": { + "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000057761676d69000000000000000000000000000000000000000000000000000000", + }, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "call", + { + "account": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "chainId": 456, + "data": "0x06fdde03", + "to": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) diff --git a/wagmi-project/packages/react/src/hooks/useCall.ts b/wagmi-project/packages/react/src/hooks/useCall.ts new file mode 100644 index 000000000..423e04fbf --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useCall.ts @@ -0,0 +1,55 @@ +'use client' + +import type { CallErrorType, Config, ResolvedRegister } from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type CallData, + type CallOptions, + type CallQueryKey, + callQueryOptions, +} from '@wagmi/core/query' +import type { CallQueryFnData } from '@wagmi/core/query' + +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseCallParameters< + config extends Config = Config, + selectData = CallData, +> = Compute< + CallOptions & + ConfigParameter & + QueryParameter< + CallQueryFnData, + CallErrorType, + selectData, + CallQueryKey + > +> + +export type UseCallReturnType = UseQueryReturnType< + selectData, + CallErrorType +> + +/** https://wagmi.sh/react/api/hooks/useCall */ +export function useCall< + config extends Config = ResolvedRegister['config'], + selectData = CallData, +>( + parameters: UseCallParameters = {}, +): UseCallReturnType { + const { query = {} } = parameters + + const config = useConfig(parameters) + const chainId = useChainId({ config }) + + const options = callQueryOptions(config, { + ...parameters, + chainId: parameters.chainId ?? chainId, + }) + + return useQuery({ ...query, ...options }) +} diff --git a/wagmi-project/packages/react/src/hooks/useCallsStatus.test.ts b/wagmi-project/packages/react/src/hooks/useCallsStatus.test.ts new file mode 100644 index 000000000..f3af1c24b --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useCallsStatus.test.ts @@ -0,0 +1,101 @@ +import { connect, disconnect } from '@wagmi/core' +import { accounts, config, testClient } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { parseEther } from 'viem' +import { expect, test } from 'vitest' + +import { useCallsStatus } from './useCallsStatus.js' +import { useSendCalls } from './useSendCalls.js' + +const connector = config.connectors[0]! + +test('default', async () => { + await connect(config, { connector }) + + const { result } = renderHook(() => useSendCalls()) + + result.current.sendCalls({ + calls: [ + { + data: '0xdeadbeef', + to: accounts[1], + value: parseEther('1'), + }, + { + to: accounts[2], + value: parseEther('2'), + }, + { + to: accounts[3], + value: parseEther('3'), + }, + ], + }) + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + const { result: result_2 } = renderHook(() => + useCallsStatus({ id: result.current.data?.id! }), + ) + await waitFor(() => expect(result_2.current.isSuccess).toBeTruthy()) + + expect(result_2.current.data).toMatchInlineSnapshot( + ` + { + "atomic": false, + "chainId": 1, + "id": "0x5dedb5a4ff8968db37459b52b83cbdc92b01c9c709c9cff26e345ef5cf27f92e", + "receipts": [], + "status": "pending", + "statusCode": 100, + "version": "2.0.0", + } + `, + ) + + await testClient.mainnet.mine({ blocks: 1 }) + + const { result: result_3 } = renderHook(() => + useCallsStatus({ id: result.current.data?.id! }), + ) + await waitFor(() => expect(result_3.current.isSuccess).toBeTruthy()) + + expect(result_3.current.data?.status).toBe('success') + expect(result_3.current.data?.statusCode).toBe(200) + expect( + result_3.current.data?.receipts?.map((x) => ({ + ...x, + blockHash: undefined, + })), + ).toMatchInlineSnapshot( + ` + [ + { + "blockHash": undefined, + "blockNumber": 19258214n, + "gasUsed": 21064n, + "logs": [], + "status": "success", + "transactionHash": "0x13c53b2d4d9da424835525349cd66e553330f323d6fb19458b801ae1f7989a41", + }, + { + "blockHash": undefined, + "blockNumber": 19258214n, + "gasUsed": 21000n, + "logs": [], + "status": "success", + "transactionHash": "0xd8397b3e82b061c26a0c2093f1ceca0c3662a512614f7d6370349e89d0eea007", + }, + { + "blockHash": undefined, + "blockNumber": 19258214n, + "gasUsed": 21000n, + "logs": [], + "status": "success", + "transactionHash": "0x4d26e346593d9ea265bb164b115e89aa92df43b0b8778ac75d4ad28e2a22b101", + }, + ] + `, + ) + + await disconnect(config, { connector }) +}) diff --git a/wagmi-project/packages/react/src/hooks/useCallsStatus.ts b/wagmi-project/packages/react/src/hooks/useCallsStatus.ts new file mode 100644 index 000000000..ab4c90c1f --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useCallsStatus.ts @@ -0,0 +1,52 @@ +'use client' + +import type { + Config, + GetCallsStatusErrorType, + ResolvedRegister, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type GetCallsStatusData, + type GetCallsStatusOptions, + type GetCallsStatusQueryFnData, + type GetCallsStatusQueryKey, + getCallsStatusQueryOptions, +} from '@wagmi/core/query' + +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useConfig } from './useConfig.js' + +export type UseCallsStatusParameters< + config extends Config = Config, + selectData = GetCallsStatusData, +> = Compute< + GetCallsStatusOptions & + ConfigParameter & + QueryParameter< + GetCallsStatusQueryFnData, + GetCallsStatusErrorType, + selectData, + GetCallsStatusQueryKey + > +> + +export type UseCallsStatusReturnType = + UseQueryReturnType + +/** https://wagmi.sh/react/api/hooks/useCallsStatus */ +export function useCallsStatus< + config extends Config = ResolvedRegister['config'], + selectData = GetCallsStatusData, +>( + parameters: UseCallsStatusParameters, +): UseCallsStatusReturnType { + const { query = {} } = parameters + + const config = useConfig(parameters) + + const options = getCallsStatusQueryOptions(config, parameters) + + return useQuery({ ...query, ...options }) +} diff --git a/wagmi-project/packages/react/src/hooks/useCapabilities.test.ts b/wagmi-project/packages/react/src/hooks/useCapabilities.test.ts new file mode 100644 index 000000000..65dcf171b --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useCapabilities.test.ts @@ -0,0 +1,167 @@ +import { connect, disconnect } from '@wagmi/core' +import { accounts, config } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { expect, test } from 'vitest' + +import { useCapabilities } from './useCapabilities.js' + +const connector = config.connectors[0]! + +test('mounts', async () => { + await connect(config, { connector }) + + const { result } = renderHook(() => useCapabilities()) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": { + "8453": { + "paymasterService": { + "supported": true, + }, + "sessionKeys": { + "supported": true, + }, + }, + "84532": { + "paymasterService": { + "supported": true, + }, + }, + }, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "capabilities", + { + "account": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + }, + ], + "refetch": [Function], + "status": "success", + } + `) + + await disconnect(config, { connector }) +}) + +test('args: account', async () => { + await connect(config, { connector }) + + const { result } = renderHook(() => useCapabilities({ account: accounts[1] })) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": { + "8453": { + "paymasterService": { + "supported": false, + }, + "sessionKeys": { + "supported": true, + }, + }, + "84532": { + "paymasterService": { + "supported": false, + }, + }, + }, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "capabilities", + { + "account": "0x70997970c51812dc3a010c7d01b50e0d17dc79c8", + }, + ], + "refetch": [Function], + "status": "success", + } + `) + + await disconnect(config, { connector }) +}) + +test('behavior: not connected', async () => { + const { result } = renderHook(() => useCapabilities()) + + await waitFor(() => expect(result.current.isError).toBeTruthy()) + + const { error, failureReason: _, ...rest } = result.current + expect(error?.message.includes('Connector not connected.')).toBeTruthy() + expect(rest).toMatchInlineSnapshot(` + { + "data": undefined, + "dataUpdatedAt": 0, + "errorUpdateCount": 2, + "errorUpdatedAt": 1675209600000, + "failureCount": 1, + "fetchStatus": "idle", + "isError": true, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": true, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": false, + "queryKey": [ + "capabilities", + { + "account": undefined, + }, + ], + "refetch": [Function], + "status": "error", + } + `) +}) diff --git a/wagmi-project/packages/react/src/hooks/useCapabilities.ts b/wagmi-project/packages/react/src/hooks/useCapabilities.ts new file mode 100644 index 000000000..399a56cd3 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useCapabilities.ts @@ -0,0 +1,62 @@ +'use client' + +import type { + Config, + GetCapabilitiesErrorType, + ResolvedRegister, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type GetCapabilitiesData, + type GetCapabilitiesOptions, + type GetCapabilitiesQueryFnData, + type GetCapabilitiesQueryKey, + getCapabilitiesQueryOptions, +} from '@wagmi/core/query' + +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useAccount } from './useAccount.js' +import { useConfig } from './useConfig.js' + +export type UseCapabilitiesParameters< + config extends Config = Config, + chainId extends config['chains'][number]['id'] | undefined = undefined, + selectData = GetCapabilitiesData, +> = Compute< + GetCapabilitiesOptions & + ConfigParameter & + QueryParameter< + GetCapabilitiesQueryFnData, + GetCapabilitiesErrorType, + selectData, + GetCapabilitiesQueryKey + > +> + +export type UseCapabilitiesReturnType< + config extends Config = Config, + chainId extends config['chains'][number]['id'] | undefined = undefined, + selectData = GetCapabilitiesData, +> = UseQueryReturnType + +/** https://wagmi.sh/react/api/hooks/useCapabilities */ +export function useCapabilities< + config extends Config = ResolvedRegister['config'], + chainId extends config['chains'][number]['id'] | undefined = undefined, + selectData = GetCapabilitiesData, +>( + parameters: UseCapabilitiesParameters = {}, +): UseCapabilitiesReturnType { + const { account, query = {} } = parameters + + const { address } = useAccount() + const config = useConfig(parameters) + + const options = getCapabilitiesQueryOptions(config, { + ...parameters, + account: account ?? address, + }) + + return useQuery({ ...query, ...options }) +} diff --git a/wagmi-project/packages/react/src/hooks/useChainId.test-d.ts b/wagmi-project/packages/react/src/hooks/useChainId.test-d.ts new file mode 100644 index 000000000..682b5fab7 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useChainId.test-d.ts @@ -0,0 +1,14 @@ +import { config } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' + +import { useChainId } from './useChainId.js' + +test('default', () => { + const chainId = useChainId() + expectTypeOf(chainId).toEqualTypeOf() +}) + +test('parameters: config', () => { + const chainId = useChainId({ config }) + expectTypeOf(chainId).toEqualTypeOf<1 | 456 | 10>() +}) diff --git a/wagmi-project/packages/react/src/hooks/useChainId.test.ts b/wagmi-project/packages/react/src/hooks/useChainId.test.ts new file mode 100644 index 000000000..e4745b46e --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useChainId.test.ts @@ -0,0 +1,24 @@ +import { config } from '@wagmi/test' +import { renderHook } from '@wagmi/test/react' +import { Fragment, createElement } from 'react' +import { expect, test } from 'vitest' + +import { useChainId } from './useChainId.js' + +test('default', async () => { + const { result, rerender } = renderHook(() => useChainId()) + + expect(result.current).toMatchInlineSnapshot('1') + + config.setState((x) => ({ ...x, chainId: 456 })) + rerender() + + expect(result.current).toMatchInlineSnapshot('456') +}) + +test('parameters: config', () => { + const { result } = renderHook(() => useChainId({ config }), { + wrapper: ({ children }) => createElement(Fragment, { children }), + }) + expect(result.current).toBeDefined() +}) diff --git a/wagmi-project/packages/react/src/hooks/useChainId.ts b/wagmi-project/packages/react/src/hooks/useChainId.ts new file mode 100644 index 000000000..ce7cb208d --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useChainId.ts @@ -0,0 +1,32 @@ +'use client' + +import { + type Config, + type GetChainIdReturnType, + type ResolvedRegister, + getChainId, + watchChainId, +} from '@wagmi/core' +import { useSyncExternalStore } from 'react' + +import type { ConfigParameter } from '../types/properties.js' +import { useConfig } from './useConfig.js' + +export type UseChainIdParameters = + ConfigParameter + +export type UseChainIdReturnType = + GetChainIdReturnType + +/** https://wagmi.sh/react/api/hooks/useChainId */ +export function useChainId( + parameters: UseChainIdParameters = {}, +): UseChainIdReturnType { + const config = useConfig(parameters) + + return useSyncExternalStore( + (onChange) => watchChainId(config, { onChange }), + () => getChainId(config), + () => getChainId(config), + ) +} diff --git a/wagmi-project/packages/react/src/hooks/useChains.test.ts b/wagmi-project/packages/react/src/hooks/useChains.test.ts new file mode 100644 index 000000000..1d9d6fca4 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useChains.test.ts @@ -0,0 +1,31 @@ +import { config } from '@wagmi/test' +import { renderHook } from '@wagmi/test/react' +import { Fragment, createElement } from 'react' +import { expect, test } from 'vitest' + +import { useChains } from './useChains.js' + +test('default', async () => { + const { result } = renderHook(() => useChains()) + + expect(result.current.map((x) => x.id)).toMatchInlineSnapshot(` + [ + 1, + 456, + 10, + ] + `) +}) + +test('parameters: config', () => { + const { result } = renderHook(() => useChains({ config }), { + wrapper: ({ children }) => createElement(Fragment, { children }), + }) + expect(result.current.map((x) => x.id)).toMatchInlineSnapshot(` + [ + 1, + 456, + 10, + ] + `) +}) diff --git a/wagmi-project/packages/react/src/hooks/useChains.ts b/wagmi-project/packages/react/src/hooks/useChains.ts new file mode 100644 index 000000000..b3e93b417 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useChains.ts @@ -0,0 +1,32 @@ +'use client' + +import { + type Config, + type GetChainsReturnType, + type ResolvedRegister, + getChains, +} from '@wagmi/core' +import { watchChains } from '@wagmi/core/internal' +import { useSyncExternalStore } from 'react' + +import type { ConfigParameter } from '../types/properties.js' +import { useConfig } from './useConfig.js' + +export type UseChainsParameters = + ConfigParameter + +export type UseChainsReturnType = + GetChainsReturnType + +/** https://wagmi.sh/react/api/hooks/useChains */ +export function useChains( + parameters: UseChainsParameters = {}, +): UseChainsReturnType { + const config = useConfig(parameters) + + return useSyncExternalStore( + (onChange) => watchChains(config, { onChange }), + () => getChains(config), + () => getChains(config), + ) +} diff --git a/wagmi-project/packages/react/src/hooks/useClient.test-d.ts b/wagmi-project/packages/react/src/hooks/useClient.test-d.ts new file mode 100644 index 000000000..80ee4ec48 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useClient.test-d.ts @@ -0,0 +1,40 @@ +import { chain, config } from '@wagmi/test' +import type { Chain } from 'viem' +import { expectTypeOf, test } from 'vitest' + +import { useClient } from './useClient.js' + +test('default', () => { + const client = useClient({ config }) + expectTypeOf(client.chain).toEqualTypeOf<(typeof config)['chains'][number]>() + expectTypeOf(client.transport.type).toEqualTypeOf<'http'>() +}) + +test('parameters: chainId', () => { + const client = useClient({ + config, + chainId: chain.mainnet.id, + }) + expectTypeOf(client.chain).toEqualTypeOf() + expectTypeOf(client.chain).not.toEqualTypeOf() + expectTypeOf(client.transport.type).toEqualTypeOf<'http'>() +}) + +test('behavior: unconfigured chain', () => { + { + const client = useClient({ chainId: 123456 }) + if (client) { + expectTypeOf(client.chain).toEqualTypeOf() + expectTypeOf(client.transport.type).toEqualTypeOf() + } else { + expectTypeOf(client).toEqualTypeOf() + } + } + + const client = useClient({ + config, + // @ts-expect-error + chainId: 123456, + }) + expectTypeOf(client).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/react/src/hooks/useClient.test.ts b/wagmi-project/packages/react/src/hooks/useClient.test.ts new file mode 100644 index 000000000..93ef8d9fa --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useClient.test.ts @@ -0,0 +1,30 @@ +import { switchChain } from '@wagmi/core' +import { config } from '@wagmi/test' +import { renderHook } from '@wagmi/test/react' +import { Fragment, createElement } from 'react' +import { expect, test } from 'vitest' + +import { useClient } from './useClient.js' + +test('default', async () => { + const { result, rerender } = renderHook(() => useClient()) + + expect(result.current?.chain.id).toEqual(1) + + await switchChain(config, { chainId: 456 }) + rerender() + + expect(result.current?.chain.id).toEqual(456) +}) + +test('parameters: config', () => { + const { result } = renderHook(() => useClient({ config }), { + wrapper: ({ children }) => createElement(Fragment, { children }), + }) + expect(result.current).toBeDefined() +}) + +test('behavior: unconfigured chain', () => { + const { result } = renderHook(() => useClient({ chainId: 123456 })) + expect(result.current).toBeUndefined() +}) diff --git a/wagmi-project/packages/react/src/hooks/useClient.ts b/wagmi-project/packages/react/src/hooks/useClient.ts new file mode 100644 index 000000000..abfee745b --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useClient.ts @@ -0,0 +1,49 @@ +'use client' + +import { + type Config, + type GetClientParameters, + type GetClientReturnType, + type ResolvedRegister, + getClient, + watchClient, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { useSyncExternalStoreWithSelector } from 'use-sync-external-store/shim/with-selector.js' + +import type { ConfigParameter } from '../types/properties.js' +import { useConfig } from './useConfig.js' + +export type UseClientParameters< + config extends Config = Config, + chainId extends config['chains'][number]['id'] | number | undefined = + | config['chains'][number]['id'] + | undefined, +> = Compute & ConfigParameter> + +export type UseClientReturnType< + config extends Config = Config, + chainId extends config['chains'][number]['id'] | number | undefined = + | config['chains'][number]['id'] + | undefined, +> = GetClientReturnType + +/** https://wagmi.sh/react/api/hooks/useClient */ +export function useClient< + config extends Config = ResolvedRegister['config'], + chainId extends config['chains'][number]['id'] | number | undefined = + | config['chains'][number]['id'] + | undefined, +>( + parameters: UseClientParameters = {}, +): UseClientReturnType { + const config = useConfig(parameters) + + return useSyncExternalStoreWithSelector( + (onChange) => watchClient(config, { onChange }), + () => getClient(config, parameters), + () => getClient(config, parameters), + (x) => x, + (a, b) => a?.uid === b?.uid, + ) as any +} diff --git a/wagmi-project/packages/react/src/hooks/useConfig.test-d.ts b/wagmi-project/packages/react/src/hooks/useConfig.test-d.ts new file mode 100644 index 000000000..f2b9d2bb3 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useConfig.test-d.ts @@ -0,0 +1,16 @@ +import type { Config } from '@wagmi/core' +import { config } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' + +import { useConfig } from './useConfig.js' + +test('default', async () => { + const result = useConfig() + expectTypeOf(result).toEqualTypeOf() +}) + +test('parameters: config', async () => { + const result = useConfig({ config }) + expectTypeOf(result).not.toEqualTypeOf() + expectTypeOf(result).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/react/src/hooks/useConfig.test.ts b/wagmi-project/packages/react/src/hooks/useConfig.test.ts new file mode 100644 index 000000000..e0fc9c40c --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useConfig.test.ts @@ -0,0 +1,23 @@ +import { createWrapper, renderHook } from '@wagmi/test/react' +import { expect, test, vi } from 'vitest' + +import { useConfig } from './useConfig.js' + +test('mounts', () => { + const { result } = renderHook(() => useConfig()) + expect(result.current).toBeDefined() +}) + +test('behavior: throws when not inside Provider', () => { + vi.spyOn(console, 'error').mockImplementation(() => {}) + + try { + renderHook(() => useConfig(), { + wrapper: createWrapper(() => null, undefined), + }) + } catch (error) { + expect(error).toMatchInlineSnapshot( + '[Error: `useConfig` must be used within `WagmiProvider`.]', + ) + } +}) diff --git a/wagmi-project/packages/react/src/hooks/useConfig.ts b/wagmi-project/packages/react/src/hooks/useConfig.ts new file mode 100644 index 000000000..af9ea5b9c --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useConfig.ts @@ -0,0 +1,22 @@ +'use client' + +import type { Config, ResolvedRegister } from '@wagmi/core' +import { useContext } from 'react' + +import { WagmiContext } from '../context.js' +import { WagmiProviderNotFoundError } from '../errors/context.js' +import type { ConfigParameter } from '../types/properties.js' + +export type UseConfigParameters = + ConfigParameter + +export type UseConfigReturnType = config + +/** https://wagmi.sh/react/api/hooks/useConfig */ +export function useConfig( + parameters: UseConfigParameters = {}, +): UseConfigReturnType { + const config = parameters.config ?? useContext(WagmiContext) + if (!config) throw new WagmiProviderNotFoundError() + return config as UseConfigReturnType +} diff --git a/wagmi-project/packages/react/src/hooks/useConnect.test-d.ts b/wagmi-project/packages/react/src/hooks/useConnect.test-d.ts new file mode 100644 index 000000000..e678d2edd --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useConnect.test-d.ts @@ -0,0 +1,124 @@ +import type { + ConnectErrorType, + Connector, + CreateConnectorFn, +} from '@wagmi/core' +import { config } from '@wagmi/test' +import type { Address } from 'viem' +import { expectTypeOf, test } from 'vitest' + +import { useConnect } from './useConnect.js' + +const connector = config.connectors[0]! +const contextValue = { foo: 'bar' } as const + +test('context', () => { + const { connect, context, data, error, variables } = useConnect({ + mutation: { + onMutate(variables) { + expectTypeOf(variables).toEqualTypeOf<{ + chainId?: number | undefined + connector: Connector | CreateConnectorFn + }>() + return contextValue + }, + onError(error, variables, context) { + expectTypeOf(variables).toEqualTypeOf<{ + chainId?: number | undefined + connector: Connector | CreateConnectorFn + }>() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSuccess(data, variables, context) { + expectTypeOf(variables).toEqualTypeOf<{ + chainId?: number | undefined + connector: Connector | CreateConnectorFn + }>() + expectTypeOf(data).toEqualTypeOf<{ + accounts: readonly [Address, ...Address[]] + chainId: number + }>() + expectTypeOf(context).toEqualTypeOf() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf< + | { + accounts: readonly [Address, ...Address[]] + chainId: number + } + | undefined + >() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toEqualTypeOf<{ + chainId?: number | undefined + connector: Connector | CreateConnectorFn + }>() + expectTypeOf(context).toEqualTypeOf() + }, + }, + }) + + expectTypeOf(data).toEqualTypeOf< + | { + accounts: readonly [Address, ...Address[]] + chainId: number + } + | undefined + >() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toMatchTypeOf< + | { + chainId?: number | undefined + connector: CreateConnectorFn | Connector + } + | undefined + >() + expectTypeOf(context).toEqualTypeOf() + + connect( + { + connector, + foo: 'bar', + }, + { + onError(error, variables, context) { + expectTypeOf(variables).toEqualTypeOf<{ + chainId?: number | undefined + connector: typeof connector | CreateConnectorFn + foo?: string | undefined + }>() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSuccess(data, variables, context) { + expectTypeOf(variables).toEqualTypeOf<{ + chainId?: number | undefined + connector: typeof connector | CreateConnectorFn + foo?: string | undefined + }>() + expectTypeOf(data).toEqualTypeOf<{ + accounts: readonly [Address, ...Address[]] + chainId: number + }>() + expectTypeOf(context).toEqualTypeOf() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf< + | { + accounts: readonly [Address, ...Address[]] + chainId: number + } + | undefined + >() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toEqualTypeOf<{ + chainId?: number | undefined + connector: typeof connector | CreateConnectorFn + foo?: string | undefined + }>() + expectTypeOf(context).toEqualTypeOf() + }, + }, + ) +}) diff --git a/wagmi-project/packages/react/src/hooks/useConnect.test.ts b/wagmi-project/packages/react/src/hooks/useConnect.test.ts new file mode 100644 index 000000000..d80ff3050 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useConnect.test.ts @@ -0,0 +1,35 @@ +import { disconnect } from '@wagmi/core' +import { config } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { afterEach, expect, test } from 'vitest' + +import { useAccount } from './useAccount.js' +import { useConnect } from './useConnect.js' + +const connector = config.connectors[0]! + +afterEach(async () => { + if (config.state.current === connector.uid) + await disconnect(config, { connector }) +}) + +test('default', async () => { + const { result } = renderHook(() => ({ + useAccount: useAccount(), + useConnect: useConnect(), + })) + + expect(result.current.useAccount.address).not.toBeDefined() + expect(result.current.useAccount.status).toEqual('disconnected') + + result.current.useConnect.connect({ + connector: result.current.useConnect.connectors[0]!, + }) + + await waitFor(() => + expect(result.current.useAccount.isConnected).toBeTruthy(), + ) + + expect(result.current.useAccount.address).toBeDefined() + expect(result.current.useAccount.status).toEqual('connected') +}) diff --git a/wagmi-project/packages/react/src/hooks/useConnect.ts b/wagmi-project/packages/react/src/hooks/useConnect.ts new file mode 100644 index 000000000..acfe69234 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useConnect.ts @@ -0,0 +1,90 @@ +'use client' + +import { useMutation } from '@tanstack/react-query' +import type { Config, ConnectErrorType, ResolvedRegister } from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type ConnectData, + type ConnectMutate, + type ConnectMutateAsync, + type ConnectVariables, + connectMutationOptions, +} from '@wagmi/core/query' +import { useEffect } from 'react' + +import type { ConfigParameter } from '../types/properties.js' +import type { + UseMutationParameters, + UseMutationReturnType, +} from '../utils/query.js' +import { useConfig } from './useConfig.js' +import { type UseConnectorsReturnType, useConnectors } from './useConnectors.js' + +export type UseConnectParameters< + config extends Config = Config, + context = unknown, +> = Compute< + ConfigParameter & { + mutation?: + | UseMutationParameters< + ConnectData, + ConnectErrorType, + ConnectVariables, + context + > + | undefined + } +> + +export type UseConnectReturnType< + config extends Config = Config, + context = unknown, +> = Compute< + UseMutationReturnType< + ConnectData, + ConnectErrorType, + ConnectVariables, + context + > & { + connect: ConnectMutate + connectAsync: ConnectMutateAsync + connectors: Compute | config['connectors'] + } +> + +/** https://wagmi.sh/react/api/hooks/useConnect */ +export function useConnect< + config extends Config = ResolvedRegister['config'], + context = unknown, +>( + parameters: UseConnectParameters = {}, +): UseConnectReturnType { + const { mutation } = parameters + + const config = useConfig(parameters) + + const mutationOptions = connectMutationOptions(config) + const { mutate, mutateAsync, ...result } = useMutation({ + ...mutation, + ...mutationOptions, + }) + + // Reset mutation back to an idle state when the connector disconnects. + useEffect(() => { + return config.subscribe( + ({ status }) => status, + (status, previousStatus) => { + if (previousStatus === 'connected' && status === 'disconnected') + result.reset() + }, + ) + }, [config, result.reset]) + + type Return = UseConnectReturnType + return { + ...(result as Return), + connect: mutate as Return['connect'], + connectAsync: mutateAsync as Return['connectAsync'], + connectors: useConnectors({ config }), + } +} diff --git a/wagmi-project/packages/react/src/hooks/useConnections.test.ts b/wagmi-project/packages/react/src/hooks/useConnections.test.ts new file mode 100644 index 000000000..1eb4febcd --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useConnections.test.ts @@ -0,0 +1,25 @@ +import { connect } from '@wagmi/core' +import { config } from '@wagmi/test' +import { renderHook } from '@wagmi/test/react' +import { Fragment, createElement } from 'react' +import { expect, test } from 'vitest' + +import { useConnections } from './useConnections.js' + +test('default', async () => { + const { result, rerender } = renderHook(() => useConnections()) + + expect(result.current).toEqual([]) + + await connect(config, { connector: config.connectors[0]! }) + rerender() + + expect(result.current.length).toBe(1) +}) + +test('parameters: config', () => { + const { result } = renderHook(() => useConnections({ config }), { + wrapper: ({ children }) => createElement(Fragment, { children }), + }) + expect(result.current).toBeDefined() +}) diff --git a/wagmi-project/packages/react/src/hooks/useConnections.ts b/wagmi-project/packages/react/src/hooks/useConnections.ts new file mode 100644 index 000000000..db53db722 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useConnections.ts @@ -0,0 +1,28 @@ +'use client' + +import { + type GetConnectionsReturnType, + getConnections, + watchConnections, +} from '@wagmi/core' +import { useSyncExternalStore } from 'react' + +import type { ConfigParameter } from '../types/properties.js' +import { useConfig } from './useConfig.js' + +export type UseConnectionsParameters = ConfigParameter + +export type UseConnectionsReturnType = GetConnectionsReturnType + +/** https://wagmi.sh/react/api/hooks/useConnections */ +export function useConnections( + parameters: UseConnectionsParameters = {}, +): UseConnectionsReturnType { + const config = useConfig(parameters) + + return useSyncExternalStore( + (onChange) => watchConnections(config, { onChange }), + () => getConnections(config), + () => getConnections(config), + ) +} diff --git a/wagmi-project/packages/react/src/hooks/useConnectorClient.test-d.ts b/wagmi-project/packages/react/src/hooks/useConnectorClient.test-d.ts new file mode 100644 index 000000000..b919e6a90 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useConnectorClient.test-d.ts @@ -0,0 +1,12 @@ +import { config } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' + +import { useConnectorClient } from './useConnectorClient.js' + +test('parameters: config', async () => { + const client = useConnectorClient({ config }) + expectTypeOf(client.data?.chain?.id!).toEqualTypeOf<1 | 456 | 10>() + + const client2 = useConnectorClient({ config, chainId: 1 }) + expectTypeOf(client2.data?.chain?.id!).toEqualTypeOf<1>() +}) diff --git a/wagmi-project/packages/react/src/hooks/useConnectorClient.test.tsx b/wagmi-project/packages/react/src/hooks/useConnectorClient.test.tsx new file mode 100644 index 000000000..f8737c53e --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useConnectorClient.test.tsx @@ -0,0 +1,239 @@ +import { connect, disconnect } from '@wagmi/core' +import { config, wait } from '@wagmi/test' +import { render, renderHook, waitFor } from '@wagmi/test/react' +import * as React from 'react' +import { expect, test } from 'vitest' + +import { useAccount } from './useAccount.js' +import { useConnect } from './useConnect.js' +import { useConnectorClient } from './useConnectorClient.js' +import { useDisconnect } from './useDisconnect.js' +import { useSwitchChain } from './useSwitchChain.js' + +const connector = config.connectors[0]! + +test('default', async () => { + const { result } = renderHook(() => useConnectorClient()) + + await waitFor(() => expect(result.current.isPending).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": undefined, + "dataUpdatedAt": 0, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": false, + "isFetchedAfterMount": false, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": true, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": false, + "isSuccess": false, + "queryKey": [ + "connectorClient", + { + "chainId": 1, + "connectorUid": undefined, + }, + ], + "refetch": [Function], + "status": "pending", + } + `) +}) + +test('behavior: connected on mount', async () => { + await connect(config, { connector }) + + const { result } = renderHook(() => useConnectorClient()) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + const { data, queryKey: _, ...rest } = result.current + expect(data).toMatchObject( + expect.objectContaining({ + account: expect.any(Object), + chain: expect.any(Object), + }), + ) + expect(rest).toMatchInlineSnapshot(` + { + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": false, + "isSuccess": true, + "refetch": [Function], + "status": "success", + } + `) + + await disconnect(config, { connector }) +}) + +test('behavior: connect and disconnect', async () => { + const { result } = renderHook(() => ({ + useConnect: useConnect(), + useConnectorClient: useConnectorClient(), + useDisconnect: useDisconnect(), + })) + + expect(result.current.useConnectorClient.data).not.toBeDefined() + + result.current.useConnect.connect({ + connector: result.current.useConnect.connectors[0]!, + }) + + await waitFor(() => + expect(result.current.useConnectorClient.data).toBeDefined(), + ) + + result.current.useDisconnect.disconnect() + + await waitFor(() => + expect(result.current.useConnectorClient.data).not.toBeDefined(), + ) +}) + +test('behavior: switch chains', async () => { + await connect(config, { connector }) + + const { result } = renderHook(() => ({ + useConnectorClient: useConnectorClient(), + useSwitchChain: useSwitchChain(), + })) + + expect(result.current.useConnectorClient.data).not.toBeDefined() + + await waitFor(() => + expect(result.current.useConnectorClient.data).toBeDefined(), + ) + + result.current.useSwitchChain.switchChain({ chainId: 456 }) + await waitFor(() => { + expect(result.current.useSwitchChain.isSuccess).toBeTruthy() + result.current.useSwitchChain.reset() + }) + expect(result.current.useConnectorClient.data?.chain.id).toEqual(456) + + result.current.useSwitchChain.switchChain({ chainId: 1 }) + await waitFor(() => + expect(result.current.useSwitchChain.isSuccess).toBeTruthy(), + ) + expect(result.current.useConnectorClient.data?.chain.id).toEqual(1) + + await disconnect(config, { connector }) +}) + +test('behavior: disabled when properties missing', async () => { + const { result } = renderHook(() => useConnectorClient()) + + await wait(100) + await waitFor(() => expect(result.current.isPending).toBeTruthy()) +}) + +test('behavior: disabled when connecting', async () => { + const { result } = renderHook(() => useConnectorClient()) + + config.setState((x) => ({ ...x, status: 'connecting' })) + + await wait(100) + expect(result.current.isLoading).not.toBeTruthy() +}) + +test('behavior: re-render does not invalidate query', async () => { + const { getByTestId } = render() + + getByTestId('connect').click() + await waitFor(() => { + expect(getByTestId('address').innerText).toContain( + '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', + ) + expect(getByTestId('client').innerText).toBeTruthy() + + expect(getByTestId('child-client').innerText).toBeTruthy() + expect(getByTestId('render-count').innerText).toEqual('1') + }) + + const initialClient = getByTestId('child-client').innerText + + getByTestId('rerender').click() + await waitFor(() => { + expect(getByTestId('render-count').innerText).toEqual('2') + }) + await wait(200) + + expect(getByTestId('child-client').innerText).toEqual(initialClient) +}) + +function Parent() { + const [renderCount, setRenderCount] = React.useState(1) + + const { connectors, connect } = useConnect() + const { address } = useAccount() + const { data } = useConnectorClient() + + return ( + <> +
{address}
+
{data?.uid}
+ + + + + + ) +} + +function Child(props: { + renderCount: number +}) { + const { renderCount } = props + const { data } = useConnectorClient() + return ( +
+ {data?.uid} + {renderCount} +
+ ) +} diff --git a/wagmi-project/packages/react/src/hooks/useConnectorClient.ts b/wagmi-project/packages/react/src/hooks/useConnectorClient.ts new file mode 100644 index 000000000..16bbf33ae --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useConnectorClient.ts @@ -0,0 +1,113 @@ +'use client' + +import { useQueryClient } from '@tanstack/react-query' +import type { + Config, + GetConnectorClientErrorType, + ResolvedRegister, +} from '@wagmi/core' +import type { Compute, Omit } from '@wagmi/core/internal' +import { + type GetConnectorClientData, + type GetConnectorClientOptions, + type GetConnectorClientQueryFnData, + type GetConnectorClientQueryKey, + getConnectorClientQueryOptions, +} from '@wagmi/core/query' +import { useEffect, useRef } from 'react' + +import type { ConfigParameter } from '../types/properties.js' +import { + type UseQueryParameters, + type UseQueryReturnType, + useQuery, +} from '../utils/query.js' +import { useAccount } from './useAccount.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseConnectorClientParameters< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = GetConnectorClientData, +> = Compute< + GetConnectorClientOptions & + ConfigParameter & { + query?: + | Compute< + Omit< + UseQueryParameters< + GetConnectorClientQueryFnData, + GetConnectorClientErrorType, + selectData, + GetConnectorClientQueryKey + >, + 'gcTime' | 'staleTime' + > + > + | undefined + } +> + +export type UseConnectorClientReturnType< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = GetConnectorClientData, +> = UseQueryReturnType + +/** https://wagmi.sh/react/api/hooks/useConnectorClient */ +export function useConnectorClient< + config extends Config = ResolvedRegister['config'], + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = GetConnectorClientData, +>( + parameters: UseConnectorClientParameters = {}, +): UseConnectorClientReturnType { + const { query = {}, ...rest } = parameters + + const config = useConfig(rest) + const queryClient = useQueryClient() + const { address, connector, status } = useAccount({ config }) + const chainId = useChainId({ config }) + const activeConnector = parameters.connector ?? connector + + const { queryKey, ...options } = getConnectorClientQueryOptions< + config, + chainId + >(config, { + ...parameters, + chainId: parameters.chainId ?? chainId, + connector: activeConnector, + }) + const enabled = Boolean( + (status === 'connected' || + (status === 'reconnecting' && activeConnector?.getProvider)) && + (query.enabled ?? true), + ) + + const addressRef = useRef(address) + // biome-ignore lint/correctness/useExhaustiveDependencies: `queryKey` not required + useEffect(() => { + const previousAddress = addressRef.current + if (!address && previousAddress) { + // remove when account is disconnected + queryClient.removeQueries({ queryKey }) + addressRef.current = undefined + } else if (address !== previousAddress) { + // invalidate when address changes + queryClient.invalidateQueries({ queryKey }) + addressRef.current = address + } + }, [address, queryClient]) + + return useQuery({ + ...query, + ...options, + queryKey, + enabled, + staleTime: Number.POSITIVE_INFINITY, + }) +} diff --git a/wagmi-project/packages/react/src/hooks/useConnectors.test.ts b/wagmi-project/packages/react/src/hooks/useConnectors.test.ts new file mode 100644 index 000000000..f287cceb3 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useConnectors.test.ts @@ -0,0 +1,30 @@ +import { mock } from '@wagmi/connectors' +import { accounts, config } from '@wagmi/test' +import { renderHook } from '@wagmi/test/react' +import { Fragment, createElement } from 'react' +import { expect, test } from 'vitest' + +import { useConnectors } from './useConnectors.js' + +test('default', async () => { + const { result, rerender } = renderHook(() => useConnectors()) + + const count = config.connectors.length + expect(result.current.length).toBe(count) + expect(result.current).toEqual(config.connectors) + + config._internal.connectors.setState(() => [ + ...config.connectors, + config._internal.connectors.setup(mock({ accounts })), + ]) + rerender() + + expect(result.current.length).toBe(count + 1) +}) + +test('parameters: config', () => { + const { result } = renderHook(() => useConnectors({ config }), { + wrapper: ({ children }) => createElement(Fragment, { children }), + }) + expect(result.current).toBeDefined() +}) diff --git a/wagmi-project/packages/react/src/hooks/useConnectors.ts b/wagmi-project/packages/react/src/hooks/useConnectors.ts new file mode 100644 index 000000000..40a681689 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useConnectors.ts @@ -0,0 +1,34 @@ +'use client' + +import { + type Config, + type GetConnectorsReturnType, + type ResolvedRegister, + getConnectors, + watchConnectors, +} from '@wagmi/core' +import { useSyncExternalStore } from 'react' + +import type { ConfigParameter } from '../types/properties.js' +import { useConfig } from './useConfig.js' + +export type UseConnectorsParameters = + ConfigParameter + +export type UseConnectorsReturnType = + GetConnectorsReturnType + +/** https://wagmi.sh/react/api/hooks/useConnectors */ +export function useConnectors< + config extends Config = ResolvedRegister['config'], +>( + parameters: UseConnectorsParameters = {}, +): UseConnectorsReturnType { + const config = useConfig(parameters) + + return useSyncExternalStore( + (onChange) => watchConnectors(config, { onChange }), + () => getConnectors(config), + () => getConnectors(config), + ) +} diff --git a/wagmi-project/packages/react/src/hooks/useDeployContract.test-d.ts b/wagmi-project/packages/react/src/hooks/useDeployContract.test-d.ts new file mode 100644 index 000000000..93e53c472 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useDeployContract.test-d.ts @@ -0,0 +1,105 @@ +import type { DeployContractErrorType } from '@wagmi/core' +import { abi, bytecode } from '@wagmi/test' +import type { Abi, Hash } from 'viem' +import { expectTypeOf, test } from 'vitest' + +import { useDeployContract } from './useDeployContract.js' + +const contextValue = { foo: 'bar' } as const + +test('context', () => { + const { context, data, error, deployContract, variables } = useDeployContract( + { + mutation: { + onMutate(variables) { + expectTypeOf(variables).toMatchTypeOf<{ + chainId?: number | undefined + abi: Abi + args?: readonly unknown[] | undefined + }>() + return contextValue + }, + onError(error, variables, context) { + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + + expectTypeOf(variables).toMatchTypeOf<{ + chainId?: number | undefined + abi: Abi + args?: readonly unknown[] | undefined + }>() + }, + onSuccess(data, variables, context) { + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + + expectTypeOf(variables).toMatchTypeOf<{ + chainId?: number | undefined + abi: Abi + args?: readonly unknown[] | undefined + }>() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + + expectTypeOf(variables).toMatchTypeOf<{ + chainId?: number | undefined + abi: Abi + args?: readonly unknown[] | undefined + }>() + }, + }, + }, + ) + + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toMatchTypeOf< + { chainId?: number | undefined } | undefined + >() + expectTypeOf(context).toEqualTypeOf() + + deployContract( + { + abi: abi.bayc, + bytecode: bytecode.bayc, + args: ['Bored Ape Wagmi Club', 'BAYC', 69420n, 0n], + chainId: 1, + }, + { + onError(error, variables, context) { + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + + expectTypeOf(variables).toMatchTypeOf<{ + chainId?: number | undefined + abi: typeof abi.bayc + args: readonly [string, string, bigint, bigint] + }>() + }, + onSuccess(data, variables, context) { + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + + expectTypeOf(variables).toMatchTypeOf<{ + chainId?: number | undefined + abi: typeof abi.bayc + args: readonly [string, string, bigint, bigint] + }>() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + + expectTypeOf(variables).toMatchTypeOf<{ + chainId?: number | undefined + abi: typeof abi.bayc + args: readonly [string, string, bigint, bigint] + }>() + }, + }, + ) +}) diff --git a/wagmi-project/packages/react/src/hooks/useDeployContract.test.ts b/wagmi-project/packages/react/src/hooks/useDeployContract.test.ts new file mode 100644 index 000000000..561129bdb --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useDeployContract.test.ts @@ -0,0 +1,24 @@ +import { connect, disconnect } from '@wagmi/core' +import { abi, bytecode, config, transactionHashRegex } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { expect, test } from 'vitest' + +import { useDeployContract } from './useDeployContract.js' + +const connector = config.connectors[0]! + +test('default', async () => { + await connect(config, { connector }) + const { result } = renderHook(() => useDeployContract()) + + result.current.deployContract({ + abi: abi.bayc, + bytecode: bytecode.bayc, + args: ['Bored Ape Wagmi Club', 'BAYC', 69420n, 0n], + }) + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current.data).toMatch(transactionHashRegex) + + await disconnect(config, { connector }) +}) diff --git a/wagmi-project/packages/react/src/hooks/useDeployContract.ts b/wagmi-project/packages/react/src/hooks/useDeployContract.ts new file mode 100644 index 000000000..d37f3206d --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useDeployContract.ts @@ -0,0 +1,78 @@ +'use client' + +import { useMutation } from '@tanstack/react-query' +import type { + Config, + DeployContractErrorType, + ResolvedRegister, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type DeployContractData, + type DeployContractMutate, + type DeployContractMutateAsync, + type DeployContractVariables, + deployContractMutationOptions, +} from '@wagmi/core/query' +import type { Abi } from 'viem' + +import type { ConfigParameter } from '../types/properties.js' +import type { + UseMutationParameters, + UseMutationReturnType, +} from '../utils/query.js' +import { useConfig } from './useConfig.js' + +export type UseDeployContractParameters< + config extends Config = Config, + context = unknown, +> = Compute< + ConfigParameter & { + mutation?: + | UseMutationParameters< + DeployContractData, + DeployContractErrorType, + DeployContractVariables, + context + > + | undefined + } +> + +export type UseDeployContractReturnType< + config extends Config = Config, + context = unknown, +> = UseMutationReturnType< + DeployContractData, + DeployContractErrorType, + DeployContractVariables, + context +> & { + deployContract: DeployContractMutate + deployContractAsync: DeployContractMutateAsync +} + +/** https://wagmi.sh/react/api/hooks/useDeployContract */ +export function useDeployContract< + config extends Config = ResolvedRegister['config'], + context = unknown, +>( + parameters: UseDeployContractParameters = {}, +): UseDeployContractReturnType { + const { mutation } = parameters + + const config = useConfig(parameters) + + const mutationOptions = deployContractMutationOptions(config) + const { mutate, mutateAsync, ...result } = useMutation({ + ...mutation, + ...mutationOptions, + }) + + type Return = UseDeployContractReturnType + return { + ...result, + deployContract: mutate as Return['deployContract'], + deployContractAsync: mutateAsync as Return['deployContractAsync'], + } +} diff --git a/wagmi-project/packages/react/src/hooks/useDisconnect.test-d.ts b/wagmi-project/packages/react/src/hooks/useDisconnect.test-d.ts new file mode 100644 index 000000000..7bf368945 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useDisconnect.test-d.ts @@ -0,0 +1,87 @@ +import type { Connector, DisconnectErrorType } from '@wagmi/core' +import { config } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' + +import { useDisconnect } from './useDisconnect.js' + +const connector = config.connectors[0]! +const contextValue = { foo: 'bar' } as const + +test('parameter', () => { + expectTypeOf(useDisconnect().disconnect) + .parameter(0) + .toEqualTypeOf<{ connector?: Connector | undefined } | undefined>() + expectTypeOf(useDisconnect().disconnect) + .parameter(0) + .toEqualTypeOf<{ connector?: Connector | undefined } | undefined>() +}) + +test('context', () => { + const { context, data, disconnect, error, variables } = useDisconnect({ + mutation: { + onMutate(variables) { + expectTypeOf(variables).toEqualTypeOf< + { connector?: Connector | undefined } | undefined + >() + return contextValue + }, + onError(error, variables, context) { + expectTypeOf(variables).toEqualTypeOf< + { connector?: Connector | undefined } | undefined + >() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSuccess(data, variables, context) { + expectTypeOf(variables).toEqualTypeOf< + { connector?: Connector | undefined } | undefined + >() + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toEqualTypeOf< + { connector?: Connector | undefined } | undefined + >() + expectTypeOf(context).toEqualTypeOf() + }, + }, + }) + + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toEqualTypeOf< + { connector?: Connector | undefined } | undefined + >() + expectTypeOf(context).toEqualTypeOf() + + disconnect( + { connector }, + { + onError(error, variables, context) { + expectTypeOf(variables).toEqualTypeOf< + { connector?: Connector | undefined } | undefined + >() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSuccess(data, variables, context) { + expectTypeOf(variables).toEqualTypeOf< + { connector?: Connector | undefined } | undefined + >() + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toEqualTypeOf< + { connector?: Connector | undefined } | undefined + >() + expectTypeOf(context).toEqualTypeOf() + }, + }, + ) +}) diff --git a/wagmi-project/packages/react/src/hooks/useDisconnect.test.ts b/wagmi-project/packages/react/src/hooks/useDisconnect.test.ts new file mode 100644 index 000000000..26c7787d9 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useDisconnect.test.ts @@ -0,0 +1,32 @@ +import { connect } from '@wagmi/core' +import { config } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { beforeEach, expect, test } from 'vitest' + +import { useAccount } from './useAccount.js' +import { useDisconnect } from './useDisconnect.js' + +const connector = config.connectors[0]! + +beforeEach(async () => { + await connect(config, { connector }) +}) + +test('default', async () => { + const { result } = renderHook(() => ({ + useAccount: useAccount(), + useDisconnect: useDisconnect(), + })) + + expect(result.current.useAccount.address).toBeDefined() + expect(result.current.useAccount.status).toEqual('connected') + + result.current.useDisconnect.disconnect() + + await waitFor(() => + expect(result.current.useAccount.isDisconnected).toBeTruthy(), + ) + + expect(result.current.useAccount.address).not.toBeDefined() + expect(result.current.useAccount.status).toEqual('disconnected') +}) diff --git a/wagmi-project/packages/react/src/hooks/useDisconnect.ts b/wagmi-project/packages/react/src/hooks/useDisconnect.ts new file mode 100644 index 000000000..b5bff5bfe --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useDisconnect.ts @@ -0,0 +1,70 @@ +'use client' + +import { useMutation } from '@tanstack/react-query' +import type { Connector, DisconnectErrorType } from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type DisconnectData, + type DisconnectMutate, + type DisconnectMutateAsync, + type DisconnectVariables, + disconnectMutationOptions, +} from '@wagmi/core/query' + +import type { ConfigParameter } from '../types/properties.js' +import type { + UseMutationParameters, + UseMutationReturnType, +} from '../utils/query.js' +import { useConfig } from './useConfig.js' +import { useConnections } from './useConnections.js' + +export type UseDisconnectParameters = Compute< + ConfigParameter & { + mutation?: + | UseMutationParameters< + DisconnectData, + DisconnectErrorType, + DisconnectVariables, + context + > + | undefined + } +> + +export type UseDisconnectReturnType = Compute< + UseMutationReturnType< + DisconnectData, + DisconnectErrorType, + DisconnectVariables, + context + > & { + connectors: readonly Connector[] + disconnect: DisconnectMutate + disconnectAsync: DisconnectMutateAsync + } +> + +/** https://wagmi.sh/react/api/hooks/useDisconnect */ +export function useDisconnect( + parameters: UseDisconnectParameters = {}, +): UseDisconnectReturnType { + const { mutation } = parameters + + const config = useConfig(parameters) + + const mutationOptions = disconnectMutationOptions(config) + const { mutate, mutateAsync, ...result } = useMutation({ + ...mutation, + ...mutationOptions, + }) + + return { + ...result, + connectors: useConnections({ config }).map( + (connection) => connection.connector, + ), + disconnect: mutate, + disconnectAsync: mutateAsync, + } +} diff --git a/wagmi-project/packages/react/src/hooks/useEnsAddress.test.ts b/wagmi-project/packages/react/src/hooks/useEnsAddress.test.ts new file mode 100644 index 000000000..ff73c45f9 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useEnsAddress.test.ts @@ -0,0 +1,50 @@ +import { renderHook, waitFor } from '@wagmi/test/react' +import { expect, test } from 'vitest' + +import { useEnsAddress } from './useEnsAddress.js' + +test('default', async () => { + const { result } = renderHook(() => + useEnsAddress({ + name: 'wevm.eth', + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": "0xd2135CfB216b74109775236E36d4b433F1DF507B", + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "ensAddress", + { + "chainId": 1, + "name": "wevm.eth", + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) diff --git a/wagmi-project/packages/react/src/hooks/useEnsAddress.ts b/wagmi-project/packages/react/src/hooks/useEnsAddress.ts new file mode 100644 index 000000000..999e07d99 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useEnsAddress.ts @@ -0,0 +1,58 @@ +'use client' + +import type { + Config, + GetEnsAddressErrorType, + ResolvedRegister, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type GetEnsAddressData, + type GetEnsAddressOptions, + type GetEnsAddressQueryFnData, + type GetEnsAddressQueryKey, + getEnsAddressQueryOptions, +} from '@wagmi/core/query' + +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseEnsAddressParameters< + config extends Config = Config, + selectData = GetEnsAddressData, +> = Compute< + GetEnsAddressOptions & + ConfigParameter & + QueryParameter< + GetEnsAddressQueryFnData, + GetEnsAddressErrorType, + selectData, + GetEnsAddressQueryKey + > +> + +export type UseEnsAddressReturnType = + UseQueryReturnType + +/** https://wagmi.sh/react/api/hooks/useEnsAddress */ +export function useEnsAddress< + config extends Config = ResolvedRegister['config'], + selectData = GetEnsAddressData, +>( + parameters: UseEnsAddressParameters = {}, +): UseEnsAddressReturnType { + const { name, query = {} } = parameters + + const config = useConfig(parameters) + const chainId = useChainId({ config }) + + const options = getEnsAddressQueryOptions(config, { + ...parameters, + chainId: parameters.chainId ?? chainId, + }) + const enabled = Boolean(name && (query.enabled ?? true)) + + return useQuery({ ...query, ...options, enabled }) +} diff --git a/wagmi-project/packages/react/src/hooks/useEnsAvatar.test.ts b/wagmi-project/packages/react/src/hooks/useEnsAvatar.test.ts new file mode 100644 index 000000000..d1f558be1 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useEnsAvatar.test.ts @@ -0,0 +1,50 @@ +import { renderHook, waitFor } from '@wagmi/test/react' +import { expect, test } from 'vitest' + +import { useEnsAvatar } from './useEnsAvatar.js' + +test('default', async () => { + const { result } = renderHook(() => + useEnsAvatar({ + name: 'wevm.eth', + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": "https://euc.li/wevm.eth", + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "ensAvatar", + { + "chainId": 1, + "name": "wevm.eth", + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) diff --git a/wagmi-project/packages/react/src/hooks/useEnsAvatar.ts b/wagmi-project/packages/react/src/hooks/useEnsAvatar.ts new file mode 100644 index 000000000..721653bf0 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useEnsAvatar.ts @@ -0,0 +1,58 @@ +'use client' + +import type { + Config, + GetEnsAvatarErrorType, + ResolvedRegister, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type GetEnsAvatarData, + type GetEnsAvatarOptions, + type GetEnsAvatarQueryFnData, + type GetEnsAvatarQueryKey, + getEnsAvatarQueryOptions, +} from '@wagmi/core/query' + +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseEnsAvatarParameters< + config extends Config = Config, + selectData = GetEnsAvatarData, +> = Compute< + GetEnsAvatarOptions & + ConfigParameter & + QueryParameter< + GetEnsAvatarQueryFnData, + GetEnsAvatarErrorType, + selectData, + GetEnsAvatarQueryKey + > +> + +export type UseEnsAvatarReturnType = + UseQueryReturnType + +/** https://wagmi.sh/react/api/hooks/useEnsAvatar */ +export function useEnsAvatar< + config extends Config = ResolvedRegister['config'], + selectData = GetEnsAvatarData, +>( + parameters: UseEnsAvatarParameters = {}, +): UseEnsAvatarReturnType { + const { name, query = {} } = parameters + + const config = useConfig(parameters) + const chainId = useChainId({ config }) + + const options = getEnsAvatarQueryOptions(config, { + ...parameters, + chainId: parameters.chainId ?? chainId, + }) + const enabled = Boolean(name && (query.enabled ?? true)) + + return useQuery({ ...query, ...options, enabled }) +} diff --git a/wagmi-project/packages/react/src/hooks/useEnsName.test.ts b/wagmi-project/packages/react/src/hooks/useEnsName.test.ts new file mode 100644 index 000000000..8a069b076 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useEnsName.test.ts @@ -0,0 +1,50 @@ +import { renderHook, waitFor } from '@wagmi/test/react' +import { expect, test } from 'vitest' + +import { useEnsName } from './useEnsName.js' + +test('default', async () => { + const { result } = renderHook(() => + useEnsName({ + address: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": "wevm.eth", + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "ensName", + { + "address": "0xd2135CfB216b74109775236E36d4b433F1DF507B", + "chainId": 1, + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) diff --git a/wagmi-project/packages/react/src/hooks/useEnsName.ts b/wagmi-project/packages/react/src/hooks/useEnsName.ts new file mode 100644 index 000000000..ddf88fed9 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useEnsName.ts @@ -0,0 +1,54 @@ +'use client' + +import type { Config, GetEnsNameErrorType, ResolvedRegister } from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type GetEnsNameData, + type GetEnsNameOptions, + type GetEnsNameQueryFnData, + type GetEnsNameQueryKey, + getEnsNameQueryOptions, +} from '@wagmi/core/query' + +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseEnsNameParameters< + config extends Config = Config, + selectData = GetEnsNameData, +> = Compute< + GetEnsNameOptions & + ConfigParameter & + QueryParameter< + GetEnsNameQueryFnData, + GetEnsNameErrorType, + selectData, + GetEnsNameQueryKey + > +> + +export type UseEnsNameReturnType = + UseQueryReturnType + +/** https://wagmi.sh/react/api/hooks/useEnsName */ +export function useEnsName< + config extends Config = ResolvedRegister['config'], + selectData = GetEnsNameData, +>( + parameters: UseEnsNameParameters = {}, +): UseEnsNameReturnType { + const { address, query = {} } = parameters + + const config = useConfig(parameters) + const chainId = useChainId({ config }) + + const options = getEnsNameQueryOptions(config, { + ...parameters, + chainId: parameters.chainId ?? chainId, + }) + const enabled = Boolean(address && (query.enabled ?? true)) + + return useQuery({ ...query, ...options, enabled }) +} diff --git a/wagmi-project/packages/react/src/hooks/useEnsResolver.test.ts b/wagmi-project/packages/react/src/hooks/useEnsResolver.test.ts new file mode 100644 index 000000000..f5b89d8f6 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useEnsResolver.test.ts @@ -0,0 +1,50 @@ +import { renderHook, waitFor } from '@wagmi/test/react' +import { expect, test } from 'vitest' + +import { useEnsResolver } from './useEnsResolver.js' + +test('default', async () => { + const { result } = renderHook(() => + useEnsResolver({ + name: 'wevm.eth', + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": "0x4976fb03C32e5B8cfe2b6cCB31c09Ba78EBaBa41", + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "ensResolver", + { + "chainId": 1, + "name": "wevm.eth", + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) diff --git a/wagmi-project/packages/react/src/hooks/useEnsResolver.ts b/wagmi-project/packages/react/src/hooks/useEnsResolver.ts new file mode 100644 index 000000000..e883debfa --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useEnsResolver.ts @@ -0,0 +1,58 @@ +'use client' + +import type { + Config, + GetEnsResolverErrorType, + ResolvedRegister, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type GetEnsResolverData, + type GetEnsResolverOptions, + type GetEnsResolverQueryFnData, + type GetEnsResolverQueryKey, + getEnsResolverQueryOptions, +} from '@wagmi/core/query' + +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseEnsResolverParameters< + config extends Config = Config, + selectData = GetEnsResolverData, +> = Compute< + GetEnsResolverOptions & + ConfigParameter & + QueryParameter< + GetEnsResolverQueryFnData, + GetEnsResolverErrorType, + selectData, + GetEnsResolverQueryKey + > +> + +export type UseEnsResolverReturnType = + UseQueryReturnType + +/** https://wagmi.sh/react/api/hooks/useEnsResolver */ +export function useEnsResolver< + config extends Config = ResolvedRegister['config'], + selectData = GetEnsResolverData, +>( + parameters: UseEnsResolverParameters = {}, +): UseEnsResolverReturnType { + const { name, query = {} } = parameters + + const config = useConfig(parameters) + const chainId = useChainId({ config }) + + const options = getEnsResolverQueryOptions(config, { + ...parameters, + chainId: parameters.chainId ?? chainId, + }) + const enabled = Boolean(name && (query.enabled ?? true)) + + return useQuery({ ...query, ...options, enabled }) +} diff --git a/wagmi-project/packages/react/src/hooks/useEnsText.test.ts b/wagmi-project/packages/react/src/hooks/useEnsText.test.ts new file mode 100644 index 000000000..5e1c4b1d8 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useEnsText.test.ts @@ -0,0 +1,150 @@ +import { wait } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { expect, test } from 'vitest' + +import { useEnsText } from './useEnsText.js' + +test('default', async () => { + const { result } = renderHook(() => + useEnsText({ + key: 'com.twitter', + name: 'wevm.eth', + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": "wevm_dev", + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "ensText", + { + "chainId": 1, + "key": "com.twitter", + "name": "wevm.eth", + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('behavior: name: undefined -> defined', async () => { + let name: string | undefined = undefined + + const { result, rerender } = renderHook(() => + useEnsText({ + key: 'com.twitter', + name, + }), + ) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": undefined, + "dataUpdatedAt": 0, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": false, + "isFetchedAfterMount": false, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": true, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": false, + "isSuccess": false, + "queryKey": [ + "ensText", + { + "chainId": 1, + "key": "com.twitter", + "name": undefined, + }, + ], + "refetch": [Function], + "status": "pending", + } + `) + + name = 'wevm.eth' + rerender() + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": "wevm_dev", + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "ensText", + { + "chainId": 1, + "key": "com.twitter", + "name": "wevm.eth", + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('behavior: disabled when properties missing', async () => { + const { result } = renderHook(() => useEnsText()) + + await wait(100) + await waitFor(() => expect(result.current.isPending).toBeTruthy()) +}) diff --git a/wagmi-project/packages/react/src/hooks/useEnsText.ts b/wagmi-project/packages/react/src/hooks/useEnsText.ts new file mode 100644 index 000000000..2e65238c4 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useEnsText.ts @@ -0,0 +1,54 @@ +'use client' + +import type { Config, GetEnsTextErrorType, ResolvedRegister } from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type GetEnsTextData, + type GetEnsTextOptions, + type GetEnsTextQueryFnData, + type GetEnsTextQueryKey, + getEnsTextQueryOptions, +} from '@wagmi/core/query' + +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseEnsTextParameters< + config extends Config = Config, + selectData = GetEnsTextData, +> = Compute< + GetEnsTextOptions & + ConfigParameter & + QueryParameter< + GetEnsTextQueryFnData, + GetEnsTextErrorType, + selectData, + GetEnsTextQueryKey + > +> + +export type UseEnsTextReturnType = + UseQueryReturnType + +/** https://wagmi.sh/react/api/hooks/useEnsText */ +export function useEnsText< + config extends Config = ResolvedRegister['config'], + selectData = GetEnsTextData, +>( + parameters: UseEnsTextParameters = {}, +): UseEnsTextReturnType { + const { key, name, query = {} } = parameters + + const config = useConfig(parameters) + const chainId = useChainId({ config }) + + const options = getEnsTextQueryOptions(config, { + ...parameters, + chainId: parameters.chainId ?? chainId, + }) + const enabled = Boolean(key && name && (query.enabled ?? true)) + + return useQuery({ ...query, ...options, enabled }) +} diff --git a/wagmi-project/packages/react/src/hooks/useEstimateFeesPerGas.test-d.ts b/wagmi-project/packages/react/src/hooks/useEstimateFeesPerGas.test-d.ts new file mode 100644 index 000000000..679def0fd --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useEstimateFeesPerGas.test-d.ts @@ -0,0 +1,49 @@ +import { expectTypeOf, test } from 'vitest' +import { useEstimateFeesPerGas } from './useEstimateFeesPerGas.js' + +test('types', () => { + const result = useEstimateFeesPerGas() + expectTypeOf(result.data).toMatchTypeOf< + | { + gasPrice?: undefined + maxFeePerGas: bigint + maxPriorityFeePerGas: bigint + formatted: { + gasPrice?: undefined + maxFeePerGas: string + maxPriorityFeePerGas: string + } + } + | undefined + >() + + const result2 = useEstimateFeesPerGas({ type: 'legacy' }) + expectTypeOf(result2.data).toMatchTypeOf< + | { + gasPrice: bigint + maxFeePerGas?: undefined + maxPriorityFeePerGas?: undefined + formatted: { + gasPrice: string + maxFeePerGas?: undefined + maxPriorityFeePerGas?: undefined + } + } + | undefined + >() + + const result3 = useEstimateFeesPerGas({ type: 'eip1559' }) + expectTypeOf(result3.data).toMatchTypeOf< + | { + gasPrice?: undefined + maxFeePerGas: bigint + maxPriorityFeePerGas: bigint + formatted: { + gasPrice?: undefined + maxFeePerGas: string + maxPriorityFeePerGas: string + } + } + | undefined + >() +}) diff --git a/wagmi-project/packages/react/src/hooks/useEstimateFeesPerGas.test.ts b/wagmi-project/packages/react/src/hooks/useEstimateFeesPerGas.test.ts new file mode 100644 index 000000000..5d1859eda --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useEstimateFeesPerGas.test.ts @@ -0,0 +1,19 @@ +import { renderHook, waitFor } from '@wagmi/test/react' +import { expect, test } from 'vitest' + +import { useEstimateFeesPerGas } from './useEstimateFeesPerGas.js' + +test('default', async () => { + const { result } = renderHook(() => useEstimateFeesPerGas()) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(Object.keys(result.current.data!)).toMatchInlineSnapshot(` + [ + "formatted", + "gasPrice", + "maxFeePerGas", + "maxPriorityFeePerGas", + ] + `) +}) diff --git a/wagmi-project/packages/react/src/hooks/useEstimateFeesPerGas.ts b/wagmi-project/packages/react/src/hooks/useEstimateFeesPerGas.ts new file mode 100644 index 000000000..59dc2aa91 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useEstimateFeesPerGas.ts @@ -0,0 +1,62 @@ +'use client' + +import type { + Config, + EstimateFeesPerGasErrorType, + ResolvedRegister, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type EstimateFeesPerGasData, + type EstimateFeesPerGasOptions, + type EstimateFeesPerGasQueryFnData, + type EstimateFeesPerGasQueryKey, + estimateFeesPerGasQueryOptions, +} from '@wagmi/core/query' +import type { FeeValuesType } from 'viem' + +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseEstimateFeesPerGasParameters< + type extends FeeValuesType = FeeValuesType, + config extends Config = Config, + selectData = EstimateFeesPerGasData, +> = Compute< + EstimateFeesPerGasOptions & + ConfigParameter & + QueryParameter< + EstimateFeesPerGasQueryFnData, + EstimateFeesPerGasErrorType, + selectData, + EstimateFeesPerGasQueryKey + > +> + +export type UseEstimateFeesPerGasReturnType< + type extends FeeValuesType = FeeValuesType, + selectData = EstimateFeesPerGasData, +> = UseQueryReturnType + +/** https://wagmi.sh/react/api/hooks/useEstimateFeesPerGas */ +export function useEstimateFeesPerGas< + config extends Config = ResolvedRegister['config'], + type extends FeeValuesType = 'eip1559', + selectData = EstimateFeesPerGasData, +>( + parameters: UseEstimateFeesPerGasParameters = {}, +): UseEstimateFeesPerGasReturnType { + const { query = {} } = parameters + + const config = useConfig(parameters) + const chainId = useChainId({ config }) + + const options = estimateFeesPerGasQueryOptions(config, { + ...parameters, + chainId: parameters.chainId ?? chainId, + }) + + return useQuery({ ...query, ...options }) +} diff --git a/wagmi-project/packages/react/src/hooks/useEstimateGas.test-d.ts b/wagmi-project/packages/react/src/hooks/useEstimateGas.test-d.ts new file mode 100644 index 000000000..d50618aad --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useEstimateGas.test-d.ts @@ -0,0 +1,14 @@ +import { expectTypeOf, test } from 'vitest' + +import { useEstimateGas } from './useEstimateGas.js' + +test('select data', () => { + const result = useEstimateGas({ + query: { + select(data) { + return data.toString() + }, + }, + }) + expectTypeOf(result.data).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/react/src/hooks/useEstimateGas.test.ts b/wagmi-project/packages/react/src/hooks/useEstimateGas.test.ts new file mode 100644 index 000000000..0c3ab0832 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useEstimateGas.test.ts @@ -0,0 +1,139 @@ +import { accounts } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { type Address, parseEther } from 'viem' +import { expect, test } from 'vitest' + +import { useEstimateGas } from './useEstimateGas.js' + +test('default', async () => { + const { result } = renderHook(() => + useEstimateGas({ + account: accounts[0], + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": 21000n, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "estimateGas", + { + "account": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "chainId": 1, + "to": "0xd2135CfB216b74109775236E36d4b433F1DF507B", + "value": 10000000000000000n, + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('behavior: address: undefined -> defined', async () => { + let account: Address | undefined = undefined + + const { result, rerender } = renderHook(() => useEstimateGas({ account })) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": undefined, + "dataUpdatedAt": 0, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": false, + "isFetchedAfterMount": false, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": true, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": false, + "isSuccess": false, + "queryKey": [ + "estimateGas", + { + "account": undefined, + "chainId": 1, + }, + ], + "refetch": [Function], + "status": "pending", + } + `) + + account = accounts[0] + rerender() + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": 53001n, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "estimateGas", + { + "account": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "chainId": 1, + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) diff --git a/wagmi-project/packages/react/src/hooks/useEstimateGas.ts b/wagmi-project/packages/react/src/hooks/useEstimateGas.ts new file mode 100644 index 000000000..87c0e19e4 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useEstimateGas.ts @@ -0,0 +1,70 @@ +'use client' + +import type { + Config, + EstimateGasErrorType, + ResolvedRegister, +} from '@wagmi/core' +import { + type EstimateGasData, + type EstimateGasOptions, + type EstimateGasQueryFnData, + type EstimateGasQueryKey, + estimateGasQueryOptions, +} from '@wagmi/core/query' + +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' +import { useConnectorClient } from './useConnectorClient.js' + +export type UseEstimateGasParameters< + config extends Config = Config, + chainId extends config['chains'][number]['id'] | undefined = undefined, + selectData = EstimateGasData, +> = EstimateGasOptions & + ConfigParameter & + QueryParameter< + EstimateGasQueryFnData, + EstimateGasErrorType, + selectData, + EstimateGasQueryKey + > + +export type UseEstimateGasReturnType = + UseQueryReturnType + +/** https://wagmi.sh/react/api/hooks/useEstimateGas */ +export function useEstimateGas< + config extends Config = ResolvedRegister['config'], + chainId extends config['chains'][number]['id'] | undefined = undefined, + selectData = EstimateGasData, +>( + parameters?: UseEstimateGasParameters, +): UseEstimateGasReturnType + +export function useEstimateGas( + parameters: UseEstimateGasParameters = {}, +): UseEstimateGasReturnType { + const { connector, query = {} } = parameters + + const config = useConfig(parameters) + const { data: connectorClient } = useConnectorClient({ + config, + connector, + query: { enabled: parameters.account === undefined }, + }) + const account = parameters.account ?? connectorClient?.account + const chainId = useChainId({ config }) + + const options = estimateGasQueryOptions(config, { + ...parameters, + account, + chainId: parameters.chainId ?? chainId, + connector, + }) + const enabled = Boolean((account || connector) && (query.enabled ?? true)) + + return useQuery({ ...query, ...options, enabled }) +} diff --git a/wagmi-project/packages/react/src/hooks/useEstimateMaxPriorityFeePerGas.test-d.ts b/wagmi-project/packages/react/src/hooks/useEstimateMaxPriorityFeePerGas.test-d.ts new file mode 100644 index 000000000..c4b1be1c8 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useEstimateMaxPriorityFeePerGas.test-d.ts @@ -0,0 +1,13 @@ +import { expectTypeOf, test } from 'vitest' +import { useEstimateMaxPriorityFeePerGas } from './useEstimateMaxPriorityFeePerGas.js' + +test('select data', () => { + const result = useEstimateMaxPriorityFeePerGas({ + query: { + select(data) { + return data.toString() + }, + }, + }) + expectTypeOf(result.data).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/react/src/hooks/useEstimateMaxPriorityFeePerGas.test.ts b/wagmi-project/packages/react/src/hooks/useEstimateMaxPriorityFeePerGas.test.ts new file mode 100644 index 000000000..21c09188e --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useEstimateMaxPriorityFeePerGas.test.ts @@ -0,0 +1,96 @@ +import { chain, testClient } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { expect, test } from 'vitest' + +import { useEstimateMaxPriorityFeePerGas } from './useEstimateMaxPriorityFeePerGas.js' + +test('default', async () => { + await testClient.mainnet.restart() + + const { result } = renderHook(() => useEstimateMaxPriorityFeePerGas()) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + const { data, ...rest } = result.current + expect(data).toBeTypeOf('bigint') + expect(rest).toMatchInlineSnapshot(` + { + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "estimateMaxPriorityFeePerGas", + { + "chainId": 1, + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('parameters: chainId', async () => { + await testClient.mainnet2.restart() + await testClient.mainnet2.mine({ blocks: 1 }) + + const { result } = renderHook(() => + useEstimateMaxPriorityFeePerGas({ chainId: chain.mainnet2.id }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + const { data, ...rest } = result.current + expect(data).toBeTypeOf('bigint') + expect(rest).toMatchInlineSnapshot(` + { + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "estimateMaxPriorityFeePerGas", + { + "chainId": 456, + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) diff --git a/wagmi-project/packages/react/src/hooks/useEstimateMaxPriorityFeePerGas.ts b/wagmi-project/packages/react/src/hooks/useEstimateMaxPriorityFeePerGas.ts new file mode 100644 index 000000000..0f884dba7 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useEstimateMaxPriorityFeePerGas.ts @@ -0,0 +1,61 @@ +'use client' + +import type { + Config, + EstimateMaxPriorityFeePerGasErrorType, + ResolvedRegister, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type EstimateMaxPriorityFeePerGasData, + type EstimateMaxPriorityFeePerGasOptions, + type EstimateMaxPriorityFeePerGasQueryFnData, + type EstimateMaxPriorityFeePerGasQueryKey, + estimateMaxPriorityFeePerGasQueryOptions, +} from '@wagmi/core/query' + +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseEstimateMaxPriorityFeePerGasParameters< + config extends Config = Config, + selectData = EstimateMaxPriorityFeePerGasData, +> = Compute< + EstimateMaxPriorityFeePerGasOptions & + ConfigParameter & + QueryParameter< + EstimateMaxPriorityFeePerGasQueryFnData, + EstimateMaxPriorityFeePerGasErrorType, + selectData, + EstimateMaxPriorityFeePerGasQueryKey + > +> + +export type UseEstimateMaxPriorityFeePerGasReturnType< + selectData = EstimateMaxPriorityFeePerGasData, +> = UseQueryReturnType + +/** https://wagmi.sh/react/api/hooks/useEstimateMaxPriorityFeePerGas */ +export function useEstimateMaxPriorityFeePerGas< + config extends Config = ResolvedRegister['config'], + selectData = EstimateMaxPriorityFeePerGasData, +>( + parameters: UseEstimateMaxPriorityFeePerGasParameters< + config, + selectData + > = {}, +): UseEstimateMaxPriorityFeePerGasReturnType { + const { query = {} } = parameters + + const config = useConfig(parameters) + const chainId = useChainId({ config }) + + const options = estimateMaxPriorityFeePerGasQueryOptions(config, { + ...parameters, + chainId: parameters.chainId ?? chainId, + }) + + return useQuery({ ...query, ...options }) +} diff --git a/wagmi-project/packages/react/src/hooks/useFeeHistory.test-d.ts b/wagmi-project/packages/react/src/hooks/useFeeHistory.test-d.ts new file mode 100644 index 000000000..855fa893a --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useFeeHistory.test-d.ts @@ -0,0 +1,14 @@ +import { expectTypeOf, test } from 'vitest' + +import { useFeeHistory } from './useFeeHistory.js' + +test('select data', () => { + const result = useFeeHistory({ + query: { + select(data) { + return data.gasUsedRatio + }, + }, + }) + expectTypeOf(result.data).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/react/src/hooks/useFeeHistory.test.ts b/wagmi-project/packages/react/src/hooks/useFeeHistory.test.ts new file mode 100644 index 000000000..53b6a8c55 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useFeeHistory.test.ts @@ -0,0 +1,452 @@ +import { chain, wait } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { expect, test } from 'vitest' + +import { useFeeHistory } from './useFeeHistory.js' + +test('default', async () => { + const { result } = renderHook(() => + useFeeHistory({ + blockCount: 4, + rewardPercentiles: [25, 75], + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + const { data, ...rest } = result.current + expect(data).toMatchObject({ + baseFeePerGas: expect.arrayContaining([expect.any(BigInt)]), + gasUsedRatio: expect.arrayContaining([expect.any(Number)]), + oldestBlock: expect.any(BigInt), + reward: expect.any(Array), + }) + expect(rest).toMatchInlineSnapshot(` + { + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "feeHistory", + { + "blockCount": 4, + "chainId": 1, + "rewardPercentiles": [ + 25, + 75, + ], + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('parameters: chainId', async () => { + const { result } = renderHook(() => + useFeeHistory({ + blockCount: 4, + rewardPercentiles: [25, 75], + chainId: chain.mainnet2.id, + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + const { data, ...rest } = result.current + expect(data).toMatchObject({ + baseFeePerGas: expect.arrayContaining([expect.any(BigInt)]), + gasUsedRatio: expect.arrayContaining([expect.any(Number)]), + oldestBlock: expect.any(BigInt), + reward: expect.any(Array), + }) + expect(rest).toMatchInlineSnapshot(` + { + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "feeHistory", + { + "blockCount": 4, + "chainId": 456, + "rewardPercentiles": [ + 25, + 75, + ], + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('parameters: blockNumber', async () => { + const { result } = renderHook(() => + useFeeHistory({ + blockCount: 4, + rewardPercentiles: [25, 75], + blockNumber: 18677379n, + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + const { data, ...rest } = result.current + expect(data).toMatchObject({ + baseFeePerGas: expect.arrayContaining([expect.any(BigInt)]), + gasUsedRatio: expect.arrayContaining([expect.any(Number)]), + oldestBlock: expect.any(BigInt), + reward: expect.any(Array), + }) + expect(rest).toMatchInlineSnapshot(` + { + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "feeHistory", + { + "blockCount": 4, + "blockNumber": 18677379n, + "chainId": 1, + "rewardPercentiles": [ + 25, + 75, + ], + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('parameters: blockTag', async () => { + const { result } = renderHook(() => + useFeeHistory({ + blockCount: 4, + rewardPercentiles: [25, 75], + blockTag: 'safe', + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + const { data, ...rest } = result.current + expect(data).toMatchObject({ + baseFeePerGas: expect.arrayContaining([expect.any(BigInt)]), + gasUsedRatio: expect.arrayContaining([expect.any(Number)]), + oldestBlock: expect.any(BigInt), + reward: expect.any(Array), + }) + expect(rest).toMatchInlineSnapshot(` + { + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "feeHistory", + { + "blockCount": 4, + "blockTag": "safe", + "chainId": 1, + "rewardPercentiles": [ + 25, + 75, + ], + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('behavior: blockCount: undefined -> defined', async () => { + let blockCount: number | undefined = undefined + + const { result, rerender } = renderHook(() => + useFeeHistory({ + blockCount, + rewardPercentiles: [25, 75], + }), + ) + + { + const { data, ...rest } = result.current + expect(data).toBeTypeOf('undefined') + expect(rest).toMatchInlineSnapshot(` + { + "dataUpdatedAt": 0, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": false, + "isFetchedAfterMount": false, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": true, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": false, + "isSuccess": false, + "queryKey": [ + "feeHistory", + { + "blockCount": undefined, + "chainId": 1, + "rewardPercentiles": [ + 25, + 75, + ], + }, + ], + "refetch": [Function], + "status": "pending", + } + `) + } + + blockCount = 4 + rerender() + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + const { data, ...rest } = result.current + expect(data).toMatchObject({ + baseFeePerGas: expect.arrayContaining([expect.any(BigInt)]), + gasUsedRatio: expect.arrayContaining([expect.any(Number)]), + oldestBlock: expect.any(BigInt), + reward: expect.any(Array), + }) + expect(rest).toMatchInlineSnapshot(` + { + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "feeHistory", + { + "blockCount": 4, + "chainId": 1, + "rewardPercentiles": [ + 25, + 75, + ], + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('behavior: rewardPercentiles: undefined -> defined', async () => { + let rewardPercentiles: number[] | undefined = undefined + + const { result, rerender } = renderHook(() => + useFeeHistory({ + blockCount: 4, + rewardPercentiles, + }), + ) + + { + const { data, ...rest } = result.current + expect(data).toBeTypeOf('undefined') + expect(rest).toMatchInlineSnapshot(` + { + "dataUpdatedAt": 0, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": false, + "isFetchedAfterMount": false, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": true, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": false, + "isSuccess": false, + "queryKey": [ + "feeHistory", + { + "blockCount": 4, + "chainId": 1, + "rewardPercentiles": undefined, + }, + ], + "refetch": [Function], + "status": "pending", + } + `) + } + + rewardPercentiles = [25, 75] + rerender() + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + const { data, ...rest } = result.current + expect(data).toMatchObject({ + baseFeePerGas: expect.arrayContaining([expect.any(BigInt)]), + gasUsedRatio: expect.arrayContaining([expect.any(Number)]), + oldestBlock: expect.any(BigInt), + reward: expect.any(Array), + }) + expect(rest).toMatchInlineSnapshot(` + { + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "feeHistory", + { + "blockCount": 4, + "chainId": 1, + "rewardPercentiles": [ + 25, + 75, + ], + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('behavior: disabled when properties missing', async () => { + const { result } = renderHook(() => useFeeHistory()) + + await wait(100) + await waitFor(() => expect(result.current.isPending).toBeTruthy()) +}) diff --git a/wagmi-project/packages/react/src/hooks/useFeeHistory.ts b/wagmi-project/packages/react/src/hooks/useFeeHistory.ts new file mode 100644 index 000000000..0754757b3 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useFeeHistory.ts @@ -0,0 +1,64 @@ +'use client' + +import type { + Config, + GetFeeHistoryErrorType, + ResolvedRegister, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type GetFeeHistoryData, + type GetFeeHistoryOptions, + type GetFeeHistoryQueryFnData, + type GetFeeHistoryQueryKey, + getFeeHistoryQueryOptions, +} from '@wagmi/core/query' + +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseFeeHistoryParameters< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = GetFeeHistoryData, +> = Compute< + GetFeeHistoryOptions & + ConfigParameter & + QueryParameter< + GetFeeHistoryQueryFnData, + GetFeeHistoryErrorType, + selectData, + GetFeeHistoryQueryKey + > +> + +export type UseFeeHistoryReturnType = + UseQueryReturnType + +/** https://wagmi.sh/react/api/hooks/useFeeHistory */ +export function useFeeHistory< + config extends Config = ResolvedRegister['config'], + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = GetFeeHistoryData, +>( + parameters: UseFeeHistoryParameters = {}, +): UseFeeHistoryReturnType { + const { blockCount, rewardPercentiles, query = {} } = parameters + + const config = useConfig(parameters) + const chainId = useChainId({ config }) + + const options = getFeeHistoryQueryOptions(config, { + ...parameters, + chainId: parameters.chainId ?? chainId, + }) + const enabled = Boolean( + blockCount && rewardPercentiles && (query.enabled ?? true), + ) + + return useQuery({ ...query, ...options, enabled }) +} diff --git a/wagmi-project/packages/react/src/hooks/useGasPrice.test-d.ts b/wagmi-project/packages/react/src/hooks/useGasPrice.test-d.ts new file mode 100644 index 000000000..7108993a2 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useGasPrice.test-d.ts @@ -0,0 +1,14 @@ +import { expectTypeOf, test } from 'vitest' + +import { useGasPrice } from './useGasPrice.js' + +test('select data', () => { + const result = useGasPrice({ + query: { + select(data) { + return data?.toString() + }, + }, + }) + expectTypeOf(result.data).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/react/src/hooks/useGasPrice.test.ts b/wagmi-project/packages/react/src/hooks/useGasPrice.test.ts new file mode 100644 index 000000000..5dd97cc96 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useGasPrice.test.ts @@ -0,0 +1,103 @@ +import { chain, testClient } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { expect, test } from 'vitest' + +import { useGasPrice } from './useGasPrice.js' + +test('default', async () => { + await testClient.mainnet.restart() + + await testClient.mainnet.setNextBlockBaseFeePerGas({ + baseFeePerGas: 2_000_000_000n, + }) + await testClient.mainnet.mine({ blocks: 1 }) + + const { result } = renderHook(() => useGasPrice()) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": 2750000000n, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "gasPrice", + { + "chainId": 1, + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('parameters: chainId', async () => { + await testClient.mainnet2.restart() + + await testClient.mainnet2.setNextBlockBaseFeePerGas({ + baseFeePerGas: 1_000_000_000n, + }) + await testClient.mainnet2.mine({ blocks: 1 }) + + const { result } = renderHook(() => + useGasPrice({ chainId: chain.mainnet2.id }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": 1875000000n, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "gasPrice", + { + "chainId": 456, + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) diff --git a/wagmi-project/packages/react/src/hooks/useGasPrice.ts b/wagmi-project/packages/react/src/hooks/useGasPrice.ts new file mode 100644 index 000000000..dc823dcf6 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useGasPrice.ts @@ -0,0 +1,62 @@ +'use client' + +import type { + Config, + GetGasPriceErrorType, + ResolvedRegister, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type GetGasPriceData, + type GetGasPriceOptions, + type GetGasPriceQueryFnData, + type GetGasPriceQueryKey, + getGasPriceQueryOptions, +} from '@wagmi/core/query' + +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseGasPriceParameters< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = GetGasPriceData, +> = Compute< + GetGasPriceOptions & + ConfigParameter & + QueryParameter< + GetGasPriceQueryFnData, + GetGasPriceErrorType, + selectData, + GetGasPriceQueryKey + > +> + +export type UseGasPriceReturnType = + UseQueryReturnType + +/** https://wagmi.sh/react/api/hooks/useGasPrice */ +export function useGasPrice< + config extends Config = ResolvedRegister['config'], + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = GetGasPriceData, +>( + parameters: UseGasPriceParameters = {}, +): UseGasPriceReturnType { + const { query = {} } = parameters + + const config = useConfig(parameters) + const configChainId = useChainId({ config }) + const chainId = parameters.chainId ?? configChainId + + const options = getGasPriceQueryOptions(config, { + ...parameters, + chainId, + }) + + return useQuery({ ...query, ...options }) +} diff --git a/wagmi-project/packages/react/src/hooks/useInfiniteReadContracts.test-d.ts b/wagmi-project/packages/react/src/hooks/useInfiniteReadContracts.test-d.ts new file mode 100644 index 000000000..60b3a2cdd --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useInfiniteReadContracts.test-d.ts @@ -0,0 +1,44 @@ +import { abi } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' + +import { useInfiniteReadContracts } from './useInfiniteReadContracts.js' + +test('select data', () => { + const result = useInfiniteReadContracts({ + allowFailure: false, + cacheKey: 'foo', + contracts(pageParam) { + expectTypeOf(pageParam).toEqualTypeOf() + return [ + { + address: '0x', + abi: abi.erc20, + functionName: 'balanceOf', + args: ['0x'], + }, + { + address: '0x', + abi: abi.wagmiMintExample, + functionName: 'tokenURI', + args: [123n], + }, + ] + }, + query: { + initialPageParam: '0', + getNextPageParam(lastPage, allPages, lastPageParam, allPageParams) { + expectTypeOf(lastPage).toEqualTypeOf<[bigint, string]>() + expectTypeOf(allPages).toEqualTypeOf<[bigint, string][]>() + expectTypeOf(lastPageParam).toEqualTypeOf() + expectTypeOf(allPageParams).toEqualTypeOf() + return lastPageParam + 1 + }, + select(data) { + expectTypeOf(data.pageParams[0]!).toEqualTypeOf() + expectTypeOf(data.pages[0]!).toEqualTypeOf<[bigint, string]>() + return data.pages[0]?.[0]! + }, + }, + }) + expectTypeOf(result.data).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/react/src/hooks/useInfiniteReadContracts.test.ts b/wagmi-project/packages/react/src/hooks/useInfiniteReadContracts.test.ts new file mode 100644 index 000000000..0feb1e0e9 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useInfiniteReadContracts.test.ts @@ -0,0 +1,91 @@ +import { abi, address } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { expect, test } from 'vitest' + +import { useInfiniteReadContracts } from './useInfiniteReadContracts.js' + +test( + 'default', + async () => { + const limit = 3 + + const { result } = renderHook(() => + useInfiniteReadContracts({ + cacheKey: 'foo', + contracts(pageParam) { + return [...new Array(limit)].map( + (_, i) => + ({ + address: address.shields, + abi: abi.shields, + functionName: 'tokenURI', + args: [BigInt(pageParam + i + 1)], + }) as const, + ) + }, + query: { + initialPageParam: 0, + getNextPageParam(_lastPage, _allPages, lastPageParam) { + return lastPageParam + limit + }, + select(data) { + const results = [] + for (const page of data.pages) { + for (const response of page) { + if (response.status === 'success') { + const decoded = atob( + response.result.replace(/(^.*base64,)/, ''), + ) + const json = JSON.parse(decoded) as { name: string } + results.push(json.name) + } else results.push('Error fetching shield') + } + } + return results + }, + }, + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + expect(result.current.data).toMatchInlineSnapshot(` + [ + "Three Shields on Pink Perfect", + "Three Shields on Sky Perfect", + "Three Shields on Evergreen Perfect", + ] + `) + + await result.current.fetchNextPage() + + await waitFor(() => expect(result.current.hasNextPage).toBeTruthy()) + expect(result.current.data).toMatchInlineSnapshot(` + [ + "Three Shields on Pink Perfect", + "Three Shields on Sky Perfect", + "Three Shields on Evergreen Perfect", + "Three Shields on Hi-Vis Perfect", + "Three Shields on Gray Perfect", + "Everlasting: Tracery on Onyx and Pink Razor Bordure", + ] + `) + + await result.current.fetchNextPage() + + await waitFor(() => expect(result.current.hasNextPage).toBeTruthy()) + expect(result.current.data).toMatchInlineSnapshot(` + [ + "Three Shields on Pink Perfect", + "Three Shields on Sky Perfect", + "Three Shields on Evergreen Perfect", + "Three Shields on Hi-Vis Perfect", + "Three Shields on Gray Perfect", + "Everlasting: Tracery on Onyx and Pink Razor Bordure", + "The Book of Shields on Pink Perfect", + "Menacing: Necklace on Evergreen and Hi-Vis Chief Indented", + "Secured: Telescope and Stars on Ultraviolet and Sky Doppler", + ] + `) + }, + { timeout: 20_000 }, +) diff --git a/wagmi-project/packages/react/src/hooks/useInfiniteReadContracts.ts b/wagmi-project/packages/react/src/hooks/useInfiniteReadContracts.ts new file mode 100644 index 000000000..2622f434a --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useInfiniteReadContracts.ts @@ -0,0 +1,89 @@ +'use client' + +import type { + Config, + ReadContractsErrorType, + ResolvedRegister, +} from '@wagmi/core' +import { + type InfiniteReadContractsQueryFnData, + type InfiniteReadContractsQueryKey, + infiniteReadContractsQueryOptions, + structuralSharing, +} from '@wagmi/core/query' +import type { ContractFunctionParameters } from 'viem' + +import type { + InfiniteReadContractsData, + InfiniteReadContractsOptions, +} from '../exports/query.js' +import type { + ConfigParameter, + InfiniteQueryParameter, +} from '../types/properties.js' +import { + type UseInfiniteQueryParameters, + type UseInfiniteQueryReturnType, + useInfiniteQuery, +} from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseInfiniteContractReadsParameters< + contracts extends readonly unknown[] = readonly ContractFunctionParameters[], + allowFailure extends boolean = true, + config extends Config = Config, + pageParam = unknown, + selectData = InfiniteReadContractsData, +> = InfiniteReadContractsOptions & + ConfigParameter & + InfiniteQueryParameter< + InfiniteReadContractsQueryFnData, + ReadContractsErrorType, + selectData, + InfiniteReadContractsData, + InfiniteReadContractsQueryKey, + pageParam + > + +export type UseInfiniteContractReadsReturnType< + contracts extends readonly unknown[] = readonly ContractFunctionParameters[], + allowFailure extends boolean = true, + selectData = InfiniteReadContractsData, +> = UseInfiniteQueryReturnType + +/** https://wagmi.sh/react/api/hooks/useInfiniteReadContracts */ +export function useInfiniteReadContracts< + const contracts extends readonly unknown[], + allowFailure extends boolean = true, + config extends Config = ResolvedRegister['config'], + pageParam = unknown, + selectData = InfiniteReadContractsData, +>( + parameters: UseInfiniteContractReadsParameters< + contracts, + allowFailure, + config, + pageParam, + selectData + >, +): UseInfiniteContractReadsReturnType { + const { contracts = [], query } = parameters + + const config = useConfig(parameters) + const chainId = useChainId({ config }) + + const options = infiniteReadContractsQueryOptions(config, { + ...parameters, + chainId, + contracts: contracts as UseInfiniteContractReadsParameters['contracts'], + query: query as UseInfiniteQueryParameters, + }) + + return useInfiniteQuery({ + ...(query as any), + ...options, + initialPageParam: options.initialPageParam, + structuralSharing: query.structuralSharing ?? structuralSharing, + }) +} diff --git a/wagmi-project/packages/react/src/hooks/usePrepareTransactionRequest.test-d.ts b/wagmi-project/packages/react/src/hooks/usePrepareTransactionRequest.test-d.ts new file mode 100644 index 000000000..9c39595ab --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/usePrepareTransactionRequest.test-d.ts @@ -0,0 +1,27 @@ +import { config } from '@wagmi/test' +import type { PrepareTransactionRequestReturnType } from 'viem' +import { expectTypeOf, test } from 'vitest' + +import { usePrepareTransactionRequest } from './usePrepareTransactionRequest.js' + +test('select data', () => { + const result = usePrepareTransactionRequest({ + query: { + select(data) { + return data + }, + }, + }) + + expectTypeOf(result.data).toMatchTypeOf< + PrepareTransactionRequestReturnType | undefined + >() +}) + +test('parameters: config', () => { + const result = usePrepareTransactionRequest({ + config, + chainId: 456, + }) + if (result.data) expectTypeOf(result.data.chainId).toEqualTypeOf<456>() +}) diff --git a/wagmi-project/packages/react/src/hooks/usePrepareTransactionRequest.test.ts b/wagmi-project/packages/react/src/hooks/usePrepareTransactionRequest.test.ts new file mode 100644 index 000000000..7b90729db --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/usePrepareTransactionRequest.test.ts @@ -0,0 +1,81 @@ +import { connect, disconnect } from '@wagmi/core' +import { config } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { parseEther } from 'viem' +import { expect, test } from 'vitest' + +import { usePrepareTransactionRequest } from './usePrepareTransactionRequest.js' + +const connector = config.connectors[0]! + +test('default', async () => { + await connect(config, { connector }) + + const { result } = renderHook(() => + usePrepareTransactionRequest({ + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + value: parseEther('1'), + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + const { + data: { + gas: _gas, + maxFeePerGas: _mfpg, + maxPriorityFeePerGas: _mpfpg, + nonce: _nonce, + ...data + } = {}, + ...rest + } = result.current + + expect(data).toMatchInlineSnapshot(` + { + "account": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "chainId": 1, + "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "to": "0x70997970c51812dc3a010c7d01b50e0d17dc79c8", + "type": "eip1559", + "value": 1000000000000000000n, + } + `) + expect(rest).toMatchInlineSnapshot(` + { + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "prepareTransactionRequest", + { + "chainId": 1, + "to": "0x70997970c51812dc3a010c7d01b50e0d17dc79c8", + "value": 1000000000000000000n, + }, + ], + "refetch": [Function], + "status": "success", + } + `) + + await disconnect(config, { connector }) +}) diff --git a/wagmi-project/packages/react/src/hooks/usePrepareTransactionRequest.ts b/wagmi-project/packages/react/src/hooks/usePrepareTransactionRequest.ts new file mode 100644 index 000000000..509d85eb0 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/usePrepareTransactionRequest.ts @@ -0,0 +1,102 @@ +'use client' + +import type { + Config, + PrepareTransactionRequestErrorType, + ResolvedRegister, + SelectChains, +} from '@wagmi/core' +import { + type PrepareTransactionRequestData, + type PrepareTransactionRequestOptions, + type PrepareTransactionRequestQueryKey, + prepareTransactionRequestQueryOptions, +} from '@wagmi/core/query' +import type { PrepareTransactionRequestQueryFnData } from '@wagmi/core/query' +import type { PrepareTransactionRequestRequest as viem_PrepareTransactionRequestRequest } from 'viem' + +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UsePrepareTransactionRequestParameters< + config extends Config = Config, + chainId extends config['chains'][number]['id'] | undefined = undefined, + request extends viem_PrepareTransactionRequestRequest< + SelectChains[0], + SelectChains[0] + > = viem_PrepareTransactionRequestRequest< + SelectChains[0], + SelectChains[0] + >, + selectData = PrepareTransactionRequestData, +> = PrepareTransactionRequestOptions & + ConfigParameter & + QueryParameter< + PrepareTransactionRequestQueryFnData, + PrepareTransactionRequestErrorType, + selectData, + PrepareTransactionRequestQueryKey + > + +export type UsePrepareTransactionRequestReturnType< + config extends Config = Config, + chainId extends config['chains'][number]['id'] | undefined = undefined, + request extends viem_PrepareTransactionRequestRequest< + SelectChains[0], + SelectChains[0] + > = viem_PrepareTransactionRequestRequest< + SelectChains[0], + SelectChains[0] + >, + selectData = PrepareTransactionRequestData, +> = UseQueryReturnType + +/** https://wagmi.sh/react/api/hooks/usePrepareTransactionRequest */ +export function usePrepareTransactionRequest< + config extends Config = ResolvedRegister['config'], + chainId extends config['chains'][number]['id'] | undefined = undefined, + request extends viem_PrepareTransactionRequestRequest< + SelectChains[0], + SelectChains[0] + > = viem_PrepareTransactionRequestRequest< + SelectChains[0], + SelectChains[0] + >, + selectData = PrepareTransactionRequestData, +>( + parameters: UsePrepareTransactionRequestParameters< + config, + chainId, + request, + selectData + > = {} as any, +): UsePrepareTransactionRequestReturnType< + config, + chainId, + request, + selectData +> { + const { to, query = {} } = parameters + + const config = useConfig(parameters) + const chainId = useChainId({ config }) + + const options = prepareTransactionRequestQueryOptions(config, { + ...parameters, + chainId: parameters.chainId ?? chainId, + } as PrepareTransactionRequestOptions) + const enabled = Boolean(to && (query.enabled ?? true)) + + return useQuery({ + ...(query as any), + ...options, + enabled, + }) as UsePrepareTransactionRequestReturnType< + config, + chainId, + request, + selectData + > +} diff --git a/wagmi-project/packages/react/src/hooks/useProof.test-d.ts b/wagmi-project/packages/react/src/hooks/useProof.test-d.ts new file mode 100644 index 000000000..55f8b1533 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useProof.test-d.ts @@ -0,0 +1,14 @@ +import type { GetProofReturnType } from 'viem' +import { expectTypeOf, test } from 'vitest' +import { useProof } from './useProof.js' + +test('select data', () => { + const result = useProof({ + query: { + select(data) { + return data + }, + }, + }) + expectTypeOf(result.data).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/react/src/hooks/useProof.test.ts b/wagmi-project/packages/react/src/hooks/useProof.test.ts new file mode 100644 index 000000000..3c3cb5194 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useProof.test.ts @@ -0,0 +1,163 @@ +import { chain, wait } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { expect, test } from 'vitest' + +import type { Address } from 'viem' +import { useProof } from './useProof.js' + +test('default', async () => { + const { result } = renderHook(() => + useProof({ + address: '0x4200000000000000000000000000000000000016', + chainId: chain.optimism.id, + storageKeys: [ + '0x4a932049252365b3eedbc5190e18949f2ec11f39d3bef2d259764799a1b27d99', + ], + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect({ ...result.current, data: null }).toMatchInlineSnapshot(` + { + "data": null, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "getProof", + { + "address": "0x4200000000000000000000000000000000000016", + "chainId": 10, + "storageKeys": [ + "0x4a932049252365b3eedbc5190e18949f2ec11f39d3bef2d259764799a1b27d99", + ], + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('behavior: address: undefined -> defined', async () => { + let address: Address | undefined = undefined + + const { result, rerender } = renderHook(() => + useProof({ + address, + chainId: chain.optimism.id, + storageKeys: [ + '0x4a932049252365b3eedbc5190e18949f2ec11f39d3bef2d259764799a1b27d99', + ], + }), + ) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": undefined, + "dataUpdatedAt": 0, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": false, + "isFetchedAfterMount": false, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": true, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": false, + "isSuccess": false, + "queryKey": [ + "getProof", + { + "address": undefined, + "chainId": 10, + "storageKeys": [ + "0x4a932049252365b3eedbc5190e18949f2ec11f39d3bef2d259764799a1b27d99", + ], + }, + ], + "refetch": [Function], + "status": "pending", + } + `) + + address = '0x4200000000000000000000000000000000000016' + rerender() + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect({ ...result.current, data: null }).toMatchInlineSnapshot(` + { + "data": null, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "getProof", + { + "address": "0x4200000000000000000000000000000000000016", + "chainId": 10, + "storageKeys": [ + "0x4a932049252365b3eedbc5190e18949f2ec11f39d3bef2d259764799a1b27d99", + ], + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('behavior: disabled when properties missing', async () => { + const { result } = renderHook(() => useProof()) + + await wait(100) + await waitFor(() => expect(result.current.isPending).toBeTruthy()) +}) diff --git a/wagmi-project/packages/react/src/hooks/useProof.ts b/wagmi-project/packages/react/src/hooks/useProof.ts new file mode 100644 index 000000000..f473d509a --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useProof.ts @@ -0,0 +1,56 @@ +'use client' + +import type { Config, GetProofErrorType, ResolvedRegister } from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type GetProofData, + type GetProofOptions, + type GetProofQueryKey, + getProofQueryOptions, +} from '@wagmi/core/query' +import type { GetProofQueryFnData } from '@wagmi/core/query' + +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseProofParameters< + config extends Config = Config, + selectData = GetProofData, +> = Compute< + GetProofOptions & + ConfigParameter & + QueryParameter< + GetProofQueryFnData, + GetProofErrorType, + selectData, + GetProofQueryKey + > +> + +export type UseProofReturnType = UseQueryReturnType< + selectData, + GetProofErrorType +> + +/** https://wagmi.sh/react/api/hooks/useProof */ +export function useProof< + config extends Config = ResolvedRegister['config'], + selectData = GetProofData, +>( + parameters: UseProofParameters = {}, +): UseProofReturnType { + const { address, storageKeys, query = {} } = parameters + + const config = useConfig(parameters) + const chainId = useChainId({ config }) + + const options = getProofQueryOptions(config, { + ...parameters, + chainId: parameters.chainId ?? chainId, + }) + const enabled = Boolean(address && storageKeys && (query.enabled ?? true)) + + return useQuery({ ...query, ...options, enabled }) +} diff --git a/wagmi-project/packages/react/src/hooks/usePublicClient.test-d.ts b/wagmi-project/packages/react/src/hooks/usePublicClient.test-d.ts new file mode 100644 index 000000000..5d259e5c4 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/usePublicClient.test-d.ts @@ -0,0 +1,40 @@ +import { chain, config } from '@wagmi/test' +import type { Chain } from 'viem' +import { expectTypeOf, test } from 'vitest' + +import { usePublicClient } from './usePublicClient.js' + +test('default', () => { + const client = usePublicClient({ config }) + expectTypeOf(client.chain).toEqualTypeOf<(typeof config)['chains'][number]>() + expectTypeOf(client.transport.type).toEqualTypeOf<'http'>() +}) + +test('parameters: chainId', () => { + const client = usePublicClient({ + config, + chainId: chain.mainnet.id, + }) + expectTypeOf(client.chain).toEqualTypeOf() + expectTypeOf(client.chain).not.toEqualTypeOf() + expectTypeOf(client.transport.type).toEqualTypeOf<'http'>() +}) + +test('behavior: unconfigured chain', () => { + { + const client = usePublicClient({ chainId: 123456 }) + if (client) { + expectTypeOf(client.chain).toEqualTypeOf() + expectTypeOf(client.transport.type).toEqualTypeOf() + } else { + expectTypeOf(client).toEqualTypeOf() + } + } + + const client = usePublicClient({ + config, + // @ts-expect-error + chainId: 123456, + }) + expectTypeOf(client).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/react/src/hooks/usePublicClient.test.ts b/wagmi-project/packages/react/src/hooks/usePublicClient.test.ts new file mode 100644 index 000000000..93602746b --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/usePublicClient.test.ts @@ -0,0 +1,30 @@ +import { switchChain } from '@wagmi/core' +import { config } from '@wagmi/test' +import { renderHook } from '@wagmi/test/react' +import { Fragment, createElement } from 'react' +import { expect, test } from 'vitest' + +import { usePublicClient } from './usePublicClient.js' + +test('default', async () => { + const { result, rerender } = renderHook(() => usePublicClient()) + + expect(result.current?.chain.id).toEqual(1) + + await switchChain(config, { chainId: 456 }) + rerender() + + expect(result.current?.chain.id).toEqual(456) +}) + +test('parameters: config', () => { + const { result } = renderHook(() => usePublicClient({ config }), { + wrapper: ({ children }) => createElement(Fragment, { children }), + }) + expect(result.current).toBeDefined() +}) + +test('behavior: unconfigured chain', () => { + const { result } = renderHook(() => usePublicClient({ chainId: 123456 })) + expect(result.current).toBeUndefined() +}) diff --git a/wagmi-project/packages/react/src/hooks/usePublicClient.ts b/wagmi-project/packages/react/src/hooks/usePublicClient.ts new file mode 100644 index 000000000..5193f170b --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/usePublicClient.ts @@ -0,0 +1,51 @@ +'use client' + +import { + type Config, + type GetPublicClientParameters, + type GetPublicClientReturnType, + type ResolvedRegister, + getPublicClient, + watchPublicClient, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { useSyncExternalStoreWithSelector } from 'use-sync-external-store/shim/with-selector.js' + +import type { ConfigParameter } from '../types/properties.js' +import { useConfig } from './useConfig.js' + +export type UsePublicClientParameters< + config extends Config = Config, + chainId extends config['chains'][number]['id'] | number | undefined = + | config['chains'][number]['id'] + | undefined, +> = Compute< + GetPublicClientParameters & ConfigParameter +> + +export type UsePublicClientReturnType< + config extends Config = Config, + chainId extends config['chains'][number]['id'] | number | undefined = + | config['chains'][number]['id'] + | undefined, +> = GetPublicClientReturnType + +/** https://wagmi.sh/react/api/hooks/usePublicClient */ +export function usePublicClient< + config extends Config = ResolvedRegister['config'], + chainId extends config['chains'][number]['id'] | number | undefined = + | config['chains'][number]['id'] + | undefined, +>( + parameters: UsePublicClientParameters = {}, +): UsePublicClientReturnType { + const config = useConfig(parameters) + + return useSyncExternalStoreWithSelector( + (onChange) => watchPublicClient(config, { onChange }), + () => getPublicClient(config, parameters), + () => getPublicClient(config, parameters), + (x) => x, + (a, b) => a?.uid === b?.uid, + ) as any +} diff --git a/wagmi-project/packages/react/src/hooks/useReadContract.test-d.ts b/wagmi-project/packages/react/src/hooks/useReadContract.test-d.ts new file mode 100644 index 000000000..3b57d49a9 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useReadContract.test-d.ts @@ -0,0 +1,96 @@ +import { abi } from '@wagmi/test' +import type { Address } from 'viem' +import { assertType, expectTypeOf, test } from 'vitest' + +import { + type UseReadContractParameters, + type UseReadContractReturnType, + useReadContract, +} from './useReadContract.js' + +test('select data', () => { + const result = useReadContract({ + address: '0x', + abi: abi.erc20, + functionName: 'balanceOf', + args: ['0x'], + query: { + select(data) { + expectTypeOf(data).toEqualTypeOf() + return data?.toString() + }, + }, + }) + expectTypeOf(result.data).toEqualTypeOf() +}) + +test('UseReadContractParameters', () => { + type Result = UseReadContractParameters + expectTypeOf>().toEqualTypeOf<{ + functionName?: + | 'symbol' + | 'name' + | 'allowance' + | 'balanceOf' + | 'decimals' + | 'totalSupply' + | undefined + args?: readonly [Address] | undefined + }>() +}) + +test('UseReadContractReturnType', () => { + type Result = UseReadContractReturnType + expectTypeOf().toEqualTypeOf() +}) + +test('overloads', () => { + const result1 = useReadContract({ + address: '0x', + abi: abi.viewOverloads, + functionName: 'foo', + }) + assertType(result1.data) + + const result2 = useReadContract({ + address: '0x', + abi: abi.viewOverloads, + functionName: 'foo', + args: [], + }) + assertType(result2.data) + + const result3 = useReadContract({ + address: '0x', + abi: abi.viewOverloads, + functionName: 'foo', + args: ['0x'], + }) + // @ts-ignore – TODO: Fix https://github.com/wevm/viem/issues/1916 + assertType(result3.data) + + const result4 = useReadContract({ + address: '0x', + abi: abi.viewOverloads, + functionName: 'foo', + args: ['0x', '0x'], + }) + assertType< + | { + foo: `0x${string}` + bar: `0x${string}` + } + | undefined + // @ts-ignore – TODO: Fix https://github.com/wevm/viem/issues/1916 + >(result4.data) +}) + +test('deployless read (bytecode)', () => { + const result = useReadContract({ + code: '0x', + abi: abi.erc20, + functionName: 'balanceOf', + args: ['0x'], + }) + expectTypeOf(result.data).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/react/src/hooks/useReadContract.test.ts b/wagmi-project/packages/react/src/hooks/useReadContract.test.ts new file mode 100644 index 000000000..c94ca996c --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useReadContract.test.ts @@ -0,0 +1,194 @@ +import { QueryClientProvider } from '@tanstack/react-query' +import { abi, address, bytecode, chain, config, wait } from '@wagmi/test' +import { queryClient, renderHook, waitFor } from '@wagmi/test/react' +import { createElement } from 'react' +import { expect, test } from 'vitest' + +import { useReadContract } from './useReadContract.js' + +test('default', async () => { + const { result } = renderHook(() => + useReadContract({ + address: address.wagmiMintExample, + abi: abi.wagmiMintExample, + functionName: 'balanceOf', + args: ['0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC'], + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": 4n, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "readContract", + { + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "args": [ + "0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC", + ], + "chainId": 1, + "functionName": "balanceOf", + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('parameters: chainId', async () => { + const { result } = renderHook(() => + useReadContract({ + address: address.wagmiMintExample, + abi: abi.wagmiMintExample, + functionName: 'balanceOf', + args: ['0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC'], + chainId: chain.mainnet2.id, + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": 4n, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "readContract", + { + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "args": [ + "0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC", + ], + "chainId": 456, + "functionName": "balanceOf", + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('parameters: config', async () => { + const { result } = renderHook( + () => + useReadContract({ + address: address.wagmiMintExample, + abi: abi.wagmiMintExample, + functionName: 'balanceOf', + args: ['0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC'], + config, + }), + { + wrapper: ({ children }) => + createElement(QueryClientProvider, { client: queryClient }, children), + }, + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": 4n, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "readContract", + { + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "args": [ + "0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC", + ], + "chainId": 1, + "functionName": "balanceOf", + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('parameters: deployless read (bytecode)', async () => { + const { result } = renderHook(() => + useReadContract({ + abi: abi.wagmiMintExample, + functionName: 'name', + code: bytecode.wagmiMintExample, + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current.data).toMatchInlineSnapshot(`"wagmi"`) +}) + +test('behavior: disabled when properties missing', async () => { + const { result } = renderHook(() => useReadContract()) + + await wait(100) + await waitFor(() => expect(result.current.isPending).toBeTruthy()) +}) diff --git a/wagmi-project/packages/react/src/hooks/useReadContract.ts b/wagmi-project/packages/react/src/hooks/useReadContract.ts new file mode 100644 index 000000000..6eb6d6d64 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useReadContract.ts @@ -0,0 +1,99 @@ +'use client' + +import type { + Config, + ReadContractErrorType, + ResolvedRegister, +} from '@wagmi/core' +import type { UnionCompute } from '@wagmi/core/internal' +import { + type ReadContractData, + type ReadContractOptions, + type ReadContractQueryFnData, + type ReadContractQueryKey, + readContractQueryOptions, + structuralSharing, +} from '@wagmi/core/query' +import type { Abi, ContractFunctionArgs, ContractFunctionName, Hex } from 'viem' + +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseReadContractParameters< + abi extends Abi | readonly unknown[] = Abi, + functionName extends ContractFunctionName< + abi, + 'pure' | 'view' + > = ContractFunctionName, + args extends ContractFunctionArgs< + abi, + 'pure' | 'view', + functionName + > = ContractFunctionArgs, + config extends Config = Config, + selectData = ReadContractData, +> = UnionCompute< + ReadContractOptions & + ConfigParameter & + QueryParameter< + ReadContractQueryFnData, + ReadContractErrorType, + selectData, + ReadContractQueryKey + > +> + +export type UseReadContractReturnType< + abi extends Abi | readonly unknown[] = Abi, + functionName extends ContractFunctionName< + abi, + 'pure' | 'view' + > = ContractFunctionName, + args extends ContractFunctionArgs< + abi, + 'pure' | 'view', + functionName + > = ContractFunctionArgs, + selectData = ReadContractData, +> = UseQueryReturnType + +/** https://wagmi.sh/react/api/hooks/useReadContract */ +export function useReadContract< + const abi extends Abi | readonly unknown[], + functionName extends ContractFunctionName, + args extends ContractFunctionArgs, + config extends Config = ResolvedRegister['config'], + selectData = ReadContractData, +>( + parameters: UseReadContractParameters< + abi, + functionName, + args, + config, + selectData + > = {} as any, +): UseReadContractReturnType { + const { abi, address, functionName, query = {} } = parameters + // @ts-ignore + const code = parameters.code as Hex | undefined + + const config = useConfig(parameters) + const chainId = useChainId({ config }) + + const options = readContractQueryOptions( + config, + { ...(parameters as any), chainId: parameters.chainId ?? chainId }, + ) + const enabled = Boolean( + (address || code) && abi && functionName && (query.enabled ?? true), + ) + + return useQuery({ + ...query, + ...options, + enabled, + structuralSharing: query.structuralSharing ?? structuralSharing, + }) +} diff --git a/wagmi-project/packages/react/src/hooks/useReadContracts.test-d.ts b/wagmi-project/packages/react/src/hooks/useReadContracts.test-d.ts new file mode 100644 index 000000000..8aa786436 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useReadContracts.test-d.ts @@ -0,0 +1,93 @@ +import { abi } from '@wagmi/test' +import { assertType, expectTypeOf, test } from 'vitest' + +import { useReadContracts } from './useReadContracts.js' + +test('select data', () => { + const result = useReadContracts({ + allowFailure: false, + contracts: [ + { + address: '0x', + abi: abi.erc20, + functionName: 'balanceOf', + chainId: 1, + args: ['0x'], + }, + { + address: '0x', + abi: abi.wagmiMintExample, + functionName: 'tokenURI', + args: [123n], + }, + ], + query: { + select(data) { + expectTypeOf(data).toEqualTypeOf<[bigint, string]>() + return data[0] + }, + }, + }) + expectTypeOf(result.data).toEqualTypeOf() +}) + +test('overloads', async () => { + const result1 = useReadContracts({ + allowFailure: false, + contracts: [ + { + address: '0x', + abi: abi.viewOverloads, + functionName: 'foo', + }, + ], + }) + assertType<[number] | undefined>(result1.data) + + const result2 = useReadContracts({ + allowFailure: false, + contracts: [ + { + address: '0x', + abi: abi.viewOverloads, + functionName: 'foo', + args: [], + }, + ], + }) + assertType<[number] | undefined>(result2.data) + + const result3 = useReadContracts({ + allowFailure: false, + contracts: [ + { + address: '0x', + abi: abi.viewOverloads, + functionName: 'foo', + args: ['0x'], + }, + ], + }) + assertType<[string] | undefined>(result3.data) + + const result4 = useReadContracts({ + allowFailure: false, + contracts: [ + { + address: '0x', + abi: abi.viewOverloads, + functionName: 'foo', + args: ['0x', '0x'], + }, + ], + }) + assertType< + | [ + { + foo: `0x${string}` + bar: `0x${string}` + }, + ] + | undefined + >(result4.data) +}) diff --git a/wagmi-project/packages/react/src/hooks/useReadContracts.test.ts b/wagmi-project/packages/react/src/hooks/useReadContracts.test.ts new file mode 100644 index 000000000..e7636b254 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useReadContracts.test.ts @@ -0,0 +1,262 @@ +import { abi, address, chain } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { expect, test } from 'vitest' + +import { useReadContracts } from './useReadContracts.js' + +test('default', async () => { + const { result } = renderHook(() => + useReadContracts({ + contracts: [ + { + address: address.wagmiMintExample, + abi: abi.wagmiMintExample, + functionName: 'balanceOf', + args: ['0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC'], + }, + { + address: address.wagmiMintExample, + abi: abi.wagmiMintExample, + functionName: 'symbol', + }, + ], + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": [ + { + "result": 4n, + "status": "success", + }, + { + "result": "WAGMI", + "status": "success", + }, + ], + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "readContracts", + { + "chainId": 1, + "contracts": [ + { + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "args": [ + "0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC", + ], + "chainId": 1, + "functionName": "balanceOf", + }, + { + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "chainId": 1, + "functionName": "symbol", + }, + ], + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test.skip('multichain', async () => { + const { mainnet, mainnet2, optimism } = chain + const { result } = renderHook(() => + useReadContracts({ + contracts: [ + { + abi: abi.wagmigotchi, + address: address.wagmigotchi, + chainId: mainnet.id, + functionName: 'love', + args: ['0x27a69ffba1e939ddcfecc8c7e0f967b872bac65c'], + }, + { + abi: abi.wagmigotchi, + address: address.wagmigotchi, + chainId: mainnet.id, + functionName: 'love', + args: ['0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC'], + }, + { + abi: abi.wagmigotchi, + address: address.wagmigotchi, + chainId: mainnet.id, + functionName: 'love', + args: ['0xd2135CfB216b74109775236E36d4b433F1DF507B'], + }, + { + abi: abi.wagmigotchi, + address: address.wagmigotchi, + chainId: mainnet2.id, + functionName: 'getAlive', + }, + { + abi: abi.mloot, + address: address.mloot, + chainId: mainnet2.id, + functionName: 'tokenOfOwnerByIndex', + args: ['0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', 0n], + }, + { + abi: abi.erc20, + address: address.optimism.usdc, + chainId: optimism.id, + functionName: 'symbol', + }, + { + abi: abi.erc20, + address: address.optimism.usdc, + chainId: optimism.id, + functionName: 'balanceOf', + args: ['0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC'], + }, + ], + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": [ + { + "result": 2n, + "status": "success", + }, + { + "result": 1n, + "status": "success", + }, + { + "result": 0n, + "status": "success", + }, + { + "result": false, + "status": "success", + }, + { + "result": 370395n, + "status": "success", + }, + { + "result": "USDC", + "status": "success", + }, + { + "result": 10959340n, + "status": "success", + }, + ], + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "readContracts", + { + "chainId": 1, + "contracts": [ + { + "address": "0xecb504d39723b0be0e3a9aa33d646642d1051ee1", + "args": [ + "0x27a69ffba1e939ddcfecc8c7e0f967b872bac65c", + ], + "chainId": 1, + "functionName": "love", + }, + { + "address": "0xecb504d39723b0be0e3a9aa33d646642d1051ee1", + "args": [ + "0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC", + ], + "chainId": 1, + "functionName": "love", + }, + { + "address": "0xecb504d39723b0be0e3a9aa33d646642d1051ee1", + "args": [ + "0xd2135CfB216b74109775236E36d4b433F1DF507B", + ], + "chainId": 1, + "functionName": "love", + }, + { + "address": "0xecb504d39723b0be0e3a9aa33d646642d1051ee1", + "chainId": 456, + "functionName": "getAlive", + }, + { + "address": "0x1dfe7ca09e99d10835bf73044a23b73fc20623df", + "args": [ + "0xA0Cf798816D4b9b9866b5330EEa46a18382f251e", + 0n, + ], + "chainId": 456, + "functionName": "tokenOfOwnerByIndex", + }, + { + "address": "0x7f5c764cbc14f9669b88837ca1490cca17c31607", + "chainId": 10, + "functionName": "symbol", + }, + { + "address": "0x7f5c764cbc14f9669b88837ca1490cca17c31607", + "args": [ + "0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC", + ], + "chainId": 10, + "functionName": "balanceOf", + }, + ], + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) diff --git a/wagmi-project/packages/react/src/hooks/useReadContracts.ts b/wagmi-project/packages/react/src/hooks/useReadContracts.ts new file mode 100644 index 000000000..7be786c4a --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useReadContracts.ts @@ -0,0 +1,91 @@ +'use client' + +import type { + Config, + ReadContractsErrorType, + ResolvedRegister, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type ReadContractsData, + type ReadContractsOptions, + type ReadContractsQueryFnData, + type ReadContractsQueryKey, + readContractsQueryOptions, + structuralSharing, +} from '@wagmi/core/query' +import { useMemo } from 'react' +import type { ContractFunctionParameters } from 'viem' + +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseReadContractsParameters< + contracts extends readonly unknown[] = readonly ContractFunctionParameters[], + allowFailure extends boolean = true, + config extends Config = Config, + selectData = ReadContractsData, +> = Compute< + ReadContractsOptions & + ConfigParameter & + QueryParameter< + ReadContractsQueryFnData, + ReadContractsErrorType, + selectData, + ReadContractsQueryKey + > +> + +export type UseReadContractsReturnType< + contracts extends readonly unknown[] = readonly ContractFunctionParameters[], + allowFailure extends boolean = true, + selectData = ReadContractsData, +> = UseQueryReturnType + +/** https://wagmi.sh/react/api/hooks/useReadContracts */ +export function useReadContracts< + const contracts extends readonly unknown[], + allowFailure extends boolean = true, + config extends Config = ResolvedRegister['config'], + selectData = ReadContractsData, +>( + parameters: UseReadContractsParameters< + contracts, + allowFailure, + config, + selectData + > = {}, +): UseReadContractsReturnType { + const { contracts = [], query = {} } = parameters + + const config = useConfig(parameters) + const chainId = useChainId({ config }) + + const options = readContractsQueryOptions( + config, + { ...parameters, chainId }, + ) + + const enabled = useMemo(() => { + let isContractsValid = false + for (const contract of contracts) { + const { abi, address, functionName } = + contract as ContractFunctionParameters + if (!abi || !address || !functionName) { + isContractsValid = false + break + } + isContractsValid = true + } + return Boolean(isContractsValid && (query.enabled ?? true)) + }, [contracts, query.enabled]) + + return useQuery({ + ...options, + ...query, + enabled, + structuralSharing: query.structuralSharing ?? structuralSharing, + }) +} diff --git a/wagmi-project/packages/react/src/hooks/useReconnect.test-d.ts b/wagmi-project/packages/react/src/hooks/useReconnect.test-d.ts new file mode 100644 index 000000000..424159e46 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useReconnect.test-d.ts @@ -0,0 +1,154 @@ +import type { + Connector, + CreateConnectorFn, + ReconnectErrorType, +} from '@wagmi/core' +import { config } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' + +import type { Address } from 'viem' +import { useReconnect } from './useReconnect.js' + +const connectors = [config.connectors[0]!] +const contextValue = { foo: 'bar' } as const + +test('context', () => { + const { context, data, error, reconnect, variables } = useReconnect({ + mutation: { + onMutate(variables) { + expectTypeOf(variables).toEqualTypeOf< + | { + connectors?: + | readonly (CreateConnectorFn | Connector)[] + | undefined + } + | undefined + >() + return contextValue + }, + onError(error, variables, context) { + expectTypeOf(variables).toEqualTypeOf< + | { + connectors?: + | readonly (CreateConnectorFn | Connector)[] + | undefined + } + | undefined + >() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSuccess(data, variables, context) { + expectTypeOf(variables).toEqualTypeOf< + | { + connectors?: + | readonly (CreateConnectorFn | Connector)[] + | undefined + } + | undefined + >() + expectTypeOf(data).toEqualTypeOf< + { + accounts: readonly [Address, ...Address[]] + chainId: number + connector: Connector + }[] + >() + expectTypeOf(context).toEqualTypeOf() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf< + | { + accounts: readonly [Address, ...Address[]] + chainId: number + connector: Connector + }[] + | undefined + >() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toEqualTypeOf< + | { + connectors?: + | readonly (CreateConnectorFn | Connector)[] + | undefined + } + | undefined + >() + expectTypeOf(context).toEqualTypeOf() + }, + }, + }) + + expectTypeOf(data).toEqualTypeOf< + | { + accounts: readonly [Address, ...Address[]] + chainId: number + connector: Connector + }[] + | undefined + >() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toEqualTypeOf< + | { + connectors?: readonly (CreateConnectorFn | Connector)[] | undefined + } + | undefined + >() + expectTypeOf(context).toEqualTypeOf() + + reconnect( + { connectors }, + { + onError(error, variables, context) { + expectTypeOf(variables).toEqualTypeOf< + | { + connectors?: + | readonly (CreateConnectorFn | Connector)[] + | undefined + } + | undefined + >() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSuccess(data, variables, context) { + expectTypeOf(variables).toEqualTypeOf< + | { + connectors?: + | readonly (CreateConnectorFn | Connector)[] + | undefined + } + | undefined + >() + expectTypeOf(data).toEqualTypeOf< + { + accounts: readonly [Address, ...Address[]] + chainId: number + connector: Connector + }[] + >() + expectTypeOf(context).toEqualTypeOf() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf< + | { + accounts: readonly [Address, ...Address[]] + chainId: number + connector: Connector + }[] + | undefined + >() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toEqualTypeOf< + | { + connectors?: + | readonly (CreateConnectorFn | Connector)[] + | undefined + } + | undefined + >() + expectTypeOf(context).toEqualTypeOf() + }, + }, + ) +}) diff --git a/wagmi-project/packages/react/src/hooks/useReconnect.test.ts b/wagmi-project/packages/react/src/hooks/useReconnect.test.ts new file mode 100644 index 000000000..be783b244 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useReconnect.test.ts @@ -0,0 +1,83 @@ +import { mock } from '@wagmi/connectors' +import { connect, disconnect } from '@wagmi/core' +import { accounts, config } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { afterEach, expect, test } from 'vitest' + +import { useReconnect } from './useReconnect.js' + +const connector = config._internal.connectors.setup( + mock({ + accounts, + features: { reconnect: true }, + }), +) + +afterEach(async () => { + if (config.state.current) await disconnect(config) +}) + +test('default', async () => { + const { result } = renderHook(() => useReconnect()) + + expect(result.current.connectors).toBeDefined() + + result.current.reconnect() + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current.data).toStrictEqual([]) +}) + +test('parameters: connectors (Connector)', async () => { + await connect(config, { connector }) + + const { result } = renderHook(() => useReconnect()) + + expect(result.current.connectors).toBeDefined() + + result.current.reconnect({ connectors: [connector] }) + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current.data).toMatchObject( + expect.arrayContaining([ + expect.objectContaining({ + accounts: expect.any(Array), + chainId: expect.any(Number), + }), + ]), + ) +}) + +test('parameters: connectors (CreateConnectorFn)', async () => { + const connector = mock({ + accounts, + features: { reconnect: true }, + }) + await connect(config, { connector }) + + const { result } = renderHook(() => useReconnect()) + + expect(result.current.connectors).toBeDefined() + + result.current.reconnect({ connectors: [connector] }) + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current.data).toMatchObject( + expect.arrayContaining([ + expect.objectContaining({ + accounts: expect.any(Array), + chainId: expect.any(Number), + }), + ]), + ) +}) + +test("behavior: doesn't reconnect if already reconnecting", async () => { + const previousStatus = config.state.status + config.setState((x) => ({ ...x, status: 'reconnecting' })) + const { result } = renderHook(() => useReconnect()) + await expect( + result.current.reconnectAsync({ connectors: [connector] }), + ).resolves.toStrictEqual([]) + config.setState((x) => ({ ...x, status: previousStatus })) +}) diff --git a/wagmi-project/packages/react/src/hooks/useReconnect.ts b/wagmi-project/packages/react/src/hooks/useReconnect.ts new file mode 100644 index 000000000..23e6d365e --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useReconnect.ts @@ -0,0 +1,67 @@ +'use client' + +import { useMutation } from '@tanstack/react-query' +import type { Connector, ReconnectErrorType } from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type ReconnectData, + type ReconnectMutate, + type ReconnectMutateAsync, + type ReconnectVariables, + reconnectMutationOptions, +} from '@wagmi/core/query' + +import type { ConfigParameter } from '../types/properties.js' +import type { + UseMutationParameters, + UseMutationReturnType, +} from '../utils/query.js' +import { useConfig } from './useConfig.js' + +export type UseReconnectParameters = Compute< + ConfigParameter & { + mutation?: + | UseMutationParameters< + ReconnectData, + ReconnectErrorType, + ReconnectVariables, + context + > + | undefined + } +> + +export type UseReconnectReturnType = Compute< + UseMutationReturnType< + ReconnectData, + ReconnectErrorType, + ReconnectVariables, + context + > & { + connectors: readonly Connector[] + reconnect: ReconnectMutate + reconnectAsync: ReconnectMutateAsync + } +> + +/** https://wagmi.sh/react/api/hooks/useReconnect */ +export function useReconnect( + parameters: UseReconnectParameters = {}, +): UseReconnectReturnType { + const { mutation } = parameters + + const config = useConfig(parameters) + + const mutationOptions = reconnectMutationOptions(config) + const { mutate, mutateAsync, ...result } = useMutation({ + ...mutation, + ...mutationOptions, + }) + + return { + ...result, + connectors: config.connectors, + reconnect: mutate, + reconnectAsync: mutateAsync, + } +} diff --git a/wagmi-project/packages/react/src/hooks/useSendCalls.test.ts b/wagmi-project/packages/react/src/hooks/useSendCalls.test.ts new file mode 100644 index 000000000..a088dcf22 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useSendCalls.test.ts @@ -0,0 +1,44 @@ +import { connect, disconnect } from '@wagmi/core' +import { accounts, config } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { parseEther } from 'viem' +import { expect, test } from 'vitest' + +import { useSendCalls } from './useSendCalls.js' + +const connector = config.connectors[0]! + +test('default', async () => { + await connect(config, { connector }) + + const { result } = renderHook(() => useSendCalls()) + + result.current.sendCalls({ + calls: [ + { + data: '0xdeadbeef', + to: accounts[1], + value: parseEther('1'), + }, + { + to: accounts[2], + value: parseEther('2'), + }, + { + to: accounts[3], + value: parseEther('3'), + }, + ], + }) + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current.data).toMatchInlineSnapshot( + ` + { + "id": "0x5dedb5a4ff8968db37459b52b83cbdc92b01c9c709c9cff26e345ef5cf27f92e", + } + `, + ) + + await disconnect(config, { connector }) +}) diff --git a/wagmi-project/packages/react/src/hooks/useSendCalls.ts b/wagmi-project/packages/react/src/hooks/useSendCalls.ts new file mode 100644 index 000000000..49366cb21 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useSendCalls.ts @@ -0,0 +1,75 @@ +'use client' + +import { useMutation } from '@tanstack/react-query' +import type { Config, ResolvedRegister, SendCallsErrorType } from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type SendCallsData, + type SendCallsMutate, + type SendCallsMutateAsync, + type SendCallsVariables, + sendCallsMutationOptions, +} from '@wagmi/core/query' + +import type { ConfigParameter } from '../types/properties.js' +import type { + UseMutationParameters, + UseMutationReturnType, +} from '../utils/query.js' +import { useConfig } from './useConfig.js' + +export type UseSendCallsParameters< + config extends Config = Config, + context = unknown, +> = Compute< + ConfigParameter & { + mutation?: + | UseMutationParameters< + SendCallsData, + SendCallsErrorType, + SendCallsVariables, + context + > + | undefined + } +> + +export type UseSendCallsReturnType< + config extends Config = Config, + context = unknown, +> = Compute< + UseMutationReturnType< + SendCallsData, + SendCallsErrorType, + SendCallsVariables, + context + > & { + sendCalls: SendCallsMutate + sendCallsAsync: SendCallsMutateAsync + } +> + +/** https://wagmi.sh/react/api/hooks/useSendCalls */ +export function useSendCalls< + config extends Config = ResolvedRegister['config'], + context = unknown, +>( + parameters: UseSendCallsParameters = {}, +): UseSendCallsReturnType { + const { mutation } = parameters + + const config = useConfig(parameters) + + const mutationOptions = sendCallsMutationOptions(config) + const { mutate, mutateAsync, ...result } = useMutation({ + ...mutation, + ...mutationOptions, + }) + + type Return = UseSendCallsReturnType + return { + ...result, + sendCalls: mutate as Return['sendCalls'], + sendCallsAsync: mutateAsync as Return['sendCallsAsync'], + } +} diff --git a/wagmi-project/packages/react/src/hooks/useSendTransaction.test-d.ts b/wagmi-project/packages/react/src/hooks/useSendTransaction.test-d.ts new file mode 100644 index 000000000..170c1e61e --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useSendTransaction.test-d.ts @@ -0,0 +1,78 @@ +import type { SendTransactionErrorType } from '@wagmi/core' +import type { Hash } from 'viem' +import { expectTypeOf, test } from 'vitest' + +import { useSendTransaction } from './useSendTransaction.js' + +const contextValue = { foo: 'bar' } as const + +test('context', () => { + const { context, data, error, sendTransaction, variables } = + useSendTransaction({ + mutation: { + onMutate(variables) { + expectTypeOf(variables).toMatchTypeOf< + { chainId?: number | undefined } | undefined + >() + return contextValue + }, + onError(error, variables, context) { + expectTypeOf(variables).toMatchTypeOf<{ + chainId?: number | undefined + }>() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSuccess(data, variables, context) { + expectTypeOf(variables).toMatchTypeOf<{ + chainId?: number | undefined + }>() + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toMatchTypeOf<{ + chainId?: number | undefined + }>() + expectTypeOf(context).toEqualTypeOf() + }, + }, + }) + + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toMatchTypeOf< + { chainId?: number | undefined } | undefined + >() + expectTypeOf(context).toEqualTypeOf() + + sendTransaction( + { to: '0x' }, + { + onError(error, variables, context) { + expectTypeOf(variables).toMatchTypeOf<{ + chainId?: number | undefined + }>() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSuccess(data, variables, context) { + expectTypeOf(variables).toMatchTypeOf<{ + chainId?: number | undefined + }>() + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toMatchTypeOf<{ + chainId?: number | undefined + }>() + expectTypeOf(context).toEqualTypeOf() + }, + }, + ) +}) diff --git a/wagmi-project/packages/react/src/hooks/useSendTransaction.test.ts b/wagmi-project/packages/react/src/hooks/useSendTransaction.test.ts new file mode 100644 index 000000000..a2e8977e2 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useSendTransaction.test.ts @@ -0,0 +1,25 @@ +import { connect, disconnect } from '@wagmi/core' +import { config, transactionHashRegex } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { parseEther } from 'viem' +import { expect, test } from 'vitest' + +import { useSendTransaction } from './useSendTransaction.js' + +const connector = config.connectors[0]! + +test('default', async () => { + await connect(config, { connector }) + + const { result } = renderHook(() => useSendTransaction()) + + result.current.sendTransaction({ + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), + }) + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current.data).toMatch(transactionHashRegex) + + await disconnect(config, { connector }) +}) diff --git a/wagmi-project/packages/react/src/hooks/useSendTransaction.ts b/wagmi-project/packages/react/src/hooks/useSendTransaction.ts new file mode 100644 index 000000000..8f57b1509 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useSendTransaction.ts @@ -0,0 +1,79 @@ +'use client' + +import { useMutation } from '@tanstack/react-query' +import type { + Config, + ResolvedRegister, + SendTransactionErrorType, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type SendTransactionData, + type SendTransactionMutate, + type SendTransactionMutateAsync, + type SendTransactionVariables, + sendTransactionMutationOptions, +} from '@wagmi/core/query' + +import type { ConfigParameter } from '../types/properties.js' +import type { + UseMutationParameters, + UseMutationReturnType, +} from '../utils/query.js' +import { useConfig } from './useConfig.js' + +export type UseSendTransactionParameters< + config extends Config = Config, + context = unknown, +> = Compute< + ConfigParameter & { + mutation?: + | UseMutationParameters< + SendTransactionData, + SendTransactionErrorType, + SendTransactionVariables, + context + > + | undefined + } +> + +export type UseSendTransactionReturnType< + config extends Config = Config, + context = unknown, +> = Compute< + UseMutationReturnType< + SendTransactionData, + SendTransactionErrorType, + SendTransactionVariables, + context + > & { + sendTransaction: SendTransactionMutate + sendTransactionAsync: SendTransactionMutateAsync + } +> + +/** https://wagmi.sh/react/api/hooks/useSendTransaction */ +export function useSendTransaction< + config extends Config = ResolvedRegister['config'], + context = unknown, +>( + parameters: UseSendTransactionParameters = {}, +): UseSendTransactionReturnType { + const { mutation } = parameters + + const config = useConfig(parameters) + + const mutationOptions = sendTransactionMutationOptions(config) + const { mutate, mutateAsync, ...result } = useMutation({ + ...mutation, + ...mutationOptions, + }) + + type Return = UseSendTransactionReturnType + return { + ...result, + sendTransaction: mutate as Return['sendTransaction'], + sendTransactionAsync: mutateAsync as Return['sendTransactionAsync'], + } +} diff --git a/wagmi-project/packages/react/src/hooks/useShowCallsStatus.ts b/wagmi-project/packages/react/src/hooks/useShowCallsStatus.ts new file mode 100644 index 000000000..82a4dd390 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useShowCallsStatus.ts @@ -0,0 +1,76 @@ +'use client' + +import { useMutation } from '@tanstack/react-query' +import type { + Config, + ResolvedRegister, + ShowCallsStatusErrorType, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type ShowCallsStatusData, + type ShowCallsStatusMutate, + type ShowCallsStatusMutateAsync, + type ShowCallsStatusVariables, + showCallsStatusMutationOptions, +} from '@wagmi/core/query' + +import type { ConfigParameter } from '../types/properties.js' +import type { + UseMutationParameters, + UseMutationReturnType, +} from '../utils/query.js' +import { useConfig } from './useConfig.js' + +export type UseShowCallsStatusParameters< + config extends Config = Config, + context = unknown, +> = Compute< + ConfigParameter & { + mutation?: + | UseMutationParameters< + ShowCallsStatusData, + ShowCallsStatusErrorType, + ShowCallsStatusVariables, + context + > + | undefined + } +> + +export type UseShowCallsStatusReturnType = Compute< + UseMutationReturnType< + ShowCallsStatusData, + ShowCallsStatusErrorType, + ShowCallsStatusVariables, + context + > & { + showCallsStatus: ShowCallsStatusMutate + showCallsStatusAsync: ShowCallsStatusMutateAsync + } +> + +/** https://wagmi.sh/react/api/hooks/useShowCallsStatus */ +export function useShowCallsStatus< + config extends Config = ResolvedRegister['config'], + context = unknown, +>( + parameters: UseShowCallsStatusParameters = {}, +): UseShowCallsStatusReturnType { + const { mutation } = parameters + + const config = useConfig(parameters) + + const mutationOptions = showCallsStatusMutationOptions(config) + const { mutate, mutateAsync, ...result } = useMutation({ + ...mutation, + ...mutationOptions, + }) + + type Return = UseShowCallsStatusReturnType + return { + ...result, + showCallsStatus: mutate as Return['showCallsStatus'], + showCallsStatusAsync: mutateAsync as Return['showCallsStatusAsync'], + } +} diff --git a/wagmi-project/packages/react/src/hooks/useSignMessage.test-d.ts b/wagmi-project/packages/react/src/hooks/useSignMessage.test-d.ts new file mode 100644 index 000000000..706c4a51f --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useSignMessage.test-d.ts @@ -0,0 +1,62 @@ +import type { SignMessageErrorType } from '@wagmi/core' +import type { SignMessageVariables } from '@wagmi/core/query' +import { expectTypeOf, test } from 'vitest' + +import { useSignMessage } from './useSignMessage.js' + +const message = 'hello world' +const contextValue = { foo: 'bar' } as const + +test('context', () => { + const { context, data, error, signMessage, variables } = useSignMessage({ + mutation: { + onMutate(variables) { + expectTypeOf(variables).toEqualTypeOf() + return contextValue + }, + onError(error, variables, context) { + expectTypeOf(variables).toEqualTypeOf() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSuccess(data, variables, context) { + expectTypeOf(variables).toEqualTypeOf() + expectTypeOf(data).toEqualTypeOf<`0x${string}`>() + expectTypeOf(context).toEqualTypeOf() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf<`0x${string}` | undefined>() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + }, + }) + + expectTypeOf(data).toEqualTypeOf<`0x${string}` | undefined>() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + + signMessage( + { message }, + { + onError(error, variables, context) { + expectTypeOf(variables).toEqualTypeOf() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSuccess(data, variables, context) { + expectTypeOf(variables).toEqualTypeOf() + expectTypeOf(data).toEqualTypeOf<`0x${string}`>() + expectTypeOf(context).toEqualTypeOf() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf<`0x${string}` | undefined>() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + }, + ) +}) diff --git a/wagmi-project/packages/react/src/hooks/useSignMessage.test.ts b/wagmi-project/packages/react/src/hooks/useSignMessage.test.ts new file mode 100644 index 000000000..aa6dd4a18 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useSignMessage.test.ts @@ -0,0 +1,43 @@ +import { connect, disconnect, getAccount } from '@wagmi/core' +import { config, privateKey } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { recoverMessageAddress } from 'viem' +import { expect, test } from 'vitest' + +import { privateKeyToAccount } from 'viem/accounts' +import { useSignMessage } from './useSignMessage.js' + +const connector = config.connectors[0]! + +test('default', async () => { + await connect(config, { connector }) + + const { result } = renderHook(() => useSignMessage()) + + result.current.signMessage({ message: 'foo bar baz' }) + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + await expect( + recoverMessageAddress({ + message: 'foo bar baz', + signature: result.current.data!, + }), + ).resolves.toEqual(getAccount(config).address) + + await disconnect(config, { connector }) +}) + +test('behavior: local account', async () => { + const { result } = renderHook(() => useSignMessage()) + + const account = privateKeyToAccount(privateKey) + result.current.signMessage({ account, message: 'foo bar baz' }) + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + await expect( + recoverMessageAddress({ + message: 'foo bar baz', + signature: result.current.data!, + }), + ).resolves.toEqual(account.address) +}) diff --git a/wagmi-project/packages/react/src/hooks/useSignMessage.ts b/wagmi-project/packages/react/src/hooks/useSignMessage.ts new file mode 100644 index 000000000..0bea4bb65 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useSignMessage.ts @@ -0,0 +1,65 @@ +'use client' + +import { useMutation } from '@tanstack/react-query' +import type { SignMessageErrorType } from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type SignMessageData, + type SignMessageMutate, + type SignMessageMutateAsync, + type SignMessageVariables, + signMessageMutationOptions, +} from '@wagmi/core/query' + +import type { ConfigParameter } from '../types/properties.js' +import type { + UseMutationParameters, + UseMutationReturnType, +} from '../utils/query.js' +import { useConfig } from './useConfig.js' + +export type UseSignMessageParameters = Compute< + ConfigParameter & { + mutation?: + | UseMutationParameters< + SignMessageData, + SignMessageErrorType, + SignMessageVariables, + context + > + | undefined + } +> + +export type UseSignMessageReturnType = Compute< + UseMutationReturnType< + SignMessageData, + SignMessageErrorType, + SignMessageVariables, + context + > & { + signMessage: SignMessageMutate + signMessageAsync: SignMessageMutateAsync + } +> + +/** https://wagmi.sh/react/api/hooks/useSignMessage */ +export function useSignMessage( + parameters: UseSignMessageParameters = {}, +): UseSignMessageReturnType { + const { mutation } = parameters + + const config = useConfig(parameters) + + const mutationOptions = signMessageMutationOptions(config) + const { mutate, mutateAsync, ...result } = useMutation({ + ...mutation, + ...mutationOptions, + }) + + return { + ...result, + signMessage: mutate, + signMessageAsync: mutateAsync, + } +} diff --git a/wagmi-project/packages/react/src/hooks/useSignTypedData.test-d.ts b/wagmi-project/packages/react/src/hooks/useSignTypedData.test-d.ts new file mode 100644 index 000000000..a51f77cfb --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useSignTypedData.test-d.ts @@ -0,0 +1,93 @@ +import type { + SignTypedDataErrorType, + SignTypedDataReturnType, +} from '@wagmi/core' +import type { SignTypedDataVariables } from '@wagmi/core/query' +import { typedData } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' + +import { useSignTypedData } from './useSignTypedData.js' + +const contextValue = { foo: 'bar' } as const + +test('context', () => { + const { context, data, error, signTypedData, variables } = useSignTypedData({ + mutation: { + onMutate(variables) { + expectTypeOf(variables).toMatchTypeOf() + return contextValue + }, + onError(error, variables, context) { + expectTypeOf(variables).toMatchTypeOf() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSuccess(data, variables, context) { + expectTypeOf(variables).toMatchTypeOf() + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toMatchTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + }, + }) + + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toMatchTypeOf() + expectTypeOf(context).toEqualTypeOf() + + signTypedData( + { + types: typedData.basic.types, + primaryType: 'Person', + message: { + name: 'Bob', + wallet: '0x', + }, + }, + { + onError(error, variables, context) { + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toMatchTypeOf<{ + types: typeof typedData.basic.types + primaryType: 'Person' + message: { + name: string + wallet: `0x${string}` + } + }>() + expectTypeOf(context).toEqualTypeOf() + }, + onSuccess(data, variables, context) { + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(variables).toMatchTypeOf<{ + types: typeof typedData.basic.types + primaryType: 'Person' + message: { + name: string + wallet: `0x${string}` + } + }>() + expectTypeOf(context).toEqualTypeOf() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toMatchTypeOf<{ + types: typeof typedData.basic.types + primaryType: 'Person' + message: { + name: string + wallet: `0x${string}` + } + }>() + expectTypeOf(context).toEqualTypeOf() + }, + }, + ) +}) diff --git a/wagmi-project/packages/react/src/hooks/useSignTypedData.test.ts b/wagmi-project/packages/react/src/hooks/useSignTypedData.test.ts new file mode 100644 index 000000000..3a38daa0d --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useSignTypedData.test.ts @@ -0,0 +1,56 @@ +import { connect, disconnect, getAccount } from '@wagmi/core' +import { config, privateKey, typedData } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { recoverTypedDataAddress } from 'viem' +import { expect, test } from 'vitest' + +import { privateKeyToAccount } from 'viem/accounts' +import { useSignTypedData } from './useSignTypedData.js' + +const connector = config.connectors[0]! + +test('default', async () => { + await connect(config, { connector }) + + const { result } = renderHook(() => useSignTypedData()) + + result.current.signTypedData({ + types: typedData.basic.types, + primaryType: 'Mail', + message: typedData.basic.message, + }) + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + await expect( + recoverTypedDataAddress({ + types: typedData.basic.types, + primaryType: 'Mail', + message: typedData.basic.message, + signature: result.current.data!, + }), + ).resolves.toEqual(getAccount(config).address) + + await disconnect(config, { connector }) +}) + +test('behavior: local account', async () => { + const { result } = renderHook(() => useSignTypedData()) + + const account = privateKeyToAccount(privateKey) + result.current.signTypedData({ + account, + types: typedData.basic.types, + primaryType: 'Mail', + message: typedData.basic.message, + }) + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + await expect( + recoverTypedDataAddress({ + types: typedData.basic.types, + primaryType: 'Mail', + message: typedData.basic.message, + signature: result.current.data!, + }), + ).resolves.toEqual(account.address) +}) diff --git a/wagmi-project/packages/react/src/hooks/useSignTypedData.ts b/wagmi-project/packages/react/src/hooks/useSignTypedData.ts new file mode 100644 index 000000000..080cd0440 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useSignTypedData.ts @@ -0,0 +1,66 @@ +'use client' + +import { useMutation } from '@tanstack/react-query' +import type { SignTypedDataErrorType } from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type SignTypedDataData, + type SignTypedDataMutate, + type SignTypedDataMutateAsync, + type SignTypedDataVariables, + signTypedDataMutationOptions, +} from '@wagmi/core/query' + +import type { ConfigParameter } from '../types/properties.js' +import type { + UseMutationParameters, + UseMutationReturnType, +} from '../utils/query.js' +import { useConfig } from './useConfig.js' + +export type UseSignTypedDataParameters = Compute< + ConfigParameter & { + mutation?: + | UseMutationParameters< + SignTypedDataData, + SignTypedDataErrorType, + SignTypedDataVariables, + context + > + | undefined + } +> + +export type UseSignTypedDataReturnType = Compute< + UseMutationReturnType< + SignTypedDataData, + SignTypedDataErrorType, + SignTypedDataVariables, + context + > & { + signTypedData: SignTypedDataMutate + signTypedDataAsync: SignTypedDataMutateAsync + } +> + +/** https://wagmi.sh/react/api/hooks/useSignTypedData */ +export function useSignTypedData( + parameters: UseSignTypedDataParameters = {}, +): UseSignTypedDataReturnType { + const { mutation } = parameters + + const config = useConfig(parameters) + + const mutationOptions = signTypedDataMutationOptions(config) + const { mutate, mutateAsync, ...result } = useMutation({ + ...mutation, + ...mutationOptions, + }) + + type Return = UseSignTypedDataReturnType + return { + ...result, + signTypedData: mutate as Return['signTypedData'], + signTypedDataAsync: mutateAsync as Return['signTypedDataAsync'], + } +} diff --git a/wagmi-project/packages/react/src/hooks/useSimulateContract.test-d.ts b/wagmi-project/packages/react/src/hooks/useSimulateContract.test-d.ts new file mode 100644 index 000000000..8159cdfcc --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useSimulateContract.test-d.ts @@ -0,0 +1,104 @@ +import { abi, type config } from '@wagmi/test' +import type { Address } from 'viem' +import { expectTypeOf, test } from 'vitest' + +import { + type UseSimulateContractParameters, + type UseSimulateContractReturnType, + useSimulateContract, +} from './useSimulateContract.js' + +test('default', () => { + const result = useSimulateContract({ + address: '0x', + abi: abi.erc20, + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + }) + + expectTypeOf(result.data).toMatchTypeOf< + | { + result: boolean + request: { + chainId?: undefined + abi: readonly [ + { + readonly name: 'transferFrom' + readonly type: 'function' + readonly stateMutability: 'nonpayable' + readonly inputs: readonly [ + { readonly type: 'address'; readonly name: 'sender' }, + { readonly type: 'address'; readonly name: 'recipient' }, + { readonly type: 'uint256'; readonly name: 'amount' }, + ] + readonly outputs: readonly [{ type: 'bool' }] + }, + ] + functionName: 'transferFrom' + args: readonly [Address, Address, bigint] + } + } + | undefined + >() +}) + +test('select data', () => { + const result = useSimulateContract({ + address: '0x', + abi: abi.erc20, + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + chainId: 1, + query: { + select(data) { + expectTypeOf(data.result).toEqualTypeOf() + return data.request.args + }, + }, + }) + expectTypeOf(result.data).toEqualTypeOf< + readonly [Address, Address, bigint] | undefined + >() +}) + +test('UseSimulateContractParameters', () => { + type Result = UseSimulateContractParameters + expectTypeOf().toMatchTypeOf<{ + functionName?: 'approve' | 'transfer' | 'transferFrom' | undefined + args?: readonly [Address, Address, bigint] | undefined + }>() +}) + +test('UseSimulateContractReturnType', () => { + type Result = UseSimulateContractReturnType< + typeof abi.erc20, + 'transferFrom', + ['0x', '0x', 123n], + typeof config, + 1 + > + expectTypeOf().toMatchTypeOf< + | { + result: boolean + request: { + chainId: number + abi: readonly [ + { + readonly name: 'transferFrom' + readonly type: 'function' + readonly stateMutability: 'nonpayable' + readonly inputs: readonly [ + { readonly type: 'address'; readonly name: 'sender' }, + { readonly type: 'address'; readonly name: 'recipient' }, + { readonly type: 'uint256'; readonly name: 'amount' }, + ] + readonly outputs: readonly [{ type: 'bool' }] + }, + ] + functionName: 'approve' | 'transfer' | 'transferFrom' + args: readonly [Address, Address, bigint] + } + } + | undefined + >() +}) diff --git a/wagmi-project/packages/react/src/hooks/useSimulateContract.test.ts b/wagmi-project/packages/react/src/hooks/useSimulateContract.test.ts new file mode 100644 index 000000000..3c785133c --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useSimulateContract.test.ts @@ -0,0 +1,95 @@ +import { connect, disconnect } from '@wagmi/core' +import { abi, address, config, wait } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { expect, test } from 'vitest' + +import { useSimulateContract } from './useSimulateContract.js' + +const connector = config.connectors[0]! + +test('default', async () => { + await connect(config, { connector }) + + const { result } = renderHook(() => + useSimulateContract({ + address: address.wagmiMintExample, + abi: abi.wagmiMintExample, + functionName: 'mint', + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": { + "chainId": 1, + "request": { + "abi": [ + { + "inputs": [], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + ], + "account": { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "type": "json-rpc", + }, + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "args": undefined, + "chainId": 1, + "dataSuffix": undefined, + "functionName": "mint", + }, + "result": undefined, + }, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "simulateContract", + { + "account": { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "type": "json-rpc", + }, + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "chainId": 1, + "functionName": "mint", + }, + ], + "refetch": [Function], + "status": "success", + } + `) + + await disconnect(config, { connector }) +}) + +test('behavior: disabled when properties missing', async () => { + const { result } = renderHook(() => useSimulateContract()) + + await wait(100) + await waitFor(() => expect(result.current.isPending).toBeTruthy()) +}) diff --git a/wagmi-project/packages/react/src/hooks/useSimulateContract.ts b/wagmi-project/packages/react/src/hooks/useSimulateContract.ts new file mode 100644 index 000000000..e17913fb4 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useSimulateContract.ts @@ -0,0 +1,117 @@ +'use client' + +import type { + Config, + ResolvedRegister, + SimulateContractErrorType, +} from '@wagmi/core' +import { + type SimulateContractData, + type SimulateContractOptions, + type SimulateContractQueryFnData, + type SimulateContractQueryKey, + simulateContractQueryOptions, +} from '@wagmi/core/query' +import type { Abi, ContractFunctionArgs, ContractFunctionName } from 'viem' + +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' +import { useConnectorClient } from './useConnectorClient.js' + +export type UseSimulateContractParameters< + abi extends Abi | readonly unknown[] = Abi, + functionName extends ContractFunctionName< + abi, + 'nonpayable' | 'payable' + > = ContractFunctionName, + args extends ContractFunctionArgs< + abi, + 'nonpayable' | 'payable', + functionName + > = ContractFunctionArgs, + config extends Config = Config, + chainId extends config['chains'][number]['id'] | undefined = undefined, + selectData = SimulateContractData, +> = SimulateContractOptions & + ConfigParameter & + QueryParameter< + SimulateContractQueryFnData, + SimulateContractErrorType, + selectData, + SimulateContractQueryKey + > + +export type UseSimulateContractReturnType< + abi extends Abi | readonly unknown[] = Abi, + functionName extends ContractFunctionName< + abi, + 'nonpayable' | 'payable' + > = ContractFunctionName, + args extends ContractFunctionArgs< + abi, + 'nonpayable' | 'payable', + functionName + > = ContractFunctionArgs, + config extends Config = Config, + chainId extends config['chains'][number]['id'] | undefined = undefined, + selectData = SimulateContractData, +> = UseQueryReturnType + +/** https://wagmi.sh/react/api/hooks/useSimulateContract */ +export function useSimulateContract< + const abi extends Abi | readonly unknown[], + functionName extends ContractFunctionName, + args extends ContractFunctionArgs< + abi, + 'nonpayable' | 'payable', + functionName + >, + config extends Config = ResolvedRegister['config'], + chainId extends config['chains'][number]['id'] | undefined = undefined, + selectData = SimulateContractData, +>( + parameters: UseSimulateContractParameters< + abi, + functionName, + args, + config, + chainId, + selectData + > = {} as any, +): UseSimulateContractReturnType< + abi, + functionName, + args, + config, + chainId, + selectData +> { + const { abi, address, connector, functionName, query = {} } = parameters + + const config = useConfig(parameters) + const { data: connectorClient } = useConnectorClient({ + config, + connector, + query: { enabled: parameters.account === undefined }, + }) + const chainId = useChainId({ config }) + + const options = simulateContractQueryOptions< + config, + abi, + functionName, + args, + chainId + >(config, { + ...parameters, + account: parameters.account ?? connectorClient?.account, + chainId: parameters.chainId ?? chainId, + }) + const enabled = Boolean( + abi && address && functionName && (query.enabled ?? true), + ) + + return useQuery({ ...query, ...options, enabled }) +} diff --git a/wagmi-project/packages/react/src/hooks/useStorageAt.test-d.ts b/wagmi-project/packages/react/src/hooks/useStorageAt.test-d.ts new file mode 100644 index 000000000..bbc37fa03 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useStorageAt.test-d.ts @@ -0,0 +1,15 @@ +import { expectTypeOf, test } from 'vitest' + +import type { Hex } from 'viem' +import { useStorageAt } from './useStorageAt.js' + +test('select data', () => { + const result = useStorageAt({ + query: { + select(data) { + return data + }, + }, + }) + expectTypeOf(result.data).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/react/src/hooks/useStorageAt.test.ts b/wagmi-project/packages/react/src/hooks/useStorageAt.test.ts new file mode 100644 index 000000000..9386480c9 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useStorageAt.test.ts @@ -0,0 +1,299 @@ +import { address, chain, wait } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { expect, test } from 'vitest' + +import type { Address } from 'viem' +import { useStorageAt } from './useStorageAt.js' + +test('default', async () => { + const { result } = renderHook(() => + useStorageAt({ + address: address.wagmiMintExample, + slot: '0x0', + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": "0x7761676d6900000000000000000000000000000000000000000000000000000a", + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "getStorageAt", + { + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "chainId": 1, + "slot": "0x0", + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('parameters: blockNumber', async () => { + const { result } = renderHook(() => + useStorageAt({ + address: address.wagmiMintExample, + blockNumber: 16280770n, + slot: '0x0', + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": "0x7761676d6900000000000000000000000000000000000000000000000000000a", + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "getStorageAt", + { + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "blockNumber": 16280770n, + "chainId": 1, + "slot": "0x0", + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('parameters: blockTag', async () => { + const { result } = renderHook(() => + useStorageAt({ + address: address.wagmiMintExample, + blockTag: 'safe', + slot: '0x0', + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": "0x7761676d6900000000000000000000000000000000000000000000000000000a", + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "getStorageAt", + { + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "blockTag": "safe", + "chainId": 1, + "slot": "0x0", + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('parameters: chainId', async () => { + const { result } = renderHook(() => + useStorageAt({ + address: address.wagmiMintExample, + chainId: chain.optimism.id, + slot: '0x0', + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": "0x0000000000000000000000000000000000000000000000000000000000000000", + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "getStorageAt", + { + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "chainId": 10, + "slot": "0x0", + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('behavior: address: undefined -> defined', async () => { + let contractAddress: Address | undefined = undefined + + const { result, rerender } = renderHook(() => + useStorageAt({ + address: contractAddress, + slot: '0x0', + }), + ) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": undefined, + "dataUpdatedAt": 0, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": false, + "isFetchedAfterMount": false, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": true, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": false, + "isSuccess": false, + "queryKey": [ + "getStorageAt", + { + "address": undefined, + "chainId": 1, + "slot": "0x0", + }, + ], + "refetch": [Function], + "status": "pending", + } + `) + + contractAddress = address.wagmiMintExample + rerender() + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + expect(result.current).toMatchInlineSnapshot(` + { + "data": "0x7761676d6900000000000000000000000000000000000000000000000000000a", + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "getStorageAt", + { + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "chainId": 1, + "slot": "0x0", + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('behavior: disabled when properties missing', async () => { + const { result } = renderHook(() => useStorageAt()) + + await wait(100) + await waitFor(() => expect(result.current.isPending).toBeTruthy()) +}) diff --git a/wagmi-project/packages/react/src/hooks/useStorageAt.ts b/wagmi-project/packages/react/src/hooks/useStorageAt.ts new file mode 100644 index 000000000..3a58376fd --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useStorageAt.ts @@ -0,0 +1,57 @@ +'use client' + +import type { + Config, + GetStorageAtErrorType, + ResolvedRegister, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type GetStorageAtData, + type GetStorageAtOptions, + type GetStorageAtQueryKey, + getStorageAtQueryOptions, +} from '@wagmi/core/query' +import type { GetStorageAtQueryFnData } from '@wagmi/core/query' +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseStorageAtParameters< + config extends Config = Config, + selectData = GetStorageAtData, +> = Compute< + GetStorageAtOptions & + ConfigParameter & + QueryParameter< + GetStorageAtQueryFnData, + GetStorageAtErrorType, + selectData, + GetStorageAtQueryKey + > +> + +export type UseStorageAtReturnType = + UseQueryReturnType + +/** https://wagmi.sh/react/api/hooks/useStorageAt */ +export function useStorageAt< + config extends Config = ResolvedRegister['config'], + selectData = GetStorageAtData, +>( + parameters: UseStorageAtParameters = {}, +): UseStorageAtReturnType { + const { address, slot, query = {} } = parameters + + const config = useConfig(parameters) + const chainId = useChainId({ config }) + + const options = getStorageAtQueryOptions(config, { + ...parameters, + chainId: parameters.chainId ?? chainId, + }) + const enabled = Boolean(address && slot && (query.enabled ?? true)) + + return useQuery({ ...query, ...options, enabled }) +} diff --git a/wagmi-project/packages/react/src/hooks/useSwitchAccount.test-d.ts b/wagmi-project/packages/react/src/hooks/useSwitchAccount.test-d.ts new file mode 100644 index 000000000..f7d97355a --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useSwitchAccount.test-d.ts @@ -0,0 +1,87 @@ +import type { Connector, SwitchAccountErrorType } from '@wagmi/core' +import { config } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' + +import type { Address } from 'viem' +import { useSwitchAccount } from './useSwitchAccount.js' + +const connector = config.connectors[0]! +const contextValue = { foo: 'bar' } as const + +test('context', () => { + const { context, data, error, switchAccount, variables } = useSwitchAccount({ + mutation: { + onMutate(variables) { + expectTypeOf(variables).toEqualTypeOf<{ connector: Connector }>() + return contextValue + }, + onError(error, variables, context) { + expectTypeOf(variables).toEqualTypeOf<{ connector: Connector }>() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSuccess(data, variables, context) { + expectTypeOf(variables).toEqualTypeOf<{ connector: Connector }>() + expectTypeOf(data).toEqualTypeOf<{ + accounts: readonly [Address, ...Address[]] + chainId: number + }>() + expectTypeOf(context).toEqualTypeOf() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf< + | { + accounts: readonly [Address, ...Address[]] + chainId: number + } + | undefined + >() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toEqualTypeOf<{ connector: Connector }>() + expectTypeOf(context).toEqualTypeOf() + }, + }, + }) + + expectTypeOf(data).toEqualTypeOf< + | { + accounts: readonly [Address, ...Address[]] + chainId: number + } + | undefined + >() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toEqualTypeOf<{ connector: Connector } | undefined>() + expectTypeOf(context).toEqualTypeOf() + + switchAccount( + { connector }, + { + onError(error, variables, context) { + expectTypeOf(variables).toEqualTypeOf<{ connector: Connector }>() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSuccess(data, variables, context) { + expectTypeOf(variables).toEqualTypeOf<{ connector: Connector }>() + expectTypeOf(data).toEqualTypeOf<{ + accounts: readonly [Address, ...Address[]] + chainId: number + }>() + expectTypeOf(context).toEqualTypeOf() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf< + | { + accounts: readonly [Address, ...Address[]] + chainId: number + } + | undefined + >() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toEqualTypeOf<{ connector: Connector }>() + expectTypeOf(context).toEqualTypeOf() + }, + }, + ) +}) diff --git a/wagmi-project/packages/react/src/hooks/useSwitchAccount.test.ts b/wagmi-project/packages/react/src/hooks/useSwitchAccount.test.ts new file mode 100644 index 000000000..5461d0821 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useSwitchAccount.test.ts @@ -0,0 +1,44 @@ +import { connect, disconnect } from '@wagmi/core' +import { config } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { expect, test } from 'vitest' + +import { useAccount } from './useAccount.js' +import { useSwitchAccount } from './useSwitchAccount.js' + +const connector1 = config.connectors[0]! +const connector2 = config.connectors[1]! + +test('default', async () => { + await connect(config, { connector: connector2 }) + await connect(config, { connector: connector1 }) + + const { result } = renderHook(() => ({ + useAccount: useAccount(), + useSwitchAccount: useSwitchAccount(), + })) + + const address1 = result.current.useAccount.address + expect(address1).toBeDefined() + + result.current.useSwitchAccount.switchAccount({ connector: connector2 }) + await waitFor(() => + expect(result.current.useSwitchAccount.isSuccess).toBeTruthy(), + ) + + const address2 = result.current.useAccount.address + expect(address2).toBeDefined() + expect(address1).not.toBe(address2) + + result.current.useSwitchAccount.switchAccount({ connector: connector1 }) + await waitFor(() => + expect(result.current.useSwitchAccount.isSuccess).toBeTruthy(), + ) + + const address3 = result.current.useAccount.address + expect(address3).toBeDefined() + expect(address1).toBe(address3) + + await disconnect(config, { connector: connector1 }) + await disconnect(config, { connector: connector2 }) +}) diff --git a/wagmi-project/packages/react/src/hooks/useSwitchAccount.ts b/wagmi-project/packages/react/src/hooks/useSwitchAccount.ts new file mode 100644 index 000000000..e9dc30554 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useSwitchAccount.ts @@ -0,0 +1,84 @@ +'use client' + +import { useMutation } from '@tanstack/react-query' +import type { + Config, + Connector, + ResolvedRegister, + SwitchAccountErrorType, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type SwitchAccountData, + type SwitchAccountMutate, + type SwitchAccountMutateAsync, + type SwitchAccountVariables, + switchAccountMutationOptions, +} from '@wagmi/core/query' + +import type { ConfigParameter } from '../types/properties.js' +import type { + UseMutationParameters, + UseMutationReturnType, +} from '../utils/query.js' +import { useConfig } from './useConfig.js' +import { useConnections } from './useConnections.js' + +export type UseSwitchAccountParameters< + config extends Config = Config, + context = unknown, +> = Compute< + ConfigParameter & { + mutation?: + | UseMutationParameters< + SwitchAccountData, + SwitchAccountErrorType, + SwitchAccountVariables, + context + > + | undefined + } +> + +export type UseSwitchAccountReturnType< + config extends Config = Config, + context = unknown, +> = Compute< + UseMutationReturnType< + SwitchAccountData, + SwitchAccountErrorType, + SwitchAccountVariables, + context + > & { + connectors: readonly Connector[] + switchAccount: SwitchAccountMutate + switchAccountAsync: SwitchAccountMutateAsync + } +> + +/** https://wagmi.sh/react/api/hooks/useSwitchAccount */ +export function useSwitchAccount< + config extends Config = ResolvedRegister['config'], + context = unknown, +>( + parameters: UseSwitchAccountParameters = {}, +): UseSwitchAccountReturnType { + const { mutation } = parameters + + const config = useConfig(parameters) + + const mutationOptions = switchAccountMutationOptions(config) + const { mutate, mutateAsync, ...result } = useMutation({ + ...mutation, + ...mutationOptions, + }) + + return { + ...result, + connectors: useConnections({ config }).map( + (connection) => connection.connector, + ), + switchAccount: mutate, + switchAccountAsync: mutateAsync, + } +} diff --git a/wagmi-project/packages/react/src/hooks/useSwitchChain.test-d.ts b/wagmi-project/packages/react/src/hooks/useSwitchChain.test-d.ts new file mode 100644 index 000000000..07098c772 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useSwitchChain.test-d.ts @@ -0,0 +1,118 @@ +import type { Connector, SwitchChainErrorType } from '@wagmi/core' +import type { Chain } from '@wagmi/core/chains' +import type { Compute, ExactPartial } from '@wagmi/core/internal' +import { chain } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' + +import type { AddEthereumChainParameter } from 'viem' +import { useSwitchChain } from './useSwitchChain.js' + +const chainId = chain.mainnet.id +const contextValue = { foo: 'bar' } as const + +test('context', () => { + const { chains, context, data, error, switchChain, variables } = + useSwitchChain({ + mutation: { + onMutate(variables) { + expectTypeOf(variables).toEqualTypeOf<{ + addEthereumChainParameter?: + | ExactPartial> + | undefined + chainId: number + connector?: Connector | undefined + }>() + return contextValue + }, + onError(error, variables, context) { + expectTypeOf(variables).toEqualTypeOf<{ + addEthereumChainParameter?: + | ExactPartial> + | undefined + chainId: number + connector?: Connector | undefined + }>() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSuccess(data, variables, context) { + expectTypeOf(variables).toEqualTypeOf<{ + addEthereumChainParameter?: + | ExactPartial> + | undefined + chainId: number + connector?: Connector | undefined + }>() + expectTypeOf(data).toEqualTypeOf>() + expectTypeOf(context).toEqualTypeOf() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf | undefined>() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toEqualTypeOf<{ + addEthereumChainParameter?: + | ExactPartial> + | undefined + chainId: number + connector?: Connector | undefined + }>() + expectTypeOf(context).toEqualTypeOf() + }, + }, + }) + + expectTypeOf(chains).toEqualTypeOf() + expectTypeOf(data).toEqualTypeOf | undefined>() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toEqualTypeOf< + | { + addEthereumChainParameter?: + | ExactPartial> + | undefined + chainId: number + connector?: Connector | undefined + } + | undefined + >() + expectTypeOf(context).toEqualTypeOf() + + switchChain( + { chainId }, + { + onError(error, variables, context) { + expectTypeOf(variables).toEqualTypeOf<{ + addEthereumChainParameter?: + | ExactPartial> + | undefined + chainId: number + connector?: Connector | undefined + }>() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSuccess(data, variables, context) { + expectTypeOf(variables).toEqualTypeOf<{ + addEthereumChainParameter?: + | ExactPartial> + | undefined + chainId: number + connector?: Connector | undefined + }>() + expectTypeOf(data).toEqualTypeOf>() + expectTypeOf(context).toEqualTypeOf() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf | undefined>() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toEqualTypeOf<{ + addEthereumChainParameter?: + | ExactPartial> + | undefined + chainId: number + connector?: Connector | undefined + }>() + expectTypeOf(context).toEqualTypeOf() + }, + }, + ) +}) diff --git a/wagmi-project/packages/react/src/hooks/useSwitchChain.test.ts b/wagmi-project/packages/react/src/hooks/useSwitchChain.test.ts new file mode 100644 index 000000000..1fe0ca46b --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useSwitchChain.test.ts @@ -0,0 +1,114 @@ +import { connect, disconnect } from '@wagmi/core' +import { chain, config } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { expect, test } from 'vitest' + +import { useAccount } from './useAccount.js' +import { useSwitchChain } from './useSwitchChain.js' + +const connector = config.connectors[0]! + +test('default', async () => { + await connect(config, { connector }) + + const { result } = renderHook(() => ({ + useAccount: useAccount(), + useSwitchChain: useSwitchChain(), + })) + + const chainId1 = result.current.useAccount.chainId + expect(chainId1).toBeDefined() + + result.current.useSwitchChain.switchChain({ chainId: chain.mainnet2.id }) + await waitFor(() => + expect(result.current.useSwitchChain.isSuccess).toBeTruthy(), + ) + + const chainId2 = result.current.useAccount.chainId + expect(chainId2).toBeDefined() + expect(chainId1).not.toBe(chainId2) + + result.current.useSwitchChain.switchChain({ chainId: chain.mainnet.id }) + await waitFor(() => + expect(result.current.useSwitchChain.isSuccess).toBeTruthy(), + ) + + const chainId3 = result.current.useAccount.chainId + expect(chainId3).toBeDefined() + expect(chainId1).toBe(chainId3) + + await disconnect(config, { connector }) +}) + +test('behavior: chains updates', () => { + const { result, rerender } = renderHook(() => useSwitchChain()) + + const chains = result.current.chains + expect( + result.current.chains.map(({ id, name }) => ({ + id, + name, + })), + ).toMatchInlineSnapshot(` + [ + { + "id": 1, + "name": "Ethereum", + }, + { + "id": 456, + "name": "Ethereum", + }, + { + "id": 10, + "name": "OP Mainnet", + }, + ] + `) + + config._internal.chains.setState([chain.mainnet, chain.mainnet2]) + rerender() + + expect( + result.current.chains.map(({ id, name }) => ({ + id, + name, + })), + ).toMatchInlineSnapshot(` + [ + { + "id": 1, + "name": "Ethereum", + }, + { + "id": 456, + "name": "Ethereum", + }, + ] + `) + + config._internal.chains.setState(chains) + rerender() + + expect( + result.current.chains.map(({ id, name }) => ({ + id, + name, + })), + ).toMatchInlineSnapshot(` + [ + { + "id": 1, + "name": "Ethereum", + }, + { + "id": 456, + "name": "Ethereum", + }, + { + "id": 10, + "name": "OP Mainnet", + }, + ] + `) +}) diff --git a/wagmi-project/packages/react/src/hooks/useSwitchChain.ts b/wagmi-project/packages/react/src/hooks/useSwitchChain.ts new file mode 100644 index 000000000..97ecf4ce9 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useSwitchChain.ts @@ -0,0 +1,82 @@ +'use client' + +import { useMutation } from '@tanstack/react-query' +import type { + Config, + ResolvedRegister, + SwitchChainErrorType, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type SwitchChainData, + type SwitchChainMutate, + type SwitchChainMutateAsync, + type SwitchChainVariables, + switchChainMutationOptions, +} from '@wagmi/core/query' + +import type { ConfigParameter } from '../types/properties.js' +import type { + UseMutationParameters, + UseMutationReturnType, +} from '../utils/query.js' +import { useChains } from './useChains.js' +import { useConfig } from './useConfig.js' + +export type UseSwitchChainParameters< + config extends Config = Config, + context = unknown, +> = Compute< + ConfigParameter & { + mutation?: + | UseMutationParameters< + SwitchChainData, + SwitchChainErrorType, + SwitchChainVariables, + context + > + | undefined + } +> + +export type UseSwitchChainReturnType< + config extends Config = Config, + context = unknown, +> = Compute< + UseMutationReturnType< + SwitchChainData, + SwitchChainErrorType, + SwitchChainVariables, + context + > & { + chains: config['chains'] + switchChain: SwitchChainMutate + switchChainAsync: SwitchChainMutateAsync + } +> + +/** https://wagmi.sh/react/api/hooks/useSwitchChain */ +export function useSwitchChain< + config extends Config = ResolvedRegister['config'], + context = unknown, +>( + parameters: UseSwitchChainParameters = {}, +): UseSwitchChainReturnType { + const { mutation } = parameters + + const config = useConfig(parameters) + + const mutationOptions = switchChainMutationOptions(config) + const { mutate, mutateAsync, ...result } = useMutation({ + ...mutation, + ...mutationOptions, + }) + + type Return = UseSwitchChainReturnType + return { + ...result, + chains: useChains({ config }) as unknown as config['chains'], + switchChain: mutate as Return['switchChain'], + switchChainAsync: mutateAsync as Return['switchChainAsync'], + } +} diff --git a/wagmi-project/packages/react/src/hooks/useSyncExternalStoreWithTracked.test.tsx b/wagmi-project/packages/react/src/hooks/useSyncExternalStoreWithTracked.test.tsx new file mode 100644 index 000000000..e0b1e71a9 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useSyncExternalStoreWithTracked.test.tsx @@ -0,0 +1,275 @@ +import { fireEvent, screen } from '@testing-library/react' +import { act, cleanup, render, renderHook } from '@wagmi/test/react' +import React from 'react' +import * as ReactDOM from 'react-dom' +import { afterEach, expect, test } from 'vitest' + +import { useSyncExternalStoreWithTracked } from './useSyncExternalStoreWithTracked.js' + +function createExternalStore(initialState: state) { + const listeners = new Set<() => void>() + let currentState = initialState + return { + set(updater: (state: state) => state) { + currentState = updater(currentState) + ReactDOM.unstable_batchedUpdates(() => { + for (const listener of listeners) { + listener() + } + }) + }, + subscribe(listener: () => void) { + listeners.add(listener) + return () => listeners.delete(listener) + }, + getState() { + return currentState + }, + } +} + +function useExternalStore( + store: ReturnType, + cb: (state: any) => void, +) { + const state = useSyncExternalStoreWithTracked( + store.subscribe, + store.getState, + store.getState, + ) + cb(state) + return state as any +} + +afterEach(() => { + cleanup() +}) + +test('rerenders only when the tracked value changes', async () => { + const externalStore = createExternalStore({ + foo: 'bar', + gm: 'wagmi', + isGonnaMakeIt: false, + }) + + const renders: any[] = [] + + renderHook(() => { + const { gm } = useExternalStore(externalStore, (state) => { + renders.push(state) + }) + + return gm + }) + + act(() => { + externalStore.set((x) => ({ ...x, foo: 'baz', isGonnaMakeIt: true })) + }) + + expect(renders).toMatchInlineSnapshot(` + [ + { + "foo": "bar", + "gm": "wagmi", + "isGonnaMakeIt": false, + }, + ] + `) + + act(() => { + externalStore.set((x) => ({ ...x, gm: 'ngmi' })) + }) + + expect(renders).toMatchInlineSnapshot(` + [ + { + "foo": "bar", + "gm": "wagmi", + "isGonnaMakeIt": false, + }, + { + "foo": "baz", + "gm": "ngmi", + "isGonnaMakeIt": true, + }, + ] + `) +}) + +test('rerenders when all values are being tracked', async () => { + const externalStore = createExternalStore({ + foo: 'bar', + gm: 'wagmi', + isGonnaMakeIt: false, + }) + + const renders: any[] = [] + + renderHook(() => { + const { foo, gm, isGonnaMakeIt } = useExternalStore( + externalStore, + (state) => { + renders.push(state) + }, + ) + + return { + foo, + gm, + isGonnaMakeIt, + } + }) + + act(() => { + externalStore.set((x) => ({ ...x, isGonnaMakeIt: true })) + }) + + expect(renders).toMatchInlineSnapshot(` + [ + { + "foo": "bar", + "gm": "wagmi", + "isGonnaMakeIt": false, + }, + { + "foo": "bar", + "gm": "wagmi", + "isGonnaMakeIt": true, + }, + ] + `) +}) + +test('rerenders when no values are being tracked', async () => { + const externalStore = createExternalStore({ + foo: 'bar', + gm: 'wagmi', + isGonnaMakeIt: false, + }) + + const renders: any[] = [] + + renderHook(() => { + useExternalStore(externalStore, (state) => { + renders.push(state) + }) + }) + + act(() => { + externalStore.set((x) => ({ ...x, isGonnaMakeIt: true })) + }) + + expect(renders).toMatchInlineSnapshot(` + [ + { + "foo": "bar", + "gm": "wagmi", + "isGonnaMakeIt": false, + }, + { + "foo": "bar", + "gm": "wagmi", + "isGonnaMakeIt": true, + }, + ] + `) +}) + +test('store object reference is stable across rerenders', async () => { + const externalStore = createExternalStore({ + foo: 'bar', + gm: 'wagmi', + isGonnaMakeIt: false, + }) + + let childRenderCount = 0 + const MemoComponent = React.memo((props: { store: any }) => { + childRenderCount++ + return
{props.store.isGonnaMakeIt}
+ }) + + const renders: any[] = [] + + function Test() { + const store = useExternalStore(externalStore, (state) => { + renders.push(state) + }) + const [, rerender] = React.useState(0) + + return ( + <> + + + + ) + } + + render() + + const forceRerenderBtn = screen.getByRole('button') + expect(childRenderCount).toBe(1) + expect(renders.length).toBe(1) + + // updating parent state, child should not rerender + fireEvent.click(forceRerenderBtn) + expect(childRenderCount).toBe(1) + expect(renders.length).toBe(2) + + // child and parent both rerender when store changes + act(() => { + externalStore.set((x) => ({ ...x, isGonnaMakeIt: true })) + }) + expect(childRenderCount).toBe(2) + expect(renders.length).toBe(3) +}) + +test('array', async () => { + const externalStore = createExternalStore(['foo']) + + const renders: any[] = [] + + renderHook(() => { + const array = useExternalStore(externalStore, (state) => { + renders.push(state) + }) + + return array + }) + + act(() => { + externalStore.set((x) => [...x, 'bar']) + }) + + expect(renders).toMatchInlineSnapshot(` + [ + [ + "foo", + ], + [ + "foo", + "bar", + ], + ] + `) + + act(() => { + externalStore.set((x) => [...x, 'baz']) + }) + + expect(renders).toMatchInlineSnapshot(` + [ + [ + "foo", + ], + [ + "foo", + "bar", + ], + [ + "foo", + "bar", + "baz", + ], + ] + `) +}) diff --git a/wagmi-project/packages/react/src/hooks/useSyncExternalStoreWithTracked.ts b/wagmi-project/packages/react/src/hooks/useSyncExternalStoreWithTracked.ts new file mode 100644 index 000000000..4e372a556 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useSyncExternalStoreWithTracked.ts @@ -0,0 +1,67 @@ +'use client' + +import { deepEqual } from '@wagmi/core/internal' +import { useMemo, useRef } from 'react' +import { useSyncExternalStoreWithSelector } from 'use-sync-external-store/shim/with-selector.js' + +const isPlainObject = (obj: unknown) => + typeof obj === 'object' && !Array.isArray(obj) + +export function useSyncExternalStoreWithTracked< + snapshot extends selection, + selection = snapshot, +>( + subscribe: (onStoreChange: () => void) => () => void, + getSnapshot: () => snapshot, + getServerSnapshot: undefined | null | (() => snapshot) = getSnapshot, + isEqual: (a: selection, b: selection) => boolean = deepEqual, +) { + const trackedKeys = useRef([]) + const result = useSyncExternalStoreWithSelector( + subscribe, + getSnapshot, + getServerSnapshot, + (x) => x, + (a, b) => { + if (isPlainObject(a) && isPlainObject(b) && trackedKeys.current.length) { + for (const key of trackedKeys.current) { + const equal = isEqual( + (a as { [_a: string]: any })[key], + (b as { [_b: string]: any })[key], + ) + if (!equal) return false + } + return true + } + return isEqual(a, b) + }, + ) + + return useMemo(() => { + if (isPlainObject(result)) { + const trackedResult = { ...result } + let properties = {} + for (const [key, value] of Object.entries( + trackedResult as { [key: string]: any }, + )) { + properties = { + ...properties, + [key]: { + configurable: false, + enumerable: true, + get: () => { + if (!trackedKeys.current.includes(key)) { + trackedKeys.current.push(key) + } + return value + }, + }, + } + } + Object.defineProperties(trackedResult, properties) + return trackedResult + } + + return result + }, [result]) +} diff --git a/wagmi-project/packages/react/src/hooks/useToken.test-d.ts b/wagmi-project/packages/react/src/hooks/useToken.test-d.ts new file mode 100644 index 000000000..201895191 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useToken.test-d.ts @@ -0,0 +1,14 @@ +import { expectTypeOf, test } from 'vitest' + +import { useToken } from './useToken.js' + +test('select data', () => { + const result = useToken({ + query: { + select(data) { + return data?.name + }, + }, + }) + expectTypeOf(result.data).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/react/src/hooks/useToken.test.ts b/wagmi-project/packages/react/src/hooks/useToken.test.ts new file mode 100644 index 000000000..602379753 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useToken.test.ts @@ -0,0 +1,59 @@ +import { renderHook, waitFor } from '@wagmi/test/react' +import { expect, test } from 'vitest' + +import { useToken } from './useToken.js' + +test('default', async () => { + const { result } = renderHook(() => + useToken({ + address: '0x1f9840a85d5af5bf1d1762f925bdaddc4201f984', + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": { + "address": "0x1f9840a85d5af5bf1d1762f925bdaddc4201f984", + "decimals": 18, + "name": "Uniswap", + "symbol": "UNI", + "totalSupply": { + "formatted": "1000000000", + "value": 1000000000000000000000000000n, + }, + }, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "token", + { + "address": "0x1f9840a85d5af5bf1d1762f925bdaddc4201f984", + "chainId": 1, + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) diff --git a/wagmi-project/packages/react/src/hooks/useToken.ts b/wagmi-project/packages/react/src/hooks/useToken.ts new file mode 100644 index 000000000..1d43912f7 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useToken.ts @@ -0,0 +1,60 @@ +'use client' + +import type { Config, GetTokenErrorType, ResolvedRegister } from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type GetTokenData, + type GetTokenOptions, + type GetTokenQueryFnData, + type GetTokenQueryKey, + getTokenQueryOptions, +} from '@wagmi/core/query' + +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseTokenParameters< + config extends Config = Config, + selectData = GetTokenData, +> = Compute< + GetTokenOptions & + ConfigParameter & + QueryParameter< + GetTokenQueryFnData, + GetTokenErrorType, + selectData, + GetTokenQueryKey + > +> + +export type UseTokenReturnType = UseQueryReturnType< + selectData, + GetTokenErrorType +> + +/** + * @deprecated + * + * https://wagmi.sh/react/api/hooks/useToken + */ +export function useToken< + config extends Config = ResolvedRegister['config'], + selectData = GetTokenData, +>( + parameters: UseTokenParameters = {}, +): UseTokenReturnType { + const { address, query = {} } = parameters + + const config = useConfig(parameters) + const chainId = useChainId({ config }) + + const options = getTokenQueryOptions(config, { + ...parameters, + chainId: parameters.chainId ?? chainId, + }) + const enabled = Boolean(address && (query.enabled ?? true)) + + return useQuery({ ...query, ...options, enabled }) +} diff --git a/wagmi-project/packages/react/src/hooks/useTransaction.test-d.ts b/wagmi-project/packages/react/src/hooks/useTransaction.test-d.ts new file mode 100644 index 000000000..211efa7f6 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useTransaction.test-d.ts @@ -0,0 +1,14 @@ +import { expectTypeOf, test } from 'vitest' + +import { useTransaction } from './useTransaction.js' + +test('select data', () => { + const result = useTransaction({ + query: { + select(data) { + return data?.nonce + }, + }, + }) + expectTypeOf(result.data).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/react/src/hooks/useTransaction.test.ts b/wagmi-project/packages/react/src/hooks/useTransaction.test.ts new file mode 100644 index 000000000..190cffb1f --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useTransaction.test.ts @@ -0,0 +1,72 @@ +import { renderHook, waitFor } from '@wagmi/test/react' +import { expect, test } from 'vitest' + +import { useTransaction } from './useTransaction.js' + +test('default', async () => { + const { result } = renderHook(() => + useTransaction({ + hash: '0x60668ed8c2dc110d61d945a936fcd45b8f13654e5c78481c8c825d1148c7ef30', + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": { + "accessList": [], + "blockHash": "0xd725a38b51e5ceec8c5f6c9ccfdb2cc423af993bb650af5eedca5e4be7156ba7", + "blockNumber": 15189204n, + "chainId": 1, + "from": "0xa0cf798816d4b9b9866b5330eea46a18382f251e", + "gas": 21000n, + "gasPrice": 9371645552n, + "hash": "0x60668ed8c2dc110d61d945a936fcd45b8f13654e5c78481c8c825d1148c7ef30", + "input": "0x", + "maxFeePerGas": 13644824566n, + "maxPriorityFeePerGas": 1500000000n, + "nonce": 86, + "r": "0x40174f9a38df876c1a7ce2587848819d4082ccd6d67a88aa5cabe59bf594e14f", + "s": "0x7c0c82f62a8a5a9b0e9cf30a54a72fdae8fc54b5b79ddafef0acd30e94e83872", + "to": "0xd2135cfb216b74109775236e36d4b433f1df507b", + "transactionIndex": 144, + "type": "eip1559", + "typeHex": "0x2", + "v": 0n, + "value": 100000000000000000n, + "yParity": 0, + }, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "transaction", + { + "chainId": 1, + "hash": "0x60668ed8c2dc110d61d945a936fcd45b8f13654e5c78481c8c825d1148c7ef30", + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) diff --git a/wagmi-project/packages/react/src/hooks/useTransaction.ts b/wagmi-project/packages/react/src/hooks/useTransaction.ts new file mode 100644 index 000000000..6cc920e87 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useTransaction.ts @@ -0,0 +1,72 @@ +'use client' + +import type { + Config, + GetTransactionErrorType, + ResolvedRegister, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type GetTransactionData, + type GetTransactionOptions, + type GetTransactionQueryFnData, + type GetTransactionQueryKey, + getTransactionQueryOptions, +} from '@wagmi/core/query' + +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseTransactionParameters< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = GetTransactionData, +> = Compute< + GetTransactionOptions & + ConfigParameter & + QueryParameter< + GetTransactionQueryFnData, + GetTransactionErrorType, + selectData, + GetTransactionQueryKey + > +> + +export type UseTransactionReturnType< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = GetTransactionData, +> = UseQueryReturnType + +/** https://wagmi.sh/react/api/hooks/useTransaction */ +export function useTransaction< + config extends Config = ResolvedRegister['config'], + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = GetTransactionData, +>( + parameters: UseTransactionParameters = {}, +): UseTransactionReturnType { + const { blockHash, blockNumber, blockTag, hash, query = {} } = parameters + + const config = useConfig(parameters) + const chainId = useChainId({ config }) + + const options = getTransactionQueryOptions(config, { + ...parameters, + chainId: parameters.chainId ?? chainId, + }) + const enabled = Boolean( + !(blockHash && blockNumber && blockTag && hash) && (query.enabled ?? true), + ) + + return useQuery({ + ...(query as any), + ...options, + enabled, + }) as UseTransactionReturnType +} diff --git a/wagmi-project/packages/react/src/hooks/useTransactionConfirmations.test-d.ts b/wagmi-project/packages/react/src/hooks/useTransactionConfirmations.test-d.ts new file mode 100644 index 000000000..e2bbcb426 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useTransactionConfirmations.test-d.ts @@ -0,0 +1,14 @@ +import { expectTypeOf, test } from 'vitest' + +import { useTransactionConfirmations } from './useTransactionConfirmations.js' + +test('select data', () => { + const result = useTransactionConfirmations({ + query: { + select(data) { + return data + }, + }, + }) + expectTypeOf(result.data).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/react/src/hooks/useTransactionConfirmations.test.ts b/wagmi-project/packages/react/src/hooks/useTransactionConfirmations.test.ts new file mode 100644 index 000000000..4f4a79c25 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useTransactionConfirmations.test.ts @@ -0,0 +1,215 @@ +import { config, wait } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import type { Hash } from 'viem' +import { expect, test } from 'vitest' + +import { getTransactionReceipt } from '@wagmi/core' +import { useTransactionConfirmations } from './useTransactionConfirmations.js' + +test('default', async () => { + const { result } = renderHook(() => + useTransactionConfirmations({ + hash: '0x60668ed8c2dc110d61d945a936fcd45b8f13654e5c78481c8c825d1148c7ef30', + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + const { data, ...rest } = result.current + expect(data).toBeTypeOf('bigint') + expect(rest).toMatchInlineSnapshot(` + { + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "transactionConfirmations", + { + "chainId": 1, + "hash": "0x60668ed8c2dc110d61d945a936fcd45b8f13654e5c78481c8c825d1148c7ef30", + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('parameters: transactionReceipt', async () => { + const transactionReceipt = await getTransactionReceipt(config, { + hash: '0x60668ed8c2dc110d61d945a936fcd45b8f13654e5c78481c8c825d1148c7ef30', + }) + + const { result } = renderHook(() => + useTransactionConfirmations({ + transactionReceipt, + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + const { data, ...rest } = result.current + expect(data).toBeTypeOf('bigint') + expect(rest).toMatchInlineSnapshot(` + { + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "transactionConfirmations", + { + "chainId": 1, + "transactionReceipt": { + "blockHash": "0xd725a38b51e5ceec8c5f6c9ccfdb2cc423af993bb650af5eedca5e4be7156ba7", + "blockNumber": 15189204n, + "contractAddress": null, + "cumulativeGasUsed": 12949744n, + "effectiveGasPrice": 9371645552n, + "from": "0xa0cf798816d4b9b9866b5330eea46a18382f251e", + "gasUsed": 21000n, + "logs": [], + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "status": "success", + "to": "0xd2135cfb216b74109775236e36d4b433f1df507b", + "transactionHash": "0x60668ed8c2dc110d61d945a936fcd45b8f13654e5c78481c8c825d1148c7ef30", + "transactionIndex": 144, + "type": "eip1559", + }, + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('behavior: hash: undefined -> defined', async () => { + let hash: Hash | undefined = undefined + + const { result, rerender } = renderHook(() => + useTransactionConfirmations({ + hash, + }), + ) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": undefined, + "dataUpdatedAt": 0, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": false, + "isFetchedAfterMount": false, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": true, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": false, + "isSuccess": false, + "queryKey": [ + "transactionConfirmations", + { + "chainId": 1, + "hash": undefined, + }, + ], + "refetch": [Function], + "status": "pending", + } + `) + + hash = '0x60668ed8c2dc110d61d945a936fcd45b8f13654e5c78481c8c825d1148c7ef30' + rerender() + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + const { data, ...rest } = result.current + expect(data).toBeTypeOf('bigint') + expect(rest).toMatchInlineSnapshot(` + { + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "transactionConfirmations", + { + "chainId": 1, + "hash": "0x60668ed8c2dc110d61d945a936fcd45b8f13654e5c78481c8c825d1148c7ef30", + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('behavior: disabled when properties missing', async () => { + const { result } = renderHook(() => useTransactionConfirmations()) + + await wait(100) + await waitFor(() => expect(result.current.isPending).toBeTruthy()) +}) diff --git a/wagmi-project/packages/react/src/hooks/useTransactionConfirmations.ts b/wagmi-project/packages/react/src/hooks/useTransactionConfirmations.ts new file mode 100644 index 000000000..c8e9ddec3 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useTransactionConfirmations.ts @@ -0,0 +1,66 @@ +'use client' + +import type { + Config, + GetTransactionConfirmationsErrorType, + ResolvedRegister, +} from '@wagmi/core' +import { + type GetTransactionConfirmationsData, + type GetTransactionConfirmationsOptions, + type GetTransactionConfirmationsQueryFnData, + type GetTransactionConfirmationsQueryKey, + getTransactionConfirmationsQueryOptions, +} from '@wagmi/core/query' + +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseTransactionConfirmationsParameters< + config extends Config = Config, + chainId extends config['chains'][number]['id'] | undefined = undefined, + selectData = GetTransactionConfirmationsData, +> = GetTransactionConfirmationsOptions & + ConfigParameter & + QueryParameter< + GetTransactionConfirmationsQueryFnData, + GetTransactionConfirmationsErrorType, + selectData, + GetTransactionConfirmationsQueryKey + > + +export type UseTransactionConfirmationsReturnType< + selectData = GetTransactionConfirmationsData, +> = UseQueryReturnType + +/** https://wagmi.sh/react/api/hooks/useTransactionConfirmations */ +export function useTransactionConfirmations< + config extends Config = ResolvedRegister['config'], + chainId extends config['chains'][number]['id'] | undefined = undefined, + selectData = GetTransactionConfirmationsData, +>( + parameters: UseTransactionConfirmationsParameters< + config, + chainId, + selectData + > = {} as any, +): UseTransactionConfirmationsReturnType { + const { hash, transactionReceipt, query = {} } = parameters + + const config = useConfig(parameters) + const chainId = useChainId({ config }) + + const options = getTransactionConfirmationsQueryOptions(config, { + ...parameters, + chainId: parameters.chainId ?? chainId, + }) + const enabled = Boolean( + !(hash && transactionReceipt) && + (hash || transactionReceipt) && + (query.enabled ?? true), + ) + + return useQuery({ ...query, ...options, enabled }) +} diff --git a/wagmi-project/packages/react/src/hooks/useTransactionCount.test-d.ts b/wagmi-project/packages/react/src/hooks/useTransactionCount.test-d.ts new file mode 100644 index 000000000..069d10b9c --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useTransactionCount.test-d.ts @@ -0,0 +1,14 @@ +import { expectTypeOf, test } from 'vitest' + +import { useTransactionCount } from './useTransactionCount.js' + +test('select data', () => { + const result = useTransactionCount({ + query: { + select(data) { + return data + }, + }, + }) + expectTypeOf(result.data).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/react/src/hooks/useTransactionCount.test.ts b/wagmi-project/packages/react/src/hooks/useTransactionCount.test.ts new file mode 100644 index 000000000..13a241ea8 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useTransactionCount.test.ts @@ -0,0 +1,238 @@ +import { accounts, chain, wait } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import type { Address } from 'viem' +import { expect, test } from 'vitest' + +import { useTransactionCount } from './useTransactionCount.js' + +const address = accounts[0] + +test('default', async () => { + const { result } = renderHook(() => useTransactionCount({ address })) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + const { data, ...rest } = result.current + expect(data).toBeTypeOf('number') + expect(rest).toMatchInlineSnapshot(` + { + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "transactionCount", + { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "chainId": 1, + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('parameters: chainId', async () => { + const { result } = renderHook(() => + useTransactionCount({ address, chainId: chain.mainnet2.id }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + const { data, ...rest } = result.current + expect(data).toBeTypeOf('number') + expect(rest).toMatchInlineSnapshot(` + { + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "transactionCount", + { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "chainId": 456, + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('parameters: blockNumber', async () => { + const { result } = renderHook(() => + useTransactionCount({ address, blockNumber: 13677382n }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + const { data, ...rest } = result.current + expect(data).toBeTypeOf('number') + expect(rest).toMatchInlineSnapshot(` + { + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "transactionCount", + { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "blockNumber": 13677382n, + "chainId": 1, + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('behavior: address: undefined -> defined', async () => { + let address: Address | undefined = undefined + + const { result, rerender } = renderHook(() => + useTransactionCount({ address }), + ) + + { + const { data, ...rest } = result.current + expect(data).toBeTypeOf('undefined') + expect(rest).toMatchInlineSnapshot(` + { + "dataUpdatedAt": 0, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": false, + "isFetchedAfterMount": false, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": true, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": false, + "isSuccess": false, + "queryKey": [ + "transactionCount", + { + "address": undefined, + "chainId": 1, + }, + ], + "refetch": [Function], + "status": "pending", + } + `) + } + + address = accounts[0] + rerender() + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + const { data, ...rest } = result.current + expect(data).toBeTypeOf('number') + expect(rest).toMatchInlineSnapshot(` + { + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "transactionCount", + { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "chainId": 1, + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('behavior: disabled when properties missing', async () => { + const { result } = renderHook(() => useTransactionCount()) + + await wait(100) + await waitFor(() => expect(result.current.isPending).toBeTruthy()) +}) diff --git a/wagmi-project/packages/react/src/hooks/useTransactionCount.ts b/wagmi-project/packages/react/src/hooks/useTransactionCount.ts new file mode 100644 index 000000000..341536aea --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useTransactionCount.ts @@ -0,0 +1,59 @@ +'use client' + +import type { + Config, + GetTransactionCountErrorType, + ResolvedRegister, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import type { GetTransactionCountQueryFnData } from '@wagmi/core/query' +import { + type GetTransactionCountData, + type GetTransactionCountOptions, + type GetTransactionCountQueryKey, + getTransactionCountQueryOptions, +} from '@wagmi/core/query' + +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseTransactionCountParameters< + config extends Config = Config, + selectData = GetTransactionCountData, +> = Compute< + GetTransactionCountOptions & + ConfigParameter & + QueryParameter< + GetTransactionCountQueryFnData, + GetTransactionCountErrorType, + selectData, + GetTransactionCountQueryKey + > +> + +export type UseTransactionCountReturnType< + selectData = GetTransactionCountData, +> = UseQueryReturnType + +/** https://wagmi.sh/react/api/hooks/useTransactionCount */ +export function useTransactionCount< + config extends Config = ResolvedRegister['config'], + selectData = GetTransactionCountData, +>( + parameters: UseTransactionCountParameters = {}, +): UseTransactionCountReturnType { + const { address, query = {} } = parameters + + const config = useConfig(parameters) + const chainId = useChainId({ config }) + + const options = getTransactionCountQueryOptions(config, { + ...parameters, + chainId: parameters.chainId ?? chainId, + }) + const enabled = Boolean(address && (query.enabled ?? true)) + + return useQuery({ ...query, ...options, enabled }) +} diff --git a/wagmi-project/packages/react/src/hooks/useTransactionReceipt.test-d.ts b/wagmi-project/packages/react/src/hooks/useTransactionReceipt.test-d.ts new file mode 100644 index 000000000..af2785934 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useTransactionReceipt.test-d.ts @@ -0,0 +1,14 @@ +import { expectTypeOf, test } from 'vitest' + +import { useTransactionReceipt } from './useTransactionReceipt.js' + +test('select data', () => { + const result = useTransactionReceipt({ + query: { + select(data) { + return data?.blockNumber + }, + }, + }) + expectTypeOf(result.data).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/react/src/hooks/useTransactionReceipt.test.ts b/wagmi-project/packages/react/src/hooks/useTransactionReceipt.test.ts new file mode 100644 index 000000000..fd2e24d76 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useTransactionReceipt.test.ts @@ -0,0 +1,237 @@ +import { chain, wait } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import type { Hash } from 'viem' +import { expect, test } from 'vitest' +import { useTransactionReceipt } from './useTransactionReceipt.js' + +test('default', async () => { + const { result } = renderHook(() => + useTransactionReceipt({ + hash: '0xbf7d27700d053765c9638d3b9d39eb3c56bfc48377583e8be483d61f9f18a871', + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": { + "blockHash": "0xb932f77cf770d1d1c8f861153eec1e990f5d56b6ffdb4ac06aef3cca51ef37d4", + "blockNumber": 16280769n, + "contractAddress": null, + "cumulativeGasUsed": 21000n, + "effectiveGasPrice": 33427926161n, + "from": "0x043022ef9fca1066024d19d681e2ccf44ff90de3", + "gasUsed": 21000n, + "logs": [], + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "status": "success", + "to": "0x318a5fb4f1604fc46375a1db9a9018b6e423b345", + "transactionHash": "0xbf7d27700d053765c9638d3b9d39eb3c56bfc48377583e8be483d61f9f18a871", + "transactionIndex": 0, + "type": "legacy", + }, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "getTransactionReceipt", + { + "chainId": 1, + "hash": "0xbf7d27700d053765c9638d3b9d39eb3c56bfc48377583e8be483d61f9f18a871", + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('parameters: chainId', async () => { + const { result } = renderHook(() => + useTransactionReceipt({ + chainId: chain.mainnet2.id, + hash: '0xbf7d27700d053765c9638d3b9d39eb3c56bfc48377583e8be483d61f9f18a871', + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": { + "blockHash": "0xb932f77cf770d1d1c8f861153eec1e990f5d56b6ffdb4ac06aef3cca51ef37d4", + "blockNumber": 16280769n, + "contractAddress": null, + "cumulativeGasUsed": 21000n, + "effectiveGasPrice": 33427926161n, + "from": "0x043022ef9fca1066024d19d681e2ccf44ff90de3", + "gasUsed": 21000n, + "logs": [], + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "status": "success", + "to": "0x318a5fb4f1604fc46375a1db9a9018b6e423b345", + "transactionHash": "0xbf7d27700d053765c9638d3b9d39eb3c56bfc48377583e8be483d61f9f18a871", + "transactionIndex": 0, + "type": "legacy", + }, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "getTransactionReceipt", + { + "chainId": 456, + "hash": "0xbf7d27700d053765c9638d3b9d39eb3c56bfc48377583e8be483d61f9f18a871", + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('behavior: hash: undefined -> defined', async () => { + let hash: Hash | undefined = undefined + + const { result, rerender } = renderHook(() => + useTransactionReceipt({ + hash, + }), + ) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": undefined, + "dataUpdatedAt": 0, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": false, + "isFetchedAfterMount": false, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": true, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": false, + "isSuccess": false, + "queryKey": [ + "getTransactionReceipt", + { + "chainId": 1, + "hash": undefined, + }, + ], + "refetch": [Function], + "status": "pending", + } + `) + + hash = '0xbf7d27700d053765c9638d3b9d39eb3c56bfc48377583e8be483d61f9f18a871' + rerender() + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": { + "blockHash": "0xb932f77cf770d1d1c8f861153eec1e990f5d56b6ffdb4ac06aef3cca51ef37d4", + "blockNumber": 16280769n, + "contractAddress": null, + "cumulativeGasUsed": 21000n, + "effectiveGasPrice": 33427926161n, + "from": "0x043022ef9fca1066024d19d681e2ccf44ff90de3", + "gasUsed": 21000n, + "logs": [], + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "status": "success", + "to": "0x318a5fb4f1604fc46375a1db9a9018b6e423b345", + "transactionHash": "0xbf7d27700d053765c9638d3b9d39eb3c56bfc48377583e8be483d61f9f18a871", + "transactionIndex": 0, + "type": "legacy", + }, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "getTransactionReceipt", + { + "chainId": 1, + "hash": "0xbf7d27700d053765c9638d3b9d39eb3c56bfc48377583e8be483d61f9f18a871", + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('behavior: disabled when properties missing', async () => { + const { result } = renderHook(() => useTransactionReceipt()) + + await wait(100) + await waitFor(() => expect(result.current.isPending).toBeTruthy()) +}) diff --git a/wagmi-project/packages/react/src/hooks/useTransactionReceipt.ts b/wagmi-project/packages/react/src/hooks/useTransactionReceipt.ts new file mode 100644 index 000000000..f29ab6204 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useTransactionReceipt.ts @@ -0,0 +1,69 @@ +'use client' + +import type { + Config, + GetTransactionReceiptErrorType, + ResolvedRegister, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type GetTransactionReceiptData, + type GetTransactionReceiptOptions, + type GetTransactionReceiptQueryKey, + getTransactionReceiptQueryOptions, +} from '@wagmi/core/query' +import type { GetTransactionReceiptQueryFnData } from '@wagmi/core/query' +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseTransactionReceiptParameters< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = GetTransactionReceiptData, +> = Compute< + GetTransactionReceiptOptions & + ConfigParameter & + QueryParameter< + GetTransactionReceiptQueryFnData, + GetTransactionReceiptErrorType, + selectData, + GetTransactionReceiptQueryKey + > +> + +export type UseTransactionReceiptReturnType< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = GetTransactionReceiptData, +> = UseQueryReturnType + +/** https://wagmi.sh/react/api/hooks/useTransactionReceipt */ +export function useTransactionReceipt< + config extends Config = ResolvedRegister['config'], + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = GetTransactionReceiptData, +>( + parameters: UseTransactionReceiptParameters = {}, +): UseTransactionReceiptReturnType { + const { hash, query = {} } = parameters + + const config = useConfig(parameters) + const chainId = useChainId({ config }) + + const options = getTransactionReceiptQueryOptions(config, { + ...parameters, + chainId: parameters.chainId ?? chainId, + }) + const enabled = Boolean(hash && (query.enabled ?? true)) + + return useQuery({ + ...(query as any), + ...options, + enabled, + }) as UseTransactionReceiptReturnType +} diff --git a/wagmi-project/packages/react/src/hooks/useVerifyMessage.test-d.ts b/wagmi-project/packages/react/src/hooks/useVerifyMessage.test-d.ts new file mode 100644 index 000000000..5a9ad7e25 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useVerifyMessage.test-d.ts @@ -0,0 +1,14 @@ +import { expectTypeOf, test } from 'vitest' + +import { useVerifyMessage } from './useVerifyMessage.js' + +test('select data', () => { + const result = useVerifyMessage({ + query: { + select(data) { + return data + }, + }, + }) + expectTypeOf(result.data).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/react/src/hooks/useVerifyMessage.test.ts b/wagmi-project/packages/react/src/hooks/useVerifyMessage.test.ts new file mode 100644 index 000000000..244b6331f --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useVerifyMessage.test.ts @@ -0,0 +1,318 @@ +import { accounts, chain, wait } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { expect, test } from 'vitest' + +import type { Hex } from 'viem' +import { useVerifyMessage } from './useVerifyMessage.js' + +const address = accounts[0] + +test('default', async () => { + const { result } = renderHook(() => + useVerifyMessage({ + address, + message: 'This is a test message for viem!', + signature: + '0xc4c7f2820177020d66d5fd00d084cdd3f575a868c059c29a2d7f23398d04819709a14f83d98b446dda539ca5dcb87d75aa3340eb15e66d67606850622a3420f61b', + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": true, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "verifyMessage", + { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "chainId": 1, + "message": "This is a test message for viem!", + "signature": "0xc4c7f2820177020d66d5fd00d084cdd3f575a868c059c29a2d7f23398d04819709a14f83d98b446dda539ca5dcb87d75aa3340eb15e66d67606850622a3420f61b", + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('parameters: chainId', async () => { + const { result } = renderHook(() => + useVerifyMessage({ + chainId: chain.mainnet2.id, + address, + message: 'This is a test message for viem!', + signature: + '0xc4c7f2820177020d66d5fd00d084cdd3f575a868c059c29a2d7f23398d04819709a14f83d98b446dda539ca5dcb87d75aa3340eb15e66d67606850622a3420f61b', + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": true, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "verifyMessage", + { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "chainId": 456, + "message": "This is a test message for viem!", + "signature": "0xc4c7f2820177020d66d5fd00d084cdd3f575a868c059c29a2d7f23398d04819709a14f83d98b446dda539ca5dcb87d75aa3340eb15e66d67606850622a3420f61b", + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('parameters: blockNumber', async () => { + const { result } = renderHook(() => + useVerifyMessage({ + blockNumber: 12345678n, + address, + message: 'This is a test message for viem!', + signature: + '0xc4c7f2820177020d66d5fd00d084cdd3f575a868c059c29a2d7f23398d04819709a14f83d98b446dda539ca5dcb87d75aa3340eb15e66d67606850622a3420f61b', + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": true, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "verifyMessage", + { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "blockNumber": 12345678n, + "chainId": 1, + "message": "This is a test message for viem!", + "signature": "0xc4c7f2820177020d66d5fd00d084cdd3f575a868c059c29a2d7f23398d04819709a14f83d98b446dda539ca5dcb87d75aa3340eb15e66d67606850622a3420f61b", + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('parameters: blockTag', async () => { + const { result } = renderHook(() => + useVerifyMessage({ + blockTag: 'pending', + address, + message: 'This is a test message for viem!', + signature: + '0xc4c7f2820177020d66d5fd00d084cdd3f575a868c059c29a2d7f23398d04819709a14f83d98b446dda539ca5dcb87d75aa3340eb15e66d67606850622a3420f61b', + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": true, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "verifyMessage", + { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "blockTag": "pending", + "chainId": 1, + "message": "This is a test message for viem!", + "signature": "0xc4c7f2820177020d66d5fd00d084cdd3f575a868c059c29a2d7f23398d04819709a14f83d98b446dda539ca5dcb87d75aa3340eb15e66d67606850622a3420f61b", + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('behavior: signature: undefined -> defined', async () => { + let signature: Hex | undefined = undefined + + const { result, rerender } = renderHook(() => + useVerifyMessage({ + address, + message: 'This is a test message for viem!', + signature, + }), + ) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": undefined, + "dataUpdatedAt": 0, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": false, + "isFetchedAfterMount": false, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": true, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": false, + "isSuccess": false, + "queryKey": [ + "verifyMessage", + { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "chainId": 1, + "message": "This is a test message for viem!", + "signature": undefined, + }, + ], + "refetch": [Function], + "status": "pending", + } + `) + + signature = + '0xc4c7f2820177020d66d5fd00d084cdd3f575a868c059c29a2d7f23398d04819709a14f83d98b446dda539ca5dcb87d75aa3340eb15e66d67606850622a3420f61b' + rerender() + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": true, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "verifyMessage", + { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "chainId": 1, + "message": "This is a test message for viem!", + "signature": "0xc4c7f2820177020d66d5fd00d084cdd3f575a868c059c29a2d7f23398d04819709a14f83d98b446dda539ca5dcb87d75aa3340eb15e66d67606850622a3420f61b", + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('behavior: disabled when properties missing', async () => { + const { result } = renderHook(() => useVerifyMessage()) + + await wait(100) + await waitFor(() => expect(result.current.isPending).toBeTruthy()) +}) diff --git a/wagmi-project/packages/react/src/hooks/useVerifyMessage.ts b/wagmi-project/packages/react/src/hooks/useVerifyMessage.ts new file mode 100644 index 000000000..ae8bb6df2 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useVerifyMessage.ts @@ -0,0 +1,59 @@ +'use client' + +import type { + Config, + ResolvedRegister, + VerifyMessageErrorType, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type VerifyMessageData, + type VerifyMessageOptions, + type VerifyMessageQueryKey, + verifyMessageQueryOptions, +} from '@wagmi/core/query' +import type { VerifyMessageQueryFnData } from '@wagmi/core/query' +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseVerifyMessageParameters< + config extends Config = Config, + selectData = VerifyMessageData, +> = Compute< + VerifyMessageOptions & + ConfigParameter & + QueryParameter< + VerifyMessageQueryFnData, + VerifyMessageErrorType, + selectData, + VerifyMessageQueryKey + > +> + +export type UseVerifyMessageReturnType = + UseQueryReturnType + +/** https://wagmi.sh/react/api/hooks/useVerifyMessage */ +export function useVerifyMessage< + config extends Config = ResolvedRegister['config'], + selectData = VerifyMessageData, +>( + parameters: UseVerifyMessageParameters = {}, +): UseVerifyMessageReturnType { + const { address, message, signature, query = {} } = parameters + + const config = useConfig(parameters) + const chainId = useChainId({ config }) + + const options = verifyMessageQueryOptions(config, { + ...parameters, + chainId: parameters.chainId ?? chainId, + }) + const enabled = Boolean( + address && message && signature && (query.enabled ?? true), + ) + + return useQuery({ ...query, ...options, enabled }) +} diff --git a/wagmi-project/packages/react/src/hooks/useVerifyTypedData.test-d.ts b/wagmi-project/packages/react/src/hooks/useVerifyTypedData.test-d.ts new file mode 100644 index 000000000..91f875e0b --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useVerifyTypedData.test-d.ts @@ -0,0 +1,40 @@ +import type { typedData } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' + +import type { Address } from 'viem' +import { + type UseVerifyTypedDataParameters, + useVerifyTypedData, +} from './useVerifyTypedData.js' + +test('select data', () => { + const result = useVerifyTypedData({ + query: { + select(data) { + return data + }, + }, + }) + expectTypeOf(result.data).toEqualTypeOf() +}) + +test('UseReadContractParameters', () => { + type Result = UseVerifyTypedDataParameters< + typeof typedData.basic.types, + 'Mail' + > + expectTypeOf>().toEqualTypeOf<{ + primaryType?: 'Mail' | 'Person' + message?: { + from: { + name: string + wallet: Address + } + to: { + name: string + wallet: Address + } + contents: string + } + }>() +}) diff --git a/wagmi-project/packages/react/src/hooks/useVerifyTypedData.test.ts b/wagmi-project/packages/react/src/hooks/useVerifyTypedData.test.ts new file mode 100644 index 000000000..d57331743 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useVerifyTypedData.test.ts @@ -0,0 +1,481 @@ +import { typedData, wait } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import type { Hex } from 'viem' +import { expect, test } from 'vitest' + +import { useVerifyTypedData } from './useVerifyTypedData.js' + +const smartAccountAddress = '0x3FCf42e10CC70Fe75A62EB3aDD6D305Aa840d145' +const notDeployedAddress = '0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef' + +test('valid signature', async () => { + const { result } = renderHook(() => + useVerifyTypedData({ + ...typedData.basic, + primaryType: 'Mail', + address: smartAccountAddress, + signature: + '0x79d756d805073dc97b7bc885b0d56ddf319a2599530fe1e178c2a7de5be88980068d24f20a79b318ea0a84d33ae06f93db77e4235e5d9eeb8b1d7a63922ada3e1c', + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": true, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "verifyTypedData", + { + "address": "0x3FCf42e10CC70Fe75A62EB3aDD6D305Aa840d145", + "chainId": 1, + "domain": { + "chainId": 1, + "name": "Ether Mail", + "verifyingContract": "0x0000000000000000000000000000000000000000", + "version": "1", + }, + "message": { + "contents": "Hello, Bob!", + "from": { + "name": "Cow", + "wallet": "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826", + }, + "to": { + "name": "Bob", + "wallet": "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB", + }, + }, + "primaryType": "Mail", + "signature": "0x79d756d805073dc97b7bc885b0d56ddf319a2599530fe1e178c2a7de5be88980068d24f20a79b318ea0a84d33ae06f93db77e4235e5d9eeb8b1d7a63922ada3e1c", + "types": { + "Mail": [ + { + "name": "from", + "type": "Person", + }, + { + "name": "to", + "type": "Person", + }, + { + "name": "contents", + "type": "string", + }, + ], + "Person": [ + { + "name": "name", + "type": "string", + }, + { + "name": "wallet", + "type": "address", + }, + ], + }, + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('invalid signature', async () => { + const { result } = renderHook(() => + useVerifyTypedData({ + ...typedData.basic, + primaryType: 'Mail', + address: smartAccountAddress, + signature: '0xdead', + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": false, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "verifyTypedData", + { + "address": "0x3FCf42e10CC70Fe75A62EB3aDD6D305Aa840d145", + "chainId": 1, + "domain": { + "chainId": 1, + "name": "Ether Mail", + "verifyingContract": "0x0000000000000000000000000000000000000000", + "version": "1", + }, + "message": { + "contents": "Hello, Bob!", + "from": { + "name": "Cow", + "wallet": "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826", + }, + "to": { + "name": "Bob", + "wallet": "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB", + }, + }, + "primaryType": "Mail", + "signature": "0xdead", + "types": { + "Mail": [ + { + "name": "from", + "type": "Person", + }, + { + "name": "to", + "type": "Person", + }, + { + "name": "contents", + "type": "string", + }, + ], + "Person": [ + { + "name": "name", + "type": "string", + }, + { + "name": "wallet", + "type": "address", + }, + ], + }, + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('account not deployed', async () => { + const { result } = renderHook(() => + useVerifyTypedData({ + ...typedData.basic, + primaryType: 'Mail', + address: notDeployedAddress, + signature: + '0x79d756d805073dc97b7bc885b0d56ddf319a2599530fe1e178c2a7de5be88980068d24f20a79b318ea0a84d33ae06f93db77e4235e5d9eeb8b1d7a63922ada3e1c', + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": false, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "verifyTypedData", + { + "address": "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef", + "chainId": 1, + "domain": { + "chainId": 1, + "name": "Ether Mail", + "verifyingContract": "0x0000000000000000000000000000000000000000", + "version": "1", + }, + "message": { + "contents": "Hello, Bob!", + "from": { + "name": "Cow", + "wallet": "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826", + }, + "to": { + "name": "Bob", + "wallet": "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB", + }, + }, + "primaryType": "Mail", + "signature": "0x79d756d805073dc97b7bc885b0d56ddf319a2599530fe1e178c2a7de5be88980068d24f20a79b318ea0a84d33ae06f93db77e4235e5d9eeb8b1d7a63922ada3e1c", + "types": { + "Mail": [ + { + "name": "from", + "type": "Person", + }, + { + "name": "to", + "type": "Person", + }, + { + "name": "contents", + "type": "string", + }, + ], + "Person": [ + { + "name": "name", + "type": "string", + }, + { + "name": "wallet", + "type": "address", + }, + ], + }, + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('behavior: signature: undefined -> defined', async () => { + let signature: Hex | undefined = undefined + + const { result, rerender } = renderHook(() => + useVerifyTypedData({ + ...typedData.basic, + primaryType: 'Mail', + address: smartAccountAddress, + signature, + }), + ) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": undefined, + "dataUpdatedAt": 0, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": false, + "isFetchedAfterMount": false, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": true, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": false, + "isSuccess": false, + "queryKey": [ + "verifyTypedData", + { + "address": "0x3FCf42e10CC70Fe75A62EB3aDD6D305Aa840d145", + "chainId": 1, + "domain": { + "chainId": 1, + "name": "Ether Mail", + "verifyingContract": "0x0000000000000000000000000000000000000000", + "version": "1", + }, + "message": { + "contents": "Hello, Bob!", + "from": { + "name": "Cow", + "wallet": "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826", + }, + "to": { + "name": "Bob", + "wallet": "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB", + }, + }, + "primaryType": "Mail", + "signature": undefined, + "types": { + "Mail": [ + { + "name": "from", + "type": "Person", + }, + { + "name": "to", + "type": "Person", + }, + { + "name": "contents", + "type": "string", + }, + ], + "Person": [ + { + "name": "name", + "type": "string", + }, + { + "name": "wallet", + "type": "address", + }, + ], + }, + }, + ], + "refetch": [Function], + "status": "pending", + } + `) + + signature = + '0x79d756d805073dc97b7bc885b0d56ddf319a2599530fe1e178c2a7de5be88980068d24f20a79b318ea0a84d33ae06f93db77e4235e5d9eeb8b1d7a63922ada3e1c' + rerender() + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": true, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "verifyTypedData", + { + "address": "0x3FCf42e10CC70Fe75A62EB3aDD6D305Aa840d145", + "chainId": 1, + "domain": { + "chainId": 1, + "name": "Ether Mail", + "verifyingContract": "0x0000000000000000000000000000000000000000", + "version": "1", + }, + "message": { + "contents": "Hello, Bob!", + "from": { + "name": "Cow", + "wallet": "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826", + }, + "to": { + "name": "Bob", + "wallet": "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB", + }, + }, + "primaryType": "Mail", + "signature": "0x79d756d805073dc97b7bc885b0d56ddf319a2599530fe1e178c2a7de5be88980068d24f20a79b318ea0a84d33ae06f93db77e4235e5d9eeb8b1d7a63922ada3e1c", + "types": { + "Mail": [ + { + "name": "from", + "type": "Person", + }, + { + "name": "to", + "type": "Person", + }, + { + "name": "contents", + "type": "string", + }, + ], + "Person": [ + { + "name": "name", + "type": "string", + }, + { + "name": "wallet", + "type": "address", + }, + ], + }, + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('behavior: disabled when properties missing', async () => { + const { result } = renderHook(() => useVerifyTypedData()) + + await wait(100) + await waitFor(() => expect(result.current.isPending).toBeTruthy()) +}) diff --git a/wagmi-project/packages/react/src/hooks/useVerifyTypedData.ts b/wagmi-project/packages/react/src/hooks/useVerifyTypedData.ts new file mode 100644 index 000000000..b02d1a851 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useVerifyTypedData.ts @@ -0,0 +1,81 @@ +'use client' + +import type { + Config, + ResolvedRegister, + VerifyTypedDataErrorType, +} from '@wagmi/core' +import { + type VerifyTypedDataData, + type VerifyTypedDataOptions, + type VerifyTypedDataQueryKey, + verifyTypedDataQueryOptions, +} from '@wagmi/core/query' +import type { VerifyTypedDataQueryFnData } from '@wagmi/core/query' +import type { TypedData } from 'viem' +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseVerifyTypedDataParameters< + typedData extends TypedData | Record = TypedData, + primaryType extends keyof typedData | 'EIP712Domain' = keyof typedData, + config extends Config = Config, + selectData = VerifyTypedDataData, +> = VerifyTypedDataOptions & + ConfigParameter & + QueryParameter< + VerifyTypedDataQueryFnData, + VerifyTypedDataErrorType, + selectData, + VerifyTypedDataQueryKey + > + +export type UseVerifyTypedDataReturnType = + UseQueryReturnType + +/** https://wagmi.sh/react/api/hooks/useVerifyTypedData */ +export function useVerifyTypedData< + const typedData extends TypedData | Record, + primaryType extends keyof typedData | 'EIP712Domain', + config extends Config = ResolvedRegister['config'], + selectData = VerifyTypedDataData, +>( + parameters: UseVerifyTypedDataParameters< + typedData, + primaryType, + config, + selectData + > = {} as any, +): UseVerifyTypedDataReturnType { + const { + address, + message, + primaryType, + signature, + types, + query = {}, + } = parameters + + const config = useConfig(parameters) + const chainId = useChainId({ config }) + + const options = verifyTypedDataQueryOptions( + config, + { + ...parameters, + chainId: parameters.chainId ?? chainId, + }, + ) + const enabled = Boolean( + address && + message && + primaryType && + signature && + types && + (query.enabled ?? true), + ) + + return useQuery({ ...query, ...options, enabled }) +} diff --git a/wagmi-project/packages/react/src/hooks/useWaitForCallsStatus.test.ts b/wagmi-project/packages/react/src/hooks/useWaitForCallsStatus.test.ts new file mode 100644 index 000000000..96f5a2a7e --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useWaitForCallsStatus.test.ts @@ -0,0 +1,101 @@ +import { connect, disconnect } from '@wagmi/core' +import { accounts, config, testClient, wait } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { parseEther } from 'viem' +import { expect, test } from 'vitest' + +import { useSendCalls } from './useSendCalls.js' +import { useWaitForCallsStatus } from './useWaitForCallsStatus.js' + +const connector = config.connectors[0]! + +test('default', async () => { + await connect(config, { connector }) + + const useSendCalls_render = renderHook(() => useSendCalls()) + const useWaitForCallsStatus_render = renderHook(() => + useWaitForCallsStatus({ id: useSendCalls_render.result.current.data?.id }), + ) + + useSendCalls_render.result.current.sendCalls({ + calls: [ + { + data: '0xdeadbeef', + to: accounts[1], + value: parseEther('1'), + }, + { + to: accounts[2], + value: parseEther('2'), + }, + { + to: accounts[3], + value: parseEther('3'), + }, + ], + }) + await waitFor(() => + expect(useSendCalls_render.result.current.isSuccess).toBeTruthy(), + ) + + expect(useWaitForCallsStatus_render.result.current.fetchStatus).toBe('idle') + useWaitForCallsStatus_render.rerender() + expect(useWaitForCallsStatus_render.result.current.fetchStatus).toBe( + 'fetching', + ) + + await Promise.all([ + waitFor(() => + expect( + useWaitForCallsStatus_render.result.current.isSuccess, + ).toBeTruthy(), + ), + (async () => { + await wait(100) + await testClient.mainnet.mine({ blocks: 1 }) + })(), + ]) + + expect(useWaitForCallsStatus_render.result.current.data?.status).toBe( + 'success', + ) + expect( + useWaitForCallsStatus_render.result.current.data?.receipts?.map((x) => ({ + ...x, + blockHash: undefined, + })), + ).toMatchInlineSnapshot( + ` + [ + { + "blockHash": undefined, + "blockNumber": 19258214n, + "gasUsed": 21064n, + "logs": [], + "status": "success", + "transactionHash": "0x13c53b2d4d9da424835525349cd66e553330f323d6fb19458b801ae1f7989a41", + }, + { + "blockHash": undefined, + "blockNumber": 19258214n, + "gasUsed": 21000n, + "logs": [], + "status": "success", + "transactionHash": "0xd8397b3e82b061c26a0c2093f1ceca0c3662a512614f7d6370349e89d0eea007", + }, + { + "blockHash": undefined, + "blockNumber": 19258214n, + "gasUsed": 21000n, + "logs": [], + "status": "success", + "transactionHash": "0x4d26e346593d9ea265bb164b115e89aa92df43b0b8778ac75d4ad28e2a22b101", + }, + ] + `, + ) + + await testClient.mainnet.mine({ blocks: 1 }) + + await disconnect(config, { connector }) +}) diff --git a/wagmi-project/packages/react/src/hooks/useWaitForCallsStatus.ts b/wagmi-project/packages/react/src/hooks/useWaitForCallsStatus.ts new file mode 100644 index 000000000..7c428c940 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useWaitForCallsStatus.ts @@ -0,0 +1,54 @@ +'use client' + +import type { + Config, + ResolvedRegister, + WaitForCallsStatusErrorType, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type WaitForCallsStatusData, + type WaitForCallsStatusOptions, + type WaitForCallsStatusQueryFnData, + type WaitForCallsStatusQueryKey, + waitForCallsStatusQueryOptions, +} from '@wagmi/core/query' + +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useConfig } from './useConfig.js' + +export type UseWaitForCallsStatusParameters< + config extends Config = Config, + selectData = WaitForCallsStatusData, +> = Compute< + WaitForCallsStatusOptions & + ConfigParameter & + QueryParameter< + WaitForCallsStatusQueryFnData, + WaitForCallsStatusErrorType, + selectData, + WaitForCallsStatusQueryKey + > +> + +export type UseWaitForCallsStatusReturnType< + selectData = WaitForCallsStatusData, +> = UseQueryReturnType + +/** https://wagmi.sh/react/api/hooks/useWaitForCallsStatus */ +export function useWaitForCallsStatus< + config extends Config = ResolvedRegister['config'], + selectData = WaitForCallsStatusData, +>( + parameters: UseWaitForCallsStatusParameters, +): UseWaitForCallsStatusReturnType { + const { id, query = {} } = parameters + + const config = useConfig(parameters) + + const options = waitForCallsStatusQueryOptions(config, parameters) + const enabled = Boolean(id && (query.enabled ?? true)) + + return useQuery({ ...query, ...options, enabled }) +} diff --git a/wagmi-project/packages/react/src/hooks/useWaitForTransactionReceipt.test-d.ts b/wagmi-project/packages/react/src/hooks/useWaitForTransactionReceipt.test-d.ts new file mode 100644 index 000000000..2d3bd2844 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useWaitForTransactionReceipt.test-d.ts @@ -0,0 +1,14 @@ +import { expectTypeOf, test } from 'vitest' + +import { useWaitForTransactionReceipt } from './useWaitForTransactionReceipt.js' + +test('select data', () => { + const result = useWaitForTransactionReceipt({ + query: { + select(data) { + return data?.blockNumber + }, + }, + }) + expectTypeOf(result.data).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/react/src/hooks/useWaitForTransactionReceipt.test.ts b/wagmi-project/packages/react/src/hooks/useWaitForTransactionReceipt.test.ts new file mode 100644 index 000000000..484d25087 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useWaitForTransactionReceipt.test.ts @@ -0,0 +1,77 @@ +import { wait } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { expect, test } from 'vitest' +import { useWaitForTransactionReceipt } from './useWaitForTransactionReceipt.js' + +test('default', async () => { + const { result } = renderHook(() => + useWaitForTransactionReceipt({ + hash: '0x60668ed8c2dc110d61d945a936fcd45b8f13654e5c78481c8c825d1148c7ef30', + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result).toMatchInlineSnapshot(` + { + "current": { + "data": { + "blockHash": "0xd725a38b51e5ceec8c5f6c9ccfdb2cc423af993bb650af5eedca5e4be7156ba7", + "blockNumber": 15189204n, + "chainId": 1, + "contractAddress": null, + "cumulativeGasUsed": 12949744n, + "effectiveGasPrice": 9371645552n, + "from": "0xa0cf798816d4b9b9866b5330eea46a18382f251e", + "gasUsed": 21000n, + "logs": [], + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "status": "success", + "to": "0xd2135cfb216b74109775236e36d4b433f1df507b", + "transactionHash": "0x60668ed8c2dc110d61d945a936fcd45b8f13654e5c78481c8c825d1148c7ef30", + "transactionIndex": 144, + "type": "eip1559", + }, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "waitForTransactionReceipt", + { + "chainId": 1, + "hash": "0x60668ed8c2dc110d61d945a936fcd45b8f13654e5c78481c8c825d1148c7ef30", + }, + ], + "refetch": [Function], + "status": "success", + }, + } + `) +}) + +test('disabled when hash is undefined', async () => { + const { result } = renderHook(() => + useWaitForTransactionReceipt({ hash: undefined }), + ) + + await wait(100) + await waitFor(() => expect(result.current.isPending).toBeTruthy()) +}) diff --git a/wagmi-project/packages/react/src/hooks/useWaitForTransactionReceipt.ts b/wagmi-project/packages/react/src/hooks/useWaitForTransactionReceipt.ts new file mode 100644 index 000000000..c07d1639b --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useWaitForTransactionReceipt.ts @@ -0,0 +1,74 @@ +'use client' + +import type { + Config, + ResolvedRegister, + WaitForTransactionReceiptErrorType, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type WaitForTransactionReceiptData, + type WaitForTransactionReceiptOptions, + type WaitForTransactionReceiptQueryFnData, + type WaitForTransactionReceiptQueryKey, + waitForTransactionReceiptQueryOptions, +} from '@wagmi/core/query' + +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseWaitForTransactionReceiptParameters< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = WaitForTransactionReceiptData, +> = Compute< + WaitForTransactionReceiptOptions & + ConfigParameter & + QueryParameter< + WaitForTransactionReceiptQueryFnData, + WaitForTransactionReceiptErrorType, + selectData, + WaitForTransactionReceiptQueryKey + > +> + +export type UseWaitForTransactionReceiptReturnType< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = WaitForTransactionReceiptData, +> = UseQueryReturnType + +/** https://wagmi.sh/react/api/hooks/useWaitForTransactionReceipt */ +export function useWaitForTransactionReceipt< + config extends Config = ResolvedRegister['config'], + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = WaitForTransactionReceiptData, +>( + parameters: UseWaitForTransactionReceiptParameters< + config, + chainId, + selectData + > = {}, +): UseWaitForTransactionReceiptReturnType { + const { hash, query = {} } = parameters + + const config = useConfig(parameters) + const chainId = useChainId({ config }) + + const options = waitForTransactionReceiptQueryOptions(config, { + ...parameters, + chainId: parameters.chainId ?? chainId, + }) + const enabled = Boolean(hash && (query.enabled ?? true)) + + return useQuery({ + ...(query as any), + ...options, + enabled, + }) as UseWaitForTransactionReceiptReturnType +} diff --git a/wagmi-project/packages/react/src/hooks/useWalletClient.test-d.ts b/wagmi-project/packages/react/src/hooks/useWalletClient.test-d.ts new file mode 100644 index 000000000..c2ea48bcb --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useWalletClient.test-d.ts @@ -0,0 +1,12 @@ +import { config } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' + +import { useWalletClient } from './useWalletClient.js' + +test('parameters: config', async () => { + const client = useWalletClient({ config }) + expectTypeOf(client.data?.chain?.id!).toEqualTypeOf<1 | 456 | 10>() + + const client2 = useWalletClient({ config, chainId: 1 }) + expectTypeOf(client2.data?.chain?.id!).toEqualTypeOf<1>() +}) diff --git a/wagmi-project/packages/react/src/hooks/useWalletClient.test.tsx b/wagmi-project/packages/react/src/hooks/useWalletClient.test.tsx new file mode 100644 index 000000000..40fdd5850 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useWalletClient.test.tsx @@ -0,0 +1,222 @@ +import { connect, disconnect } from '@wagmi/core' +import { config, wait } from '@wagmi/test' +import { render, renderHook, waitFor } from '@wagmi/test/react' +import * as React from 'react' +import { expect, test } from 'vitest' + +import { useAccount } from './useAccount.js' +import { useConnect } from './useConnect.js' +import { useDisconnect } from './useDisconnect.js' +import { useSwitchChain } from './useSwitchChain.js' +import { useWalletClient } from './useWalletClient.js' + +// Almost identical implementation to `useConnectorClient` (except for return type) +// Should update both in tandem + +const connector = config.connectors[0]! + +test('default', async () => { + const { result } = renderHook(() => useWalletClient()) + + await waitFor(() => expect(result.current.isPending).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": undefined, + "dataUpdatedAt": 0, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": false, + "isFetchedAfterMount": false, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": true, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": false, + "isSuccess": false, + "queryKey": [ + "walletClient", + { + "chainId": 1, + "connectorUid": undefined, + }, + ], + "refetch": [Function], + "status": "pending", + } + `) +}) + +test('behavior: connected on mount', async () => { + await connect(config, { connector }) + + const { result } = renderHook(() => useWalletClient()) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + const { data, queryKey: _, ...rest } = result.current + expect(data).toMatchObject( + expect.objectContaining({ + account: expect.any(Object), + chain: expect.any(Object), + }), + ) + expect(rest).toMatchInlineSnapshot(` + { + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": false, + "isSuccess": true, + "refetch": [Function], + "status": "success", + } + `) + + await disconnect(config, { connector }) +}) + +test('behavior: connect and disconnect', async () => { + const { result } = renderHook(() => ({ + useConnect: useConnect(), + useWalletClient: useWalletClient(), + useDisconnect: useDisconnect(), + })) + + expect(result.current.useWalletClient.data).not.toBeDefined() + + result.current.useConnect.connect({ + connector: result.current.useConnect.connectors[0]!, + }) + + await waitFor(() => expect(result.current.useWalletClient.data).toBeDefined()) + + result.current.useDisconnect.disconnect() + + await waitFor(() => + expect(result.current.useWalletClient.data).not.toBeDefined(), + ) +}) + +test('behavior: switch chains', async () => { + await connect(config, { connector }) + + const { result } = renderHook(() => ({ + useWalletClient: useWalletClient(), + useSwitchChain: useSwitchChain(), + })) + + expect(result.current.useWalletClient.data).not.toBeDefined() + + await waitFor(() => expect(result.current.useWalletClient.data).toBeDefined()) + + result.current.useSwitchChain.switchChain({ chainId: 456 }) + await waitFor(() => { + expect(result.current.useSwitchChain.isSuccess).toBeTruthy() + result.current.useSwitchChain.reset() + }) + expect(result.current.useWalletClient.data?.chain.id).toEqual(456) + + result.current.useSwitchChain.switchChain({ chainId: 1 }) + await waitFor(() => + expect(result.current.useSwitchChain.isSuccess).toBeTruthy(), + ) + expect(result.current.useWalletClient.data?.chain.id).toEqual(1) + + await disconnect(config, { connector }) +}) + +test('behavior: re-render does not invalidate query', async () => { + const { getByTestId } = render() + + getByTestId('connect').click() + await waitFor(() => { + expect(getByTestId('address').innerText).toContain( + '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', + ) + expect(getByTestId('client').innerText).toBeTruthy() + + expect(getByTestId('child-client').innerText).toBeTruthy() + expect(getByTestId('render-count').innerText).toEqual('1') + }) + + const initialClient = getByTestId('child-client').innerText + + getByTestId('rerender').click() + await waitFor(() => { + expect(getByTestId('render-count').innerText).toEqual('2') + }) + await wait(200) + + expect(getByTestId('child-client').innerText).toEqual(initialClient) +}) + +function Parent() { + const [renderCount, setRenderCount] = React.useState(1) + + const { connectors, connect } = useConnect() + const { address } = useAccount() + const { data } = useWalletClient() + + return ( + <> +
{address}
+
{data?.uid}
+ + + + + + ) +} + +function Child(props: { + renderCount: number +}) { + const { renderCount } = props + const { data } = useWalletClient() + return ( +
+ {data?.uid} + {renderCount} +
+ ) +} diff --git a/wagmi-project/packages/react/src/hooks/useWalletClient.ts b/wagmi-project/packages/react/src/hooks/useWalletClient.ts new file mode 100644 index 000000000..24a3bccdd --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useWalletClient.ts @@ -0,0 +1,116 @@ +'use client' + +// Almost identical implementation to `useConnectorClient` (except for return type) +// Should update both in tandem + +import { useQueryClient } from '@tanstack/react-query' +import type { + Config, + GetWalletClientErrorType, + ResolvedRegister, +} from '@wagmi/core' +import type { Compute, Omit } from '@wagmi/core/internal' +import { + type GetWalletClientData, + type GetWalletClientOptions, + type GetWalletClientQueryFnData, + type GetWalletClientQueryKey, + getWalletClientQueryOptions, +} from '@wagmi/core/query' +import { useEffect, useRef } from 'react' + +import type { ConfigParameter } from '../types/properties.js' +import { + type UseQueryParameters, + type UseQueryReturnType, + useQuery, +} from '../utils/query.js' +import { useAccount } from './useAccount.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseWalletClientParameters< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = GetWalletClientData, +> = Compute< + GetWalletClientOptions & + ConfigParameter & { + query?: + | Compute< + Omit< + UseQueryParameters< + GetWalletClientQueryFnData, + GetWalletClientErrorType, + selectData, + GetWalletClientQueryKey + >, + 'gcTime' | 'staleTime' + > + > + | undefined + } +> + +export type UseWalletClientReturnType< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = GetWalletClientData, +> = UseQueryReturnType + +/** https://wagmi.sh/react/api/hooks/useWalletClient */ +export function useWalletClient< + config extends Config = ResolvedRegister['config'], + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = GetWalletClientData, +>( + parameters: UseWalletClientParameters = {}, +): UseWalletClientReturnType { + const { query = {}, ...rest } = parameters + + const config = useConfig(rest) + const queryClient = useQueryClient() + const { address, connector, status } = useAccount({ config }) + const chainId = useChainId({ config }) + const activeConnector = parameters.connector ?? connector + + const { queryKey, ...options } = getWalletClientQueryOptions( + config, + { + ...parameters, + chainId: parameters.chainId ?? chainId, + connector: parameters.connector ?? connector, + }, + ) + const enabled = Boolean( + (status === 'connected' || + (status === 'reconnecting' && activeConnector?.getProvider)) && + (query.enabled ?? true), + ) + + const addressRef = useRef(address) + // biome-ignore lint/correctness/useExhaustiveDependencies: `queryKey` not required + useEffect(() => { + const previousAddress = addressRef.current + if (!address && previousAddress) { + // remove when account is disconnected + queryClient.removeQueries({ queryKey }) + addressRef.current = undefined + } else if (address !== previousAddress) { + // invalidate when address changes + queryClient.invalidateQueries({ queryKey }) + addressRef.current = address + } + }, [address, queryClient]) + + return useQuery({ + ...query, + ...options, + queryKey, + enabled, + staleTime: Number.POSITIVE_INFINITY, + } as any) as UseWalletClientReturnType +} diff --git a/wagmi-project/packages/react/src/hooks/useWatchAsset.test-d.ts b/wagmi-project/packages/react/src/hooks/useWatchAsset.test-d.ts new file mode 100644 index 000000000..0b7258c58 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useWatchAsset.test-d.ts @@ -0,0 +1,66 @@ +import type { WatchAssetErrorType } from '@wagmi/core' +import type { WatchAssetVariables } from '@wagmi/core/query' +import { expectTypeOf, test } from 'vitest' + +import { useWatchAsset } from './useWatchAsset.js' + +const tokenInfo = { + address: '0x0000000000000000000000000000000000000000', + symbol: 'NULL', + decimals: 18, +} +const contextValue = { foo: 'bar' } as const + +test('context', () => { + const { context, data, error, watchAsset, variables } = useWatchAsset({ + mutation: { + onMutate(variables) { + expectTypeOf(variables).toEqualTypeOf() + return contextValue + }, + onError(error, variables, context) { + expectTypeOf(variables).toEqualTypeOf() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSuccess(data, variables, context) { + expectTypeOf(variables).toEqualTypeOf() + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + }, + }) + + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + + watchAsset( + { type: 'ERC20', options: tokenInfo }, + { + onError(error, variables, context) { + expectTypeOf(variables).toEqualTypeOf() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSuccess(data, variables, context) { + expectTypeOf(variables).toEqualTypeOf() + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + }, + ) +}) diff --git a/wagmi-project/packages/react/src/hooks/useWatchAsset.test.ts b/wagmi-project/packages/react/src/hooks/useWatchAsset.test.ts new file mode 100644 index 000000000..989b0323c --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useWatchAsset.test.ts @@ -0,0 +1,27 @@ +import { connect, disconnect } from '@wagmi/core' +import { config } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { expect, test } from 'vitest' + +import { useWatchAsset } from './useWatchAsset.js' + +const connector = config.connectors[0]! + +const tokenInfo = { + address: '0x0000000000000000000000000000000000000000', + symbol: 'NULL', + decimals: 18, +} + +test('default', async () => { + await connect(config, { connector }) + + const { result } = renderHook(() => useWatchAsset()) + + result.current.watchAsset({ type: 'ERC20', options: tokenInfo }) + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current.data).toEqual(true) + + await disconnect(config, { connector }) +}) diff --git a/wagmi-project/packages/react/src/hooks/useWatchAsset.ts b/wagmi-project/packages/react/src/hooks/useWatchAsset.ts new file mode 100644 index 000000000..cda4d6b0b --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useWatchAsset.ts @@ -0,0 +1,65 @@ +'use client' + +import { useMutation } from '@tanstack/react-query' +import type { WatchAssetErrorType } from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type WatchAssetData, + type WatchAssetMutate, + type WatchAssetMutateAsync, + type WatchAssetVariables, + watchAssetMutationOptions, +} from '@wagmi/core/query' + +import type { ConfigParameter } from '../types/properties.js' +import type { + UseMutationParameters, + UseMutationReturnType, +} from '../utils/query.js' +import { useConfig } from './useConfig.js' + +export type UseWatchAssetParameters = Compute< + ConfigParameter & { + mutation?: + | UseMutationParameters< + WatchAssetData, + WatchAssetErrorType, + WatchAssetVariables, + context + > + | undefined + } +> + +export type UseWatchAssetReturnType = Compute< + UseMutationReturnType< + WatchAssetData, + WatchAssetErrorType, + WatchAssetVariables, + context + > & { + watchAsset: WatchAssetMutate + watchAssetAsync: WatchAssetMutateAsync + } +> + +/** https://wagmi.sh/react/api/hooks/useWatchAsset */ +export function useWatchAsset( + parameters: UseWatchAssetParameters = {}, +): UseWatchAssetReturnType { + const { mutation } = parameters + + const config = useConfig(parameters) + + const mutationOptions = watchAssetMutationOptions(config) + const { mutate, mutateAsync, ...result } = useMutation({ + ...mutation, + ...mutationOptions, + }) + + return { + ...result, + watchAsset: mutate, + watchAssetAsync: mutateAsync, + } +} diff --git a/wagmi-project/packages/react/src/hooks/useWatchBlockNumber.test-d.ts b/wagmi-project/packages/react/src/hooks/useWatchBlockNumber.test-d.ts new file mode 100644 index 000000000..0d669725b --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useWatchBlockNumber.test-d.ts @@ -0,0 +1,71 @@ +import { createConfig } from '@wagmi/core' +import { http, webSocket } from 'viem' +import { mainnet, optimism } from 'viem/chains' +import { expectTypeOf, test } from 'vitest' + +import { + type UseWatchBlockNumberParameters, + useWatchBlockNumber, +} from './useWatchBlockNumber.js' + +test('default', () => { + useWatchBlockNumber({ + poll: false, + onBlockNumber() {}, + }) +}) + +test('differing transports', () => { + const config = createConfig({ + chains: [mainnet, optimism], + transports: { + [mainnet.id]: http(), + [optimism.id]: webSocket(), + }, + }) + + type Result = UseWatchBlockNumberParameters< + typeof config, + typeof mainnet.id | typeof optimism.id + > + expectTypeOf().toEqualTypeOf() + useWatchBlockNumber({ + config, + poll: false, + onBlockNumber() {}, + }) + + type Result2 = UseWatchBlockNumberParameters + expectTypeOf().toEqualTypeOf() + useWatchBlockNumber({ + config, + chainId: mainnet.id, + poll: true, + onBlockNumber() {}, + }) + useWatchBlockNumber({ + config, + chainId: mainnet.id, + // @ts-expect-error + poll: false, + onBlockNumber() {}, + }) + + type Result3 = UseWatchBlockNumberParameters< + typeof config, + typeof optimism.id + > + expectTypeOf().toEqualTypeOf() + useWatchBlockNumber({ + config, + chainId: optimism.id, + poll: true, + onBlockNumber() {}, + }) + useWatchBlockNumber({ + config, + chainId: optimism.id, + poll: false, + onBlockNumber() {}, + }) +}) diff --git a/wagmi-project/packages/react/src/hooks/useWatchBlockNumber.test.ts b/wagmi-project/packages/react/src/hooks/useWatchBlockNumber.test.ts new file mode 100644 index 000000000..ecb900b35 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useWatchBlockNumber.test.ts @@ -0,0 +1,28 @@ +import { testClient, wait } from '@wagmi/test' +import { renderHook } from '@wagmi/test/react' +import { expect, test } from 'vitest' + +import { useWatchBlockNumber } from './useWatchBlockNumber.js' + +test('default', async () => { + const blockNumbers: bigint[] = [] + renderHook(() => + useWatchBlockNumber({ + onBlockNumber(blockNumber) { + blockNumbers.push(blockNumber) + }, + }), + ) + + await testClient.mainnet.mine({ blocks: 1 }) + await wait(100) + await testClient.mainnet.mine({ blocks: 1 }) + await wait(100) + await testClient.mainnet.mine({ blocks: 1 }) + await wait(100) + + expect(blockNumbers.length).toBe(3) + expect( + blockNumbers.map((blockNumber) => blockNumber - blockNumbers[0]!), + ).toEqual([0n, 1n, 2n]) +}) diff --git a/wagmi-project/packages/react/src/hooks/useWatchBlockNumber.ts b/wagmi-project/packages/react/src/hooks/useWatchBlockNumber.ts new file mode 100644 index 000000000..33ddac48a --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useWatchBlockNumber.ts @@ -0,0 +1,65 @@ +'use client' + +import { + type Config, + type ResolvedRegister, + type WatchBlockNumberParameters, + watchBlockNumber, +} from '@wagmi/core' +import type { UnionCompute, UnionExactPartial } from '@wagmi/core/internal' +import { useEffect } from 'react' + +import type { ConfigParameter, EnabledParameter } from '../types/properties.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseWatchBlockNumberParameters< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +> = UnionCompute< + UnionExactPartial> & + ConfigParameter & + EnabledParameter +> + +export type UseWatchBlockNumberReturnType = void + +/** https://wagmi.sh/react/api/hooks/useWatchBlockNumber */ +export function useWatchBlockNumber< + config extends Config = ResolvedRegister['config'], + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +>( + parameters: UseWatchBlockNumberParameters = {} as any, +): UseWatchBlockNumberReturnType { + const { enabled = true, onBlockNumber, config: _, ...rest } = parameters + + const config = useConfig(parameters) + const configChainId = useChainId({ config }) + const chainId = parameters.chainId ?? configChainId + + // TODO(react@19): cleanup + // biome-ignore lint/correctness/useExhaustiveDependencies: `rest` changes every render so only including properties in dependency array + useEffect(() => { + if (!enabled) return + if (!onBlockNumber) return + return watchBlockNumber(config, { + ...(rest as any), + chainId, + onBlockNumber, + }) + }, [ + chainId, + config, + enabled, + onBlockNumber, + /// + rest.onError, + rest.emitMissed, + rest.emitOnBegin, + rest.poll, + rest.pollingInterval, + rest.syncConnectedChain, + ]) +} diff --git a/wagmi-project/packages/react/src/hooks/useWatchBlocks.test-d.ts b/wagmi-project/packages/react/src/hooks/useWatchBlocks.test-d.ts new file mode 100644 index 000000000..2051bfb66 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useWatchBlocks.test-d.ts @@ -0,0 +1,73 @@ +import { createConfig } from '@wagmi/core' +import { http, webSocket } from 'viem' +import { mainnet, optimism } from 'viem/chains' +import { expectTypeOf, test } from 'vitest' + +import { + type UseWatchBlocksParameters, + useWatchBlocks, +} from './useWatchBlocks.js' + +test('default', () => { + useWatchBlocks({ + poll: false, + onBlock() {}, + }) +}) + +test('differing transports', () => { + const config = createConfig({ + chains: [mainnet, optimism], + transports: { + [mainnet.id]: http(), + [optimism.id]: webSocket(), + }, + }) + + type Result = UseWatchBlocksParameters< + false, + 'latest', + typeof config, + typeof mainnet.id | typeof optimism.id + > + expectTypeOf().toEqualTypeOf() + useWatchBlocks({ + config, + poll: false, + onBlock() {}, + }) + + type Result2 = UseWatchBlocksParameters< + false, + 'latest', + typeof config, + typeof mainnet.id + > + expectTypeOf().toEqualTypeOf() + useWatchBlocks({ + config, + chainId: mainnet.id, + poll: true, + onBlock() {}, + }) + + type Result3 = UseWatchBlocksParameters< + false, + 'latest', + typeof config, + typeof optimism.id + > + expectTypeOf().toEqualTypeOf() + useWatchBlocks({ + config, + chainId: optimism.id, + poll: true, + onBlock() {}, + }) + useWatchBlocks({ + config, + chainId: optimism.id, + poll: false, + onBlock() {}, + }) +}) diff --git a/wagmi-project/packages/react/src/hooks/useWatchBlocks.test.ts b/wagmi-project/packages/react/src/hooks/useWatchBlocks.test.ts new file mode 100644 index 000000000..039c71883 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useWatchBlocks.test.ts @@ -0,0 +1,31 @@ +import { testClient, wait } from '@wagmi/test' +import { renderHook } from '@wagmi/test/react' +import type { Block } from 'viem' +import { expect, test } from 'vitest' + +import { useWatchBlocks } from './useWatchBlocks.js' + +test('default', async () => { + const blocks: Block[] = [] + renderHook(() => + useWatchBlocks({ + onBlock(block) { + blocks.push(block) + }, + }), + ) + + await testClient.mainnet.mine({ blocks: 1 }) + await wait(100) + await testClient.mainnet.mine({ blocks: 1 }) + await wait(100) + await testClient.mainnet.mine({ blocks: 1 }) + await wait(100) + + expect(blocks.length).toBe(3) + expect(blocks.map((block) => block.number! - blocks[0]!.number!)).toEqual([ + 0n, + 1n, + 2n, + ]) +}) diff --git a/wagmi-project/packages/react/src/hooks/useWatchBlocks.ts b/wagmi-project/packages/react/src/hooks/useWatchBlocks.ts new file mode 100644 index 000000000..466929c84 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useWatchBlocks.ts @@ -0,0 +1,79 @@ +'use client' + +import { + type Config, + type ResolvedRegister, + type WatchBlocksParameters, + watchBlocks, +} from '@wagmi/core' +import type { UnionCompute, UnionExactPartial } from '@wagmi/core/internal' +import { useEffect } from 'react' +import type { BlockTag } from 'viem' + +import type { ConfigParameter, EnabledParameter } from '../types/properties.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseWatchBlocksParameters< + includeTransactions extends boolean = false, + blockTag extends BlockTag = 'latest', + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +> = UnionCompute< + UnionExactPartial< + WatchBlocksParameters + > & + ConfigParameter & + EnabledParameter +> + +export type UseWatchBlocksReturnType = void + +/** https://wagmi.sh/react/hooks/useWatchBlocks */ +export function useWatchBlocks< + config extends Config = ResolvedRegister['config'], + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + includeTransactions extends boolean = false, + blockTag extends BlockTag = 'latest', +>( + parameters: UseWatchBlocksParameters< + includeTransactions, + blockTag, + config, + chainId + > = {} as any, +): UseWatchBlocksReturnType { + const { enabled = true, onBlock, config: _, ...rest } = parameters + + const config = useConfig(parameters) + const configChainId = useChainId({ config }) + const chainId = parameters.chainId ?? configChainId + + // TODO(react@19): cleanup + // biome-ignore lint/correctness/useExhaustiveDependencies: `rest` changes every render so only including properties in dependency array + useEffect(() => { + if (!enabled) return + if (!onBlock) return + return watchBlocks(config, { + ...(rest as any), + chainId, + onBlock, + }) + }, [ + chainId, + config, + enabled, + onBlock, + /// + rest.blockTag, + rest.emitMissed, + rest.emitOnBegin, + rest.includeTransactions, + rest.onError, + rest.poll, + rest.pollingInterval, + rest.syncConnectedChain, + ]) +} diff --git a/wagmi-project/packages/react/src/hooks/useWatchContractEvent.test-d.ts b/wagmi-project/packages/react/src/hooks/useWatchContractEvent.test-d.ts new file mode 100644 index 000000000..b1d74de45 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useWatchContractEvent.test-d.ts @@ -0,0 +1,128 @@ +import { http, createConfig, webSocket } from '@wagmi/core' +import { mainnet, optimism } from '@wagmi/core/chains' +import { abi } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' + +import { + type UseWatchContractEventParameters, + useWatchContractEvent, +} from './useWatchContractEvent.js' + +test('default', () => { + useWatchContractEvent({ + address: '0x', + abi: abi.erc20, + eventName: 'Transfer', + poll: false, + args: { + from: '0x', + to: '0x', + }, + onLogs(logs) { + expectTypeOf(logs[0]!.eventName).toEqualTypeOf<'Transfer'>() + expectTypeOf(logs[0]!.args).toEqualTypeOf<{ + from?: `0x${string}` | undefined + to?: `0x${string}` | undefined + value?: bigint | undefined + }>() + }, + }) +}) + +test('behavior: no eventName', () => { + useWatchContractEvent({ + address: '0x', + abi: abi.erc20, + args: { + // TODO: Figure out why this is not working + // @ts-ignore + from: '0x', + to: '0x', + }, + onLogs(logs) { + expectTypeOf(logs[0]!.eventName).toEqualTypeOf<'Transfer' | 'Approval'>() + expectTypeOf(logs[0]!.args).toEqualTypeOf< + | Record + | readonly unknown[] + | { + from?: `0x${string}` | undefined + to?: `0x${string}` | undefined + value?: bigint | undefined + } + | { + owner?: `0x${string}` | undefined + spender?: `0x${string}` | undefined + value?: bigint | undefined + } + >() + }, + }) +}) + +test('differing transports', () => { + const config = createConfig({ + chains: [mainnet, optimism], + transports: { + [mainnet.id]: http(), + [optimism.id]: webSocket(), + }, + }) + + type Result = UseWatchContractEventParameters< + typeof abi.erc20, + 'Transfer' | 'Approval', + true, + typeof config, + typeof mainnet.id | typeof optimism.id + > + expectTypeOf().toEqualTypeOf() + useWatchContractEvent({ + config, + poll: false, + address: '0x', + abi: abi.erc20, + onLogs() {}, + }) + + type Result2 = UseWatchContractEventParameters< + typeof abi.erc20, + 'Transfer' | 'Approval', + true, + typeof config, + typeof mainnet.id + > + expectTypeOf().toEqualTypeOf() + useWatchContractEvent({ + config, + chainId: mainnet.id, + poll: true, + address: '0x', + abi: abi.erc20, + onLogs() {}, + }) + + type Result3 = UseWatchContractEventParameters< + typeof abi.erc20, + 'Transfer' | 'Approval', + true, + typeof config, + typeof optimism.id + > + expectTypeOf().toEqualTypeOf() + useWatchContractEvent({ + config, + chainId: optimism.id, + poll: true, + address: '0x', + abi: abi.erc20, + onLogs() {}, + }) + useWatchContractEvent({ + config, + chainId: optimism.id, + poll: false, + address: '0x', + abi: abi.erc20, + onLogs() {}, + }) +}) diff --git a/wagmi-project/packages/react/src/hooks/useWatchContractEvent.test.ts b/wagmi-project/packages/react/src/hooks/useWatchContractEvent.test.ts new file mode 100644 index 000000000..e6ad2aa1d --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useWatchContractEvent.test.ts @@ -0,0 +1,86 @@ +import { connect, disconnect, getBalance, writeContract } from '@wagmi/core' +import { + abi, + accounts, + address, + config, + testClient, + transactionHashRegex, + wait, +} from '@wagmi/test' +import { renderHook } from '@wagmi/test/react' +import { http, createWalletClient, parseEther } from 'viem' +import type { WatchEventOnLogsParameter } from 'viem/actions' +import { expect, test } from 'vitest' + +import { useWatchContractEvent } from './useWatchContractEvent.js' + +const connector = config.connectors[0]! + +test('default', async () => { + const data = await connect(config, { connector }) + const connectedAddress = data.accounts[0] + + // impersonate usdc holder account and transfer usdc to connected account + await testClient.mainnet.impersonateAccount({ address: address.usdcHolder }) + await testClient.mainnet.setBalance({ + address: address.usdcHolder, + value: 10000000000000000000000n, + }) + await createWalletClient({ + account: address.usdcHolder, + chain: testClient.mainnet.chain, + transport: http(), + }).writeContract({ + address: address.usdc, + abi: abi.erc20, + functionName: 'transfer', + args: [connectedAddress, parseEther('10', 'gwei')], + }) + await testClient.mainnet.mine({ blocks: 1 }) + await testClient.mainnet.stopImpersonatingAccount({ + address: address.usdcHolder, + }) + + const balance = await getBalance(config, { + address: connectedAddress, + token: address.usdc, + }) + expect(balance.value).toBeGreaterThan(0n) + + // start watching transfer events + let logs: WatchEventOnLogsParameter = [] + renderHook(() => + useWatchContractEvent({ + address: address.usdc, + abi: abi.erc20, + eventName: 'Transfer', + onLogs(next) { + logs = logs.concat(next) + }, + }), + ) + + await writeContract(config, { + address: address.usdc, + abi: abi.erc20, + functionName: 'transfer', + args: [accounts[1], parseEther('1', 'gwei')], + }) + + await writeContract(config, { + address: address.usdc, + abi: abi.erc20, + functionName: 'transfer', + args: [accounts[3], parseEther('1', 'gwei')], + }) + + await testClient.mainnet.mine({ blocks: 1 }) + await testClient.mainnet.mine({ blocks: 1 }) + await wait(1000) // wait for events to be emitted + + expect(logs.length).toBe(2) + expect(logs[0]?.transactionHash).toMatch(transactionHashRegex) + + await disconnect(config, { connector }) +}) diff --git a/wagmi-project/packages/react/src/hooks/useWatchContractEvent.ts b/wagmi-project/packages/react/src/hooks/useWatchContractEvent.ts new file mode 100644 index 000000000..0d7710df2 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useWatchContractEvent.ts @@ -0,0 +1,85 @@ +'use client' + +import { + type Config, + type ResolvedRegister, + type WatchContractEventParameters, + watchContractEvent, +} from '@wagmi/core' +import type { UnionCompute, UnionExactPartial } from '@wagmi/core/internal' +import { useEffect } from 'react' +import type { Abi, ContractEventName } from 'viem' + +import type { ConfigParameter, EnabledParameter } from '../types/properties.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseWatchContractEventParameters< + abi extends Abi | readonly unknown[] = Abi, + eventName extends ContractEventName = ContractEventName, + strict extends boolean | undefined = undefined, + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +> = UnionCompute< + UnionExactPartial< + WatchContractEventParameters + > & + ConfigParameter & + EnabledParameter +> + +export type UseWatchContractEventReturnType = void + +/** https://wagmi.sh/react/api/hooks/useWatchContractEvent */ +export function useWatchContractEvent< + const abi extends Abi | readonly unknown[], + eventName extends ContractEventName, + strict extends boolean | undefined = undefined, + config extends Config = ResolvedRegister['config'], + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +>( + parameters: UseWatchContractEventParameters< + abi, + eventName, + strict, + config, + chainId + > = {} as any, +): UseWatchContractEventReturnType { + const { enabled = true, onLogs, config: _, ...rest } = parameters + + const config = useConfig(parameters) + const configChainId = useChainId({ config }) + const chainId = parameters.chainId ?? configChainId + + // TODO(react@19): cleanup + // biome-ignore lint/correctness/useExhaustiveDependencies: `rest` changes every render so only including properties in dependency array + useEffect(() => { + if (!enabled) return + if (!onLogs) return + return watchContractEvent(config, { + ...(rest as any), + chainId, + onLogs, + }) + }, [ + chainId, + config, + enabled, + onLogs, + /// + rest.abi, + rest.address, + rest.args, + rest.batch, + rest.eventName, + rest.fromBlock, + rest.onError, + rest.poll, + rest.pollingInterval, + rest.strict, + rest.syncConnectedChain, + ]) +} diff --git a/wagmi-project/packages/react/src/hooks/useWatchPendingTransactions.test-d.ts b/wagmi-project/packages/react/src/hooks/useWatchPendingTransactions.test-d.ts new file mode 100644 index 000000000..56ccc49cb --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useWatchPendingTransactions.test-d.ts @@ -0,0 +1,67 @@ +import { createConfig } from '@wagmi/core' +import { http, webSocket } from 'viem' +import { mainnet, optimism } from 'viem/chains' +import { expectTypeOf, test } from 'vitest' + +import { + type UseWatchPendingTransactionsParameters, + useWatchPendingTransactions, +} from './useWatchPendingTransactions.js' + +test('default', () => { + useWatchPendingTransactions({ + poll: false, + onTransactions() {}, + }) +}) + +test('differing transports', () => { + const config = createConfig({ + chains: [mainnet, optimism], + transports: { + [mainnet.id]: http(), + [optimism.id]: webSocket(), + }, + }) + + type Result = UseWatchPendingTransactionsParameters< + typeof config, + typeof mainnet.id | typeof optimism.id + > + expectTypeOf().toEqualTypeOf() + useWatchPendingTransactions({ + config, + poll: false, + onTransactions() {}, + }) + + type Result2 = UseWatchPendingTransactionsParameters< + typeof config, + typeof mainnet.id + > + expectTypeOf().toEqualTypeOf() + useWatchPendingTransactions({ + config, + chainId: mainnet.id, + poll: true, + onTransactions() {}, + }) + + type Result3 = UseWatchPendingTransactionsParameters< + typeof config, + typeof optimism.id + > + expectTypeOf().toEqualTypeOf() + useWatchPendingTransactions({ + config, + chainId: optimism.id, + poll: true, + onTransactions() {}, + }) + useWatchPendingTransactions({ + config, + chainId: optimism.id, + poll: false, + onTransactions() {}, + }) +}) diff --git a/wagmi-project/packages/react/src/hooks/useWatchPendingTransactions.test.ts b/wagmi-project/packages/react/src/hooks/useWatchPendingTransactions.test.ts new file mode 100644 index 000000000..e1981f3fa --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useWatchPendingTransactions.test.ts @@ -0,0 +1,49 @@ +import { connect, disconnect, sendTransaction } from '@wagmi/core' +import { + accounts, + config, + testClient, + transactionHashRegex, + wait, +} from '@wagmi/test' +import { renderHook } from '@wagmi/test/react' +import { parseEther } from 'viem' +import type { OnTransactionsParameter } from 'viem/actions' +import { expect, test } from 'vitest' + +import { useWatchPendingTransactions } from './useWatchPendingTransactions.js' + +const connector = config.connectors[0]! + +test('default', async () => { + await connect(config, { connector }) + + let transactions: OnTransactionsParameter = [] + renderHook(() => + useWatchPendingTransactions({ + onTransactions(next) { + transactions = [...transactions, ...next] + }, + }), + ) + await wait(1000) + + await sendTransaction(config, { + to: accounts[1], + value: parseEther('1'), + }) + await wait(200) + + await sendTransaction(config, { + to: accounts[3], + value: parseEther('1'), + }) + await wait(200) + + await testClient.mainnet.mine({ blocks: 1 }) + + expect(transactions.length).toBe(2) + expect(transactions[0]).toMatch(transactionHashRegex) + + await disconnect(config, { connector }) +}) diff --git a/wagmi-project/packages/react/src/hooks/useWatchPendingTransactions.ts b/wagmi-project/packages/react/src/hooks/useWatchPendingTransactions.ts new file mode 100644 index 000000000..7461ffcfb --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useWatchPendingTransactions.ts @@ -0,0 +1,67 @@ +'use client' + +import { + type Config, + type ResolvedRegister, + type WatchPendingTransactionsParameters, + watchPendingTransactions, +} from '@wagmi/core' +import type { UnionCompute, UnionExactPartial } from '@wagmi/core/internal' +import { useEffect } from 'react' + +import type { ConfigParameter, EnabledParameter } from '../types/properties.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseWatchPendingTransactionsParameters< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +> = UnionCompute< + UnionExactPartial> & + ConfigParameter & + EnabledParameter +> + +export type UseWatchPendingTransactionsReturnType = void + +/** https://wagmi.sh/react/api/hooks/useWatchPendingTransactions */ +export function useWatchPendingTransactions< + config extends Config = ResolvedRegister['config'], + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +>( + parameters: UseWatchPendingTransactionsParameters< + config, + chainId + > = {} as any, +): UseWatchPendingTransactionsReturnType { + const { enabled = true, onTransactions, config: _, ...rest } = parameters + + const config = useConfig(parameters) + const configChainId = useChainId({ config }) + const chainId = parameters.chainId ?? configChainId + + // TODO(react@19): cleanup + // biome-ignore lint/correctness/useExhaustiveDependencies: `rest` changes every render so only including properties in dependency array + useEffect(() => { + if (!enabled) return + if (!onTransactions) return + return watchPendingTransactions(config, { + ...(rest as any), + chainId, + onTransactions, + }) + }, [ + chainId, + config, + enabled, + onTransactions, + /// + rest.batch, + rest.onError, + rest.poll, + rest.pollingInterval, + rest.syncConnectedChain, + ]) +} diff --git a/wagmi-project/packages/react/src/hooks/useWriteContract.test-d.ts b/wagmi-project/packages/react/src/hooks/useWriteContract.test-d.ts new file mode 100644 index 000000000..344c11255 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useWriteContract.test-d.ts @@ -0,0 +1,185 @@ +import { http, type WriteContractErrorType, createConfig } from '@wagmi/core' +import { base } from '@wagmi/core/chains' +import { abi } from '@wagmi/test' +import type { Abi, Address, Hash } from 'viem' +import { expectTypeOf, test } from 'vitest' + +import { useSimulateContract } from './useSimulateContract.js' +import { useWriteContract } from './useWriteContract.js' + +const contextValue = { foo: 'bar' } as const + +test('context', () => { + const { + context, + data, + error, + writeContract: write, + variables, + } = useWriteContract({ + mutation: { + onMutate(variables) { + expectTypeOf(variables).toMatchTypeOf<{ + chainId?: number | undefined + abi: Abi + functionName: string + args?: readonly unknown[] | undefined + }>() + return contextValue + }, + onError(error, variables, context) { + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + + expectTypeOf(variables).toMatchTypeOf<{ + chainId?: number | undefined + abi: Abi + functionName: string + args?: readonly unknown[] | undefined + }>() + }, + onSuccess(data, variables, context) { + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + + expectTypeOf(variables).toMatchTypeOf<{ + chainId?: number | undefined + abi: Abi + functionName: string + args?: readonly unknown[] | undefined + }>() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + + expectTypeOf(variables).toMatchTypeOf<{ + chainId?: number | undefined + abi: Abi + functionName: string + args?: readonly unknown[] | undefined + }>() + }, + }, + }) + + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toMatchTypeOf< + { chainId?: number | undefined } | undefined + >() + expectTypeOf(context).toEqualTypeOf() + + write( + { + address: '0x', + abi: abi.erc20, + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + chainId: 1, + }, + { + onError(error, variables, context) { + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + + expectTypeOf(variables).toMatchTypeOf<{ + chainId?: number | undefined + abi: typeof abi.erc20 + functionName: 'transferFrom' + args: readonly [Address, Address, bigint] + }>() + }, + onSuccess(data, variables, context) { + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + + expectTypeOf(variables.functionName).toEqualTypeOf<'transferFrom'>() + expectTypeOf(variables.args).toEqualTypeOf< + readonly [Address, Address, bigint] + >() + expectTypeOf(variables).toMatchTypeOf<{ + chainId?: number | undefined + abi: typeof abi.erc20 + functionName: 'transferFrom' + args: readonly [Address, Address, bigint] + }>() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + + expectTypeOf(variables).toMatchTypeOf<{ + chainId?: number | undefined + abi: typeof abi.erc20 + functionName: 'transferFrom' + args: readonly [Address, Address, bigint] + }>() + }, + }, + ) +}) + +test('useSimulateContract', () => { + const { data } = useSimulateContract({ + address: '0x', + abi: abi.erc20, + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + chainId: 1, + }) + const { writeContract } = useWriteContract() + + const request = data?.request + if (request) writeContract(request) +}) + +// https://github.com/wevm/wagmi/issues/3981 +test('gh#3981', () => { + const config = createConfig({ + chains: [base], + transports: { + [base.id]: http(), + }, + }) + + const abi = [ + { + type: 'function', + name: 'example1', + inputs: [ + { name: 'exampleName', type: 'address', internalType: 'address' }, + ], + outputs: [], + stateMutability: 'payable', + }, + { + type: 'function', + name: 'example2', + inputs: [ + { name: 'exampleName', type: 'address', internalType: 'address' }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + ] as const + + const { writeContract } = useWriteContract({ config }) + writeContract({ + abi, + address: '0x...', + functionName: 'example1', + args: ['0x...'], + value: 123n, + }) + writeContract({ + abi, + address: '0x...', + functionName: 'example2', + args: ['0x...'], + // @ts-expect-error + value: 123n, + }) +}) diff --git a/wagmi-project/packages/react/src/hooks/useWriteContract.test.ts b/wagmi-project/packages/react/src/hooks/useWriteContract.test.ts new file mode 100644 index 000000000..16ef870c2 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useWriteContract.test.ts @@ -0,0 +1,25 @@ +import { connect, disconnect } from '@wagmi/core' +import { abi, address, config } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { expect, test } from 'vitest' + +import { useWriteContract } from './useWriteContract.js' + +const connector = config.connectors[0]! + +test('default', async () => { + await connect(config, { connector }) + + const { result } = renderHook(() => useWriteContract()) + + result.current.writeContract({ + abi: abi.wagmiMintExample, + address: address.wagmiMintExample, + functionName: 'mint', + }) + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current.data).toBeDefined() + + await disconnect(config, { connector }) +}) diff --git a/wagmi-project/packages/react/src/hooks/useWriteContract.ts b/wagmi-project/packages/react/src/hooks/useWriteContract.ts new file mode 100644 index 000000000..b07e856c9 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useWriteContract.ts @@ -0,0 +1,87 @@ +'use client' + +import { useMutation } from '@tanstack/react-query' +import type { + Config, + ResolvedRegister, + WriteContractErrorType, +} from '@wagmi/core' +import { + type WriteContractData, + type WriteContractMutate, + type WriteContractMutateAsync, + type WriteContractVariables, + writeContractMutationOptions, +} from '@wagmi/core/query' +import type { Abi } from 'viem' + +import type { ConfigParameter } from '../types/properties.js' +import type { + UseMutationParameters, + UseMutationReturnType, +} from '../utils/query.js' +import { useConfig } from './useConfig.js' + +export type UseWriteContractParameters< + config extends Config = Config, + context = unknown, +> = ConfigParameter & { + mutation?: + | UseMutationParameters< + WriteContractData, + WriteContractErrorType, + WriteContractVariables< + Abi, + string, + readonly unknown[], + config, + config['chains'][number]['id'] + >, + context + > + | undefined +} + +export type UseWriteContractReturnType< + config extends Config = Config, + context = unknown, +> = UseMutationReturnType< + WriteContractData, + WriteContractErrorType, + WriteContractVariables< + Abi, + string, + readonly unknown[], + config, + config['chains'][number]['id'] + >, + context +> & { + writeContract: WriteContractMutate + writeContractAsync: WriteContractMutateAsync +} + +/** https://wagmi.sh/react/api/hooks/useWriteContract */ +export function useWriteContract< + config extends Config = ResolvedRegister['config'], + context = unknown, +>( + parameters: UseWriteContractParameters = {}, +): UseWriteContractReturnType { + const { mutation } = parameters + + const config = useConfig(parameters) + + const mutationOptions = writeContractMutationOptions(config) + const { mutate, mutateAsync, ...result } = useMutation({ + ...mutation, + ...mutationOptions, + }) + + type Return = UseWriteContractReturnType + return { + ...result, + writeContract: mutate as Return['writeContract'], + writeContractAsync: mutateAsync as Return['writeContractAsync'], + } +} diff --git a/wagmi-project/packages/react/src/hydrate.ts b/wagmi-project/packages/react/src/hydrate.ts new file mode 100644 index 000000000..b185929c2 --- /dev/null +++ b/wagmi-project/packages/react/src/hydrate.ts @@ -0,0 +1,36 @@ +'use client' + +import { type ResolvedRegister, type State, hydrate } from '@wagmi/core' +import { type ReactElement, useEffect, useRef } from 'react' + +export type HydrateProps = { + config: ResolvedRegister['config'] + initialState?: State | undefined + reconnectOnMount?: boolean | undefined +} + +export function Hydrate(parameters: React.PropsWithChildren) { + const { children, config, initialState, reconnectOnMount = true } = parameters + + const { onMount } = hydrate(config, { + initialState, + reconnectOnMount, + }) + + // Hydrate for non-SSR + if (!config._internal.ssr) onMount() + + // Hydrate for SSR + const active = useRef(true) + // biome-ignore lint/correctness/useExhaustiveDependencies: `queryKey` not required + useEffect(() => { + if (!active.current) return + if (!config._internal.ssr) return + onMount() + return () => { + active.current = false + } + }, []) + + return children as ReactElement +} diff --git a/wagmi-project/packages/react/src/types/properties.ts b/wagmi-project/packages/react/src/types/properties.ts new file mode 100644 index 000000000..7d903faf0 --- /dev/null +++ b/wagmi-project/packages/react/src/types/properties.ts @@ -0,0 +1,51 @@ +import type { DefaultError, QueryKey } from '@tanstack/react-query' +import type { Config } from '@wagmi/core' +import type { Omit } from '@wagmi/core/internal' + +import type { + UseInfiniteQueryParameters, + UseQueryParameters, +} from '../utils/query.js' + +export type EnabledParameter = { + enabled?: boolean | undefined +} + +export type ConfigParameter = { + config?: Config | config | undefined +} + +export type QueryParameter< + queryFnData = unknown, + error = DefaultError, + data = queryFnData, + queryKey extends QueryKey = QueryKey, +> = { + query?: + | Omit< + UseQueryParameters, + 'queryFn' | 'queryHash' | 'queryKey' | 'queryKeyHashFn' | 'throwOnError' + > + | undefined +} + +export type InfiniteQueryParameter< + queryFnData = unknown, + error = DefaultError, + data = queryFnData, + queryData = queryFnData, + queryKey extends QueryKey = QueryKey, + pageParam = unknown, +> = { + query: Omit< + UseInfiniteQueryParameters< + queryFnData, + error, + data, + queryData, + queryKey, + pageParam + >, + 'queryFn' | 'queryHash' | 'queryKey' | 'queryKeyHashFn' | 'throwOnError' + > +} diff --git a/wagmi-project/packages/react/src/utils/getVersion.test.ts b/wagmi-project/packages/react/src/utils/getVersion.test.ts new file mode 100644 index 000000000..e8368face --- /dev/null +++ b/wagmi-project/packages/react/src/utils/getVersion.test.ts @@ -0,0 +1,7 @@ +import { expect, test } from 'vitest' + +import { getVersion } from './getVersion.js' + +test('default', () => { + expect(getVersion()).toMatchInlineSnapshot(`"wagmi@x.y.z"`) +}) diff --git a/wagmi-project/packages/react/src/utils/getVersion.ts b/wagmi-project/packages/react/src/utils/getVersion.ts new file mode 100644 index 000000000..1a8a9437b --- /dev/null +++ b/wagmi-project/packages/react/src/utils/getVersion.ts @@ -0,0 +1,3 @@ +import { version } from '../version.js' + +export const getVersion = () => `wagmi@${version}` diff --git a/wagmi-project/packages/react/src/utils/query.ts b/wagmi-project/packages/react/src/utils/query.ts new file mode 100644 index 000000000..3aafb1612 --- /dev/null +++ b/wagmi-project/packages/react/src/utils/query.ts @@ -0,0 +1,145 @@ +import { + type DefaultError, + type QueryKey, + type UseInfiniteQueryOptions, + type UseInfiniteQueryResult, + type UseMutationOptions, + type UseMutationResult, + type UseQueryOptions, + type UseQueryResult, + useInfiniteQuery as tanstack_useInfiniteQuery, + useQuery as tanstack_useQuery, + useMutation, +} from '@tanstack/react-query' +import type { + Compute, + ExactPartial, + Omit, + UnionStrictOmit, +} from '@wagmi/core/internal' +import { hashFn } from '@wagmi/core/query' + +export type UseMutationParameters< + data = unknown, + error = Error, + variables = void, + context = unknown, +> = Compute< + Omit< + UseMutationOptions, context>, + 'mutationFn' | 'mutationKey' | 'throwOnError' + > +> + +export type UseMutationReturnType< + data = unknown, + error = Error, + variables = void, + context = unknown, +> = Compute< + UnionStrictOmit< + UseMutationResult, + 'mutate' | 'mutateAsync' + > +> + +export { useMutation } + +//////////////////////////////////////////////////////////////////////////////// + +export type UseQueryParameters< + queryFnData = unknown, + error = DefaultError, + data = queryFnData, + queryKey extends QueryKey = QueryKey, +> = Compute< + ExactPartial< + Omit, 'initialData'> + > & { + // Fix `initialData` type + initialData?: + | UseQueryOptions['initialData'] + | undefined + } +> + +export type UseQueryReturnType = Compute< + UseQueryResult & { + queryKey: QueryKey + } +> + +// Adding some basic customization. +// Ideally we don't have this function, but `import('@tanstack/react-query').useQuery` currently has some quirks where it is super hard to +// pass down the inferred `initialData` type because of it's discriminated overload in the on `useQuery`. +export function useQuery( + parameters: UseQueryParameters & { + queryKey: QueryKey + }, +): UseQueryReturnType { + const result = tanstack_useQuery({ + ...(parameters as any), + queryKeyHashFn: hashFn, // for bigint support + }) as UseQueryReturnType + result.queryKey = parameters.queryKey + return result +} + +//////////////////////////////////////////////////////////////////////////////// + +export type UseInfiniteQueryParameters< + queryFnData = unknown, + error = DefaultError, + data = queryFnData, + queryData = queryFnData, + queryKey extends QueryKey = QueryKey, + pageParam = unknown, +> = Compute< + Omit< + UseInfiniteQueryOptions< + queryFnData, + error, + data, + queryData, + queryKey, + pageParam + >, + 'initialData' + > & { + // Fix `initialData` type + initialData?: + | UseInfiniteQueryOptions< + queryFnData, + error, + data, + queryKey + >['initialData'] + | undefined + } +> + +export type UseInfiniteQueryReturnType< + data = unknown, + error = DefaultError, +> = UseInfiniteQueryResult & { + queryKey: QueryKey +} + +// Adding some basic customization. +export function useInfiniteQuery< + queryFnData, + error, + data, + queryKey extends QueryKey, +>( + parameters: UseInfiniteQueryParameters & { + queryKey: QueryKey + }, +): UseInfiniteQueryReturnType { + const result = tanstack_useInfiniteQuery({ + ...(parameters as any), + queryKeyHashFn: hashFn, // for bigint support + }) as UseInfiniteQueryReturnType + result.queryKey = parameters.queryKey + return result +} diff --git a/wagmi-project/packages/react/src/version.ts b/wagmi-project/packages/react/src/version.ts new file mode 100644 index 000000000..0ec209c46 --- /dev/null +++ b/wagmi-project/packages/react/src/version.ts @@ -0,0 +1 @@ +export const version = '2.15.4' diff --git a/wagmi-project/packages/react/test/setup.ts b/wagmi-project/packages/react/test/setup.ts new file mode 100644 index 000000000..5c0dcc071 --- /dev/null +++ b/wagmi-project/packages/react/test/setup.ts @@ -0,0 +1,8 @@ +import { vi } from 'vitest' + +// Make dates stable across runs +Date.now = vi.fn(() => new Date(Date.UTC(2023, 1, 1)).valueOf()) + +vi.mock('../src/version.ts', () => { + return { version: 'x.y.z' } +}) diff --git a/wagmi-project/packages/react/tsconfig.build.json b/wagmi-project/packages/react/tsconfig.build.json new file mode 100644 index 000000000..fbed2b103 --- /dev/null +++ b/wagmi-project/packages/react/tsconfig.build.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.base.json", + "include": ["src/**/*.ts"], + "exclude": ["src/**/*.test.ts", "src/**/*.test-d.ts"], + "compilerOptions": { + "sourceMap": true + } +} diff --git a/wagmi-project/packages/react/tsconfig.json b/wagmi-project/packages/react/tsconfig.json new file mode 100644 index 000000000..1b247fdd4 --- /dev/null +++ b/wagmi-project/packages/react/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "./tsconfig.build.json", + "compilerOptions": { + "jsx": "preserve" + }, + "include": ["src/**/*.ts", "src/**/*.tsx", "test/**/*.ts", "test/**/*.tsx"], + "exclude": [] +} diff --git a/wagmi-project/packages/register-tests/react/package.json b/wagmi-project/packages/register-tests/react/package.json new file mode 100644 index 000000000..769092f95 --- /dev/null +++ b/wagmi-project/packages/register-tests/react/package.json @@ -0,0 +1,16 @@ +{ + "name": "react-register", + "private": true, + "type": "module", + "scripts": { + "check:types": "tsc --noEmit" + }, + "dependencies": { + "@tanstack/react-query": "catalog:", + "react": "catalog:", + "wagmi": "workspace:*" + }, + "devDependencies": { + "@types/react": "catalog:" + } +} diff --git a/wagmi-project/packages/register-tests/react/src/config.ts b/wagmi-project/packages/register-tests/react/src/config.ts new file mode 100644 index 000000000..5772212c1 --- /dev/null +++ b/wagmi-project/packages/register-tests/react/src/config.ts @@ -0,0 +1,26 @@ +import { http } from 'viem' +import { createConfig, mock } from 'wagmi' +import { celo, mainnet, optimism, zkSync } from 'wagmi/chains' + +export const config = createConfig({ + chains: [celo, mainnet, optimism, zkSync], + connectors: [mock({ accounts: ['0x'] })], + transports: { + [celo.id]: http(), + [mainnet.id]: http(), + [optimism.id]: http(), + [zkSync.id]: http(), + }, +}) + +export type ChainId = + | typeof celo.id + | typeof mainnet.id + | typeof optimism.id + | typeof zkSync.id + +declare module 'wagmi' { + interface Register { + config: typeof config + } +} diff --git a/wagmi-project/packages/register-tests/react/src/createUseSimulateContract.test-d.ts b/wagmi-project/packages/register-tests/react/src/createUseSimulateContract.test-d.ts new file mode 100644 index 000000000..b469ccd02 --- /dev/null +++ b/wagmi-project/packages/register-tests/react/src/createUseSimulateContract.test-d.ts @@ -0,0 +1,39 @@ +import { abi, config as testConfig } from '@wagmi/test' +import { test } from 'vitest' +import { celo, mainnet, optimism } from 'wagmi/chains' +import { createUseSimulateContract } from 'wagmi/codegen' + +const useSimulateErc20 = createUseSimulateContract({ + abi: abi.erc20, +}) + +test('chain formatters', () => { + useSimulateErc20({ + feeCurrency: '0x', + }) + + useSimulateErc20({ + chainId: celo.id, + feeCurrency: '0x', + }) + + useSimulateErc20({ + chainId: mainnet.id, + // @ts-expect-error + feeCurrency: '0x', + }) + + useSimulateErc20({ + chainId: optimism.id, + // @ts-expect-error + feeCurrency: '0x', + }) +}) + +test('parameters: config', async () => { + useSimulateErc20({ + config: testConfig, + // @ts-expect-error + feeCurrency: '0x', + }) +}) diff --git a/wagmi-project/packages/register-tests/react/src/createUseWriteContract.test-d.ts b/wagmi-project/packages/register-tests/react/src/createUseWriteContract.test-d.ts new file mode 100644 index 000000000..0b6c53813 --- /dev/null +++ b/wagmi-project/packages/register-tests/react/src/createUseWriteContract.test-d.ts @@ -0,0 +1,66 @@ +import { abi, config } from '@wagmi/test' +import type { Address } from 'viem' +import { expectTypeOf, test } from 'vitest' +import { celo, mainnet, optimism } from 'wagmi/chains' +import { createUseWriteContract } from 'wagmi/codegen' + +const useWriteErc20 = createUseWriteContract({ + abi: abi.erc20, +}) + +test('chain formatters', () => { + const { writeContract } = useWriteErc20() + const shared = { + address: '0x', + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + } as const + + writeContract({ + ...shared, + feeCurrency: '0x', + }) + + type Result = Parameters< + typeof writeContract< + typeof abi.erc20, + 'transferFrom', + [Address, Address, bigint], + typeof celo.id + > + >[0] + expectTypeOf().toEqualTypeOf< + `0x${string}` | undefined + >() + writeContract({ + ...shared, + chainId: celo.id, + feeCurrency: '0x', + }) + + writeContract({ + ...shared, + chainId: mainnet.id, + // @ts-expect-error + feeCurrency: '0x', + }) + + writeContract({ + ...shared, + chainId: optimism.id, + // @ts-expect-error + feeCurrency: '0x', + }) +}) + +test('parameters: config', async () => { + const { writeContract } = useWriteErc20({ config }) + + writeContract({ + address: '0x', + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + // @ts-expect-error + feeCurrency: '0x', + }) +}) diff --git a/wagmi-project/packages/register-tests/react/src/useAccount.test-d.ts b/wagmi-project/packages/register-tests/react/src/useAccount.test-d.ts new file mode 100644 index 000000000..be563933a --- /dev/null +++ b/wagmi-project/packages/register-tests/react/src/useAccount.test-d.ts @@ -0,0 +1,15 @@ +import { config } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' +import { useAccount } from 'wagmi' + +import type { ChainId } from './config.js' + +test('default', () => { + const result = useAccount() + if (result.chain) expectTypeOf(result.chain.id).toEqualTypeOf() +}) + +test('parameters: config', async () => { + const result = useAccount({ config }) + if (result.chain) expectTypeOf(result.chain.id).toEqualTypeOf<1 | 10 | 456>() +}) diff --git a/wagmi-project/packages/register-tests/react/src/useBlock.test-d.ts b/wagmi-project/packages/register-tests/react/src/useBlock.test-d.ts new file mode 100644 index 000000000..5f583a63e --- /dev/null +++ b/wagmi-project/packages/register-tests/react/src/useBlock.test-d.ts @@ -0,0 +1,27 @@ +import type { Hex } from 'viem' +import { expectTypeOf, test } from 'vitest' +import { useBlock } from 'wagmi' +import { celo } from 'wagmi/chains' + +test('chain formatters', () => { + const result = useBlock() + + if (result.data) expectTypeOf(result.data.difficulty).toEqualTypeOf() + + if (result.data?.chainId === celo.id) { + expectTypeOf(result.data.difficulty).toEqualTypeOf() + expectTypeOf(result.data.gasLimit).toEqualTypeOf() + expectTypeOf(result.data.mixHash).toEqualTypeOf() + expectTypeOf(result.data.nonce).toEqualTypeOf<`0x${string}`>() + expectTypeOf(result.data.uncles).toEqualTypeOf() + } + + const result2 = useBlock({ chainId: celo.id }) + if (result2.data) { + expectTypeOf(result2.data.difficulty).toEqualTypeOf() + expectTypeOf(result2.data.gasLimit).toEqualTypeOf() + expectTypeOf(result2.data.mixHash).toEqualTypeOf() + expectTypeOf(result2.data.nonce).toEqualTypeOf<`0x${string}`>() + expectTypeOf(result2.data.uncles).toEqualTypeOf() + } +}) diff --git a/wagmi-project/packages/register-tests/react/src/useChainId.test-d.ts b/wagmi-project/packages/register-tests/react/src/useChainId.test-d.ts new file mode 100644 index 000000000..d1a8e035d --- /dev/null +++ b/wagmi-project/packages/register-tests/react/src/useChainId.test-d.ts @@ -0,0 +1,15 @@ +import { config } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' +import { useChainId } from 'wagmi' + +import type { ChainId } from './config.js' + +test('default', async () => { + const chainId = useChainId() + expectTypeOf(chainId).toEqualTypeOf() +}) + +test('parameters: config', async () => { + const chainId = useChainId({ config }) + expectTypeOf(chainId).toEqualTypeOf<1 | 456 | 10>() +}) diff --git a/wagmi-project/packages/register-tests/react/src/useChains.test-d.ts b/wagmi-project/packages/register-tests/react/src/useChains.test-d.ts new file mode 100644 index 000000000..c40fd5e1d --- /dev/null +++ b/wagmi-project/packages/register-tests/react/src/useChains.test-d.ts @@ -0,0 +1,11 @@ +import { expectTypeOf, test } from 'vitest' +import { useChains } from 'wagmi' +import type { Chain, celo, optimism } from 'wagmi/chains' + +test('default', () => { + const chains = useChains() + + expectTypeOf(chains[0]).toEqualTypeOf() + expectTypeOf(chains[2]).toEqualTypeOf() + expectTypeOf(chains[5]).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/register-tests/react/src/useClient.test-d.ts b/wagmi-project/packages/register-tests/react/src/useClient.test-d.ts new file mode 100644 index 000000000..0ce810b31 --- /dev/null +++ b/wagmi-project/packages/register-tests/react/src/useClient.test-d.ts @@ -0,0 +1,38 @@ +import { type chain, config } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' +import { useClient } from 'wagmi' +import { mainnet } from 'wagmi/chains' + +import type { ChainId } from './config.js' + +test('default', () => { + const client = useClient() + expectTypeOf(client.chain.id).toEqualTypeOf() + expectTypeOf(client.transport.type).toEqualTypeOf<'http'>() +}) + +test('parameters: config', () => { + const client = useClient({ config }) + expectTypeOf(client.chain.id).toEqualTypeOf< + (typeof config)['chains'][number]['id'] + >() + expectTypeOf(client.transport.type).toEqualTypeOf<'http'>() +}) + +test('parameters: chainId', () => { + const client = useClient({ + config, + chainId: mainnet.id, + }) + expectTypeOf(client.chain).toEqualTypeOf() + expectTypeOf(client.transport.type).toEqualTypeOf<'http'>() +}) + +test('behavior: unconfigured chain', () => { + const client = useClient({ + config, + // @ts-expect-error + chainId: 123456, + }) + expectTypeOf(client).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/register-tests/react/src/useConfig.test-d.ts b/wagmi-project/packages/register-tests/react/src/useConfig.test-d.ts new file mode 100644 index 000000000..25eb5246d --- /dev/null +++ b/wagmi-project/packages/register-tests/react/src/useConfig.test-d.ts @@ -0,0 +1,17 @@ +import { config as testConfig } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' +import { type Config, useConfig } from 'wagmi' + +import type { config } from './config.js' + +test('default', async () => { + const result = useConfig() + expectTypeOf(result).not.toEqualTypeOf() + expectTypeOf(result).toEqualTypeOf() +}) + +test('parameters: config', async () => { + const result = useConfig({ config: testConfig }) + expectTypeOf(result).not.toEqualTypeOf() + expectTypeOf(result).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/register-tests/react/src/useConnect.test-d.ts b/wagmi-project/packages/register-tests/react/src/useConnect.test-d.ts new file mode 100644 index 000000000..2386dca7e --- /dev/null +++ b/wagmi-project/packages/register-tests/react/src/useConnect.test-d.ts @@ -0,0 +1,13 @@ +import { expectTypeOf, test } from 'vitest' +import { useConnect } from 'wagmi' + +test('infers connect parameters', () => { + const { connect, connectors, variables } = useConnect() + const connector = connectors[0]! + + expectTypeOf(variables?.foo).toEqualTypeOf() + connect({ + connector, + foo: 'bar', + }) +}) diff --git a/wagmi-project/packages/register-tests/react/src/usePrepareTransactionRequest.test-d.ts b/wagmi-project/packages/register-tests/react/src/usePrepareTransactionRequest.test-d.ts new file mode 100644 index 000000000..460408515 --- /dev/null +++ b/wagmi-project/packages/register-tests/react/src/usePrepareTransactionRequest.test-d.ts @@ -0,0 +1,42 @@ +import { config as testConfig } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' +import { usePrepareTransactionRequest } from 'wagmi' +import { celo, mainnet, optimism } from 'wagmi/chains' + +test('chain formatters', () => { + const { data } = usePrepareTransactionRequest({ + feeCurrency: '0x', + }) + if (data && data.chainId === celo.id) { + expectTypeOf(data.feeCurrency).toEqualTypeOf<`0x${string}` | undefined>() + } + + const { data: data2 } = usePrepareTransactionRequest({ + chainId: celo.id, + feeCurrency: '0x', + }) + if (data2) { + expectTypeOf(data2.chainId).toEqualTypeOf(celo.id) + expectTypeOf(data2.feeCurrency).toEqualTypeOf<`0x${string}` | undefined>() + } + + usePrepareTransactionRequest({ + chainId: mainnet.id, + // @ts-expect-error + feeCurrency: '0x', + }) + + usePrepareTransactionRequest({ + chainId: optimism.id, + // @ts-expect-error + feeCurrency: '0x', + }) +}) + +test('parameters: config', async () => { + usePrepareTransactionRequest({ + config: testConfig, + // @ts-expect-error + feeCurrency: '0x', + }) +}) diff --git a/wagmi-project/packages/register-tests/react/src/usePublicClient.ts b/wagmi-project/packages/register-tests/react/src/usePublicClient.ts new file mode 100644 index 000000000..55c6967ab --- /dev/null +++ b/wagmi-project/packages/register-tests/react/src/usePublicClient.ts @@ -0,0 +1,38 @@ +import { type chain, config } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' +import { usePublicClient } from 'wagmi' +import { mainnet } from 'wagmi/chains' + +import type { ChainId } from './config.js' + +test('default', () => { + const client = usePublicClient() + expectTypeOf(client.chain.id).toEqualTypeOf() + expectTypeOf(client.transport.type).toEqualTypeOf<'http'>() +}) + +test('parameters: config', () => { + const client = usePublicClient({ config }) + expectTypeOf(client.chain.id).toEqualTypeOf< + (typeof config)['chains'][number]['id'] + >() + expectTypeOf(client.transport.type).toEqualTypeOf<'http'>() +}) + +test('parameters: chainId', () => { + const client = usePublicClient({ + config, + chainId: mainnet.id, + }) + expectTypeOf(client.chain).toEqualTypeOf() + expectTypeOf(client.transport.type).toEqualTypeOf<'http'>() +}) + +test('behavior: unconfigured chain', () => { + const client = usePublicClient({ + config, + // @ts-expect-error + chainId: 123456, + }) + expectTypeOf(client).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/register-tests/react/src/useReadContract.test-d.ts b/wagmi-project/packages/register-tests/react/src/useReadContract.test-d.ts new file mode 100644 index 000000000..02ca83ed6 --- /dev/null +++ b/wagmi-project/packages/register-tests/react/src/useReadContract.test-d.ts @@ -0,0 +1,24 @@ +import type { abi } from '@wagmi/test' +import type { Address } from 'viem' +import { expectTypeOf, test } from 'vitest' +import type { useReadContract } from 'wagmi' + +import type { ChainId } from './config.js' + +test('UseReadContractParameters', () => { + type Result = NonNullable< + Parameters>[0] + > + expectTypeOf().toMatchTypeOf<{ + functionName?: + | 'symbol' + | 'name' + | 'allowance' + | 'balanceOf' + | 'decimals' + | 'totalSupply' + | undefined + args?: readonly [Address] | undefined + chainId?: ChainId | undefined + }>() +}) diff --git a/wagmi-project/packages/register-tests/react/src/useReadContracts.test-d.ts b/wagmi-project/packages/register-tests/react/src/useReadContracts.test-d.ts new file mode 100644 index 000000000..bb719b7c4 --- /dev/null +++ b/wagmi-project/packages/register-tests/react/src/useReadContracts.test-d.ts @@ -0,0 +1,45 @@ +import type { abi } from '@wagmi/test' +import type { Address } from 'viem' +import { expectTypeOf, test } from 'vitest' +import type { useReadContracts } from 'wagmi' + +import type { ChainId } from './config.js' + +test('UseReadContractsParameters', () => { + type Result = NonNullable< + Parameters< + typeof useReadContracts< + [ + { + abi: typeof abi.erc20 + functionName: 'balanceOf' + address: Address + args: readonly [Address] + }, + ] + > + >[0] + >['contracts'] + expectTypeOf().toMatchTypeOf< + | readonly [ + { + abi?: typeof abi.erc20 | undefined + functionName?: + | 'approve' + | 'symbol' + | 'name' + | 'allowance' + | 'balanceOf' + | 'decimals' + | 'totalSupply' + | 'transfer' + | 'transferFrom' + | undefined + address?: Address | undefined + args?: readonly [Address] | undefined + chainId?: ChainId | undefined + }, + ] + | undefined + >() +}) diff --git a/wagmi-project/packages/register-tests/react/src/useSendTransaction.test-d.ts b/wagmi-project/packages/register-tests/react/src/useSendTransaction.test-d.ts new file mode 100644 index 000000000..60839f502 --- /dev/null +++ b/wagmi-project/packages/register-tests/react/src/useSendTransaction.test-d.ts @@ -0,0 +1,55 @@ +import { config } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' +import { useSendTransaction } from 'wagmi' +import { celo, mainnet, optimism } from 'wagmi/chains' +import type { ChainId } from './config.js' + +test('chain formatters', () => { + const { sendTransaction } = useSendTransaction() + + sendTransaction( + { + to: '0x', + feeCurrency: '0x', + }, + { + onSuccess(_data, variables) { + expectTypeOf(variables.chainId).toEqualTypeOf() + }, + }, + ) + + type Result = Parameters>[0] + expectTypeOf().toEqualTypeOf< + `0x${string}` | undefined + >() + sendTransaction({ + chainId: celo.id, + to: '0x', + feeCurrency: '0x', + }) + + sendTransaction({ + chainId: mainnet.id, + to: '0x', + // @ts-expect-error + feeCurrency: '0x', + }) + + sendTransaction({ + chainId: optimism.id, + to: '0x', + // @ts-expect-error + feeCurrency: '0x', + }) +}) + +test('parameters: config', async () => { + const { sendTransaction } = useSendTransaction({ config }) + + sendTransaction({ + to: '0x', + // @ts-expect-error + feeCurrency: '0x', + }) +}) diff --git a/wagmi-project/packages/register-tests/react/src/useSimulateContract.test-d.ts b/wagmi-project/packages/register-tests/react/src/useSimulateContract.test-d.ts new file mode 100644 index 000000000..96c75d76e --- /dev/null +++ b/wagmi-project/packages/register-tests/react/src/useSimulateContract.test-d.ts @@ -0,0 +1,94 @@ +import { type abi, config as testConfig } from '@wagmi/test' +import type { Address } from 'viem' +import { expectTypeOf, test } from 'vitest' +import { type UseSimulateContractParameters, useSimulateContract } from 'wagmi' +import type { SimulateContractParameters } from 'wagmi/actions' +import { celo, mainnet, optimism } from 'wagmi/chains' +import type { SimulateContractOptions } from 'wagmi/query' + +import type { ChainId, config } from './config.js' + +test('chain formatters', () => { + const { data } = useSimulateContract({ + feeCurrency: '0x', + }) + if (data && data.chainId === celo.id) { + expectTypeOf(data.request.feeCurrency).toEqualTypeOf< + `0x${string}` | undefined + >() + } + + const { data: data2 } = useSimulateContract({ + chainId: celo.id, + feeCurrency: '0x', + }) + if (data2) { + expectTypeOf(data2.request.feeCurrency).toEqualTypeOf< + `0x${string}` | undefined + >() + } + + useSimulateContract({ + chainId: mainnet.id, + // @ts-expect-error + feeCurrency: '0x', + }) + + useSimulateContract({ + chainId: optimism.id, + // @ts-expect-error + feeCurrency: '0x', + }) +}) + +test('UseSimulateContractParameters', () => { + type Result = UseSimulateContractParameters< + typeof abi.erc20, + 'transferFrom', + [Address, Address, bigint], + typeof config + > + + expectTypeOf<{ + functionName?: 'approve' | 'transfer' | 'transferFrom' | undefined + args?: readonly [Address, Address, bigint] | undefined + chainId?: ChainId | undefined + }>().toMatchTypeOf() + + type Result2 = UseSimulateContractParameters< + typeof abi.erc20, + 'transferFrom', + [Address, Address, bigint], + typeof config, + typeof celo.id + > + expectTypeOf().toEqualTypeOf() + expectTypeOf().toEqualTypeOf< + `0x${string}` | undefined + >() + + type Result3 = SimulateContractParameters< + typeof abi.erc20, + 'transferFrom', + [Address, Address, bigint], + typeof config, + typeof celo.id + > + expectTypeOf().toEqualTypeOf() + type Result4 = SimulateContractOptions< + typeof abi.erc20, + 'transferFrom', + [Address, Address, bigint], + typeof config, + typeof celo.id + > + expectTypeOf().toEqualTypeOf() +}) + +test('parameters: config', async () => { + useSimulateContract({ + config: testConfig, + // @ts-expect-error + feeCurrency: '0x', + }) +}) diff --git a/wagmi-project/packages/register-tests/react/src/useSwitchChain.test-d.ts b/wagmi-project/packages/register-tests/react/src/useSwitchChain.test-d.ts new file mode 100644 index 000000000..2d02557b8 --- /dev/null +++ b/wagmi-project/packages/register-tests/react/src/useSwitchChain.test-d.ts @@ -0,0 +1,25 @@ +import { expectTypeOf, test } from 'vitest' +import { useSwitchChain } from 'wagmi' +import { type celo, mainnet, type optimism } from 'wagmi/chains' + +import type { ChainId, config } from './config.js' + +test('default', () => { + const { chains, switchChain } = useSwitchChain() + + expectTypeOf(chains).toEqualTypeOf<(typeof config)['chains']>() + expectTypeOf(chains[0]).toEqualTypeOf() + expectTypeOf(chains[2]).toEqualTypeOf() + + switchChain( + { chainId: 1 }, + { + onSuccess(data) { + expectTypeOf(data).toEqualTypeOf(mainnet) + }, + }, + ) + + type Result = Parameters[0] + expectTypeOf().toEqualTypeOf() +}) diff --git a/wagmi-project/packages/register-tests/react/src/useTransaction.test-d.ts b/wagmi-project/packages/register-tests/react/src/useTransaction.test-d.ts new file mode 100644 index 000000000..135b99bb2 --- /dev/null +++ b/wagmi-project/packages/register-tests/react/src/useTransaction.test-d.ts @@ -0,0 +1,23 @@ +import { config } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' +import { useTransaction } from 'wagmi' +import { celo } from 'wagmi/chains' + +test('chain formatters', () => { + const result = useTransaction() + if (result.data?.chainId === celo.id) { + expectTypeOf(result.data.feeCurrency).toEqualTypeOf<`0x${string}` | null>() + } + + const result2 = useTransaction({ chainId: celo.id }) + expectTypeOf(result2.data?.feeCurrency).toEqualTypeOf< + `0x${string}` | null | undefined + >() +}) + +test('parameters: config', async () => { + const result = useTransaction({ config }) + + if (result.data && 'feeCurrency' in result.data) + expectTypeOf(result.data.feeCurrency).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/register-tests/react/src/useTransactionConfirmations.test-d.ts b/wagmi-project/packages/register-tests/react/src/useTransactionConfirmations.test-d.ts new file mode 100644 index 000000000..fe2445db2 --- /dev/null +++ b/wagmi-project/packages/register-tests/react/src/useTransactionConfirmations.test-d.ts @@ -0,0 +1,66 @@ +import { config as testConfig } from '@wagmi/test' +import { test } from 'vitest' +import { useTransactionConfirmations } from 'wagmi' +import { mainnet, zkSync } from 'wagmi/chains' + +const transactionReceipt = { + blockHash: '0x', + blockNumber: 1n, + contractAddress: '0x', + cumulativeGasUsed: 1n, + effectiveGasPrice: 1n, + from: '0x', + gasUsed: 1n, + logsBloom: '0x', + status: 'success', + to: '0x', + transactionHash: '0x', + transactionIndex: 1, + type: 'eip1559', +} as const + +test('chain formatters', async () => { + useTransactionConfirmations({ + transactionReceipt: { + ...transactionReceipt, + l1BatchNumber: 1n, + l1BatchTxIndex: 1n, + logs: [], + l2ToL1Logs: [], + }, + }) + + useTransactionConfirmations({ + chainId: zkSync.id, + transactionReceipt: { + ...transactionReceipt, + l1BatchNumber: 1n, + l1BatchTxIndex: 1n, + logs: [], + l2ToL1Logs: [], + }, + }) + + useTransactionConfirmations({ + chainId: mainnet.id, + transactionReceipt: { + ...transactionReceipt, + // @ts-expect-error + l1BatchNumber: 1n, + l1BatchTxIndex: 1n, + logs: [], + l2ToL1Logs: [], + }, + }) +}) + +test('parameters: config', async () => { + useTransactionConfirmations({ + config: testConfig, + transactionReceipt: { + ...transactionReceipt, + // @ts-expect-error + l1BatchNumber: 1n, + }, + }) +}) diff --git a/wagmi-project/packages/register-tests/react/src/useTransactionReceipt.test-d.ts b/wagmi-project/packages/register-tests/react/src/useTransactionReceipt.test-d.ts new file mode 100644 index 000000000..1bbd8183d --- /dev/null +++ b/wagmi-project/packages/register-tests/react/src/useTransactionReceipt.test-d.ts @@ -0,0 +1,31 @@ +import { config } from '@wagmi/test' +import type { ZkSyncL2ToL1Log, ZkSyncLog } from 'viem/zksync' +import { expectTypeOf, test } from 'vitest' +import { useTransactionReceipt } from 'wagmi' +import { zkSync } from 'wagmi/chains' + +test('chain formatters', () => { + const result = useTransactionReceipt() + + if (result.data?.chainId === zkSync.id) { + expectTypeOf(result.data.l1BatchNumber).toEqualTypeOf() + expectTypeOf(result.data.l1BatchTxIndex).toEqualTypeOf() + expectTypeOf(result.data.logs).toEqualTypeOf() + expectTypeOf(result.data.l2ToL1Logs).toEqualTypeOf() + } + + const result2 = useTransactionReceipt({ chainId: zkSync.id }) + if (result2.data) { + expectTypeOf(result2.data.l1BatchNumber).toEqualTypeOf() + expectTypeOf(result2.data.l1BatchTxIndex).toEqualTypeOf() + expectTypeOf(result2.data.logs).toEqualTypeOf() + expectTypeOf(result2.data.l2ToL1Logs).toEqualTypeOf() + } +}) + +test('parameters: config', async () => { + const result = useTransactionReceipt({ config }) + + if (result.data && 'l1BatchNumber' in result.data) + expectTypeOf(result.data.l1BatchNumber).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/register-tests/react/src/useWaitForTransactionReceipt.ts b/wagmi-project/packages/register-tests/react/src/useWaitForTransactionReceipt.ts new file mode 100644 index 000000000..0d2501f50 --- /dev/null +++ b/wagmi-project/packages/register-tests/react/src/useWaitForTransactionReceipt.ts @@ -0,0 +1,31 @@ +import { config } from '@wagmi/test' +import type { ZkSyncL2ToL1Log, ZkSyncLog } from 'viem/zksync' +import { expectTypeOf, test } from 'vitest' +import { useWaitForTransactionReceipt } from 'wagmi' +import { zkSync } from 'wagmi/chains' + +test('chain formatters', () => { + const result = useWaitForTransactionReceipt() + + if (result.data?.chainId === zkSync.id) { + expectTypeOf(result.data.l1BatchNumber).toEqualTypeOf() + expectTypeOf(result.data.l1BatchTxIndex).toEqualTypeOf() + expectTypeOf(result.data.logs).toEqualTypeOf() + expectTypeOf(result.data.l2ToL1Logs).toEqualTypeOf() + } + + const result2 = useWaitForTransactionReceipt({ chainId: zkSync.id }) + if (result2.data) { + expectTypeOf(result2.data.l1BatchNumber).toEqualTypeOf() + expectTypeOf(result2.data.l1BatchTxIndex).toEqualTypeOf() + expectTypeOf(result2.data.logs).toEqualTypeOf() + expectTypeOf(result2.data.l2ToL1Logs).toEqualTypeOf() + } +}) + +test('parameters: config', async () => { + const result = useWaitForTransactionReceipt({ config }) + + if (result.data && 'l1BatchNumber' in result.data) + expectTypeOf(result.data.l1BatchNumber).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/register-tests/react/src/useWriteContract.test-d.ts b/wagmi-project/packages/register-tests/react/src/useWriteContract.test-d.ts new file mode 100644 index 000000000..c499ff8f3 --- /dev/null +++ b/wagmi-project/packages/register-tests/react/src/useWriteContract.test-d.ts @@ -0,0 +1,65 @@ +import { abi, config } from '@wagmi/test' +import type { Address } from 'viem' +import { expectTypeOf, test } from 'vitest' +import { useWriteContract } from 'wagmi' +import { celo, mainnet, optimism } from 'wagmi/chains' + +test('chain formatters', () => { + const { writeContract } = useWriteContract() + + const shared = { + address: '0x', + abi: abi.erc20, + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + } as const + + writeContract({ + ...shared, + feeCurrency: '0x', + }) + + type Result = Parameters< + typeof writeContract< + typeof abi.erc20, + 'transferFrom', + [Address, Address, bigint], + typeof celo.id + > + >[0] + expectTypeOf().toEqualTypeOf< + `0x${string}` | undefined + >() + writeContract({ + ...shared, + chainId: celo.id, + feeCurrency: '0x', + }) + + writeContract({ + ...shared, + chainId: mainnet.id, + // @ts-expect-error + feeCurrency: '0x', + }) + + writeContract({ + ...shared, + chainId: optimism.id, + // @ts-expect-error + feeCurrency: '0x', + }) +}) + +test('parameters: config', async () => { + const { writeContract } = useWriteContract({ config }) + + writeContract({ + address: '0x', + abi: abi.erc20, + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + // @ts-expect-error + feeCurrency: '0x', + }) +}) diff --git a/wagmi-project/packages/register-tests/react/tsconfig.json b/wagmi-project/packages/register-tests/react/tsconfig.json new file mode 100644 index 000000000..77a211dbb --- /dev/null +++ b/wagmi-project/packages/register-tests/react/tsconfig.json @@ -0,0 +1,5 @@ +{ + "extends": "../../../tsconfig.base.json", + "include": ["src/**/*.ts"], + "exclude": [] +} diff --git a/wagmi-project/packages/register-tests/vue/package.json b/wagmi-project/packages/register-tests/vue/package.json new file mode 100644 index 000000000..fc41697d7 --- /dev/null +++ b/wagmi-project/packages/register-tests/vue/package.json @@ -0,0 +1,13 @@ +{ + "name": "vue-register", + "private": true, + "type": "module", + "scripts": { + "check:types": "tsc --noEmit" + }, + "dependencies": { + "@tanstack/vue-query": "catalog:", + "@wagmi/vue": "workspace:*", + "vue": "catalog:" + } +} diff --git a/wagmi-project/packages/register-tests/vue/src/config.ts b/wagmi-project/packages/register-tests/vue/src/config.ts new file mode 100644 index 000000000..fd13c5a6b --- /dev/null +++ b/wagmi-project/packages/register-tests/vue/src/config.ts @@ -0,0 +1,26 @@ +import { createConfig, mock } from '@wagmi/vue' +import { celo, mainnet, optimism, zkSync } from '@wagmi/vue/chains' +import { http } from 'viem' + +export const config = createConfig({ + chains: [celo, mainnet, optimism, zkSync], + connectors: [mock({ accounts: ['0x'] })], + transports: { + [celo.id]: http(), + [mainnet.id]: http(), + [optimism.id]: http(), + [zkSync.id]: http(), + }, +}) + +export type ChainId = + | typeof celo.id + | typeof mainnet.id + | typeof optimism.id + | typeof zkSync.id + +declare module '@wagmi/vue' { + interface Register { + config: typeof config + } +} diff --git a/wagmi-project/packages/register-tests/vue/src/useAccount.test-d.ts b/wagmi-project/packages/register-tests/vue/src/useAccount.test-d.ts new file mode 100644 index 000000000..6471bf455 --- /dev/null +++ b/wagmi-project/packages/register-tests/vue/src/useAccount.test-d.ts @@ -0,0 +1,17 @@ +import { config } from '@wagmi/test' +import { useAccount } from '@wagmi/vue' +import { expectTypeOf, test } from 'vitest' + +import type { ChainId } from './config.js' + +test('default', () => { + const result = useAccount() + if (result.chain.value) + expectTypeOf(result.chain.value.id).toEqualTypeOf() +}) + +test('parameters: config', async () => { + const result = useAccount({ config }) + if (result.chain.value) + expectTypeOf(result.chain.value.id).toEqualTypeOf<1 | 10 | 456>() +}) diff --git a/wagmi-project/packages/register-tests/vue/src/useChainId.test-d.ts b/wagmi-project/packages/register-tests/vue/src/useChainId.test-d.ts new file mode 100644 index 000000000..ffeddcb6b --- /dev/null +++ b/wagmi-project/packages/register-tests/vue/src/useChainId.test-d.ts @@ -0,0 +1,15 @@ +import { config } from '@wagmi/test' +import { useChainId } from '@wagmi/vue' +import { expectTypeOf, test } from 'vitest' + +import type { ChainId } from './config.js' + +test('default', async () => { + const chainId = useChainId() + expectTypeOf(chainId.value).toEqualTypeOf() +}) + +test('parameters: config', async () => { + const chainId = useChainId({ config }) + expectTypeOf(chainId.value).toEqualTypeOf<1 | 456 | 10>() +}) diff --git a/wagmi-project/packages/register-tests/vue/src/useChains.test-d.ts b/wagmi-project/packages/register-tests/vue/src/useChains.test-d.ts new file mode 100644 index 000000000..d1bf0eb15 --- /dev/null +++ b/wagmi-project/packages/register-tests/vue/src/useChains.test-d.ts @@ -0,0 +1,11 @@ +import { useChains } from '@wagmi/vue' +import type { Chain, celo, optimism } from '@wagmi/vue/chains' +import { expectTypeOf, test } from 'vitest' + +test('default', () => { + const chains = useChains() + + expectTypeOf(chains.value[0]).toEqualTypeOf() + expectTypeOf(chains.value[2]).toEqualTypeOf() + expectTypeOf(chains.value[5]).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/register-tests/vue/src/useClient.test-d.ts b/wagmi-project/packages/register-tests/vue/src/useClient.test-d.ts new file mode 100644 index 000000000..99cea8d3f --- /dev/null +++ b/wagmi-project/packages/register-tests/vue/src/useClient.test-d.ts @@ -0,0 +1,38 @@ +import { type chain, config } from '@wagmi/test' +import { useClient } from '@wagmi/vue' +import { mainnet } from '@wagmi/vue/chains' +import { expectTypeOf, test } from 'vitest' + +import type { ChainId } from './config.js' + +test('default', () => { + const client = useClient() + expectTypeOf(client.value.chain.id).toEqualTypeOf() + expectTypeOf(client.value.transport.type).toEqualTypeOf<'http'>() +}) + +test('parameters: config', () => { + const client = useClient({ config }) + expectTypeOf(client.value.chain.id).toEqualTypeOf< + (typeof config)['chains'][number]['id'] + >() + expectTypeOf(client.value.transport.type).toEqualTypeOf<'http'>() +}) + +test('parameters: chainId', () => { + const client = useClient({ + config, + chainId: mainnet.id, + }) + expectTypeOf(client.value.chain).toEqualTypeOf() + expectTypeOf(client.value.transport.type).toEqualTypeOf<'http'>() +}) + +test('behavior: unconfigured chain', () => { + const client = useClient({ + config, + // @ts-expect-error + chainId: 123456, + }) + expectTypeOf(client.value).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/register-tests/vue/src/useConfig.test-d.ts b/wagmi-project/packages/register-tests/vue/src/useConfig.test-d.ts new file mode 100644 index 000000000..c65f70c21 --- /dev/null +++ b/wagmi-project/packages/register-tests/vue/src/useConfig.test-d.ts @@ -0,0 +1,17 @@ +import { config as testConfig } from '@wagmi/test' +import { type Config, useConfig } from '@wagmi/vue' +import { expectTypeOf, test } from 'vitest' + +import type { config } from './config.js' + +test('default', async () => { + const result = useConfig() + expectTypeOf(result).not.toEqualTypeOf() + expectTypeOf(result).toEqualTypeOf() +}) + +test('parameters: config', async () => { + const result = useConfig({ config: testConfig }) + expectTypeOf(result).not.toEqualTypeOf() + expectTypeOf(result).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/register-tests/vue/src/useConnect.test-d.ts b/wagmi-project/packages/register-tests/vue/src/useConnect.test-d.ts new file mode 100644 index 000000000..128834ff6 --- /dev/null +++ b/wagmi-project/packages/register-tests/vue/src/useConnect.test-d.ts @@ -0,0 +1,13 @@ +import { useConnect } from '@wagmi/vue' +import { expectTypeOf, test } from 'vitest' + +test('infers connect parameters', () => { + const { connect, connectors, variables } = useConnect() + const connector = connectors[0]! + + expectTypeOf(variables.value?.foo).toEqualTypeOf() + connect({ + connector, + foo: 'bar', + }) +}) diff --git a/wagmi-project/packages/register-tests/vue/src/useReadContract.test-d.ts b/wagmi-project/packages/register-tests/vue/src/useReadContract.test-d.ts new file mode 100644 index 000000000..c2a1a6386 --- /dev/null +++ b/wagmi-project/packages/register-tests/vue/src/useReadContract.test-d.ts @@ -0,0 +1,30 @@ +import type { abi } from '@wagmi/test' +import type { useReadContract } from '@wagmi/vue' +import type { Address } from 'viem' +import { expectTypeOf, test } from 'vitest' + +import type { DeepUnwrapRef } from '../../../vue/src/types/ref.js' +import type { ChainId } from './config.js' + +test('UseReadContractParameters', () => { + type Result = DeepUnwrapRef< + NonNullable< + Parameters< + typeof useReadContract + >[0] + > + > + + expectTypeOf().toMatchTypeOf<{ + functionName?: + | 'symbol' + | 'name' + | 'allowance' + | 'balanceOf' + | 'decimals' + | 'totalSupply' + | undefined + args?: readonly [Address] | undefined + chainId?: ChainId | undefined + }>() +}) diff --git a/wagmi-project/packages/register-tests/vue/src/useSendTransaction.test-d.ts b/wagmi-project/packages/register-tests/vue/src/useSendTransaction.test-d.ts new file mode 100644 index 000000000..c49a8ef38 --- /dev/null +++ b/wagmi-project/packages/register-tests/vue/src/useSendTransaction.test-d.ts @@ -0,0 +1,55 @@ +import { config } from '@wagmi/test' +import { useSendTransaction } from '@wagmi/vue' +import { celo, mainnet, optimism } from '@wagmi/vue/chains' +import { expectTypeOf, test } from 'vitest' +import type { ChainId } from './config.js' + +test('chain formatters', () => { + const { sendTransaction } = useSendTransaction() + + sendTransaction( + { + to: '0x', + feeCurrency: '0x', + }, + { + onSuccess(_data, variables) { + expectTypeOf(variables.chainId).toEqualTypeOf() + }, + }, + ) + + type Result = Parameters>[0] + expectTypeOf().toEqualTypeOf< + `0x${string}` | undefined + >() + sendTransaction({ + chainId: celo.id, + to: '0x', + feeCurrency: '0x', + }) + + sendTransaction({ + chainId: mainnet.id, + to: '0x', + // @ts-expect-error + feeCurrency: '0x', + }) + + sendTransaction({ + chainId: optimism.id, + to: '0x', + // @ts-expect-error + feeCurrency: '0x', + }) +}) + +test('parameters: config', async () => { + const { sendTransaction } = useSendTransaction({ config }) + + sendTransaction({ + to: '0x', + // @ts-expect-error + feeCurrency: '0x', + }) +}) diff --git a/wagmi-project/packages/register-tests/vue/src/useSimulateContract.test-d.ts b/wagmi-project/packages/register-tests/vue/src/useSimulateContract.test-d.ts new file mode 100644 index 000000000..2a2b65c4d --- /dev/null +++ b/wagmi-project/packages/register-tests/vue/src/useSimulateContract.test-d.ts @@ -0,0 +1,86 @@ +import { type abi, config as testConfig } from '@wagmi/test' +import { + type UseSimulateContractParameters, + useSimulateContract, +} from '@wagmi/vue' +import type { SimulateContractParameters } from '@wagmi/vue/actions' +import { celo, mainnet, optimism } from '@wagmi/vue/chains' +import type { SimulateContractOptions } from '@wagmi/vue/query' +import type { Address } from 'viem' +import { expectTypeOf, test } from 'vitest' + +import type { ChainId, config } from './config.js' + +test('chain formatters', () => { + const { data } = useSimulateContract({ + feeCurrency: '0x', + }) + if (data.value && data.value.chainId === celo.id) { + expectTypeOf(data.value.request.feeCurrency).toEqualTypeOf< + `0x${string}` | undefined + >() + } + + const { data: data2 } = useSimulateContract({ + chainId: celo.id, + feeCurrency: '0x', + }) + if (data2.value) { + expectTypeOf(data2.value.request.feeCurrency).toEqualTypeOf< + `0x${string}` | undefined + >() + } + + useSimulateContract({ + chainId: mainnet.id, + // @ts-expect-error + feeCurrency: '0x', + }) + + useSimulateContract({ + chainId: optimism.id, + // @ts-expect-error + feeCurrency: '0x', + }) +}) + +test('UseSimulateContractParameters', () => { + type Result = UseSimulateContractParameters< + typeof abi.erc20, + 'transferFrom', + [Address, Address, bigint], + typeof config + > + + expectTypeOf<{ + functionName?: 'approve' | 'transfer' | 'transferFrom' | undefined + args?: readonly [Address, Address, bigint] | undefined + chainId?: ChainId | undefined + }>().toMatchTypeOf() + + type Result2 = SimulateContractParameters< + typeof abi.erc20, + 'transferFrom', + [Address, Address, bigint], + typeof config, + typeof celo.id + > + expectTypeOf().toEqualTypeOf() + + type Result3 = SimulateContractOptions< + typeof abi.erc20, + 'transferFrom', + [Address, Address, bigint], + typeof config, + typeof celo.id + > + expectTypeOf().toEqualTypeOf() +}) + +test('parameters: config', async () => { + useSimulateContract({ + config: testConfig, + // @ts-expect-error + feeCurrency: '0x', + }) +}) diff --git a/wagmi-project/packages/register-tests/vue/src/useSwitchChain.test-d.ts b/wagmi-project/packages/register-tests/vue/src/useSwitchChain.test-d.ts new file mode 100644 index 000000000..cf0153b3b --- /dev/null +++ b/wagmi-project/packages/register-tests/vue/src/useSwitchChain.test-d.ts @@ -0,0 +1,27 @@ +import { useSwitchChain } from '@wagmi/vue' +import { type celo, mainnet, type optimism } from '@wagmi/vue/chains' +import { expectTypeOf, test } from 'vitest' + +import type { ChainId, config } from './config.js' + +test('default', () => { + const switchChain = useSwitchChain() + + const chains = switchChain.chains.value + + expectTypeOf(chains).toEqualTypeOf<(typeof config)['chains']>() + expectTypeOf(chains[0]).toEqualTypeOf() + expectTypeOf(chains[2]).toEqualTypeOf() + + switchChain.switchChain( + { chainId: 1 }, + { + onSuccess(data) { + expectTypeOf(data).toEqualTypeOf(mainnet) + }, + }, + ) + + type Result = Parameters<(typeof switchChain)['switchChain']>[0] + expectTypeOf().toEqualTypeOf() +}) diff --git a/wagmi-project/packages/register-tests/vue/src/useTransaction.test-d.ts b/wagmi-project/packages/register-tests/vue/src/useTransaction.test-d.ts new file mode 100644 index 000000000..7bc262c38 --- /dev/null +++ b/wagmi-project/packages/register-tests/vue/src/useTransaction.test-d.ts @@ -0,0 +1,25 @@ +import { config } from '@wagmi/test' +import { useTransaction } from '@wagmi/vue' +import { celo } from '@wagmi/vue/chains' +import { expectTypeOf, test } from 'vitest' + +test('chain formatters', () => { + const result = useTransaction() + if (result.data?.value?.chainId === celo.id) { + expectTypeOf(result.data.value.feeCurrency).toEqualTypeOf< + `0x${string}` | null + >() + } + + const result2 = useTransaction({ chainId: celo.id }) + expectTypeOf(result2.data?.value?.feeCurrency).toEqualTypeOf< + `0x${string}` | null | undefined + >() +}) + +test('parameters: config', async () => { + const result = useTransaction({ config }) + + if (result.data && 'feeCurrency' in result.data) + expectTypeOf(result.data.feeCurrency).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/register-tests/vue/src/useTransactionReceipt.test-d.ts b/wagmi-project/packages/register-tests/vue/src/useTransactionReceipt.test-d.ts new file mode 100644 index 000000000..c202d82db --- /dev/null +++ b/wagmi-project/packages/register-tests/vue/src/useTransactionReceipt.test-d.ts @@ -0,0 +1,41 @@ +import { config } from '@wagmi/test' +import { useTransactionReceipt } from '@wagmi/vue' +import { zkSync } from '@wagmi/vue/chains' +import type { ZkSyncL2ToL1Log, ZkSyncLog } from 'viem/zksync' +import { expectTypeOf, test } from 'vitest' + +test('chain formatters', () => { + const result = useTransactionReceipt() + + if (result.data?.value?.chainId === zkSync.id) { + expectTypeOf(result.data.value.l1BatchNumber).toEqualTypeOf() + expectTypeOf(result.data.value.l1BatchTxIndex).toEqualTypeOf< + bigint | null + >() + expectTypeOf(result.data.value.logs).toEqualTypeOf() + expectTypeOf(result.data.value.l2ToL1Logs).toEqualTypeOf< + ZkSyncL2ToL1Log[] + >() + } + + const result2 = useTransactionReceipt({ chainId: zkSync.id }) + if (result2.data.value) { + expectTypeOf(result2.data.value.l1BatchNumber).toEqualTypeOf< + bigint | null + >() + expectTypeOf(result2.data.value.l1BatchTxIndex).toEqualTypeOf< + bigint | null + >() + expectTypeOf(result2.data.value.logs).toEqualTypeOf() + expectTypeOf(result2.data.value.l2ToL1Logs).toEqualTypeOf< + ZkSyncL2ToL1Log[] + >() + } +}) + +test('parameters: config', async () => { + const result = useTransactionReceipt({ config }) + + if (result.data && 'l1BatchNumber' in result.data) + expectTypeOf(result.data.l1BatchNumber).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/register-tests/vue/src/useWaitForTransaction.test-d.ts b/wagmi-project/packages/register-tests/vue/src/useWaitForTransaction.test-d.ts new file mode 100644 index 000000000..e0286617c --- /dev/null +++ b/wagmi-project/packages/register-tests/vue/src/useWaitForTransaction.test-d.ts @@ -0,0 +1,41 @@ +import { config } from '@wagmi/test' +import { useWaitForTransactionReceipt } from '@wagmi/vue' +import { zkSync } from '@wagmi/vue/chains' +import type { ZkSyncL2ToL1Log, ZkSyncLog } from 'viem/zksync' +import { expectTypeOf, test } from 'vitest' + +test('chain formatters', () => { + const result = useWaitForTransactionReceipt() + + if (result.data?.value?.chainId === zkSync.id) { + expectTypeOf(result.data.value.l1BatchNumber).toEqualTypeOf() + expectTypeOf(result.data.value.l1BatchTxIndex).toEqualTypeOf< + bigint | null + >() + expectTypeOf(result.data.value.logs).toEqualTypeOf() + expectTypeOf(result.data.value.l2ToL1Logs).toEqualTypeOf< + ZkSyncL2ToL1Log[] + >() + } + + const result2 = useWaitForTransactionReceipt({ chainId: zkSync.id }) + if (result2.data.value) { + expectTypeOf(result2.data.value.l1BatchNumber).toEqualTypeOf< + bigint | null + >() + expectTypeOf(result2.data.value.l1BatchTxIndex).toEqualTypeOf< + bigint | null + >() + expectTypeOf(result2.data.value.logs).toEqualTypeOf() + expectTypeOf(result2.data.value.l2ToL1Logs).toEqualTypeOf< + ZkSyncL2ToL1Log[] + >() + } +}) + +test('parameters: config', async () => { + const result = useWaitForTransactionReceipt({ config }) + + if (result.data && 'l1BatchNumber' in result.data) + expectTypeOf(result.data.l1BatchNumber).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/register-tests/vue/src/useWriteContract.test-d.ts b/wagmi-project/packages/register-tests/vue/src/useWriteContract.test-d.ts new file mode 100644 index 000000000..ec4f38430 --- /dev/null +++ b/wagmi-project/packages/register-tests/vue/src/useWriteContract.test-d.ts @@ -0,0 +1,65 @@ +import { abi, config } from '@wagmi/test' +import { useWriteContract } from '@wagmi/vue' +import { celo, mainnet, optimism } from '@wagmi/vue/chains' +import type { Address } from 'viem' +import { expectTypeOf, test } from 'vitest' + +test('chain formatters', () => { + const { writeContract } = useWriteContract() + + const shared = { + address: '0x', + abi: abi.erc20, + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + } as const + + writeContract({ + ...shared, + feeCurrency: '0x', + }) + + type Result = Parameters< + typeof writeContract< + typeof abi.erc20, + 'transferFrom', + [Address, Address, bigint], + typeof celo.id + > + >[0] + expectTypeOf().toEqualTypeOf< + `0x${string}` | undefined + >() + writeContract({ + ...shared, + chainId: celo.id, + feeCurrency: '0x', + }) + + writeContract({ + ...shared, + chainId: mainnet.id, + // @ts-expect-error + feeCurrency: '0x', + }) + + writeContract({ + ...shared, + chainId: optimism.id, + // @ts-expect-error + feeCurrency: '0x', + }) +}) + +test('parameters: config', async () => { + const { writeContract } = useWriteContract({ config }) + + writeContract({ + address: '0x', + abi: abi.erc20, + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + // @ts-expect-error + feeCurrency: '0x', + }) +}) diff --git a/wagmi-project/packages/register-tests/vue/tsconfig.json b/wagmi-project/packages/register-tests/vue/tsconfig.json new file mode 100644 index 000000000..77a211dbb --- /dev/null +++ b/wagmi-project/packages/register-tests/vue/tsconfig.json @@ -0,0 +1,5 @@ +{ + "extends": "../../../tsconfig.base.json", + "include": ["src/**/*.ts"], + "exclude": [] +} diff --git a/wagmi-project/packages/test/package.json b/wagmi-project/packages/test/package.json new file mode 100644 index 000000000..d1c6fb9c1 --- /dev/null +++ b/wagmi-project/packages/test/package.json @@ -0,0 +1,118 @@ +{ + "name": "@wagmi/test", + "description": "Test utils for wagmi", + "private": true, + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/wevm/wagmi.git", + "directory": "packages/test" + }, + "scripts": { + "build": "pnpm run clean && pnpm run build:esm+types", + "build:esm+types": "tsc --project tsconfig.build.json --outDir ./dist/esm --declaration --declarationMap --declarationDir ./dist/types", + "check:types": "tsc --noEmit", + "clean": "rm -rf dist tsconfig.tsbuildinfo", + "test:build": "publint --strict" + }, + "files": [ + "dist/**", + "!dist/**/*.tsbuildinfo", + "src/**/*.ts", + "!src/**/*.test.ts", + "!src/**/*.test-d.ts", + "react/**", + "vue/**" + ], + "sideEffects": false, + "type": "module", + "main": "./dist/esm/exports/index.js", + "types": "./dist/types/exports/index.d.ts", + "typings": "./dist/types/exports/index.d.ts", + "exports": { + ".": { + "types": "./dist/types/exports/index.d.ts", + "default": "./dist/esm/exports/index.js" + }, + "./react": { + "types": "./dist/types/exports/react.d.ts", + "default": "./dist/esm/exports/react.js" + }, + "./vue": { + "types": "./dist/types/exports/vue.d.ts", + "default": "./dist/esm/exports/vue.js" + }, + "./package.json": "./package.json" + }, + "typesVersions": { + "*": { + "react": ["./dist/types/exports/react.d.ts"], + "vue": ["./dist/types/exports/vue.d.ts"] + } + }, + "peerDependencies": { + "@tanstack/react-query": ">=5.0.0", + "@tanstack/vue-query": ">=5.0.0", + "@testing-library/react": ">=14.0.0", + "@types/react": ">=18", + "@types/react-dom": ">=18", + "@wagmi/core": "workspace:*", + "@wagmi/vue": "workspace:*", + "prool": "^0.0.23", + "react": ">=18", + "react-dom": ">=18", + "typescript": ">=5.0.4", + "viem": "2.x", + "vue": ">=3", + "wagmi": "workspace:*" + }, + "peerDependenciesMeta": { + "@tanstack/react-query": { + "optional": true + }, + "@tanstack/vue-query": { + "optional": true + }, + "@testing-library/react": { + "optional": true + }, + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + }, + "typescript": { + "optional": true + }, + "vue": { + "optional": true + }, + "wagmi": { + "optional": true + } + }, + "devDependencies": { + "@tanstack/react-query": "catalog:", + "@tanstack/vue-query": "catalog:", + "@testing-library/dom": "catalog:", + "@testing-library/react": "catalog:", + "@types/react": "catalog:", + "@types/react-dom": "catalog:", + "@wagmi/core": "workspace:*", + "@wagmi/vue": "workspace:*", + "react": "catalog:", + "react-dom": "catalog:", + "vue": "catalog:", + "wagmi": "workspace:*" + }, + "contributors": ["awkweb.eth ", "jxom.eth "], + "funding": "https://github.com/sponsors/wevm", + "keywords": ["eth", "ethereum", "dapps", "wallet", "web3"] +} diff --git a/wagmi-project/packages/test/src/chains.ts b/wagmi-project/packages/test/src/chains.ts new file mode 100644 index 000000000..af9bdc5d9 --- /dev/null +++ b/wagmi-project/packages/test/src/chains.ts @@ -0,0 +1,51 @@ +import type { Compute } from '@wagmi/core/internal' +import { + type Chain as viem_Chain, + mainnet as viem_mainnet, + optimism as viem_optimism, +} from 'viem/chains' + +import { getRpcUrls } from './utils.js' + +type Fork = { blockNumber: bigint; url: string } + +export type Chain = Compute< + viem_Chain & { + fork: Fork + port: number + } +> + +const mainnetFork = { + blockNumber: 19_258_213n, + url: process.env.VITE_MAINNET_FORK_URL ?? 'https://eth.merkle.io', +} as const satisfies Fork + +export const mainnet = { + ...viem_mainnet, + ...getRpcUrls({ port: 8545 }), + fork: mainnetFork, +} as const satisfies Chain + +export const mainnet2 = { + ...viem_mainnet, + ...getRpcUrls({ port: 8546 }), + id: 456, + nativeCurrency: { decimals: 18, name: 'wagmi', symbol: 'WAG' }, + fork: mainnetFork, +} as const satisfies Chain + +export const optimism = { + ...getRpcUrls({ port: 8547 }), + ...viem_optimism, + fork: { + blockNumber: 107_317_577n, + url: process.env.VITE_OPTIMISM_FORK_URL ?? 'https://mainnet.optimism.io', + }, +} as const satisfies Chain + +export const chain = { + mainnet, + mainnet2, + optimism, +} diff --git a/wagmi-project/packages/test/src/clients.ts b/wagmi-project/packages/test/src/clients.ts new file mode 100644 index 000000000..5a2d86005 --- /dev/null +++ b/wagmi-project/packages/test/src/clients.ts @@ -0,0 +1,62 @@ +import { + http, + type Account, + type Client, + type TestActions, + type TestRpcSchema, + type Transport, + createTestClient, +} from 'viem' + +import { type Chain, mainnet, mainnet2, optimism } from './chains.js' + +export const mainnetTestClient = createTestClient({ + mode: 'anvil', + cacheTime: 0, + chain: mainnet, + transport: http(), +}).extend(wagmiTestMethods) + +export const mainnet2TestClient = createTestClient({ + mode: 'anvil', + cacheTime: 0, + chain: mainnet2, + transport: http(), +}).extend(wagmiTestMethods) + +export const optimismTestClient = createTestClient({ + mode: 'anvil', + cacheTime: 0, + chain: optimism, + transport: http(), +}).extend(wagmiTestMethods) + +export const testClient = { + mainnet: mainnetTestClient, + mainnet2: mainnet2TestClient, + optimism: optimismTestClient, +} + +function wagmiTestMethods( + client: Client< + Transport, + Chain, + Account | undefined, + TestRpcSchema<'anvil'>, + TestActions + >, +) { + return { + /** Resets instance attached to chain. */ + async restart() { + return await fetch(`${client.chain.rpcUrls.default.http[0]}/restart`) + }, + /** Resets fork attached to chain at starting block number. */ + resetFork() { + return client.reset({ + jsonRpcUrl: client.chain.fork.url, + blockNumber: client.chain.fork.blockNumber, + }) + }, + } +} diff --git a/wagmi-project/packages/test/src/config.ts b/wagmi-project/packages/test/src/config.ts new file mode 100644 index 000000000..a94cdf45d --- /dev/null +++ b/wagmi-project/packages/test/src/config.ts @@ -0,0 +1,29 @@ +import { createConfig, mock } from '@wagmi/core' +import { http } from 'viem' + +import { mainnet, mainnet2, optimism } from './chains.js' +import { accounts } from './constants.js' + +export const config = createConfig({ + chains: [mainnet, mainnet2, optimism], + connectors: [mock({ accounts }), mock({ accounts: reverse(accounts) })], + pollingInterval: 100, + storage: null, + transports: { + [mainnet.id]: http(), + [mainnet2.id]: http(), + [optimism.id]: http(), + }, +}) + +type Reverse< + list extends readonly unknown[], + /// + result extends readonly unknown[] = [], +> = list extends readonly [infer head, ...infer tail] + ? Reverse + : result + +function reverse(list: list): Reverse { + return [...list].reverse() as Reverse +} diff --git a/wagmi-project/packages/test/src/constants.ts b/wagmi-project/packages/test/src/constants.ts new file mode 100644 index 000000000..96ca5a9ef --- /dev/null +++ b/wagmi-project/packages/test/src/constants.ts @@ -0,0 +1,318 @@ +import { type Address, parseAbi } from 'viem' + +import type { chain } from './chains.js' + +/** + * The id of the current test worker. + * + * This is used by the anvil proxy to route requests to the correct anvil instance. + */ +export const pool = Number(process.env.VITEST_POOL_ID ?? 1) + +// Test accounts +export const accounts = [ + '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', + '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + '0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC', + '0x90F79bf6EB2c4f870365E785982E1f101E93b906', + '0x15d34aaf54267db7d7c367839aaf71a00a2c6a65', + '0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc', + '0x976EA74026E726554dB657fA54763abd0C3a0aa9', + '0x14dC79964da2C08b23698B3D3cc7Ca32193d9955', + '0x23618e81E3f5cdF7f54C3d65f7FBc0aBf5B21E8f', + '0xa0Ee7A142d267C1f36714E4a8F75612F20a79720', +] as const + +// for `'0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266'` +export const privateKey = + '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80' + +export let walletConnectProjectId: string +if (process.env.VITE_WC_PROJECT_ID) + walletConnectProjectId = process.env.VITE_WC_PROJECT_ID +else walletConnectProjectId = 'foobarbaz' + +export const typedData = { + basic: { + domain: { + name: 'Ether Mail', + version: '1', + chainId: 1, + verifyingContract: '0x0000000000000000000000000000000000000000', + }, + types: { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], + }, + message: { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, + }, + complex: { + domain: { + name: 'Ether Mail 🥵', + version: '1.1.1', + chainId: 1, + verifyingContract: '0x0000000000000000000000000000000000000000', + }, + types: { + Name: [ + { name: 'first', type: 'string' }, + { name: 'last', type: 'string' }, + ], + Person: [ + { name: 'name', type: 'Name' }, + { name: 'wallet', type: 'address' }, + { name: 'favoriteColors', type: 'string[3]' }, + { name: 'foo', type: 'uint256' }, + { name: 'age', type: 'uint8' }, + { name: 'isCool', type: 'bool' }, + ], + Mail: [ + { name: 'timestamp', type: 'uint256' }, + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + { name: 'hash', type: 'bytes' }, + ], + }, + message: { + timestamp: 1234567890n, + contents: 'Hello, Bob! 🖤', + hash: '0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef', + from: { + name: { + first: 'Cow', + last: 'Burns', + }, + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + age: 69, + foo: 123123123123123123n, + favoriteColors: ['red', 'green', 'blue'], + isCool: false, + }, + to: { + name: { first: 'Bob', last: 'Builder' }, + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + age: 70, + foo: 123123123123123123n, + favoriteColors: ['orange', 'yellow', 'green'], + isCool: true, + }, + }, + }, +} as const + +export const abi = { + erc20: parseAbi([ + 'event Approval(address indexed owner, address indexed spender, uint256 value)', + 'event Transfer(address indexed from, address indexed to, uint256 value)', + 'function allowance(address owner, address spender) view returns (uint256)', + 'function approve(address spender, uint256 amount) returns (bool)', + 'function balanceOf(address account) view returns (uint256)', + 'function decimals() view returns (uint8)', + 'function name() view returns (string)', + 'function symbol() view returns (string)', + 'function totalSupply() view returns (uint256)', + 'function transfer(address recipient, uint256 amount) returns (bool)', + 'function transferFrom(address sender, address recipient, uint256 amount) returns (bool)', + ]), + mloot: parseAbi([ + 'constructor()', + 'event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId)', + 'event ApprovalForAll(address indexed owner, address indexed operator, bool approved)', + 'event OwnershipTransferred(address indexed previousOwner, address indexed newOwner)', + 'event Transfer(address indexed from, address indexed to, uint256 indexed tokenId)', + 'function approve(address to, uint256 tokenId)', + 'function balanceOf(address owner) view returns (uint256)', + 'function claim(uint256 tokenId)', + 'function getApproved(uint256 tokenId) view returns (address)', + 'function getChest(uint256 tokenId) view returns (string)', + 'function getFoot(uint256 tokenId) view returns (string)', + 'function getHand(uint256 tokenId) view returns (string)', + 'function getHead(uint256 tokenId) view returns (string)', + 'function getNeck(uint256 tokenId) view returns (string)', + 'function getRing(uint256 tokenId) view returns (string)', + 'function getWaist(uint256 tokenId) view returns (string)', + 'function getWeapon(uint256 tokenId) view returns (string)', + 'function isApprovedForAll(address owner, address operator) view returns (bool)', + 'function name() view returns (string)', + 'function owner() view returns (address)', + 'function ownerOf(uint256 tokenId) view returns (address)', + 'function renounceOwnership()', + 'function safeTransferFrom(address from, address to, uint256 tokenId)', + 'function safeTransferFrom(address from, address to, uint256 tokenId, bytes _data)', + 'function setApprovalForAll(address operator, bool approved)', + 'function supportsInterface(bytes4 interfaceId) view returns (bool)', + 'function symbol() view returns (string)', + 'function tokenByIndex(uint256 index) view returns (uint256)', + 'function tokenOfOwnerByIndex(address owner, uint256 index) view returns (uint256)', + 'function tokenURI(uint256 tokenId) view returns (string)', + 'function totalSupply() view returns (uint256)', + 'function transferFrom(address from, address to, uint256 tokenId)', + 'function transferOwnership(address newOwner)', + ]), + shields: parseAbi([ + 'constructor(string name_, string symbol_, address _emblemWeaver, address makerBadgeRecipient, address granteeBadgeRecipient)', + 'event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId)', + 'event ApprovalForAll(address indexed owner, address indexed operator, bool approved)', + 'event OwnershipTransferred(address indexed previousOwner, address indexed newOwner)', + 'event ShieldBuilt(uint256 tokenId, uint16 field, uint16 hardware, uint16 frame, uint24[4] colors, uint8 shieldBadge)', + 'event Transfer(address indexed from, address indexed to, uint256 indexed tokenId)', + 'function approve(address to, uint256 tokenId)', + 'function balanceOf(address owner) view returns (uint256)', + 'function build(uint16 field, uint16 hardware, uint16 frame, uint24[4] colors, uint256 tokenId) payable', + 'function collectFees()', + 'function emblemWeaver() view returns (address)', + 'function getApproved(uint256 tokenId) view returns (address)', + 'function isApprovedForAll(address owner, address operator) view returns (bool)', + 'function mint(address to, uint8 count) payable', + 'function mythicFee() view returns (uint256)', + 'function name() view returns (string)', + 'function owner() view returns (address)', + 'function ownerOf(uint256 tokenId) view returns (address)', + 'function publicMintActive() view returns (bool)', + 'function publicMintPrice() view returns (uint256)', + 'function renounceOwnership()', + 'function safeTransferFrom(address from, address to, uint256 tokenId)', + 'function safeTransferFrom(address from, address to, uint256 tokenId, bytes _data)', + 'function setApprovalForAll(address operator, bool approved)', + 'function setPublicMintActive()', + 'function setPublicMintPrice(uint256 _publicMintPrice)', + 'function shieldHashes(bytes32) view returns (bool)', + 'function shields(uint256 tokenId) view returns (uint16 field, uint16 hardware, uint16 frame, uint24 color1, uint24 color2, uint24 color3, uint24 color4, uint8 shieldBadge)', + 'function specialFee() view returns (uint256)', + 'function supportsInterface(bytes4 interfaceId) view returns (bool)', + 'function symbol() view returns (string)', + 'function tokenURI(uint256 tokenId) view returns (string)', + 'function totalSupply() view returns (uint256)', + 'function transferFrom(address from, address to, uint256 tokenId)', + 'function transferOwnership(address newOwner)', + ]), + wagmigotchi: parseAbi([ + 'constructor()', + 'event CaretakerLoved(address indexed caretaker, uint256 indexed amount)', + 'function clean()', + 'function feed()', + 'function getAlive() view returns (bool)', + 'function getBoredom() view returns (uint256)', + 'function getHunger() view returns (uint256)', + 'function getSleepiness() view returns (uint256)', + 'function getStatus() view returns (string)', + 'function getUncleanliness() view returns (uint256)', + 'function love(address) view returns (uint256)', + 'function play()', + 'function sleep()', + ]), + wagmiMintExample: parseAbi([ + 'constructor()', + 'event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId)', + 'event ApprovalForAll(address indexed owner, address indexed operator, bool approved)', + 'event Transfer(address indexed from, address indexed to, uint256 indexed tokenId)', + 'function approve(address to, uint256 tokenId)', + 'function balanceOf(address owner) view returns (uint256)', + 'function getApproved(uint256 tokenId) view returns (address)', + 'function isApprovedForAll(address owner, address operator) view returns (bool)', + 'function mint()', + 'function name() view returns (string)', + 'function ownerOf(uint256 tokenId) view returns (address)', + 'function safeTransferFrom(address from, address to, uint256 tokenId)', + 'function safeTransferFrom(address from, address to, uint256 tokenId, bytes _data)', + 'function setApprovalForAll(address operator, bool approved)', + 'function supportsInterface(bytes4 interfaceId) view returns (bool)', + 'function symbol() view returns (string)', + 'function tokenURI(uint256 tokenId) pure returns (string)', + 'function totalSupply() view returns (uint256)', + 'function transferFrom(address from, address to, uint256 tokenId)', + ]), + viewOverloads: parseAbi([ + 'function foo() view returns (int8)', + 'function foo(address) view returns (string)', + 'function foo(address, address) view returns ((address foo, address bar))', + 'function bar() view returns (int8)', + ]), + writeOverloads: parseAbi([ + 'function foo() payable returns (int8)', + 'function foo(address) returns (string)', + 'function foo(address, address) returns ((address foo, address bar))', + 'function bar() payable returns (int8)', + ]), + bayc: parseAbi([ + 'constructor(string name, string symbol, uint256 maxNftSupply, uint256 saleStart)', + 'function mintApe(uint256 numberOfTokens) payable', + 'function reserveApes()', + 'function flipSaleState()', + 'function emergencySetStartingIndexBlock()', + 'function setStartingIndex()', + 'function setRevealTimestamp(uint256 revealTimeStamp)', + 'function setProvenanceHash(string provenanceHash)', + 'function setBaseURI(string baseURI)', + 'function startingIndex() view returns (uint256)', + 'function startingIndexBlock() view returns (uint256)', + 'function saleIsActive() view returns (bool)', + 'function maxApePurchase() view returns (uint256)', + 'function apePrice() view returns (uint256)', + 'function REVEAL_TIMESTAMP() view returns (uint256)', + 'function MAX_APES() view returns (uint256)', + 'function BAYC_PROVENANCE() view returns (string)', + 'function name() view returns (string)', + 'function symbol() view returns (string)', + 'function totalSupply() view returns (uint256)', + 'function balanceOf(address owner) view returns (uint256)', + 'function ownerOf(uint256 tokenId) view returns (address)', + 'function getApproved(uint256 tokenId) view returns (address)', + 'function isApprovedForAll(address owner, address operator) view returns (bool)', + 'function approve(address to, uint256 tokenId)', + 'function setApprovalForAll(address operator, bool approved)', + 'function safeTransferFrom(address from, address to, uint256 tokenId)', + 'function safeTransferFrom(address from, address to, uint256 tokenId, bytes _data)', + 'function tokenOfOwnerByIndex(address owner, uint256 index) view returns (uint256)', + 'function tokenByIndex(uint256 index) view returns (uint256)', + 'function tokenURI(uint256 tokenId) view returns (string)', + 'function supportsInterface(bytes4 interfaceId) view returns (bool)', + 'function transferFrom(address from, address to, uint256 tokenId)', + 'function renounceOwnership()', + 'function transferOwnership(address newOwner)', + 'function withdraw()', + ]), +} as const + +const mainnetAddress = { + mloot: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + shields: '0x0747118c9f44c7a23365b2476dcd05e03114c747', + usdc: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', + usdcHolder: '0x5414d89a8bf7e99d732bc52f3e6a3ef461c0c078', + wagmigotchi: '0xecb504d39723b0be0e3a9aa33d646642d1051ee1', + wagmiMintExample: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', +} as const + +export const address = { + ...mainnetAddress, + mainnet: mainnetAddress, + mainnet2: mainnetAddress, + optimism: { + usdc: '0x7f5c764cbc14f9669b88837ca1490cca17c31607', + }, +} as const satisfies Record & + Record> + +export const bytecode = { + bayc: '0x608060405260405180602001604052806000815250600b90805190602001906200002b92919062000484565b506000600f60006101000a81548160ff0219169083151502179055503480156200005457600080fd5b50604051620046d0380380620046d0833981810160405260808110156200007a57600080fd5b81019080805160405193929190846401000000008211156200009b57600080fd5b83820191506020820185811115620000b257600080fd5b8251866001820283011164010000000082111715620000d057600080fd5b8083526020830192505050908051906020019080838360005b8381101562000106578082015181840152602081019050620000e9565b50505050905090810190601f168015620001345780820380516001836020036101000a031916815260200191505b50604052602001805160405193929190846401000000008211156200015857600080fd5b838201915060208201858111156200016f57600080fd5b82518660018202830111640100000000821117156200018d57600080fd5b8083526020830192505050908051906020019080838360005b83811015620001c3578082015181840152602081019050620001a6565b50505050905090810190601f168015620001f15780820380516001836020036101000a031916815260200191505b5060405260200180519060200190929190805190602001909291905050508383620002296301ffc9a760e01b6200037360201b60201c565b81600690805190602001906200024192919062000484565b5080600790805190602001906200025a92919062000484565b50620002736380ac58cd60e01b6200037360201b60201c565b6200028b635b5e139f60e01b6200037360201b60201c565b620002a363780e9d6360e01b6200037360201b60201c565b50506000620002b76200047c60201b60201c565b905080600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35081600e81905550620bdd808101601081905550505050506200052a565b63ffffffff60e01b817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141562000410576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601c8152602001807f4552433136353a20696e76616c696420696e746572666163652069640000000081525060200191505060405180910390fd5b6001600080837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b600033905090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10620004c757805160ff1916838001178555620004f8565b82800160010185558215620004f8579182015b82811115620004f7578251825591602001919060010190620004da565b5b5090506200050791906200050b565b5090565b5b80821115620005265760008160009055506001016200050c565b5090565b614196806200053a6000396000f3fe60806040526004361061021a5760003560e01c80636c0360eb11610123578063b0f67427116100ab578063e36d64981161006f578063e36d649814610ddf578063e985e9c514610e0a578063e986655014610e91578063eb8d244414610ea8578063f2fde38b14610ed55761021a565b8063b0f6742714610bac578063b88d4fde14610bc3578063bb8a16bd14610cd5578063c87b56dd14610d00578063cb774d4714610db45761021a565b80637d17fcbe116100f25780637d17fcbe14610a395780638da5cb5b14610a5057806395d89b4114610a91578063a22cb46514610b21578063a723533e14610b7e5761021a565b80636c0360eb1461090257806370a0823114610992578063715018a6146109f75780637a3f451e14610a0e5761021a565b80632f745c59116101a65780634f6ccce7116101755780634f6ccce7146106cb57806355f804b31461071a578063571dff3b146107e2578063607e20e31461080d5780636352211e1461089d5761021a565b80632f745c59146105b357806334918dfd146106225780633ccfd60b1461063957806342842e0e146106505761021a565b8063095ea7b3116101ed578063095ea7b3146103bf578063109695231461041a57806318160ddd146104e257806318e20a381461050d57806323b872dd146105385761021a565b8063018a2c371461021f57806301ffc9a71461025a57806306fdde03146102ca578063081812fc1461035a575b600080fd5b34801561022b57600080fd5b506102586004803603602081101561024257600080fd5b8101908080359060200190929190505050610f26565b005b34801561026657600080fd5b506102b26004803603602081101561027d57600080fd5b8101908080357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19169060200190929190505050610fdf565b60405180821515815260200191505060405180910390f35b3480156102d657600080fd5b506102df611046565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561031f578082015181840152602081019050610304565b50505050905090810190601f16801561034c5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561036657600080fd5b506103936004803603602081101561037d57600080fd5b81019080803590602001909291905050506110e8565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156103cb57600080fd5b50610418600480360360408110156103e257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611183565b005b34801561042657600080fd5b506104e06004803603602081101561043d57600080fd5b810190808035906020019064010000000081111561045a57600080fd5b82018360208201111561046c57600080fd5b8035906020019184600183028401116401000000008311171561048e57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192905050506112c7565b005b3480156104ee57600080fd5b506104f7611390565b6040518082815260200191505060405180910390f35b34801561051957600080fd5b506105226113a1565b6040518082815260200191505060405180910390f35b34801561054457600080fd5b506105b16004803603606081101561055b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506113a7565b005b3480156105bf57600080fd5b5061060c600480360360408110156105d657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061141d565b6040518082815260200191505060405180910390f35b34801561062e57600080fd5b50610637611478565b005b34801561064557600080fd5b5061064e611553565b005b34801561065c57600080fd5b506106c96004803603606081101561067357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611651565b005b3480156106d757600080fd5b50610704600480360360208110156106ee57600080fd5b8101908080359060200190929190505050611671565b6040518082815260200191505060405180910390f35b34801561072657600080fd5b506107e06004803603602081101561073d57600080fd5b810190808035906020019064010000000081111561075a57600080fd5b82018360208201111561076c57600080fd5b8035906020019184600183028401116401000000008311171561078e57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050611694565b005b3480156107ee57600080fd5b506107f761174f565b6040518082815260200191505060405180910390f35b34801561081957600080fd5b50610822611754565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610862578082015181840152602081019050610847565b50505050905090810190601f16801561088f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156108a957600080fd5b506108d6600480360360208110156108c057600080fd5b81019080803590602001909291905050506117f2565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561090e57600080fd5b50610917611829565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561095757808201518184015260208101905061093c565b50505050905090810190601f1680156109845780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561099e57600080fd5b506109e1600480360360208110156109b557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506118cb565b6040518082815260200191505060405180910390f35b348015610a0357600080fd5b50610a0c6119a0565b005b348015610a1a57600080fd5b50610a23611b10565b6040518082815260200191505060405180910390f35b348015610a4557600080fd5b50610a4e611b1c565b005b348015610a5c57600080fd5b50610a65611c4c565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b348015610a9d57600080fd5b50610aa6611c76565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610ae6578082015181840152602081019050610acb565b50505050905090810190601f168015610b135780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b348015610b2d57600080fd5b50610b7c60048036036040811015610b4457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803515159060200190929190505050611d18565b005b610baa60048036036020811015610b9457600080fd5b8101908080359060200190929190505050611ece565b005b348015610bb857600080fd5b50610bc1612127565b005b348015610bcf57600080fd5b50610cd360048036036080811015610be657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190640100000000811115610c4d57600080fd5b820183602082011115610c5f57600080fd5b80359060200191846001830284011164010000000083111715610c8157600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929050505061220b565b005b348015610ce157600080fd5b50610cea612283565b6040518082815260200191505060405180910390f35b348015610d0c57600080fd5b50610d3960048036036020811015610d2357600080fd5b8101908080359060200190929190505050612289565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610d79578082015181840152602081019050610d5e565b50505050905090810190601f168015610da65780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b348015610dc057600080fd5b50610dc961255a565b6040518082815260200191505060405180910390f35b348015610deb57600080fd5b50610df4612560565b6040518082815260200191505060405180910390f35b348015610e1657600080fd5b50610e7960048036036040811015610e2d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612566565b60405180821515815260200191505060405180910390f35b348015610e9d57600080fd5b50610ea66125fa565b005b348015610eb457600080fd5b50610ebd612764565b60405180821515815260200191505060405180910390f35b348015610ee157600080fd5b50610f2460048036036020811015610ef857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612777565b005b610f2e61296c565b73ffffffffffffffffffffffffffffffffffffffff16610f4c611c4c565b73ffffffffffffffffffffffffffffffffffffffff1614610fd5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b8060108190555050565b6000806000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060009054906101000a900460ff169050919050565b606060068054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156110de5780601f106110b3576101008083540402835291602001916110de565b820191906000526020600020905b8154815290600101906020018083116110c157829003601f168201915b5050505050905090565b60006110f382612974565b611148576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c81526020018061408b602c913960400191505060405180910390fd5b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600061118e826117f2565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415611215576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602181526020018061410f6021913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1661123461296c565b73ffffffffffffffffffffffffffffffffffffffff16148061126357506112628161125d61296c565b612566565b5b6112b8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526038815260200180613f956038913960400191505060405180910390fd5b6112c28383612991565b505050565b6112cf61296c565b73ffffffffffffffffffffffffffffffffffffffff166112ed611c4c565b73ffffffffffffffffffffffffffffffffffffffff1614611376576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b80600b908051906020019061138c929190613de6565b5050565b600061139c6002612a4a565b905090565b60105481565b6113b86113b261296c565b82612a5f565b61140d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260318152602001806141306031913960400191505060405180910390fd5b611418838383612b53565b505050565b600061147082600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020612d9690919063ffffffff16565b905092915050565b61148061296c565b73ffffffffffffffffffffffffffffffffffffffff1661149e611c4c565b73ffffffffffffffffffffffffffffffffffffffff1614611527576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600f60009054906101000a900460ff1615600f60006101000a81548160ff021916908315150217905550565b61155b61296c565b73ffffffffffffffffffffffffffffffffffffffff16611579611c4c565b73ffffffffffffffffffffffffffffffffffffffff1614611602576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b60004790503373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f1935050505015801561164d573d6000803e3d6000fd5b5050565b61166c8383836040518060200160405280600081525061220b565b505050565b600080611688836002612db090919063ffffffff16565b50905080915050919050565b61169c61296c565b73ffffffffffffffffffffffffffffffffffffffff166116ba611c4c565b73ffffffffffffffffffffffffffffffffffffffff1614611743576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b61174c81612ddc565b50565b601481565b600b8054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156117ea5780601f106117bf576101008083540402835291602001916117ea565b820191906000526020600020905b8154815290600101906020018083116117cd57829003601f168201915b505050505081565b600061182282604051806060016040528060298152602001613ff7602991396002612df69092919063ffffffff16565b9050919050565b606060098054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156118c15780601f10611896576101008083540402835291602001916118c1565b820191906000526020600020905b8154815290600101906020018083116118a457829003601f168201915b5050505050905090565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611952576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180613fcd602a913960400191505060405180910390fd5b611999600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020612e15565b9050919050565b6119a861296c565b73ffffffffffffffffffffffffffffffffffffffff166119c6611c4c565b73ffffffffffffffffffffffffffffffffffffffff1614611a4f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a36000600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b67011c37937e08000081565b611b2461296c565b73ffffffffffffffffffffffffffffffffffffffff16611b42611c4c565b73ffffffffffffffffffffffffffffffffffffffff1614611bcb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b6000600d5414611c43576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f5374617274696e6720696e64657820697320616c72656164792073657400000081525060200191505060405180910390fd5b43600c81905550565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060078054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015611d0e5780601f10611ce357610100808354040283529160200191611d0e565b820191906000526020600020905b815481529060010190602001808311611cf157829003601f168201915b5050505050905090565b611d2061296c565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611dc1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f4552433732313a20617070726f766520746f2063616c6c65720000000000000081525060200191505060405180910390fd5b8060056000611dce61296c565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16611e7b61296c565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405180821515815260200191505060405180910390a35050565b600f60009054906101000a900460ff16611f50576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f53616c65206d7573742062652061637469766520746f206d696e74204170650081525060200191505060405180910390fd5b6014811115611faa576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180613f746021913960400191505060405180910390fd5b600e54611fc782611fb9611390565b612e2a90919063ffffffff16565b111561201e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260288152602001806140426028913960400191505060405180910390fd5b3461203a8267011c37937e080000612eb290919063ffffffff16565b11156120ae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f45746865722076616c75652073656e74206973206e6f7420636f72726563740081525060200191505060405180910390fd5b60005b818110156120ef5760006120c3611390565b9050600e546120d0611390565b10156120e1576120e03382612f38565b5b5080806001019150506120b1565b506000600c541480156121175750600e54612108611390565b148061211657506010544210155b5b156121245743600c819055505b50565b61212f61296c565b73ffffffffffffffffffffffffffffffffffffffff1661214d611c4c565b73ffffffffffffffffffffffffffffffffffffffff16146121d6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b60006121e0611390565b905060005b601e811015612207576121fa33828401612f38565b80806001019150506121e5565b5050565b61221c61221661296c565b83612a5f565b612271576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260318152602001806141306031913960400191505060405180910390fd5b61227d84848484612f56565b50505050565b600e5481565b606061229482612974565b6122e9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602f8152602001806140e0602f913960400191505060405180910390fd5b6060600860008481526020019081526020016000208054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156123925780601f1061236757610100808354040283529160200191612392565b820191906000526020600020905b81548152906001019060200180831161237557829003601f168201915b5050505050905060606123a3611829565b90506000815114156123b9578192505050612555565b60008251111561248a5780826040516020018083805190602001908083835b602083106123fb57805182526020820191506020810190506020830392506123d8565b6001836020036101000a03801982511681845116808217855250505050505090500182805190602001908083835b6020831061244c5780518252602082019150602081019050602083039250612429565b6001836020036101000a0380198251168184511680821785525050505050509050019250505060405160208183030381529060405292505050612555565b8061249485612fc8565b6040516020018083805190602001908083835b602083106124ca57805182526020820191506020810190506020830392506124a7565b6001836020036101000a03801982511681845116808217855250505050505090500182805190602001908083835b6020831061251b57805182526020820191506020810190506020830392506124f8565b6001836020036101000a03801982511681845116808217855250505050505090500192505050604051602081830303815290604052925050505b919050565b600d5481565b600c5481565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6000600d5414612672576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f5374617274696e6720696e64657820697320616c72656164792073657400000081525060200191505060405180910390fd5b6000600c5414156126eb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f5374617274696e6720696e64657820626c6f636b206d7573742062652073657481525060200191505060405180910390fd5b600e54600c544060001c816126fc57fe5b06600d8190555060ff61271a600c544361310f90919063ffffffff16565b111561273a57600e54600143034060001c8161273257fe5b06600d819055505b6000600d5414156127625761275b6001600d54612e2a90919063ffffffff16565b600d819055505b565b600f60009054906101000a900460ff1681565b61277f61296c565b73ffffffffffffffffffffffffffffffffffffffff1661279d611c4c565b73ffffffffffffffffffffffffffffffffffffffff1614612826576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156128ac576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180613ed86026913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a380600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600033905090565b600061298a82600261319290919063ffffffff16565b9050919050565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16612a04836117f2565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000612a58826000016131ac565b9050919050565b6000612a6a82612974565b612abf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180613f48602c913960400191505060405180910390fd5b6000612aca836117f2565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480612b3957508373ffffffffffffffffffffffffffffffffffffffff16612b21846110e8565b73ffffffffffffffffffffffffffffffffffffffff16145b80612b4a5750612b498185612566565b5b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff16612b73826117f2565b73ffffffffffffffffffffffffffffffffffffffff1614612bdf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260298152602001806140b76029913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612c65576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526024815260200180613efe6024913960400191505060405180910390fd5b612c708383836131bd565b612c7b600082612991565b612ccc81600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206131c290919063ffffffff16565b50612d1e81600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206131dc90919063ffffffff16565b50612d35818360026131f69092919063ffffffff16565b50808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b6000612da5836000018361322b565b60001c905092915050565b600080600080612dc386600001866132ae565b915091508160001c8160001c9350935050509250929050565b8060099080519060200190612df2929190613de6565b5050565b6000612e09846000018460001b84613347565b60001c90509392505050565b6000612e238260000161343d565b9050919050565b600080828401905083811015612ea8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b600080831415612ec55760009050612f32565b6000828402905082848281612ed657fe5b0414612f2d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602181526020018061406a6021913960400191505060405180910390fd5b809150505b92915050565b612f5282826040518060200160405280600081525061344e565b5050565b612f61848484612b53565b612f6d848484846134bf565b612fc2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526032815260200180613ea66032913960400191505060405180910390fd5b50505050565b60606000821415613010576040518060400160405280600181526020017f3000000000000000000000000000000000000000000000000000000000000000815250905061310a565b600082905060005b6000821461303a578080600101915050600a828161303257fe5b049150613018565b60608167ffffffffffffffff8111801561305357600080fd5b506040519080825280601f01601f1916602001820160405280156130865781602001600182028036833780820191505090505b50905060006001830390508593505b6000841461310257600a84816130a757fe5b0660300160f81b828280600190039350815181106130c157fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a84816130fa57fe5b049350613095565b819450505050505b919050565b600082821115613187576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525060200191505060405180910390fd5b818303905092915050565b60006131a4836000018360001b6136d8565b905092915050565b600081600001805490509050919050565b505050565b60006131d4836000018360001b6136fb565b905092915050565b60006131ee836000018360001b6137e3565b905092915050565b6000613222846000018460001b8473ffffffffffffffffffffffffffffffffffffffff1660001b613853565b90509392505050565b60008183600001805490501161328c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180613e846022913960400191505060405180910390fd5b82600001828154811061329b57fe5b9060005260206000200154905092915050565b60008082846000018054905011613310576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806140206022913960400191505060405180910390fd5b600084600001848154811061332157fe5b906000526020600020906002020190508060000154816001015492509250509250929050565b6000808460010160008581526020019081526020016000205490506000811415839061340e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b838110156133d35780820151818401526020810190506133b8565b50505050905090810190601f1680156134005780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5084600001600182038154811061342157fe5b9060005260206000209060020201600101549150509392505050565b600081600001805490509050919050565b613458838361392f565b61346560008484846134bf565b6134ba576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526032815260200180613ea66032913960400191505060405180910390fd5b505050565b60006134e08473ffffffffffffffffffffffffffffffffffffffff16613b23565b6134ed57600190506136d0565b606061365763150b7a0260e01b61350261296c565b888787604051602401808573ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff16815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561358657808201518184015260208101905061356b565b50505050905090810190601f1680156135b35780820380516001836020036101000a031916815260200191505b5095505050505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051806060016040528060328152602001613ea6603291398773ffffffffffffffffffffffffffffffffffffffff16613b369092919063ffffffff16565b9050600081806020019051602081101561367057600080fd5b8101908080519060200190929190505050905063150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614925050505b949350505050565b600080836001016000848152602001908152602001600020541415905092915050565b600080836001016000848152602001908152602001600020549050600081146137d7576000600182039050600060018660000180549050039050600086600001828154811061374657fe5b906000526020600020015490508087600001848154811061376357fe5b906000526020600020018190555060018301876001016000838152602001908152602001600020819055508660000180548061379b57fe5b600190038181906000526020600020016000905590558660010160008781526020019081526020016000206000905560019450505050506137dd565b60009150505b92915050565b60006137ef8383613b4e565b61384857826000018290806001815401808255809150506001900390600052602060002001600090919091909150558260000180549050836001016000848152602001908152602001600020819055506001905061384d565b600090505b92915050565b60008084600101600085815260200190815260200160002054905060008114156138fa57846000016040518060400160405280868152602001858152509080600181540180825580915050600190039060005260206000209060020201600090919091909150600082015181600001556020820151816001015550508460000180549050856001016000868152602001908152602001600020819055506001915050613928565b8285600001600183038154811061390d57fe5b90600052602060002090600202016001018190555060009150505b9392505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156139d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4552433732313a206d696e7420746f20746865207a65726f206164647265737381525060200191505060405180910390fd5b6139db81612974565b15613a4e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601c8152602001807f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000081525060200191505060405180910390fd5b613a5a600083836131bd565b613aab81600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206131dc90919063ffffffff16565b50613ac2818360026131f69092919063ffffffff16565b50808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050565b600080823b905060008111915050919050565b6060613b458484600085613b71565b90509392505050565b600080836001016000848152602001908152602001600020541415905092915050565b606082471015613bcc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180613f226026913960400191505060405180910390fd5b613bd585613b23565b613c47576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000081525060200191505060405180910390fd5b600060608673ffffffffffffffffffffffffffffffffffffffff1685876040518082805190602001908083835b60208310613c975780518252602082019150602081019050602083039250613c74565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114613cf9576040519150601f19603f3d011682016040523d82523d6000602084013e613cfe565b606091505b5091509150613d0e828286613d1a565b92505050949350505050565b60608315613d2a57829050613ddf565b600083511115613d3d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613da4578082015181840152602081019050613d89565b50505050905090810190601f168015613dd15780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b9392505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10613e2757805160ff1916838001178555613e55565b82800160010185558215613e55579182015b82811115613e54578251825591602001919060010190613e39565b5b509050613e629190613e66565b5090565b5b80821115613e7f576000816000905550600101613e67565b509056fe456e756d657261626c655365743a20696e646578206f7574206f6620626f756e64734552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e7465724f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573734552433732313a207472616e7366657220746f20746865207a65726f2061646472657373416464726573733a20696e73756666696369656e742062616c616e636520666f722063616c6c4552433732313a206f70657261746f7220717565727920666f72206e6f6e6578697374656e7420746f6b656e43616e206f6e6c79206d696e7420323020746f6b656e7320617420612074696d654552433732313a20617070726f76652063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f76656420666f7220616c6c4552433732313a2062616c616e636520717565727920666f7220746865207a65726f20616464726573734552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656e456e756d657261626c654d61703a20696e646578206f7574206f6620626f756e6473507572636861736520776f756c6420657863656564206d617820737570706c79206f662041706573536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774552433732313a20617070726f76656420717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732313a207472616e73666572206f6620746f6b656e2074686174206973206e6f74206f776e4552433732314d657461646174613a2055524920717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732313a20617070726f76616c20746f2063757272656e74206f776e65724552433732313a207472616e736665722063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f766564a2646970667358221220b0e64d1fa6c4dbeb9c6f54607d7e1996943fe27624a80652f57b53fda084621b64736f6c63430007000033000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000002710000000000000000000000000000000000000000000000000000000006080e6d70000000000000000000000000000000000000000000000000000000000000011426f7265644170655961636874436c756200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044241594300000000000000000000000000000000000000000000000000000000', + wagmiMintExample: + '0x608060405260006007553480156200001657600080fd5b50604051806040016040528060058152602001647761676d6960d81b815250604051806040016040528060058152602001645741474d4960d81b81525081600090805190602001906200006b9291906200008a565b508051620000819060019060208401906200008a565b5050506200016c565b828054620000989062000130565b90600052602060002090601f016020900481019282620000bc576000855562000107565b82601f10620000d757805160ff191683800117855562000107565b8280016001018555821562000107579182015b8281111562000107578251825591602001919060010190620000ea565b506200011592915062000119565b5090565b5b808211156200011557600081556001016200011a565b600181811c908216806200014557607f821691505b6020821081036200016657634e487b7160e01b600052602260045260246000fd5b50919050565b6128c2806200017c6000396000f3fe608060405234801561001057600080fd5b50600436106101005760003560e01c80636352211e11610097578063a22cb46511610066578063a22cb46514610215578063b88d4fde14610228578063c87b56dd1461023b578063e985e9c51461024e57600080fd5b80636352211e146101d457806370a08231146101e757806395d89b41146101fa578063a0712d681461020257600080fd5b80631249c58b116100d35780631249c58b1461018f57806318160ddd1461019757806323b872dd146101ae57806342842e0e146101c157600080fd5b806301ffc9a71461010557806306fdde031461012d578063081812fc14610142578063095ea7b31461017a575b600080fd5b61011861011336600461178f565b610297565b60405190151581526020015b60405180910390f35b61013561037c565b6040516101249190611829565b61015561015036600461183c565b61040e565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610124565b61018d61018836600461187e565b6104d3565b005b61018d61062b565b6101a060065481565b604051908152602001610124565b61018d6101bc3660046118a8565b61067d565b61018d6101cf3660046118a8565b610704565b6101556101e236600461183c565b61071f565b6101a06101f53660046118e4565b6107b7565b61013561086b565b61018d61021036600461183c565b61087a565b61018d6102233660046118ff565b610902565b61018d61023636600461196a565b610911565b61013561024936600461183c565b61099f565b61011861025c366004611a64565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260056020908152604080832093909416825291909152205460ff1690565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f80ac58cd00000000000000000000000000000000000000000000000000000000148061032a57507fffffffff0000000000000000000000000000000000000000000000000000000082167f5b5e139f00000000000000000000000000000000000000000000000000000000145b8061037657507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b60606000805461038b90611a97565b80601f01602080910402602001604051908101604052809291908181526020018280546103b790611a97565b80156104045780601f106103d957610100808354040283529160200191610404565b820191906000526020600020905b8154815290600101906020018083116103e757829003601f168201915b5050505050905090565b60008181526002602052604081205473ffffffffffffffffffffffffffffffffffffffff166104aa5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201527f697374656e7420746f6b656e000000000000000000000000000000000000000060648201526084015b60405180910390fd5b5060009081526004602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b60006104de8261071f565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036105815760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560448201527f720000000000000000000000000000000000000000000000000000000000000060648201526084016104a1565b3373ffffffffffffffffffffffffffffffffffffffff821614806105aa57506105aa813361025c565b61061c5760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c000000000000000060648201526084016104a1565b6106268383610b07565b505050565b6007545b60008181526002602052604090205473ffffffffffffffffffffffffffffffffffffffff16156106615760010161062f565b61066b3382610ba7565b60068054600190810190915501600755565b6106873382610bc1565b6106f95760405162461bcd60e51b815260206004820152603160248201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60448201527f776e6572206e6f7220617070726f76656400000000000000000000000000000060648201526084016104a1565b610626838383610d17565b61062683838360405180602001604052806000815250610911565b60008181526002602052604081205473ffffffffffffffffffffffffffffffffffffffff16806103765760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201527f656e7420746f6b656e000000000000000000000000000000000000000000000060648201526084016104a1565b600073ffffffffffffffffffffffffffffffffffffffff82166108425760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a6560448201527f726f20616464726573730000000000000000000000000000000000000000000060648201526084016104a1565b5073ffffffffffffffffffffffffffffffffffffffff1660009081526003602052604090205490565b60606001805461038b90611a97565b60008181526002602052604090205473ffffffffffffffffffffffffffffffffffffffff16156108ec5760405162461bcd60e51b815260206004820152601160248201527f546f6b656e2049442069732074616b656e00000000000000000000000000000060448201526064016104a1565b6108f63382610ba7565b50600680546001019055565b61090d338383610f4a565b5050565b61091b3383610bc1565b61098d5760405162461bcd60e51b815260206004820152603160248201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60448201527f776e6572206e6f7220617070726f76656400000000000000000000000000000060648201526084016104a1565b6109998484848461105d565b50505050565b6040517f666f726567726f756e64000000000000000000000000000000000000000000006020820152602a810182905260609060009061016890604a016040516020818303038152906040528051906020012060001c6109ff9190611b19565b6040517f6261636b67726f756e64000000000000000000000000000000000000000000006020820152602a810185905290915060009061016890604a016040516020818303038152906040528051906020012060001c610a5f9190611b19565b90506000610aba610a6f866110e6565b610aa9610a7b866110e6565b610a84866110e6565b604051602001610a95929190611b2d565b60405160208183030381529060405261121b565b604051602001610a959291906125ba565b9050600081604051602001610acf919061268b565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190529695505050505050565b600081815260046020526040902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84169081179091558190610b618261071f565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b61090d82826040518060200160405280600081525061136e565b60008181526002602052604081205473ffffffffffffffffffffffffffffffffffffffff16610c585760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201527f697374656e7420746f6b656e000000000000000000000000000000000000000060648201526084016104a1565b6000610c638361071f565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480610cd1575073ffffffffffffffffffffffffffffffffffffffff80821660009081526005602090815260408083209388168352929052205460ff165b80610d0f57508373ffffffffffffffffffffffffffffffffffffffff16610cf78461040e565b73ffffffffffffffffffffffffffffffffffffffff16145b949350505050565b8273ffffffffffffffffffffffffffffffffffffffff16610d378261071f565b73ffffffffffffffffffffffffffffffffffffffff1614610dc05760405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201527f6f776e657200000000000000000000000000000000000000000000000000000060648201526084016104a1565b73ffffffffffffffffffffffffffffffffffffffff8216610e485760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f2061646460448201527f726573730000000000000000000000000000000000000000000000000000000060648201526084016104a1565b610e53600082610b07565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600360205260408120805460019290610e899084906126ff565b909155505073ffffffffffffffffffffffffffffffffffffffff82166000908152600360205260408120805460019290610ec4908490612716565b909155505060008181526002602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff86811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610fc55760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c65720000000000000060448201526064016104a1565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526005602090815260408083209487168084529482529182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b611068848484610d17565b611074848484846113f7565b6109995760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e746572000000000000000000000000000060648201526084016104a1565b60608160000361112957505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115611153578061113d8161272e565b915061114c9050600a83612766565b915061112d565b60008167ffffffffffffffff81111561116e5761116e61193b565b6040519080825280601f01601f191660200182016040528015611198576020820181803683370190505b5090505b8415610d0f576111ad6001836126ff565b91506111ba600a86611b19565b6111c5906030612716565b60f81b8183815181106111da576111da61277a565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350611214600a86612766565b945061119c565b6060815160000361123a57505060408051602081019091526000815290565b600060405180606001604052806040815260200161284d60409139905060006003845160026112699190612716565b6112739190612766565b61127e9060046127a9565b67ffffffffffffffff8111156112965761129661193b565b6040519080825280601f01601f1916602001820160405280156112c0576020820181803683370190505b509050600182016020820185865187015b8082101561132c576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f81168501518453506001830192506112d1565b5050600386510660018114611348576002811461135b57611363565b603d6001830353603d6002830353611363565b603d60018303535b509195945050505050565b61137883836115d0565b61138560008484846113f7565b6106265760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e746572000000000000000000000000000060648201526084016104a1565b600073ffffffffffffffffffffffffffffffffffffffff84163b156115c5576040517f150b7a0200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85169063150b7a029061146e9033908990889088906004016127e6565b6020604051808303816000875af19250505080156114c7575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682019092526114c49181019061282f565b60015b61157a573d8080156114f5576040519150601f19603f3d011682016040523d82523d6000602084013e6114fa565b606091505b5080516000036115725760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e746572000000000000000000000000000060648201526084016104a1565b805181602001fd5b7fffffffff00000000000000000000000000000000000000000000000000000000167f150b7a0200000000000000000000000000000000000000000000000000000000149050610d0f565b506001949350505050565b73ffffffffffffffffffffffffffffffffffffffff82166116335760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f206164647265737360448201526064016104a1565b60008181526002602052604090205473ffffffffffffffffffffffffffffffffffffffff16156116a55760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000060448201526064016104a1565b73ffffffffffffffffffffffffffffffffffffffff821660009081526003602052604081208054600192906116db908490612716565b909155505060008181526002602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b7fffffffff000000000000000000000000000000000000000000000000000000008116811461178c57600080fd5b50565b6000602082840312156117a157600080fd5b81356117ac8161175e565b9392505050565b60005b838110156117ce5781810151838201526020016117b6565b838111156109995750506000910152565b600081518084526117f78160208601602086016117b3565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006117ac60208301846117df565b60006020828403121561184e57600080fd5b5035919050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461187957600080fd5b919050565b6000806040838503121561189157600080fd5b61189a83611855565b946020939093013593505050565b6000806000606084860312156118bd57600080fd5b6118c684611855565b92506118d460208501611855565b9150604084013590509250925092565b6000602082840312156118f657600080fd5b6117ac82611855565b6000806040838503121561191257600080fd5b61191b83611855565b91506020830135801515811461193057600080fd5b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000806000806080858703121561198057600080fd5b61198985611855565b935061199760208601611855565b925060408501359150606085013567ffffffffffffffff808211156119bb57600080fd5b818701915087601f8301126119cf57600080fd5b8135818111156119e1576119e161193b565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715611a2757611a2761193b565b816040528281528a6020848701011115611a4057600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b60008060408385031215611a7757600080fd5b611a8083611855565b9150611a8e60208401611855565b90509250929050565b600181811c90821680611aab57607f821691505b602082108103611ae4577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082611b2857611b28611aea565b500690565b7f3c73766720786d6c6e733d22687474703a2f2f7777772e77332e6f72672f323081527f30302f737667222077696474683d223130323422206865696768743d2231303260208201527f34222066696c6c3d226e6f6e65223e3c706174682066696c6c3d2268736c2800604082015260008351611bb181605f8501602088016117b3565b7f2c20313030252c20313025292220643d224d3020306831303234763130323448605f918401918201527f307a22202f3e3c672066696c6c3d2268736c2800000000000000000000000000607f8201528351611c148160928401602088016117b3565b7f2c20313030252c2039302529223e3c7061746820643d224d393033203433372e609292909101918201527f35633020392e3131332d372e3338382031362e352d31362e352031362e35732d60b28201527f31362e352d372e3338372d31362e352d31362e3520372e3338382d31362e352060d28201527f31362e352d31362e352031362e3520372e3338372031362e352031362e357a4d60f28201527f3639382e3532392035363663362e39323120302031322e35332d352e353936206101128201527f31322e35332d31322e35762d353063302d362e39303420352e3630392d31322e6101328201527f352031322e3532392d31322e356832352e30353963362e393220302031322e356101528201527f323920352e3539362031322e3532392031322e35763530633020362e393034206101728201527f352e3630392031322e352031322e35332031322e357331322e3532392d352e356101928201527f39362031322e3532392d31322e35762d353063302d362e39303420352e3630396101b28201527f2d31322e352031322e35332d31322e356832352e30353963362e3932203020316101d28201527f322e35323920352e3539362031322e3532392031322e35763530633020362e396101f28201527f303420352e3630392031322e352031322e3532392031322e356833372e3538396102128201527f63362e393220302031322e3532392d352e3539362031322e3532392d31322e356102328201527f762d373563302d362e3930342d352e3630392d31322e352d31322e3532392d316102528201527f322e35732d31322e353320352e3539362d31322e35332031322e357635362e326102728201527f3561362e32363420362e3236342030203120312d31322e3532392030563437386102928201527f2e3563302d362e3930342d352e3630392d31322e352d31322e35332d31322e356102b28201527f483639382e353239632d362e393220302d31322e35323920352e3539362d31326102d28201527f2e3532392031322e35763735633020362e39303420352e3630392031322e35206102f28201527f31322e3532392031322e357a22202f3e3c7061746820643d224d3135372e36356103128201527f3520353431632d362e39333220302d31322e3535322d352e3539362d31322e356103328201527f35322d31322e35762d353063302d362e3930342d352e3631392d31322e352d316103528201527f322e3535312d31322e3553313230203437312e35393620313230203437382e356103728201527f763735633020362e39303420352e36322031322e352031322e3535322031322e6103928201527f35683135302e363263362e39333320302031322e3535322d352e3539362031326103b28201527f2e3535322d31322e35762d353063302d362e39303420352e3631392d31322e356103d28201527f2031322e3535322d31322e35683134342e33343563332e343635203020362e326103f28201527f373620322e37393820362e32373620362e3235732d322e38313120362e32352d6104128201527f362e32373620362e3235483332302e383238632d362e39333320302d31322e356104328201527f353220352e3539362d31322e3535322031322e357633372e35633020362e39306104528201527f3420352e3631392031322e352031322e3535322031322e35683135302e3632636104728201527f362e39333320302031322e3535322d352e3539362031322e3535322d31322e356104928201527f762d373563302d362e3930342d352e3631392d31322e352d31322e3535322d316104b28201527f322e35483238332e313732632d362e39333220302d31322e35353120352e35396104d28201527f362d31322e3535312031322e35763530633020362e3930342d352e36313920316104f28201527f322e352d31322e3535322031322e35682d32352e313033632d362e39333320306105128201527f2d31322e3535322d352e3539362d31322e3535322d31322e35762d353063302d6105328201527f362e3930342d352e36322d31322e352d31322e3535322d31322e35732d31322e6105528201527f35353220352e3539362d31322e3535322031322e35763530633020362e3930346105728201527f2d352e3631392031322e352d31322e3535312031322e35682d32352e3130347a6105928201527f6d3330312e3234322d362e3235633020332e3435322d322e38313120362e32356105b28201527f2d362e32373620362e3235483333392e363535632d332e34363520302d362e326105d28201527f37362d322e3739382d362e3237362d362e323573322e3831312d362e323520366105f28201527f2e3237362d362e3235683131322e39363663332e343635203020362e323736206106128201527f322e37393820362e32373620362e32357a4d343937203535332e3831386330206106328201527f362e39323920352e3632382031322e3534362031322e3537312031322e3534366106528201527f6831333261362e323820362e323820302030203120362e32383620362e3237326106728201527f20362e323820362e32382030203020312d362e32383620362e323733682d31336106928201527f32632d362e39343320302d31322e35373120352e3631362d31322e35373120316106b28201527f322e3534364131322e35362031322e3536203020302030203530392e353731206106d28201527f363034683135302e38353863362e39343320302031322e3537312d352e3631366106f28201527f2031322e3537312d31322e353435762d3131322e393163302d362e3932382d356107128201527f2e3632382d31322e3534352d31322e3537312d31322e353435483530392e35376107328201527f31632d362e39343320302d31322e35373120352e3631372d31322e35373120316107528201527f322e3534357637352e3237337a6d33372e3731342d36322e373237632d362e396107728201527f343320302d31322e35373120352e3631372d31322e3537312031322e353435766107928201527f32352e303931633020362e39323920352e3632382031322e3534362031322e356107b28201527f37312031322e353436683130302e35373263362e39343320302031322e3537316107d28201527f2d352e3631372031322e3537312d31322e353436762d32352e30393163302d366107f28201527f2e3932382d352e3632382d31322e3534352d31322e3537312d31322e353435486108128201527f3533342e3731347a222066696c6c2d72756c653d226576656e6f646422202f3e6108328201527f3c2f673e3c2f7376673e0000000000000000000000000000000000000000000061085282015261085c01949350505050565b7f7b226e616d65223a20227761676d6920230000000000000000000000000000008152600083516125f28160118501602088016117b3565b7f222c2022696d616765223a2022646174613a696d6167652f7376672b786d6c3b6011918401918201527f6261736536342c00000000000000000000000000000000000000000000000000603182015283516126558160388401602088016117b3565b7f227d00000000000000000000000000000000000000000000000000000000000060389290910191820152603a01949350505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c0000008152600082516126c381601d8501602087016117b3565b91909101601d0192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015612711576127116126d0565b500390565b60008219821115612729576127296126d0565b500190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361275f5761275f6126d0565b5060010190565b60008261277557612775611aea565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156127e1576127e16126d0565b500290565b600073ffffffffffffffffffffffffffffffffffffffff80871683528086166020840152508360408301526080606083015261282560808301846117df565b9695505050505050565b60006020828403121561284157600080fd5b81516117ac8161175e56fe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fa26469706673582212201665a4f9111990d7529375848d3fd02c0121091a940da59e763eba826e7b077064736f6c634300080d0033', +} as const diff --git a/wagmi-project/packages/test/src/exports/index.test-d.ts b/wagmi-project/packages/test/src/exports/index.test-d.ts new file mode 100644 index 000000000..b056d5635 --- /dev/null +++ b/wagmi-project/packages/test/src/exports/index.test-d.ts @@ -0,0 +1,4 @@ +import { expectTypeOf } from 'vitest' + +// noop test because vitest typecheck fails unless each workspace project has type test +expectTypeOf(1).toEqualTypeOf() diff --git a/wagmi-project/packages/test/src/exports/index.test.ts b/wagmi-project/packages/test/src/exports/index.test.ts new file mode 100644 index 000000000..2a44ddbf8 --- /dev/null +++ b/wagmi-project/packages/test/src/exports/index.test.ts @@ -0,0 +1,29 @@ +import { expect, test } from 'vitest' + +import * as react from './index.js' + +test('exports', () => { + expect(Object.keys(react)).toMatchInlineSnapshot(` + [ + "chain", + "mainnet", + "mainnet2", + "optimism", + "abi", + "accounts", + "address", + "bytecode", + "privateKey", + "typedData", + "walletConnectProjectId", + "testClient", + "mainnetTestClient", + "mainnet2TestClient", + "optimismTestClient", + "config", + "addressRegex", + "transactionHashRegex", + "wait", + ] + `) +}) diff --git a/wagmi-project/packages/test/src/exports/index.ts b/wagmi-project/packages/test/src/exports/index.ts new file mode 100644 index 000000000..5844aeac0 --- /dev/null +++ b/wagmi-project/packages/test/src/exports/index.ts @@ -0,0 +1,25 @@ +// biome-ignore lint/performance/noBarrelFile: entrypoint module +export { chain, mainnet, mainnet2, optimism } from '../chains.js' + +export { + abi, + accounts, + address, + bytecode, + privateKey, + typedData, + walletConnectProjectId, +} from '../constants.js' + +export { + testClient, + mainnetTestClient, + mainnet2TestClient, + optimismTestClient, +} from '../clients.js' + +export { config } from '../config.js' + +export { addressRegex, transactionHashRegex } from '../regex.js' + +export { wait } from '../utils.js' diff --git a/wagmi-project/packages/test/src/exports/react.ts b/wagmi-project/packages/test/src/exports/react.ts new file mode 100644 index 000000000..f9dfe5c4b --- /dev/null +++ b/wagmi-project/packages/test/src/exports/react.ts @@ -0,0 +1,63 @@ +import { QueryClient, QueryClientProvider } from '@tanstack/react-query' +import { + type RenderHookOptions, + type RenderHookResult, + type RenderOptions, + type RenderResult, + render as rtl_render, + renderHook as rtl_renderHook, + waitFor as rtl_waitFor, + type waitForOptions, +} from '@testing-library/react' +import { type ReactElement, createElement } from 'react' +import { WagmiProvider } from 'wagmi' + +import { config } from '../config.js' + +// biome-ignore lint/performance/noBarrelFile: entrypoint module +export { act, cleanup } from '@testing-library/react' + +export const queryClient = new QueryClient() + +export function createWrapper>( + Wrapper: TComponent, + props: Parameters[0], +) { + type Props = { children?: React.ReactNode | undefined } + return function CreatedWrapper({ children }: Props) { + return createElement( + Wrapper, + props, + createElement(QueryClientProvider, { client: queryClient }, children), + ) + } +} + +export function renderHook( + render: (props: Props) => Result, + options?: RenderHookOptions | undefined, +): RenderHookResult { + queryClient.clear() + return rtl_renderHook(render, { + wrapper: createWrapper(WagmiProvider, { config, reconnectOnMount: false }), + ...options, + }) +} + +export function render( + element: ReactElement, + options?: RenderOptions | undefined, +): RenderResult { + queryClient.clear() + return rtl_render(element, { + wrapper: createWrapper(WagmiProvider, { config, reconnectOnMount: false }), + ...options, + }) +} + +export function waitFor( + callback: () => Promise | T, + options?: waitForOptions | undefined, +): Promise { + return rtl_waitFor(callback, { timeout: 10_000, ...options }) +} diff --git a/wagmi-project/packages/test/src/exports/vue.ts b/wagmi-project/packages/test/src/exports/vue.ts new file mode 100644 index 000000000..ac49b17a3 --- /dev/null +++ b/wagmi-project/packages/test/src/exports/vue.ts @@ -0,0 +1,66 @@ +import { VueQueryPlugin } from '@tanstack/vue-query' +import { WagmiPlugin } from '@wagmi/vue' +import { type App, type Ref, createApp, watch } from 'vue' + +import { config } from '../config.js' + +export type RenderComposableReturnType unknown> = [ + ReturnType, + App, +] + +export function renderComposable unknown>( + composable: composable, + options: { attach?: (app: App) => void } | undefined = { + attach(app) { + app + .use(WagmiPlugin, { + config, + reconnectOnMount: false, + }) + .use(VueQueryPlugin, {}) + }, + }, +): RenderComposableReturnType { + let result = undefined + const app = createApp({ + setup() { + result = composable() + return () => {} + }, + }) + + options.attach?.(app) + app.mount(document.createElement('div')) + + return [result, app] as unknown as RenderComposableReturnType +} + +export type WaitForOptions = { + timeout?: number +} + +export function waitFor( + ref: ref, + predicate: (value: ref['value']) => boolean = (value) => value, + options: WaitForOptions = {}, +) { + const { timeout = 10_000 } = options + return new Promise((resolve, reject) => { + const timer = timeout + ? setTimeout(() => { + _unwatch() + if (predicate(ref.value)) resolve() + else reject(new Error(`\`waitFor\` timed out in ${timeout}ms.`)) + }, timeout) + : undefined + + const _unwatch = watch(ref, (value) => { + if (predicate(value)) { + if (timer) clearTimeout(timer) + _unwatch() + resolve() + } + }) + }) +} diff --git a/wagmi-project/packages/test/src/globalSetup.ts b/wagmi-project/packages/test/src/globalSetup.ts new file mode 100644 index 000000000..f8248e839 --- /dev/null +++ b/wagmi-project/packages/test/src/globalSetup.ts @@ -0,0 +1,26 @@ +import { createServer } from 'prool' +import { anvil } from 'prool/instances' + +import { chain as chainLookup } from './chains.js' + +export default async function () { + const promises = [] + for (const chain of Object.values(chainLookup)) { + promises.push( + createServer({ + instance: anvil({ + chainId: chain.id, + forkUrl: chain.fork.url, + forkBlockNumber: chain.fork.blockNumber, + noMining: true, + }), + port: chain.port, + }).start(), + ) + } + const results = await Promise.all(promises) + + return async () => { + await Promise.all(results.map((stop) => stop())) + } +} diff --git a/wagmi-project/packages/test/src/regex.ts b/wagmi-project/packages/test/src/regex.ts new file mode 100644 index 000000000..5998ea513 --- /dev/null +++ b/wagmi-project/packages/test/src/regex.ts @@ -0,0 +1,3 @@ +export const addressRegex = /^0x([A-Fa-f0-9]{40})$/ + +export const transactionHashRegex = /^0x([A-Fa-f0-9]{64})$/ diff --git a/wagmi-project/packages/test/src/setup.ts b/wagmi-project/packages/test/src/setup.ts new file mode 100644 index 000000000..1a41b7a6e --- /dev/null +++ b/wagmi-project/packages/test/src/setup.ts @@ -0,0 +1,8 @@ +import { afterAll } from 'vitest' + +import { testClient } from './clients.js' + +afterAll(async () => { + // If you are using a fork, you can reset your anvil instance to the initial fork block. + await Promise.all(Object.values(testClient).map((client) => client.restart())) +}) diff --git a/wagmi-project/packages/test/src/utils.ts b/wagmi-project/packages/test/src/utils.ts new file mode 100644 index 000000000..85afe15c4 --- /dev/null +++ b/wagmi-project/packages/test/src/utils.ts @@ -0,0 +1,25 @@ +const pool = + Number(process.env.VITEST_POOL_ID ?? 1) + Math.floor(Math.random() * 10000) + +export function getRpcUrls({ port }: { port: number }) { + return { + port, + rpcUrls: { + // These rpc urls are automatically used in the transports. + default: { + // Note how we append the worker id to the local rpc urls. + http: [`http://127.0.0.1:${port}/${pool}`], + webSocket: [`ws://127.0.0.1:${port}/${pool}`], + }, + public: { + // Note how we append the worker id to the local rpc urls. + http: [`http://127.0.0.1:${port}/${pool}`], + webSocket: [`ws://127.0.0.1:${port}/${pool}`], + }, + }, + } as const +} + +export async function wait(time: number) { + return new Promise((res) => setTimeout(res, time)) +} diff --git a/wagmi-project/packages/test/tsconfig.build.json b/wagmi-project/packages/test/tsconfig.build.json new file mode 100644 index 000000000..fbed2b103 --- /dev/null +++ b/wagmi-project/packages/test/tsconfig.build.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.base.json", + "include": ["src/**/*.ts"], + "exclude": ["src/**/*.test.ts", "src/**/*.test-d.ts"], + "compilerOptions": { + "sourceMap": true + } +} diff --git a/wagmi-project/packages/test/tsconfig.json b/wagmi-project/packages/test/tsconfig.json new file mode 100644 index 000000000..bd33919ac --- /dev/null +++ b/wagmi-project/packages/test/tsconfig.json @@ -0,0 +1,5 @@ +{ + "extends": "./tsconfig.build.json", + "include": ["src/**/*.ts"], + "exclude": [] +} diff --git a/wagmi-project/packages/vue/CHANGELOG.md b/wagmi-project/packages/vue/CHANGELOG.md new file mode 100644 index 000000000..324b962b2 --- /dev/null +++ b/wagmi-project/packages/vue/CHANGELOG.md @@ -0,0 +1,706 @@ +# @wagmi/vue + +## 0.1.20 + +### Patch Changes + +- Updated dependencies [[`42b1fed58e9ac09da0f8ebf3e9271f98a707aaac`](https://github.com/wevm/wagmi/commit/42b1fed58e9ac09da0f8ebf3e9271f98a707aaac)]: + - @wagmi/connectors@5.8.3 + +## 0.1.19 + +### Patch Changes + +- Updated dependencies [[`29297a48af72b537173d948ccd2fe37d39914c66`](https://github.com/wevm/wagmi/commit/29297a48af72b537173d948ccd2fe37d39914c66), [`07370106d5fb6b8fe300992d93abf25b3d0eaf57`](https://github.com/wevm/wagmi/commit/07370106d5fb6b8fe300992d93abf25b3d0eaf57)]: + - @wagmi/core@2.17.2 + - @wagmi/connectors@5.8.2 + +## 0.1.18 + +### Patch Changes + +- Updated dependencies [[`01f64e64fa4f85cdd30023903f972f4f9023681f`](https://github.com/wevm/wagmi/commit/01f64e64fa4f85cdd30023903f972f4f9023681f)]: + - @wagmi/core@2.17.1 + - @wagmi/connectors@5.8.1 + +## 0.1.17 + +### Patch Changes + +- Updated dependencies [[`cc5517ff6880bb630f1b201930acc20dd1a0b451`](https://github.com/wevm/wagmi/commit/cc5517ff6880bb630f1b201930acc20dd1a0b451)]: + - @wagmi/connectors@5.8.0 + +## 0.1.16 + +### Patch Changes + +- Updated dependencies [[`88427b2bcd13ec375ef519e9ad1ccffef9f02a7b`](https://github.com/wevm/wagmi/commit/88427b2bcd13ec375ef519e9ad1ccffef9f02a7b), [`799ee4d4b23c2ecd64e3f3668e67634e81939719`](https://github.com/wevm/wagmi/commit/799ee4d4b23c2ecd64e3f3668e67634e81939719), [`3f8b2edc4f237cccff1009bcef03d51ca27a7324`](https://github.com/wevm/wagmi/commit/3f8b2edc4f237cccff1009bcef03d51ca27a7324)]: + - @wagmi/connectors@6.0.0 + - @wagmi/core@2.17.0 + +## 0.1.15 + +### Patch Changes + +- Updated dependencies [[`b59c024b23c69f5459b17390531207cfdf126ce4`](https://github.com/wevm/wagmi/commit/b59c024b23c69f5459b17390531207cfdf126ce4)]: + - @wagmi/connectors@5.7.12 + +## 0.1.14 + +### Patch Changes + +- Updated dependencies [[`a4bd0623eed28e3761a27295831a60ad835f0ee0`](https://github.com/wevm/wagmi/commit/a4bd0623eed28e3761a27295831a60ad835f0ee0)]: + - @wagmi/core@2.16.7 + - @wagmi/connectors@5.7.11 + +## 0.1.13 + +### Patch Changes + +- Updated dependencies [[`edf47477b2f6385a1c3ae01d36a8498c47f30a0b`](https://github.com/wevm/wagmi/commit/edf47477b2f6385a1c3ae01d36a8498c47f30a0b), [`e944812ebc234a72c1417b77cff341166f5e0fef`](https://github.com/wevm/wagmi/commit/e944812ebc234a72c1417b77cff341166f5e0fef)]: + - @wagmi/core@2.16.6 + - @wagmi/connectors@5.7.10 + +## 0.1.12 + +### Patch Changes + +- Updated dependencies [[`5b7101fddb61df56e34b2e02b46bc409e496eaf9`](https://github.com/wevm/wagmi/commit/5b7101fddb61df56e34b2e02b46bc409e496eaf9)]: + - @wagmi/connectors@5.7.9 + +## 0.1.11 + +### Patch Changes + +- Updated dependencies [[`d0c9a86921a4e939373cc6e763284e53f2a2e93c`](https://github.com/wevm/wagmi/commit/d0c9a86921a4e939373cc6e763284e53f2a2e93c)]: + - @wagmi/core@2.16.5 + - @wagmi/connectors@5.7.8 + +## 0.1.10 + +### Patch Changes + +- [`507f864d91238bfd423d0e36d3619eb9f6e52eec`](https://github.com/wevm/wagmi/commit/507f864d91238bfd423d0e36d3619eb9f6e52eec) Thanks [@jxom](https://github.com/jxom)! - Updated `@coinbase/wallet-sdk`. + +- Updated dependencies [[`507f864d91238bfd423d0e36d3619eb9f6e52eec`](https://github.com/wevm/wagmi/commit/507f864d91238bfd423d0e36d3619eb9f6e52eec)]: + - @wagmi/connectors@5.7.7 + - @wagmi/core@2.16.4 + +## 0.1.9 + +### Patch Changes + +- Updated dependencies [[`639952c97f0fe3927106f42d3c9f7f366cdf7f7a`](https://github.com/wevm/wagmi/commit/639952c97f0fe3927106f42d3c9f7f366cdf7f7a), [`5aa2c095f7bfb6dfcf91c6945c3e1f9c9dd05766`](https://github.com/wevm/wagmi/commit/5aa2c095f7bfb6dfcf91c6945c3e1f9c9dd05766)]: + - @wagmi/connectors@5.7.6 + +## 0.1.8 + +### Patch Changes + +- Updated dependencies [[`a257e8d4f97431a4af872cda1817b4ae17c7bbed`](https://github.com/wevm/wagmi/commit/a257e8d4f97431a4af872cda1817b4ae17c7bbed)]: + - @wagmi/connectors@5.7.5 + +## 0.1.7 + +### Patch Changes + +- Updated dependencies [[`c8a257e0f6d2ece013b873895c35769a8a804fdc`](https://github.com/wevm/wagmi/commit/c8a257e0f6d2ece013b873895c35769a8a804fdc)]: + - @wagmi/connectors@5.7.4 + +## 0.1.6 + +### Patch Changes + +- [#4480](https://github.com/wevm/wagmi/pull/4480) [`384a1d91597622eb59e1c05dc13ce25017c5b6d8`](https://github.com/wevm/wagmi/commit/384a1d91597622eb59e1c05dc13ce25017c5b6d8) Thanks [@RodeRickIsWatching](https://github.com/RodeRickIsWatching)! - Fixed invocation of default storage. + +- Updated dependencies [[`384a1d91597622eb59e1c05dc13ce25017c5b6d8`](https://github.com/wevm/wagmi/commit/384a1d91597622eb59e1c05dc13ce25017c5b6d8)]: + - @wagmi/core@2.16.3 + - @wagmi/connectors@5.7.3 + +## 0.1.5 + +### Patch Changes + +- [`012907032b532a438fce48f407470250cbc8f0c6`](https://github.com/wevm/wagmi/commit/012907032b532a438fce48f407470250cbc8f0c6) Thanks [@jxom](https://github.com/jxom)! - Fixed assignment in `getDefaultStorage`. + +- Updated dependencies [[`012907032b532a438fce48f407470250cbc8f0c6`](https://github.com/wevm/wagmi/commit/012907032b532a438fce48f407470250cbc8f0c6)]: + - @wagmi/core@2.16.2 + - @wagmi/connectors@5.7.2 + +## 0.1.4 + +### Patch Changes + +- Updated dependencies [[`9c8c35a3b829f2c58edcd3a29e2dcd99974d7470`](https://github.com/wevm/wagmi/commit/9c8c35a3b829f2c58edcd3a29e2dcd99974d7470), [`3892ebd21c06beef4b28ece4e70d2a38807bce6f`](https://github.com/wevm/wagmi/commit/3892ebd21c06beef4b28ece4e70d2a38807bce6f)]: + - @wagmi/connectors@5.7.1 + - @wagmi/core@2.16.1 + +## 0.1.3 + +### Patch Changes + +- Updated dependencies [[`e3f63a02c1f7d80481804584f262bc98dab0400d`](https://github.com/wevm/wagmi/commit/e3f63a02c1f7d80481804584f262bc98dab0400d)]: + - @wagmi/connectors@5.7.0 + +## 0.1.2 + +### Patch Changes + +- Updated dependencies [[`adf2253b10c6d4fc583e4bc9f01a8ef5ca267c85`](https://github.com/wevm/wagmi/commit/adf2253b10c6d4fc583e4bc9f01a8ef5ca267c85)]: + - @wagmi/connectors@5.6.2 + +## 0.1.1 + +### Patch Changes + +- Updated dependencies [[`987404f590c1d29ebb3cb68928f5e54aa032793d`](https://github.com/wevm/wagmi/commit/987404f590c1d29ebb3cb68928f5e54aa032793d)]: + - @wagmi/connectors@5.6.1 + +## 0.1.0 + +### Minor Changes + +- [#4453](https://github.com/wevm/wagmi/pull/4453) [`070e48480194c8d7f45bda1d7dd1346e6f5d7227`](https://github.com/wevm/wagmi/commit/070e48480194c8d7f45bda1d7dd1346e6f5d7227) Thanks [@tmm](https://github.com/tmm)! - Added support to `useConnect` for custom `connector.connect` parameters. + +### Patch Changes + +- Updated dependencies [[`afea6b67822a7a2b96901ec851441d27ee0f7a52`](https://github.com/wevm/wagmi/commit/afea6b67822a7a2b96901ec851441d27ee0f7a52), [`070e48480194c8d7f45bda1d7dd1346e6f5d7227`](https://github.com/wevm/wagmi/commit/070e48480194c8d7f45bda1d7dd1346e6f5d7227), [`8b0726c1106fce88b782e676498eabf0718b2619`](https://github.com/wevm/wagmi/commit/8b0726c1106fce88b782e676498eabf0718b2619)]: + - @wagmi/core@2.16.0 + - @wagmi/connectors@5.6.0 + +## 0.0.69 + +### Patch Changes + +- [`2f79a3da4872d6158569017b1927a07a1ff5e7ba`](https://github.com/wevm/wagmi/commit/2f79a3da4872d6158569017b1927a07a1ff5e7ba) Thanks [@tmm](https://github.com/tmm)! - Exported `injected` and `mock`. + +## 0.0.68 + +### Patch Changes + +- [#4433](https://github.com/wevm/wagmi/pull/4433) [`06e186cd679b27fe195309110e766fcf46d4efbc`](https://github.com/wevm/wagmi/commit/06e186cd679b27fe195309110e766fcf46d4efbc) Thanks [@Aerilym](https://github.com/Aerilym)! - Bumped Metamask SDK version to `0.31.1`. + +- Updated dependencies [[`06e186cd679b27fe195309110e766fcf46d4efbc`](https://github.com/wevm/wagmi/commit/06e186cd679b27fe195309110e766fcf46d4efbc)]: + - @wagmi/connectors@5.5.3 + - @wagmi/core@2.15.2 + +## 0.0.67 + +### Patch Changes + +- Updated dependencies [[`e563ef69130a511fd6f3f72ed4cd4fbe1390541f`](https://github.com/wevm/wagmi/commit/e563ef69130a511fd6f3f72ed4cd4fbe1390541f)]: + - @wagmi/connectors@5.5.2 + +## 0.0.66 + +### Patch Changes + +- [`b8bbb409f4934538e3dd6cac5aaf7346292d0693`](https://github.com/wevm/wagmi/commit/b8bbb409f4934538e3dd6cac5aaf7346292d0693) Thanks [@jxom](https://github.com/jxom)! - Fixed issue where `null` gas would accidentally pass through. + +- Updated dependencies [[`b8bbb409f4934538e3dd6cac5aaf7346292d0693`](https://github.com/wevm/wagmi/commit/b8bbb409f4934538e3dd6cac5aaf7346292d0693)]: + - @wagmi/core@2.15.1 + - @wagmi/connectors@5.5.1 + +## 0.0.65 + +### Minor Changes + +- [#4417](https://github.com/wevm/wagmi/pull/4417) [`42e65ea4fea99c639817088bba915e0933d17141`](https://github.com/wevm/wagmi/commit/42e65ea4fea99c639817088bba915e0933d17141) Thanks [@jxom](https://github.com/jxom)! - Removed simulation in `writeContract` & `sendTransaction`. + +### Patch Changes + +- Updated dependencies [[`42e65ea4fea99c639817088bba915e0933d17141`](https://github.com/wevm/wagmi/commit/42e65ea4fea99c639817088bba915e0933d17141)]: + - @wagmi/connectors@6.0.0 + - @wagmi/core@2.15.0 + +## 0.0.64 + +### Patch Changes + +- Updated dependencies [[`7ca62b44cd997d48f92c2b81343726a5908aa00b`](https://github.com/wevm/wagmi/commit/7ca62b44cd997d48f92c2b81343726a5908aa00b)]: + - @wagmi/connectors@5.4.0 + +## 0.0.63 + +### Patch Changes + +- Updated dependencies [[`a13aa8d7c38eb3cc8171a02d6302e6d12cf6bcb3`](https://github.com/wevm/wagmi/commit/a13aa8d7c38eb3cc8171a02d6302e6d12cf6bcb3), [`a13aa8d7c38eb3cc8171a02d6302e6d12cf6bcb3`](https://github.com/wevm/wagmi/commit/a13aa8d7c38eb3cc8171a02d6302e6d12cf6bcb3)]: + - @wagmi/core@2.14.6 + - @wagmi/connectors@5.3.10 + +## 0.0.62 + +### Patch Changes + +- Updated dependencies [[`b12a04eeec985c48d2feac94b011d41fb29ca23e`](https://github.com/wevm/wagmi/commit/b12a04eeec985c48d2feac94b011d41fb29ca23e)]: + - @wagmi/connectors@5.3.9 + +## 0.0.61 + +### Patch Changes + +- Updated dependencies [[`6b9bbacdc7bffd44fc2165362a5e65fd434e7646`](https://github.com/wevm/wagmi/commit/6b9bbacdc7bffd44fc2165362a5e65fd434e7646), [`dac62dc99a0679fa632a0fae49873d6053d06b35`](https://github.com/wevm/wagmi/commit/dac62dc99a0679fa632a0fae49873d6053d06b35)]: + - @wagmi/core@2.14.5 + - @wagmi/connectors@5.3.8 + +## 0.0.60 + +### Patch Changes + +- Updated dependencies [[`e08681c81fbdf475213e2d0f4c5517d0abf4e743`](https://github.com/wevm/wagmi/commit/e08681c81fbdf475213e2d0f4c5517d0abf4e743)]: + - @wagmi/core@2.14.4 + - @wagmi/connectors@5.3.7 + +## 0.0.59 + +### Patch Changes + +- Updated dependencies [[`7558ff3133c11bc4c49473d08ee9a47eaa12df5b`](https://github.com/wevm/wagmi/commit/7558ff3133c11bc4c49473d08ee9a47eaa12df5b)]: + - @wagmi/connectors@5.3.6 + +## 0.0.58 + +### Patch Changes + +- Updated dependencies [[`cb7dd2ebb871d0be8f1a11a8cd8ce592cd74b7c7`](https://github.com/wevm/wagmi/commit/cb7dd2ebb871d0be8f1a11a8cd8ce592cd74b7c7), [`7fe78f2d09778fc01fd0cffe85ba198e64999275`](https://github.com/wevm/wagmi/commit/7fe78f2d09778fc01fd0cffe85ba198e64999275)]: + - @wagmi/core@2.14.3 + - @wagmi/connectors@5.3.5 + +## 0.0.57 + +### Patch Changes + +- Updated dependencies [[`b6861a4c378dab78d8751ae0ac2aa425f3c24b8f`](https://github.com/wevm/wagmi/commit/b6861a4c378dab78d8751ae0ac2aa425f3c24b8f), [`d0d0963bb5904a15cf0355862d62dd141ce0c31c`](https://github.com/wevm/wagmi/commit/d0d0963bb5904a15cf0355862d62dd141ce0c31c), [`ecac0ba36243d94c9199d0bd21937104c835d9a0`](https://github.com/wevm/wagmi/commit/ecac0ba36243d94c9199d0bd21937104c835d9a0)]: + - @wagmi/connectors@5.3.4 + - @wagmi/core@2.14.2 + +## 0.0.56 + +### Patch Changes + +- Updated dependencies [[`83c6d16b7d6dddfa6bda036e04f00ec313c6248c`](https://github.com/wevm/wagmi/commit/83c6d16b7d6dddfa6bda036e04f00ec313c6248c)]: + - @wagmi/connectors@5.3.3 + +## 0.0.55 + +### Patch Changes + +- Updated dependencies [[`8970cc51398e1ac713435533096215c6d31ffdf9`](https://github.com/wevm/wagmi/commit/8970cc51398e1ac713435533096215c6d31ffdf9)]: + - @wagmi/connectors@5.3.2 + +## 0.0.54 + +### Patch Changes + +- Updated dependencies [[`052e72e1f8c1c14fcbdce04a9f8fa7ec28d83702`](https://github.com/wevm/wagmi/commit/052e72e1f8c1c14fcbdce04a9f8fa7ec28d83702), [`b250fc21ee577b2a75c5a34ff684f62fb4ad771a`](https://github.com/wevm/wagmi/commit/b250fc21ee577b2a75c5a34ff684f62fb4ad771a)]: + - @wagmi/core@2.14.1 + - @wagmi/connectors@5.3.1 + +## 0.0.53 + +### Patch Changes + +- Updated dependencies [[`f43e074f473820b208a6295d7c97f847332f1a1d`](https://github.com/wevm/wagmi/commit/f43e074f473820b208a6295d7c97f847332f1a1d)]: + - @wagmi/connectors@6.0.0 + - @wagmi/core@2.14.0 + +## 0.0.52 + +### Patch Changes + +- Updated dependencies [[`c05caabc20c3ced9682cfc7ba1f3f7dcfece0703`](https://github.com/wevm/wagmi/commit/c05caabc20c3ced9682cfc7ba1f3f7dcfece0703), [`5ae49af590ff168426c9c283d54c34ae5148fcd9`](https://github.com/wevm/wagmi/commit/5ae49af590ff168426c9c283d54c34ae5148fcd9), [`f3182b22e6e454d9bd74f1b940ef34431fd9555d`](https://github.com/wevm/wagmi/commit/f3182b22e6e454d9bd74f1b940ef34431fd9555d)]: + - @wagmi/core@2.13.9 + - @wagmi/connectors@5.2.2 + +## 0.0.51 + +### Patch Changes + +- Updated dependencies [[`91a40f2db08e3a91db421b8732a5511a1e6c88fd`](https://github.com/wevm/wagmi/commit/91a40f2db08e3a91db421b8732a5511a1e6c88fd)]: + - @wagmi/connectors@5.2.1 + +## 0.0.50 + +### Patch Changes + +- Updated dependencies [[`34a0c3b7eea778aee7c27f7ace5e4b2be4e8a0a4`](https://github.com/wevm/wagmi/commit/34a0c3b7eea778aee7c27f7ace5e4b2be4e8a0a4)]: + - @wagmi/connectors@5.2.0 + +## 0.0.49 + +### Patch Changes + +- Updated dependencies [[`3b2123664b7ac66848390739e855c3b9702ab60c`](https://github.com/wevm/wagmi/commit/3b2123664b7ac66848390739e855c3b9702ab60c)]: + - @wagmi/connectors@5.1.15 + +## 0.0.48 + +### Patch Changes + +- Updated dependencies [[`56f2482508f2ba71bd6b0295c70c6abca7101e57`](https://github.com/wevm/wagmi/commit/56f2482508f2ba71bd6b0295c70c6abca7101e57)]: + - @wagmi/connectors@5.1.14 + - @wagmi/core@2.13.8 + +## 0.0.47 + +### Patch Changes + +- Updated dependencies [[`be75c2d4ef636d7362420ab0a106bfdf63f5d1e6`](https://github.com/wevm/wagmi/commit/be75c2d4ef636d7362420ab0a106bfdf63f5d1e6)]: + - @wagmi/core@2.13.7 + - @wagmi/connectors@5.1.13 + +## 0.0.46 + +### Patch Changes + +- Updated dependencies [[`edcbf5d6fbe92f639bead800502edda9e0aa39f1`](https://github.com/wevm/wagmi/commit/edcbf5d6fbe92f639bead800502edda9e0aa39f1)]: + - @wagmi/core@2.13.6 + - @wagmi/connectors@5.1.12 + +## 0.0.45 + +### Patch Changes + +- Updated dependencies [[`82404c960e04c83e0bae6e1e12459ef9debf9554`](https://github.com/wevm/wagmi/commit/82404c960e04c83e0bae6e1e12459ef9debf9554), [`d07ad7f63a018256908a673d078aaf79e47ac703`](https://github.com/wevm/wagmi/commit/d07ad7f63a018256908a673d078aaf79e47ac703)]: + - @wagmi/connectors@5.1.11 + +## 0.0.44 + +### Patch Changes + +- [#4262](https://github.com/wevm/wagmi/pull/4262) [`8531f83db3a1fbb8202c3e426b7f85679f587a52`](https://github.com/wevm/wagmi/commit/8531f83db3a1fbb8202c3e426b7f85679f587a52) Thanks [@nezouse](https://github.com/nezouse)! - Added experimental actions entrypoint. + +## 0.0.43 + +### Patch Changes + +- [#4260](https://github.com/wevm/wagmi/pull/4260) [`969a208a110b760a13fd7263360320f52440a9b6`](https://github.com/wevm/wagmi/commit/969a208a110b760a13fd7263360320f52440a9b6) Thanks [@tmm](https://github.com/tmm)! - Fixed `useReadContract` deployless reads support. + +- [#4259](https://github.com/wevm/wagmi/pull/4259) [`f47ce8f6d263e49fdff90b8edb3190142d2657bb`](https://github.com/wevm/wagmi/commit/f47ce8f6d263e49fdff90b8edb3190142d2657bb) Thanks [@tmm](https://github.com/tmm)! - Disabled `useConnectorClient` during reconnection if connector is not fully restored. + +- Updated dependencies [[`81de006e66121a18c61945c1f9b8426c83a5713c`](https://github.com/wevm/wagmi/commit/81de006e66121a18c61945c1f9b8426c83a5713c), [`f47ce8f6d263e49fdff90b8edb3190142d2657bb`](https://github.com/wevm/wagmi/commit/f47ce8f6d263e49fdff90b8edb3190142d2657bb)]: + - @wagmi/connectors@5.1.10 + - @wagmi/core@2.13.5 + +## 0.0.42 + +### Patch Changes + +- [#4252](https://github.com/wevm/wagmi/pull/4252) [`67defb516bbd9b2c7b03e376ecd3aca8a001d065`](https://github.com/wevm/wagmi/commit/67defb516bbd9b2c7b03e376ecd3aca8a001d065) Thanks [@tmm](https://github.com/tmm)! - Added `useWatchContractEvent`. + +## 0.0.41 + +### Patch Changes + +- Updated dependencies [[`21bd0e473d374cbbd7a01bececa6022d529026ba`](https://github.com/wevm/wagmi/commit/21bd0e473d374cbbd7a01bececa6022d529026ba), [`5c89c6853e616437a3be2b019db895451fecfb3c`](https://github.com/wevm/wagmi/commit/5c89c6853e616437a3be2b019db895451fecfb3c)]: + - @wagmi/connectors@5.1.9 + +## 0.0.40 + +### Patch Changes + +- Updated dependencies [[`b580ad4edff1721e0b9d138cf5ae2ec74d2374c7`](https://github.com/wevm/wagmi/commit/b580ad4edff1721e0b9d138cf5ae2ec74d2374c7)]: + - @wagmi/connectors@5.1.8 + +## 0.0.39 + +### Patch Changes + +- Updated dependencies [[`91fd81a068789c5020e891f539bcad8f54a7a52f`](https://github.com/wevm/wagmi/commit/91fd81a068789c5020e891f539bcad8f54a7a52f)]: + - @wagmi/connectors@5.1.7 + +## 0.0.38 + +### Patch Changes + +- Updated dependencies [[`3168616298cbb6135d0ffda771cba4126e83eba8`](https://github.com/wevm/wagmi/commit/3168616298cbb6135d0ffda771cba4126e83eba8), [`d7608ef9a79459465dc8c06a2ab740465c881907`](https://github.com/wevm/wagmi/commit/d7608ef9a79459465dc8c06a2ab740465c881907)]: + - @wagmi/connectors@5.1.6 + +## 0.0.37 + +### Patch Changes + +- Updated dependencies [[`b4c8971788c70b09479946ecfa998cff2f1b3953`](https://github.com/wevm/wagmi/commit/b4c8971788c70b09479946ecfa998cff2f1b3953)]: + - @wagmi/core@2.13.4 + - @wagmi/connectors@5.1.5 + +## 0.0.36 + +### Patch Changes + +- Updated dependencies [[`871dbdbfe59ac8ad01d1ec6150ea7b091b7b7de4`](https://github.com/wevm/wagmi/commit/871dbdbfe59ac8ad01d1ec6150ea7b091b7b7de4)]: + - @wagmi/core@2.13.3 + - @wagmi/connectors@5.1.4 + +## 0.0.35 + +### Patch Changes + +- Updated dependencies [[`1b9b523fa9b9dfe839aecdf4b40caa9547d7e594`](https://github.com/wevm/wagmi/commit/1b9b523fa9b9dfe839aecdf4b40caa9547d7e594)]: + - @wagmi/core@2.13.2 + - @wagmi/connectors@5.1.3 + +## 0.0.34 + +### Patch Changes + +- Updated dependencies [[`abb490dac4f0f02f46cb0878e7ca9a0db6aada56`](https://github.com/wevm/wagmi/commit/abb490dac4f0f02f46cb0878e7ca9a0db6aada56), [`28e0e5c9a4f856583f9d36a807502bd51a0c6ec2`](https://github.com/wevm/wagmi/commit/28e0e5c9a4f856583f9d36a807502bd51a0c6ec2)]: + - @wagmi/connectors@5.1.2 + +## 0.0.33 + +### Patch Changes + +- Updated dependencies [[`07c1227f306d0efb9421d4bb77a774f92f5fcf45`](https://github.com/wevm/wagmi/commit/07c1227f306d0efb9421d4bb77a774f92f5fcf45)]: + - @wagmi/core@2.13.1 + - @wagmi/connectors@5.1.1 + +## 0.0.32 + +### Patch Changes + +- [#4162](https://github.com/wevm/wagmi/pull/4162) [`a73a7737b756886b388f120ae423e72cca53e8a0`](https://github.com/wevm/wagmi/commit/a73a7737b756886b388f120ae423e72cca53e8a0) Thanks [@jxom](https://github.com/jxom)! - Added functionality for consumer-defined RPC URLs (`config.transports`) to be propagated to the WalletConnect & MetaMask Connectors. + +- Updated dependencies [[`a73a7737b756886b388f120ae423e72cca53e8a0`](https://github.com/wevm/wagmi/commit/a73a7737b756886b388f120ae423e72cca53e8a0)]: + - @wagmi/connectors@6.0.0 + - @wagmi/core@2.13.0 + +## 0.0.31 + +### Patch Changes + +- [#4124](https://github.com/wevm/wagmi/pull/4124) [`26616462db2e0140025f22c505c4541cfecb9308`](https://github.com/wevm/wagmi/commit/26616462db2e0140025f22c505c4541cfecb9308) Thanks [@t0rbik](https://github.com/t0rbik)! - Updated `useConnectorClient` to be enabled when status is `'reconnecting'` or `'connected'` (previously was also enabled when status was `'connecting'`). + +## 0.0.30 + +### Patch Changes + +- Updated dependencies [[`5bc8c8877810b2eec24a829df87dce40a51e6f20`](https://github.com/wevm/wagmi/commit/5bc8c8877810b2eec24a829df87dce40a51e6f20), [`8d81df5cc884d0a210dedd3c1ea0e2e9e52b83c5`](https://github.com/wevm/wagmi/commit/8d81df5cc884d0a210dedd3c1ea0e2e9e52b83c5)]: + - @wagmi/core@2.12.2 + - @wagmi/connectors@5.0.26 + +## 0.0.29 + +### Patch Changes + +- [#4146](https://github.com/wevm/wagmi/pull/4146) [`cc996e08e930c9e88cf753a1e874652059e81a3b`](https://github.com/wevm/wagmi/commit/cc996e08e930c9e88cf753a1e874652059e81a3b) Thanks [@jxom](https://github.com/jxom)! - Updated `@safe-global/safe-apps-sdk` + `@safe-global/safe-apps-provider` dependencies. + +- Updated dependencies [[`cc996e08e930c9e88cf753a1e874652059e81a3b`](https://github.com/wevm/wagmi/commit/cc996e08e930c9e88cf753a1e874652059e81a3b)]: + - @wagmi/connectors@5.0.25 + - @wagmi/core@2.12.1 + +## 0.0.28 + +### Patch Changes + +- [`b6cb1477e3e87984917b172a909f1968e0d77dc9`](https://github.com/wevm/wagmi/commit/b6cb1477e3e87984917b172a909f1968e0d77dc9) Thanks [@tmm](https://github.com/tmm)! - Added `useBytecode` composable. + +- Updated dependencies [[`5581a810ef70308e99c6f8b630cd4bca59f64afc`](https://github.com/wevm/wagmi/commit/5581a810ef70308e99c6f8b630cd4bca59f64afc)]: + - @wagmi/core@2.12.0 + - @wagmi/connectors@6.0.0 + +## 0.0.27 + +### Patch Changes + +- [`d3814ab4b88f9f0e052b53bc3d458df87b43f01d`](https://github.com/wevm/wagmi/commit/d3814ab4b88f9f0e052b53bc3d458df87b43f01d) Thanks [@jxom](https://github.com/jxom)! - Updated `mipd` dependency. + +- Updated dependencies [[`b08013eaa9ce97c02f8a7128ea400e3da7ef74bb`](https://github.com/wevm/wagmi/commit/b08013eaa9ce97c02f8a7128ea400e3da7ef74bb), [`d3814ab4b88f9f0e052b53bc3d458df87b43f01d`](https://github.com/wevm/wagmi/commit/d3814ab4b88f9f0e052b53bc3d458df87b43f01d)]: + - @wagmi/core@2.11.8 + - @wagmi/connectors@5.0.23 + +## 0.0.26 + +### Patch Changes + +- Updated dependencies [[`0bb8b562ae04ecfeb2d6b2f1b980ebae31dc127e`](https://github.com/wevm/wagmi/commit/0bb8b562ae04ecfeb2d6b2f1b980ebae31dc127e)]: + - @wagmi/connectors@5.0.22 + - @wagmi/core@2.11.7 + +## 0.0.25 + +### Patch Changes + +- [#4060](https://github.com/wevm/wagmi/pull/4060) [`95965c1f19d480b97f2b297a077a9e607dee32ad`](https://github.com/wevm/wagmi/commit/95965c1f19d480b97f2b297a077a9e607dee32ad) Thanks [@dalechyn](https://github.com/dalechyn)! - Bumped Tanstack Query dependencies to fix typing issues between exported Wagmi query options and TanStack Query suspense query methods (due to [`direction` property in `QueryFunctionContext` being deprecated](https://github.com/TanStack/query/pull/7410)). + +- Updated dependencies [[`ff0760b5900114bcfdf420a9fba3cc278ac95afe`](https://github.com/wevm/wagmi/commit/ff0760b5900114bcfdf420a9fba3cc278ac95afe), [`95965c1f19d480b97f2b297a077a9e607dee32ad`](https://github.com/wevm/wagmi/commit/95965c1f19d480b97f2b297a077a9e607dee32ad)]: + - @wagmi/connectors@5.0.21 + - @wagmi/core@2.11.6 + +## 0.0.24 + +### Patch Changes + +- Updated dependencies [[`43fa971d34cac57fa5a2898ad4d839b95d7af37c`](https://github.com/wevm/wagmi/commit/43fa971d34cac57fa5a2898ad4d839b95d7af37c)]: + - @wagmi/connectors@5.0.20 + +## 0.0.23 + +### Patch Changes + +- Updated dependencies [[`b7ad208030d9f2e3f89912ff76b16cdbd848feda`](https://github.com/wevm/wagmi/commit/b7ad208030d9f2e3f89912ff76b16cdbd848feda)]: + - @wagmi/connectors@5.0.19 + +## 0.0.22 + +### Patch Changes + +- Updated dependencies [[`44d24620c9e3957f3245d14d6a042736371df70b`](https://github.com/wevm/wagmi/commit/44d24620c9e3957f3245d14d6a042736371df70b)]: + - @wagmi/connectors@5.0.18 + +## 0.0.21 + +### Patch Changes + +- Updated dependencies [[`04f2b846b113f3d300d82c9fa75212f1805817c5`](https://github.com/wevm/wagmi/commit/04f2b846b113f3d300d82c9fa75212f1805817c5)]: + - @wagmi/core@2.11.5 + - @wagmi/connectors@5.0.17 + +## 0.0.20 + +### Patch Changes + +- Updated dependencies [[`9e8345cd56186b997b5e56deaa2cfc69b30d15f6`](https://github.com/wevm/wagmi/commit/9e8345cd56186b997b5e56deaa2cfc69b30d15f6), [`02c38c28d1aa0ad7a61c33775de603ed974c5c1b`](https://github.com/wevm/wagmi/commit/02c38c28d1aa0ad7a61c33775de603ed974c5c1b)]: + - @wagmi/core@2.11.4 + - @wagmi/connectors@5.0.16 + +## 0.0.19 + +### Patch Changes + +- Updated dependencies [[`8974e6269bb5d7bfaa90db0246bc7d13e8bff798`](https://github.com/wevm/wagmi/commit/8974e6269bb5d7bfaa90db0246bc7d13e8bff798)]: + - @wagmi/core@2.11.3 + - @wagmi/connectors@5.0.15 + +## 0.0.18 + +### Patch Changes + +- Updated dependencies [[`b4d9ef79deb554ee20fed6666a474be5e7cdd522`](https://github.com/wevm/wagmi/commit/b4d9ef79deb554ee20fed6666a474be5e7cdd522)]: + - @wagmi/core@2.11.2 + - @wagmi/connectors@5.0.14 + +## 0.0.17 + +### Patch Changes + +- Updated dependencies [[`9c862d8d63e3d692a22cef2a90782b74a9103f17`](https://github.com/wevm/wagmi/commit/9c862d8d63e3d692a22cef2a90782b74a9103f17)]: + - @wagmi/connectors@5.0.13 + - @wagmi/core@2.11.1 + +## 0.0.16 + +### Patch Changes + +- Updated dependencies [[`06bb598a7f04c7b167f5b7ff6d46bd15886a6a14`](https://github.com/wevm/wagmi/commit/06bb598a7f04c7b167f5b7ff6d46bd15886a6a14), [`24a45b269bd0214a29d6f82a84ac66ef8c3f3822`](https://github.com/wevm/wagmi/commit/24a45b269bd0214a29d6f82a84ac66ef8c3f3822)]: + - @wagmi/core@2.11.0 + - @wagmi/connectors@6.0.0 + +## 0.0.15 + +### Patch Changes + +- Updated dependencies [[`f2a7cefab96691ebed8b8e45ffde071c47b58dbe`](https://github.com/wevm/wagmi/commit/f2a7cefab96691ebed8b8e45ffde071c47b58dbe), [`f0ea0b2a7fe193dadfeb49a4c8031ee451c638b5`](https://github.com/wevm/wagmi/commit/f0ea0b2a7fe193dadfeb49a4c8031ee451c638b5), [`e3b124ce414b8fd1b2214e2c5a28dc72158a13d1`](https://github.com/wevm/wagmi/commit/e3b124ce414b8fd1b2214e2c5a28dc72158a13d1)]: + - @wagmi/core@2.10.6 + - @wagmi/connectors@5.0.11 + +## 0.0.14 + +### Patch Changes + +- Updated dependencies [[`560952acd4bfe33db6c7c07b35c613cef278677c`](https://github.com/wevm/wagmi/commit/560952acd4bfe33db6c7c07b35c613cef278677c)]: + - @wagmi/connectors@5.0.10 + +## 0.0.13 + +### Patch Changes + +- Updated dependencies [[`32cdd7b7dc5aff916c040628519562c3a99d418d`](https://github.com/wevm/wagmi/commit/32cdd7b7dc5aff916c040628519562c3a99d418d)]: + - @wagmi/connectors@5.0.9 + +## 0.0.12 + +### Patch Changes + +- Updated dependencies [[`c1952d1ff7f0a491dc88595a49159451b07b5621`](https://github.com/wevm/wagmi/commit/c1952d1ff7f0a491dc88595a49159451b07b5621)]: + - @wagmi/connectors@5.0.8 + +## 0.0.11 + +### Patch Changes + +- Updated dependencies [[`030c7c2cb380dfd67a2182f62e2aa7a6e1601898`](https://github.com/wevm/wagmi/commit/030c7c2cb380dfd67a2182f62e2aa7a6e1601898)]: + - @wagmi/core@2.10.5 + - @wagmi/connectors@5.0.7 + +## 0.0.10 + +### Patch Changes + +- Updated dependencies [[`51fde8a0433b4fff357c1a8d7e08b41b4c86c968`](https://github.com/wevm/wagmi/commit/51fde8a0433b4fff357c1a8d7e08b41b4c86c968)]: + - @wagmi/core@2.10.4 + - @wagmi/connectors@5.0.6 + +## 0.0.9 + +### Patch Changes + +- Updated dependencies [[`70dd28669dd8d2ce08217cd02e29a8fbba7a08d4`](https://github.com/wevm/wagmi/commit/70dd28669dd8d2ce08217cd02e29a8fbba7a08d4)]: + - @wagmi/connectors@5.0.5 + +## 0.0.8 + +### Patch Changes + +- Updated dependencies [[`be9e1b8a9818b92eb0654a20d9471e9e39329e7e`](https://github.com/wevm/wagmi/commit/be9e1b8a9818b92eb0654a20d9471e9e39329e7e)]: + - @wagmi/connectors@5.0.4 + +## 0.0.7 + +### Patch Changes + +- Updated dependencies [[`2804a8a583b1874271154898b4bae38756ef581c`](https://github.com/wevm/wagmi/commit/2804a8a583b1874271154898b4bae38756ef581c), [`2804a8a583b1874271154898b4bae38756ef581c`](https://github.com/wevm/wagmi/commit/2804a8a583b1874271154898b4bae38756ef581c)]: + - @wagmi/connectors@5.0.3 + - @wagmi/core@2.10.3 + +## 0.0.6 + +### Patch Changes + +- [`ec2f63f106fd468f28b43d3b88ab3e89aaf5e81a`](https://github.com/wevm/wagmi/commit/ec2f63f106fd468f28b43d3b88ab3e89aaf5e81a) Thanks [@tmm](https://github.com/tmm)! - Fixed `useSwitchChain` `chains` typing. + +## 0.0.5 + +### Patch Changes + +- [#3940](https://github.com/wevm/wagmi/pull/3940) [`a5071f581dfdfb961718873643a2fc629101c72a`](https://github.com/wevm/wagmi/commit/a5071f581dfdfb961718873643a2fc629101c72a) Thanks [@jxom](https://github.com/jxom)! - Fixed usage of `metaMask` connector in Vite environments. + +- Updated dependencies [[`a5071f581dfdfb961718873643a2fc629101c72a`](https://github.com/wevm/wagmi/commit/a5071f581dfdfb961718873643a2fc629101c72a)]: + - @wagmi/connectors@5.0.2 + - @wagmi/core@2.10.2 + +## 0.0.4 + +### Patch Changes + +- Updated dependencies []: + - @wagmi/connectors@5.0.1 + - @wagmi/core@2.10.1 + +## 0.0.3 + +### Patch Changes + +- Updated dependencies [[`3117e71825f9c58a0d718f3d1686f1a191fa9cb1`](https://github.com/wevm/wagmi/commit/3117e71825f9c58a0d718f3d1686f1a191fa9cb1), [`3117e71825f9c58a0d718f3d1686f1a191fa9cb1`](https://github.com/wevm/wagmi/commit/3117e71825f9c58a0d718f3d1686f1a191fa9cb1)]: + - @wagmi/connectors@5.0.0 + - @wagmi/core@2.10.0 + +## 0.0.2 + +### Patch Changes + +- [#3906](https://github.com/wevm/wagmi/pull/3906) [`32fcb4a31dde6b0206961d8ffe9c651f8a459c67`](https://github.com/wevm/wagmi/commit/32fcb4a31dde6b0206961d8ffe9c651f8a459c67) Thanks [@tmm](https://github.com/tmm)! - Added support for Vue. + +- Updated dependencies [[`32fcb4a31dde6b0206961d8ffe9c651f8a459c67`](https://github.com/wevm/wagmi/commit/32fcb4a31dde6b0206961d8ffe9c651f8a459c67)]: + - @wagmi/connectors@4.3.10 + - @wagmi/core@2.9.8 diff --git a/wagmi-project/packages/vue/README.md b/wagmi-project/packages/vue/README.md new file mode 100644 index 000000000..10a4b805d --- /dev/null +++ b/wagmi-project/packages/vue/README.md @@ -0,0 +1,14 @@ +# @wagmi/vue + +Vue Composables for Ethereum + +## Installation + +```bash +pnpm add @wagmi/vue viem @tanstack/vue-query +``` + +## Documentation + +For documentation and guides, visit [wagmi.sh](https://wagmi.sh). + diff --git a/wagmi-project/packages/vue/package.json b/wagmi-project/packages/vue/package.json new file mode 100644 index 000000000..5d299133a --- /dev/null +++ b/wagmi-project/packages/vue/package.json @@ -0,0 +1,113 @@ +{ + "name": "@wagmi/vue", + "description": "Vue Composables for Ethereum", + "version": "0.1.20", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/wevm/wagmi.git", + "directory": "packages/vue" + }, + "scripts": { + "build": "pnpm run clean && pnpm run build:esm+types", + "build:esm+types": "tsc --project tsconfig.build.json --outDir ./dist/esm --declaration --declarationMap --declarationDir ./dist/types", + "check:types": "tsc --noEmit", + "clean": "rm -rf dist tsconfig.tsbuildinfo actions chains connectors nuxt query", + "test:build": "publint --strict && attw --pack --ignore-rules cjs-resolves-to-esm" + }, + "files": [ + "dist/**", + "!dist/**/*.tsbuildinfo", + "src/**/*.ts", + "!src/**/*.test.ts", + "!src/**/*.test-d.ts", + "/actions", + "/chains", + "/connectors", + "/nuxt", + "/query" + ], + "sideEffects": false, + "type": "module", + "main": "./dist/esm/exports/index.js", + "types": "./dist/types/exports/index.d.ts", + "typings": "./dist/types/exports/index.d.ts", + "exports": { + ".": { + "types": "./dist/types/exports/index.d.ts", + "default": "./dist/esm/exports/index.js" + }, + "./actions": { + "types": "./dist/types/exports/actions.d.ts", + "default": "./dist/esm/exports/actions.js" + }, + "./actions/experimental": { + "types": "./dist/types/exports/actions/experimental.d.ts", + "default": "./dist/esm/exports/actions/experimental.js" + }, + "./chains": { + "types": "./dist/types/exports/chains.d.ts", + "default": "./dist/esm/exports/chains.js" + }, + "./connectors": { + "types": "./dist/types/exports/connectors.d.ts", + "default": "./dist/esm/exports/connectors.js" + }, + "./nuxt": { + "types": "./dist/types/exports/nuxt.d.ts", + "default": "./dist/esm/exports/nuxt.js" + }, + "./query": { + "types": "./dist/types/exports/query.d.ts", + "default": "./dist/esm/exports/query.js" + }, + "./package.json": "./package.json" + }, + "typesVersions": { + "*": { + "actions": ["./dist/types/exports/actions.d.ts"], + "chains": ["./dist/types/exports/chains.d.ts"], + "connectors": ["./dist/types/exports/connectors.d.ts"], + "nuxt": ["./dist/types/exports/nuxt.d.ts"], + "query": ["./dist/types/exports/query.d.ts"] + } + }, + "peerDependencies": { + "@tanstack/vue-query": ">=5.0.0", + "nuxt": ">=3.0.0", + "typescript": ">=5.0.4", + "viem": "2.x", + "vue": ">=3" + }, + "peerDependenciesMeta": { + "nuxt": { + "optional": true + }, + "typescript": { + "optional": true + } + }, + "dependencies": { + "@wagmi/connectors": "workspace:*", + "@wagmi/core": "workspace:*" + }, + "devDependencies": { + "@nuxt/schema": "^3.11.2", + "@tanstack/vue-query": "catalog:", + "@vue/test-utils": "^2.4.6", + "nuxt": "^3.16.0", + "vue": "catalog:" + }, + "contributors": ["awkweb.eth ", "jxom.eth "], + "funding": "https://github.com/sponsors/wevm", + "keywords": [ + "wagmi", + "vue", + "composables", + "eth", + "ethereum", + "dapps", + "wallet", + "web3" + ] +} diff --git a/wagmi-project/packages/vue/src/composables/useAccount.test-d.ts b/wagmi-project/packages/vue/src/composables/useAccount.test-d.ts new file mode 100644 index 000000000..cc0ef07dc --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useAccount.test-d.ts @@ -0,0 +1,69 @@ +import type { Connector } from '@wagmi/core' +import type { Address, Chain } from 'viem' +import { expectTypeOf, test } from 'vitest' + +import { deepUnref } from '../utils/cloneDeep.js' +import { useAccount } from './useAccount.js' + +test('states', () => { + const result = deepUnref(useAccount()) + + switch (result.status) { + case 'reconnecting': { + expectTypeOf(result).toMatchTypeOf<{ + address: Address | undefined + chain: Chain | undefined + chainId: number | undefined + connector: Connector | undefined + isConnected: boolean + isConnecting: false + isDisconnected: false + isReconnecting: true + status: 'reconnecting' + }>() + break + } + case 'connecting': { + expectTypeOf(result).toMatchTypeOf<{ + address: Address | undefined + chain: Chain | undefined + chainId: number | undefined + connector: Connector | undefined + isConnected: false + isReconnecting: false + isConnecting: true + isDisconnected: false + status: 'connecting' + }>() + break + } + case 'connected': { + expectTypeOf(result).toMatchTypeOf<{ + address: Address + chain: Chain | undefined + chainId: number + connector: Connector + isConnected: true + isConnecting: false + isDisconnected: false + isReconnecting: false + status: 'connected' + }>() + break + } + case 'disconnected': { + expectTypeOf(result).toMatchTypeOf<{ + address: undefined + chain: undefined + chainId: undefined + connector: undefined + isConnected: false + isReconnecting: false + isConnecting: false + isDisconnected: true + status: 'disconnected' + }>() + break + } + } +}) diff --git a/wagmi-project/packages/vue/src/composables/useAccount.test.ts b/wagmi-project/packages/vue/src/composables/useAccount.test.ts new file mode 100644 index 000000000..773532857 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useAccount.test.ts @@ -0,0 +1,20 @@ +import { connect, disconnect } from '@wagmi/core' +import { config } from '@wagmi/test' +import { renderComposable } from '@wagmi/test/vue' +import { expect, test } from 'vitest' + +import { useAccount } from './useAccount.js' + +test('default', async () => { + const [account] = renderComposable(() => useAccount()) + + expect(account.address.value).not.toBeDefined() + expect(account.status.value).toEqual('disconnected') + + await connect(config, { connector: config.connectors[0]! }) + + expect(account.address.value).toBeDefined() + expect(account.status.value).toEqual('connected') + + await disconnect(config) +}) diff --git a/wagmi-project/packages/vue/src/composables/useAccount.ts b/wagmi-project/packages/vue/src/composables/useAccount.ts new file mode 100644 index 000000000..136595fb2 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useAccount.ts @@ -0,0 +1,37 @@ +import { + type Config, + type GetAccountReturnType, + type ResolvedRegister, + getAccount, + watchAccount, +} from '@wagmi/core' +import { type ToRefs, onScopeDispose, reactive, readonly, toRefs } from 'vue' + +import type { ConfigParameter } from '../types/properties.js' +import { updateState } from '../utils/updateState.js' +import { useConfig } from './useConfig.js' + +export type UseAccountParameters = + ConfigParameter + +export type UseAccountReturnType = ToRefs< + GetAccountReturnType +> + +/** https://wagmi.sh/vue/api/composables/useAccount */ +export function useAccount( + parameters: UseAccountParameters = {}, +): UseAccountReturnType { + const config = useConfig(parameters) + + const account = reactive(getAccount(config)) + + const unsubscribe = watchAccount(config, { + onChange(data) { + updateState(account, data) + }, + }) + onScopeDispose(() => unsubscribe()) + + return toRefs(readonly(account)) as UseAccountReturnType +} diff --git a/wagmi-project/packages/vue/src/composables/useAccountEffect.test.ts b/wagmi-project/packages/vue/src/composables/useAccountEffect.test.ts new file mode 100644 index 000000000..10ed7a3e3 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useAccountEffect.test.ts @@ -0,0 +1,75 @@ +import { VueQueryPlugin } from '@tanstack/vue-query' +import { mock } from '@wagmi/connectors' +import { http, connect, createConfig, disconnect } from '@wagmi/core' +import { accounts, chain } from '@wagmi/test' +import { renderComposable, waitFor } from '@wagmi/test/vue' +import { expect, test, vi } from 'vitest' +import type { App } from 'vue' + +import { WagmiPlugin } from '../plugin.js' +import { useAccount } from './useAccount.js' +import { useAccountEffect } from './useAccountEffect.js' +import { useConnect } from './useConnect.js' +import { useDisconnect } from './useDisconnect.js' + +test('behavior: connect and disconnect called once', async () => { + const onConnect = vi.fn() + const onDisconnect = vi.fn() + + renderComposable(() => useAccountEffect({ onConnect, onDisconnect })) + const [connect] = renderComposable(() => useConnect()) + const [disconnect] = renderComposable(() => useDisconnect()) + + connect.connect({ + connector: connect.connectors[0]!, + }) + await waitFor(connect.isSuccess) + connect.connect({ + connector: connect.connectors[0]!, + }) + + disconnect.disconnect() + await waitFor(disconnect.isSuccess) + disconnect.disconnect() + + expect(onConnect).toBeCalledTimes(1) + expect(onDisconnect).toBeCalledTimes(1) +}) + +test('behavior: connect called on reconnect', async () => { + const config = createConfig({ + chains: [chain.mainnet], + connectors: [ + mock({ + accounts, + features: { reconnect: true }, + }), + ], + transports: { [chain.mainnet.id]: http() }, + }) + + function attach(app: App) { + app + .use(WagmiPlugin, { + config, + reconnectOnMount: true, + }) + .use(VueQueryPlugin, {}) + } + + await connect(config, { connector: config.connectors[0]! }) + const onConnect = vi.fn((data) => { + expect(data.isReconnected).toBeTruthy() + }) + + renderComposable(() => useAccountEffect({ onConnect }), { + attach, + }) + const [account] = renderComposable(() => useAccount(), { attach }) + + await waitFor(account.status, (status) => status === 'connected') + + expect(onConnect).toBeCalledTimes(1) + + await disconnect(config) +}) diff --git a/wagmi-project/packages/vue/src/composables/useAccountEffect.ts b/wagmi-project/packages/vue/src/composables/useAccountEffect.ts new file mode 100644 index 000000000..021624cea --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useAccountEffect.ts @@ -0,0 +1,66 @@ +import { type GetAccountReturnType, watchAccount } from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { watchEffect } from 'vue' + +import type { ConfigParameter } from '../types/properties.js' +import type { DeepMaybeRef } from '../types/ref.js' +import { deepUnref } from '../utils/cloneDeep.js' +import { useConfig } from './useConfig.js' + +export type UseAccountEffectParameters = Compute< + DeepMaybeRef< + { + onConnect?( + data: Compute< + Pick< + Extract, + 'address' | 'addresses' | 'chain' | 'chainId' | 'connector' + > & { + isReconnected: boolean + } + >, + ): void + onDisconnect?(): void + } & ConfigParameter + > +> + +/** https://wagmi.sh/vue/api/composables/useAccountEffect */ +export function useAccountEffect(parameters: UseAccountEffectParameters = {}) { + const config = useConfig(parameters) + + watchEffect((onCleanup) => { + const { onConnect, onDisconnect } = deepUnref(parameters) + + const unwatch = watchAccount(config, { + onChange(data, prevData) { + if ( + (prevData.status === 'reconnecting' || + (prevData.status === 'connecting' && + prevData.address === undefined)) && + data.status === 'connected' + ) { + const { address, addresses, chain, chainId, connector } = data + const isReconnected = + prevData.status === 'reconnecting' || + // if `previousAccount.status` is `undefined`, the connector connected immediately. + prevData.status === undefined + onConnect?.({ + address, + addresses, + chain, + chainId, + connector, + isReconnected, + }) + } else if ( + prevData.status === 'connected' && + data.status === 'disconnected' + ) + onDisconnect?.() + }, + }) + + onCleanup(() => unwatch()) + }) +} diff --git a/wagmi-project/packages/vue/src/composables/useBalance.test-d.ts b/wagmi-project/packages/vue/src/composables/useBalance.test-d.ts new file mode 100644 index 000000000..44ba34ea4 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useBalance.test-d.ts @@ -0,0 +1,15 @@ +import { expectTypeOf, test } from 'vitest' +import type { Ref } from 'vue' + +import { useBalance } from './useBalance.js' + +test('select data', () => { + const result = useBalance({ + query: { + select(data) { + return data?.value + }, + }, + }) + expectTypeOf(result.data).toEqualTypeOf | Ref>() +}) diff --git a/wagmi-project/packages/vue/src/composables/useBalance.test.ts b/wagmi-project/packages/vue/src/composables/useBalance.test.ts new file mode 100644 index 000000000..cf2662d30 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useBalance.test.ts @@ -0,0 +1,119 @@ +import { accounts, chain, testClient, wait } from '@wagmi/test' +import { renderComposable, waitFor } from '@wagmi/test/vue' +import { parseEther } from 'viem' +import { beforeEach, expect, test } from 'vitest' + +import { ref } from 'vue' +import { useBalance } from './useBalance.js' + +const address = accounts[0] + +beforeEach(async () => { + await testClient.mainnet.setBalance({ address, value: parseEther('10000') }) + await testClient.mainnet.mine({ blocks: 1 }) + await testClient.mainnet2.setBalance({ address, value: parseEther('69') }) + await testClient.mainnet2.mine({ blocks: 1 }) +}) + +test('default', async () => { + const [query] = renderComposable(() => useBalance({ address })) + + await waitFor(query.isSuccess) + + expect(query.data.value).toMatchObject( + expect.objectContaining({ + decimals: expect.any(Number), + formatted: expect.any(String), + symbol: expect.any(String), + value: expect.any(BigInt), + }), + ) +}) + +test('parameters: chainId', async () => { + const [query] = renderComposable(() => + useBalance({ address, chainId: chain.mainnet2.id }), + ) + + await waitFor(query.isSuccess) + + expect(query.data.value).toMatchInlineSnapshot(` + { + "decimals": 18, + "formatted": "69", + "symbol": "WAG", + "value": 69000000000000000000n, + } + `) +}) + +test('parameters: token', async () => { + const [query] = renderComposable(() => + useBalance({ + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', + token: '0x6B175474E89094C44Da98b954EedeAC495271d0F', + }), + ) + + await waitFor(query.isSuccess) + + expect(query.data.value).toMatchInlineSnapshot(` + { + "decimals": 18, + "formatted": "0.559062564299199392", + "symbol": "DAI", + "value": 559062564299199392n, + } + `) +}) + +test('parameters: unit', async () => { + const [query] = renderComposable(() => + useBalance({ + address, + chainId: chain.mainnet2.id, + unit: 'wei', + }), + ) + + await waitFor(query.isSuccess) + + expect(query.data.value).toMatchInlineSnapshot(` + { + "decimals": 18, + "formatted": "69000000000000000000", + "symbol": "WAG", + "value": 69000000000000000000n, + } + `) +}) + +test('behavior: address: undefined -> defined', async () => { + const address = ref() + + const [query] = renderComposable(() => useBalance({ address })) + + await wait(100) + expect(query.fetchStatus.value).toMatchInlineSnapshot(`"idle"`) + + address.value = accounts[0] + + await waitFor(query.isSuccess) + + expect(query.data.value).toMatchInlineSnapshot(` + { + "decimals": 18, + "formatted": "10000", + "symbol": "ETH", + "value": 10000000000000000000000n, + } + `) +}) + +test('behavior: disabled when properties missing', async () => { + const [query] = renderComposable(() => useBalance({ address })) + + await wait(100) + + expect(query.fetchStatus.value).toMatchInlineSnapshot(`"idle"`) +}) diff --git a/wagmi-project/packages/vue/src/composables/useBalance.ts b/wagmi-project/packages/vue/src/composables/useBalance.ts new file mode 100644 index 000000000..1fdcdc945 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useBalance.ts @@ -0,0 +1,65 @@ +import type { Config, GetBalanceErrorType, ResolvedRegister } from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type GetBalanceData, + type GetBalanceOptions, + type GetBalanceQueryKey, + getBalanceQueryOptions, +} from '@wagmi/core/query' +import type { GetBalanceQueryFnData } from '@wagmi/core/query' + +import { computed } from 'vue' +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import type { DeepMaybeRef } from '../types/ref.js' +import { deepUnref } from '../utils/cloneDeep.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseBalanceParameters< + config extends Config = Config, + selectData = GetBalanceData, +> = Compute< + DeepMaybeRef< + GetBalanceOptions & + ConfigParameter & + QueryParameter< + GetBalanceQueryFnData, + GetBalanceErrorType, + selectData, + GetBalanceQueryKey + > + > +> + +export type UseBalanceReturnType = + UseQueryReturnType + +/** https://wagmi.sh/vue/api/composables/useBalance */ +export function useBalance< + config extends Config = ResolvedRegister['config'], + selectData = GetBalanceData, +>( + parameters_: UseBalanceParameters = {}, +): UseBalanceReturnType { + const parameters = computed(() => deepUnref(parameters_)) + + const config = useConfig(parameters) + const configChainId = useChainId({ config }) + + const queryOptions = computed(() => { + const { + address, + chainId = configChainId.value, + query = {}, + } = parameters.value + const options = getBalanceQueryOptions(config, { + ...parameters.value, + chainId, + }) + const enabled = Boolean(address && (query.enabled ?? true)) + return { ...query, ...options, enabled } + }) + + return useQuery(queryOptions as any) as UseBalanceReturnType +} diff --git a/wagmi-project/packages/vue/src/composables/useBlockNumber.test-d.ts b/wagmi-project/packages/vue/src/composables/useBlockNumber.test-d.ts new file mode 100644 index 000000000..255a1e02e --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useBlockNumber.test-d.ts @@ -0,0 +1,65 @@ +import { http, createConfig, webSocket } from '@wagmi/core' +import { mainnet, optimism } from '@wagmi/core/chains' +import { expectTypeOf, test } from 'vitest' + +import { useBlockNumber } from './useBlockNumber.js' + +test('select data', () => { + const result = useBlockNumber({ + query: { + select(data) { + expectTypeOf(data).toEqualTypeOf() + return data?.toString() + }, + }, + }) + expectTypeOf(result.data.value).toEqualTypeOf() +}) + +test('differing transports', () => { + const config = createConfig({ + chains: [mainnet, optimism], + transports: { + [mainnet.id]: http(), + [optimism.id]: webSocket(), + }, + }) + + useBlockNumber({ + config, + watch: { + poll: false, + }, + }) + + useBlockNumber({ + config, + chainId: mainnet.id, + watch: { + poll: true, + }, + }) + useBlockNumber({ + config, + chainId: mainnet.id, + watch: { + // @ts-expect-error + poll: false, + }, + }) + + useBlockNumber({ + config, + chainId: optimism.id, + watch: { + poll: true, + }, + }) + useBlockNumber({ + config, + chainId: optimism.id, + watch: { + poll: false, + }, + }) +}) diff --git a/wagmi-project/packages/vue/src/composables/useBlockNumber.test.ts b/wagmi-project/packages/vue/src/composables/useBlockNumber.test.ts new file mode 100644 index 000000000..68e7e6241 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useBlockNumber.test.ts @@ -0,0 +1,65 @@ +import { config, testClient } from '@wagmi/test' +import { renderComposable, waitFor } from '@wagmi/test/vue' +import { expect, test } from 'vitest' +import { ref } from 'vue' +import { useBlockNumber } from './useBlockNumber.js' + +test('default', async () => { + await testClient.mainnet.resetFork() + + const [blockNumberQuery] = renderComposable(() => useBlockNumber()) + + await waitFor(blockNumberQuery.status, (status) => status === 'success') + + expect(blockNumberQuery.data.value).toMatchInlineSnapshot('19258213n') +}) + +test('parameters: chainId', async () => { + config.setState((state) => ({ ...state, chainId: config.chains[0].id })) + + const [blockNumberQuery] = renderComposable(() => useBlockNumber()) + + await waitFor(blockNumberQuery.status, (status) => status === 'success') + expect(blockNumberQuery.data.value).toBeTypeOf('bigint') + + config.setState((state) => ({ ...state, chainId: config.chains[2].id })) + + await waitFor(blockNumberQuery.status, (status) => status === 'success') + expect(blockNumberQuery.data.value).toBeTypeOf('bigint') +}) + +test('parameters: watch', async () => { + const [blockNumberQuery] = renderComposable(() => + useBlockNumber({ watch: true }), + ) + + await waitFor(blockNumberQuery.status, (status) => status === 'success') + + const blockNumber = blockNumberQuery.data.value! + await testClient.mainnet.mine({ blocks: 1 }) + + await waitFor(blockNumberQuery.data, (data) => data === blockNumber + 1n) +}) + +test('parameters: watch (reactive)', async () => { + const watch = ref(true) + + const [blockNumberQuery] = renderComposable(() => useBlockNumber({ watch })) + + await waitFor(blockNumberQuery.status, (status) => status === 'success') + + const blockNumber = blockNumberQuery.data.value! + + await testClient.mainnet.mine({ blocks: 1 }) + await waitFor(blockNumberQuery.data, (data) => data === blockNumber + 1n) + + await testClient.mainnet.mine({ blocks: 1 }) + await waitFor(blockNumberQuery.data, (data) => data === blockNumber + 2n) + + watch.value = false + + await testClient.mainnet.mine({ blocks: 1 }) + await waitFor(blockNumberQuery.data, (data) => data === blockNumber + 2n, { + timeout: 1_000, + }) +}) diff --git a/wagmi-project/packages/vue/src/composables/useBlockNumber.ts b/wagmi-project/packages/vue/src/composables/useBlockNumber.ts new file mode 100644 index 000000000..aadf04fb2 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useBlockNumber.ts @@ -0,0 +1,120 @@ +import { useQueryClient } from '@tanstack/vue-query' +import type { + Config, + GetBlockNumberErrorType, + ResolvedRegister, +} from '@wagmi/core' +import type { + Compute, + UnionCompute, + UnionStrictOmit, +} from '@wagmi/core/internal' +import { + type GetBlockNumberData, + type GetBlockNumberOptions, + type GetBlockNumberQueryFnData, + type GetBlockNumberQueryKey, + getBlockNumberQueryOptions, +} from '@wagmi/core/query' +import { computed } from 'vue' + +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import type { DeepMaybeRef, DeepUnwrapRef } from '../types/ref.js' +import { deepUnref } from '../utils/cloneDeep.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' +import { + type UseWatchBlockNumberParameters, + useWatchBlockNumber, +} from './useWatchBlockNumber.js' + +export type UseBlockNumberParameters< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = GetBlockNumberData, +> = Compute< + DeepMaybeRef< + GetBlockNumberOptions & + ConfigParameter & + QueryParameter< + GetBlockNumberQueryFnData, + GetBlockNumberErrorType, + selectData, + GetBlockNumberQueryKey + > & { + watch?: + | boolean + | UnionCompute< + UnionStrictOmit< + DeepUnwrapRef>, + 'chainId' | 'config' | 'onBlockNumber' | 'onError' + > + > + | undefined + } + > +> + +export type UseBlockNumberReturnType = + UseQueryReturnType + +/** https://wagmi.sh/vue/api/composables/useBlockNumber */ +export function useBlockNumber< + config extends Config = ResolvedRegister['config'], + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = GetBlockNumberData, +>( + parameters_: UseBlockNumberParameters = {}, +): UseBlockNumberReturnType { + const parameters = computed(() => deepUnref(parameters_)) + + const config = useConfig(parameters) + const queryClient = useQueryClient() + const configChainId = useChainId({ config }) + + const queryOptions = computed(() => { + const { + chainId = configChainId.value, + query = {}, + watch: _, + ...rest + } = parameters.value + const options = getBlockNumberQueryOptions(config, { + ...deepUnref(rest), + chainId, + }) + return { + ...query, + ...options, + } + }) + + const watchBlockNumberArgs = computed(() => { + const { + config, + chainId = configChainId.value, + query, + watch, + } = parameters.value + return { + ...({ + config, + chainId, + ...(typeof watch === 'object' ? watch : {}), + } as UseWatchBlockNumberParameters), + enabled: + (query?.enabled ?? true) && + (typeof watch === 'object' ? watch.enabled : watch), + onBlockNumber(blockNumber) { + queryClient.setQueryData(queryOptions.value.queryKey, blockNumber) + }, + } satisfies UseWatchBlockNumberParameters + }) + + useWatchBlockNumber(watchBlockNumberArgs) + + return useQuery(queryOptions as any) as UseBlockNumberReturnType +} diff --git a/wagmi-project/packages/vue/src/composables/useBytecode.test-d.ts b/wagmi-project/packages/vue/src/composables/useBytecode.test-d.ts new file mode 100644 index 000000000..16fb3a36f --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useBytecode.test-d.ts @@ -0,0 +1,16 @@ +import type { Hex } from 'viem' +import { expectTypeOf, test } from 'vitest' + +import { useBytecode } from './useBytecode.js' + +test('select data', () => { + const result = useBytecode({ + query: { + select(data) { + expectTypeOf(data).toEqualTypeOf() + return data + }, + }, + }) + expectTypeOf(result.data.value).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/vue/src/composables/useBytecode.test.ts b/wagmi-project/packages/vue/src/composables/useBytecode.test.ts new file mode 100644 index 000000000..f98eccc8d --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useBytecode.test.ts @@ -0,0 +1,296 @@ +import { address, chain, wait } from '@wagmi/test' +import { renderComposable, waitFor } from '@wagmi/test/vue' +import { expect, test } from 'vitest' + +import { ref } from 'vue' +import { deepUnref } from '../utils/cloneDeep.js' +import { useBytecode } from './useBytecode.js' + +test('default', async () => { + const [result] = renderComposable(() => + useBytecode({ + address: address.wagmiMintExample, + }), + ) + + await waitFor(result.isSuccess) + + expect(deepUnref(result)).toMatchInlineSnapshot(` + { + "data": "0x608060405234801561001057600080fd5b50600436106101005760003560e01c80636352211e11610097578063a22cb46511610066578063a22cb46514610215578063b88d4fde14610228578063c87b56dd1461023b578063e985e9c51461024e57600080fd5b80636352211e146101d457806370a08231146101e757806395d89b41146101fa578063a0712d681461020257600080fd5b80631249c58b116100d35780631249c58b1461018f57806318160ddd1461019757806323b872dd146101ae57806342842e0e146101c157600080fd5b806301ffc9a71461010557806306fdde031461012d578063081812fc14610142578063095ea7b31461017a575b600080fd5b61011861011336600461178f565b610297565b60405190151581526020015b60405180910390f35b61013561037c565b6040516101249190611829565b61015561015036600461183c565b61040e565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610124565b61018d61018836600461187e565b6104d3565b005b61018d61062b565b6101a060065481565b604051908152602001610124565b61018d6101bc3660046118a8565b61067d565b61018d6101cf3660046118a8565b610704565b6101556101e236600461183c565b61071f565b6101a06101f53660046118e4565b6107b7565b61013561086b565b61018d61021036600461183c565b61087a565b61018d6102233660046118ff565b610902565b61018d61023636600461196a565b610911565b61013561024936600461183c565b61099f565b61011861025c366004611a64565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260056020908152604080832093909416825291909152205460ff1690565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f80ac58cd00000000000000000000000000000000000000000000000000000000148061032a57507fffffffff0000000000000000000000000000000000000000000000000000000082167f5b5e139f00000000000000000000000000000000000000000000000000000000145b8061037657507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b60606000805461038b90611a97565b80601f01602080910402602001604051908101604052809291908181526020018280546103b790611a97565b80156104045780601f106103d957610100808354040283529160200191610404565b820191906000526020600020905b8154815290600101906020018083116103e757829003601f168201915b5050505050905090565b60008181526002602052604081205473ffffffffffffffffffffffffffffffffffffffff166104aa5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201527f697374656e7420746f6b656e000000000000000000000000000000000000000060648201526084015b60405180910390fd5b5060009081526004602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b60006104de8261071f565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036105815760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560448201527f720000000000000000000000000000000000000000000000000000000000000060648201526084016104a1565b3373ffffffffffffffffffffffffffffffffffffffff821614806105aa57506105aa813361025c565b61061c5760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c000000000000000060648201526084016104a1565b6106268383610b07565b505050565b6007545b60008181526002602052604090205473ffffffffffffffffffffffffffffffffffffffff16156106615760010161062f565b61066b3382610ba7565b60068054600190810190915501600755565b6106873382610bc1565b6106f95760405162461bcd60e51b815260206004820152603160248201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60448201527f776e6572206e6f7220617070726f76656400000000000000000000000000000060648201526084016104a1565b610626838383610d17565b61062683838360405180602001604052806000815250610911565b60008181526002602052604081205473ffffffffffffffffffffffffffffffffffffffff16806103765760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201527f656e7420746f6b656e000000000000000000000000000000000000000000000060648201526084016104a1565b600073ffffffffffffffffffffffffffffffffffffffff82166108425760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a6560448201527f726f20616464726573730000000000000000000000000000000000000000000060648201526084016104a1565b5073ffffffffffffffffffffffffffffffffffffffff1660009081526003602052604090205490565b60606001805461038b90611a97565b60008181526002602052604090205473ffffffffffffffffffffffffffffffffffffffff16156108ec5760405162461bcd60e51b815260206004820152601160248201527f546f6b656e2049442069732074616b656e00000000000000000000000000000060448201526064016104a1565b6108f63382610ba7565b50600680546001019055565b61090d338383610f4a565b5050565b61091b3383610bc1565b61098d5760405162461bcd60e51b815260206004820152603160248201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60448201527f776e6572206e6f7220617070726f76656400000000000000000000000000000060648201526084016104a1565b6109998484848461105d565b50505050565b6040517f666f726567726f756e64000000000000000000000000000000000000000000006020820152602a810182905260609060009061016890604a016040516020818303038152906040528051906020012060001c6109ff9190611b19565b6040517f6261636b67726f756e64000000000000000000000000000000000000000000006020820152602a810185905290915060009061016890604a016040516020818303038152906040528051906020012060001c610a5f9190611b19565b90506000610aba610a6f866110e6565b610aa9610a7b866110e6565b610a84866110e6565b604051602001610a95929190611b2d565b60405160208183030381529060405261121b565b604051602001610a959291906125ba565b9050600081604051602001610acf919061268b565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190529695505050505050565b600081815260046020526040902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84169081179091558190610b618261071f565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b61090d82826040518060200160405280600081525061136e565b60008181526002602052604081205473ffffffffffffffffffffffffffffffffffffffff16610c585760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201527f697374656e7420746f6b656e000000000000000000000000000000000000000060648201526084016104a1565b6000610c638361071f565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480610cd1575073ffffffffffffffffffffffffffffffffffffffff80821660009081526005602090815260408083209388168352929052205460ff165b80610d0f57508373ffffffffffffffffffffffffffffffffffffffff16610cf78461040e565b73ffffffffffffffffffffffffffffffffffffffff16145b949350505050565b8273ffffffffffffffffffffffffffffffffffffffff16610d378261071f565b73ffffffffffffffffffffffffffffffffffffffff1614610dc05760405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201527f6f776e657200000000000000000000000000000000000000000000000000000060648201526084016104a1565b73ffffffffffffffffffffffffffffffffffffffff8216610e485760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f2061646460448201527f726573730000000000000000000000000000000000000000000000000000000060648201526084016104a1565b610e53600082610b07565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600360205260408120805460019290610e899084906126ff565b909155505073ffffffffffffffffffffffffffffffffffffffff82166000908152600360205260408120805460019290610ec4908490612716565b909155505060008181526002602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff86811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610fc55760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c65720000000000000060448201526064016104a1565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526005602090815260408083209487168084529482529182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b611068848484610d17565b611074848484846113f7565b6109995760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e746572000000000000000000000000000060648201526084016104a1565b60608160000361112957505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115611153578061113d8161272e565b915061114c9050600a83612766565b915061112d565b60008167ffffffffffffffff81111561116e5761116e61193b565b6040519080825280601f01601f191660200182016040528015611198576020820181803683370190505b5090505b8415610d0f576111ad6001836126ff565b91506111ba600a86611b19565b6111c5906030612716565b60f81b8183815181106111da576111da61277a565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350611214600a86612766565b945061119c565b6060815160000361123a57505060408051602081019091526000815290565b600060405180606001604052806040815260200161284d60409139905060006003845160026112699190612716565b6112739190612766565b61127e9060046127a9565b67ffffffffffffffff8111156112965761129661193b565b6040519080825280601f01601f1916602001820160405280156112c0576020820181803683370190505b509050600182016020820185865187015b8082101561132c576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f81168501518453506001830192506112d1565b5050600386510660018114611348576002811461135b57611363565b603d6001830353603d6002830353611363565b603d60018303535b509195945050505050565b61137883836115d0565b61138560008484846113f7565b6106265760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e746572000000000000000000000000000060648201526084016104a1565b600073ffffffffffffffffffffffffffffffffffffffff84163b156115c5576040517f150b7a0200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85169063150b7a029061146e9033908990889088906004016127e6565b6020604051808303816000875af19250505080156114c7575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682019092526114c49181019061282f565b60015b61157a573d8080156114f5576040519150601f19603f3d011682016040523d82523d6000602084013e6114fa565b606091505b5080516000036115725760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e746572000000000000000000000000000060648201526084016104a1565b805181602001fd5b7fffffffff00000000000000000000000000000000000000000000000000000000167f150b7a0200000000000000000000000000000000000000000000000000000000149050610d0f565b506001949350505050565b73ffffffffffffffffffffffffffffffffffffffff82166116335760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f206164647265737360448201526064016104a1565b60008181526002602052604090205473ffffffffffffffffffffffffffffffffffffffff16156116a55760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000060448201526064016104a1565b73ffffffffffffffffffffffffffffffffffffffff821660009081526003602052604081208054600192906116db908490612716565b909155505060008181526002602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b7fffffffff000000000000000000000000000000000000000000000000000000008116811461178c57600080fd5b50565b6000602082840312156117a157600080fd5b81356117ac8161175e565b9392505050565b60005b838110156117ce5781810151838201526020016117b6565b838111156109995750506000910152565b600081518084526117f78160208601602086016117b3565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006117ac60208301846117df565b60006020828403121561184e57600080fd5b5035919050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461187957600080fd5b919050565b6000806040838503121561189157600080fd5b61189a83611855565b946020939093013593505050565b6000806000606084860312156118bd57600080fd5b6118c684611855565b92506118d460208501611855565b9150604084013590509250925092565b6000602082840312156118f657600080fd5b6117ac82611855565b6000806040838503121561191257600080fd5b61191b83611855565b91506020830135801515811461193057600080fd5b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000806000806080858703121561198057600080fd5b61198985611855565b935061199760208601611855565b925060408501359150606085013567ffffffffffffffff808211156119bb57600080fd5b818701915087601f8301126119cf57600080fd5b8135818111156119e1576119e161193b565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715611a2757611a2761193b565b816040528281528a6020848701011115611a4057600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b60008060408385031215611a7757600080fd5b611a8083611855565b9150611a8e60208401611855565b90509250929050565b600181811c90821680611aab57607f821691505b602082108103611ae4577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082611b2857611b28611aea565b500690565b7f3c73766720786d6c6e733d22687474703a2f2f7777772e77332e6f72672f323081527f30302f737667222077696474683d223130323422206865696768743d2231303260208201527f34222066696c6c3d226e6f6e65223e3c706174682066696c6c3d2268736c2800604082015260008351611bb181605f8501602088016117b3565b7f2c20313030252c20313025292220643d224d3020306831303234763130323448605f918401918201527f307a22202f3e3c672066696c6c3d2268736c2800000000000000000000000000607f8201528351611c148160928401602088016117b3565b7f2c20313030252c2039302529223e3c7061746820643d224d393033203433372e609292909101918201527f35633020392e3131332d372e3338382031362e352d31362e352031362e35732d60b28201527f31362e352d372e3338372d31362e352d31362e3520372e3338382d31362e352060d28201527f31362e352d31362e352031362e3520372e3338372031362e352031362e357a4d60f28201527f3639382e3532392035363663362e39323120302031322e35332d352e353936206101128201527f31322e35332d31322e35762d353063302d362e39303420352e3630392d31322e6101328201527f352031322e3532392d31322e356832352e30353963362e393220302031322e356101528201527f323920352e3539362031322e3532392031322e35763530633020362e393034206101728201527f352e3630392031322e352031322e35332031322e357331322e3532392d352e356101928201527f39362031322e3532392d31322e35762d353063302d362e39303420352e3630396101b28201527f2d31322e352031322e35332d31322e356832352e30353963362e3932203020316101d28201527f322e35323920352e3539362031322e3532392031322e35763530633020362e396101f28201527f303420352e3630392031322e352031322e3532392031322e356833372e3538396102128201527f63362e393220302031322e3532392d352e3539362031322e3532392d31322e356102328201527f762d373563302d362e3930342d352e3630392d31322e352d31322e3532392d316102528201527f322e35732d31322e353320352e3539362d31322e35332031322e357635362e326102728201527f3561362e32363420362e3236342030203120312d31322e3532392030563437386102928201527f2e3563302d362e3930342d352e3630392d31322e352d31322e35332d31322e356102b28201527f483639382e353239632d362e393220302d31322e35323920352e3539362d31326102d28201527f2e3532392031322e35763735633020362e39303420352e3630392031322e35206102f28201527f31322e3532392031322e357a22202f3e3c7061746820643d224d3135372e36356103128201527f3520353431632d362e39333220302d31322e3535322d352e3539362d31322e356103328201527f35322d31322e35762d353063302d362e3930342d352e3631392d31322e352d316103528201527f322e3535312d31322e3553313230203437312e35393620313230203437382e356103728201527f763735633020362e39303420352e36322031322e352031322e3535322031322e6103928201527f35683135302e363263362e39333320302031322e3535322d352e3539362031326103b28201527f2e3535322d31322e35762d353063302d362e39303420352e3631392d31322e356103d28201527f2031322e3535322d31322e35683134342e33343563332e343635203020362e326103f28201527f373620322e37393820362e32373620362e3235732d322e38313120362e32352d6104128201527f362e32373620362e3235483332302e383238632d362e39333320302d31322e356104328201527f353220352e3539362d31322e3535322031322e357633372e35633020362e39306104528201527f3420352e3631392031322e352031322e3535322031322e35683135302e3632636104728201527f362e39333320302031322e3535322d352e3539362031322e3535322d31322e356104928201527f762d373563302d362e3930342d352e3631392d31322e352d31322e3535322d316104b28201527f322e35483238332e313732632d362e39333220302d31322e35353120352e35396104d28201527f362d31322e3535312031322e35763530633020362e3930342d352e36313920316104f28201527f322e352d31322e3535322031322e35682d32352e313033632d362e39333320306105128201527f2d31322e3535322d352e3539362d31322e3535322d31322e35762d353063302d6105328201527f362e3930342d352e36322d31322e352d31322e3535322d31322e35732d31322e6105528201527f35353220352e3539362d31322e3535322031322e35763530633020362e3930346105728201527f2d352e3631392031322e352d31322e3535312031322e35682d32352e3130347a6105928201527f6d3330312e3234322d362e3235633020332e3435322d322e38313120362e32356105b28201527f2d362e32373620362e3235483333392e363535632d332e34363520302d362e326105d28201527f37362d322e3739382d362e3237362d362e323573322e3831312d362e323520366105f28201527f2e3237362d362e3235683131322e39363663332e343635203020362e323736206106128201527f322e37393820362e32373620362e32357a4d343937203535332e3831386330206106328201527f362e39323920352e3632382031322e3534362031322e3537312031322e3534366106528201527f6831333261362e323820362e323820302030203120362e32383620362e3237326106728201527f20362e323820362e32382030203020312d362e32383620362e323733682d31336106928201527f32632d362e39343320302d31322e35373120352e3631362d31322e35373120316106b28201527f322e3534364131322e35362031322e3536203020302030203530392e353731206106d28201527f363034683135302e38353863362e39343320302031322e3537312d352e3631366106f28201527f2031322e3537312d31322e353435762d3131322e393163302d362e3932382d356107128201527f2e3632382d31322e3534352d31322e3537312d31322e353435483530392e35376107328201527f31632d362e39343320302d31322e35373120352e3631372d31322e35373120316107528201527f322e3534357637352e3237337a6d33372e3731342d36322e373237632d362e396107728201527f343320302d31322e35373120352e3631372d31322e3537312031322e353435766107928201527f32352e303931633020362e39323920352e3632382031322e3534362031322e356107b28201527f37312031322e353436683130302e35373263362e39343320302031322e3537316107d28201527f2d352e3631372031322e3537312d31322e353436762d32352e30393163302d366107f28201527f2e3932382d352e3632382d31322e3534352d31322e3537312d31322e353435486108128201527f3533342e3731347a222066696c6c2d72756c653d226576656e6f646422202f3e6108328201527f3c2f673e3c2f7376673e0000000000000000000000000000000000000000000061085282015261085c01949350505050565b7f7b226e616d65223a20227761676d6920230000000000000000000000000000008152600083516125f28160118501602088016117b3565b7f222c2022696d616765223a2022646174613a696d6167652f7376672b786d6c3b6011918401918201527f6261736536342c00000000000000000000000000000000000000000000000000603182015283516126558160388401602088016117b3565b7f227d00000000000000000000000000000000000000000000000000000000000060389290910191820152603a01949350505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c0000008152600082516126c381601d8501602087016117b3565b91909101601d0192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015612711576127116126d0565b500390565b60008219821115612729576127296126d0565b500190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361275f5761275f6126d0565b5060010190565b60008261277557612775611aea565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156127e1576127e16126d0565b500290565b600073ffffffffffffffffffffffffffffffffffffffff80871683528086166020840152508360408301526080606083015261282560808301846117df565b9695505050505050565b60006020828403121561284157600080fd5b81516117ac8161175e56fe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fa26469706673582212201665a4f9111990d7529375848d3fd02c0121091a940da59e763eba826e7b077064736f6c634300080d0033", + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "getBytecode", + { + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "chainId": 1, + }, + ], + "refetch": [Function], + "status": "success", + "suspense": [Function], + } + `) +}) + +test('parameters: blockNumber', async () => { + const [result] = renderComposable(() => + useBytecode({ + address: address.wagmiMintExample, + blockNumber: 15564163n, + }), + ) + + await waitFor(result.isSuccess) + + expect(deepUnref(result)).toMatchInlineSnapshot(` + { + "data": null, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "getBytecode", + { + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "blockNumber": 15564163n, + "chainId": 1, + }, + ], + "refetch": [Function], + "status": "success", + "suspense": [Function], + } + `) +}) + +test('parameters: blockTag', async () => { + const [result] = renderComposable(() => + useBytecode({ + address: address.wagmiMintExample, + blockTag: 'earliest', + }), + ) + + await waitFor(result.isSuccess) + + expect(deepUnref(result)).toMatchInlineSnapshot(` + { + "data": null, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "getBytecode", + { + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "blockTag": "earliest", + "chainId": 1, + }, + ], + "refetch": [Function], + "status": "success", + "suspense": [Function], + } + `) +}) + +test('parameters: chainId', async () => { + const [result] = renderComposable(() => + useBytecode({ + address: address.wagmiMintExample, + chainId: chain.optimism.id, + }), + ) + + await waitFor(result.isSuccess) + + expect(deepUnref(result)).toMatchInlineSnapshot(` + { + "data": null, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "getBytecode", + { + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "chainId": 10, + }, + ], + "refetch": [Function], + "status": "success", + "suspense": [Function], + } + `) +}) + +test('behavior: address: undefined -> defined', async () => { + const contractAddress = ref() + + const [result] = renderComposable(() => + useBytecode({ address: contractAddress }), + ) + + await wait(100) + expect(result.fetchStatus.value).toBe('idle') + + expect(deepUnref(result)).toMatchInlineSnapshot(` + { + "data": undefined, + "dataUpdatedAt": 0, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": false, + "isFetchedAfterMount": false, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": true, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": false, + "isSuccess": false, + "queryKey": [ + "getBytecode", + { + "address": undefined, + "chainId": 1, + }, + ], + "refetch": [Function], + "status": "pending", + "suspense": [Function], + } + `) + + contractAddress.value = address.wagmiMintExample + + await waitFor(result.isSuccess) + + expect(deepUnref(result)).toMatchInlineSnapshot(` + { + "data": "0x608060405234801561001057600080fd5b50600436106101005760003560e01c80636352211e11610097578063a22cb46511610066578063a22cb46514610215578063b88d4fde14610228578063c87b56dd1461023b578063e985e9c51461024e57600080fd5b80636352211e146101d457806370a08231146101e757806395d89b41146101fa578063a0712d681461020257600080fd5b80631249c58b116100d35780631249c58b1461018f57806318160ddd1461019757806323b872dd146101ae57806342842e0e146101c157600080fd5b806301ffc9a71461010557806306fdde031461012d578063081812fc14610142578063095ea7b31461017a575b600080fd5b61011861011336600461178f565b610297565b60405190151581526020015b60405180910390f35b61013561037c565b6040516101249190611829565b61015561015036600461183c565b61040e565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610124565b61018d61018836600461187e565b6104d3565b005b61018d61062b565b6101a060065481565b604051908152602001610124565b61018d6101bc3660046118a8565b61067d565b61018d6101cf3660046118a8565b610704565b6101556101e236600461183c565b61071f565b6101a06101f53660046118e4565b6107b7565b61013561086b565b61018d61021036600461183c565b61087a565b61018d6102233660046118ff565b610902565b61018d61023636600461196a565b610911565b61013561024936600461183c565b61099f565b61011861025c366004611a64565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260056020908152604080832093909416825291909152205460ff1690565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f80ac58cd00000000000000000000000000000000000000000000000000000000148061032a57507fffffffff0000000000000000000000000000000000000000000000000000000082167f5b5e139f00000000000000000000000000000000000000000000000000000000145b8061037657507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b60606000805461038b90611a97565b80601f01602080910402602001604051908101604052809291908181526020018280546103b790611a97565b80156104045780601f106103d957610100808354040283529160200191610404565b820191906000526020600020905b8154815290600101906020018083116103e757829003601f168201915b5050505050905090565b60008181526002602052604081205473ffffffffffffffffffffffffffffffffffffffff166104aa5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201527f697374656e7420746f6b656e000000000000000000000000000000000000000060648201526084015b60405180910390fd5b5060009081526004602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b60006104de8261071f565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036105815760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560448201527f720000000000000000000000000000000000000000000000000000000000000060648201526084016104a1565b3373ffffffffffffffffffffffffffffffffffffffff821614806105aa57506105aa813361025c565b61061c5760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c000000000000000060648201526084016104a1565b6106268383610b07565b505050565b6007545b60008181526002602052604090205473ffffffffffffffffffffffffffffffffffffffff16156106615760010161062f565b61066b3382610ba7565b60068054600190810190915501600755565b6106873382610bc1565b6106f95760405162461bcd60e51b815260206004820152603160248201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60448201527f776e6572206e6f7220617070726f76656400000000000000000000000000000060648201526084016104a1565b610626838383610d17565b61062683838360405180602001604052806000815250610911565b60008181526002602052604081205473ffffffffffffffffffffffffffffffffffffffff16806103765760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201527f656e7420746f6b656e000000000000000000000000000000000000000000000060648201526084016104a1565b600073ffffffffffffffffffffffffffffffffffffffff82166108425760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a6560448201527f726f20616464726573730000000000000000000000000000000000000000000060648201526084016104a1565b5073ffffffffffffffffffffffffffffffffffffffff1660009081526003602052604090205490565b60606001805461038b90611a97565b60008181526002602052604090205473ffffffffffffffffffffffffffffffffffffffff16156108ec5760405162461bcd60e51b815260206004820152601160248201527f546f6b656e2049442069732074616b656e00000000000000000000000000000060448201526064016104a1565b6108f63382610ba7565b50600680546001019055565b61090d338383610f4a565b5050565b61091b3383610bc1565b61098d5760405162461bcd60e51b815260206004820152603160248201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60448201527f776e6572206e6f7220617070726f76656400000000000000000000000000000060648201526084016104a1565b6109998484848461105d565b50505050565b6040517f666f726567726f756e64000000000000000000000000000000000000000000006020820152602a810182905260609060009061016890604a016040516020818303038152906040528051906020012060001c6109ff9190611b19565b6040517f6261636b67726f756e64000000000000000000000000000000000000000000006020820152602a810185905290915060009061016890604a016040516020818303038152906040528051906020012060001c610a5f9190611b19565b90506000610aba610a6f866110e6565b610aa9610a7b866110e6565b610a84866110e6565b604051602001610a95929190611b2d565b60405160208183030381529060405261121b565b604051602001610a959291906125ba565b9050600081604051602001610acf919061268b565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190529695505050505050565b600081815260046020526040902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84169081179091558190610b618261071f565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b61090d82826040518060200160405280600081525061136e565b60008181526002602052604081205473ffffffffffffffffffffffffffffffffffffffff16610c585760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201527f697374656e7420746f6b656e000000000000000000000000000000000000000060648201526084016104a1565b6000610c638361071f565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480610cd1575073ffffffffffffffffffffffffffffffffffffffff80821660009081526005602090815260408083209388168352929052205460ff165b80610d0f57508373ffffffffffffffffffffffffffffffffffffffff16610cf78461040e565b73ffffffffffffffffffffffffffffffffffffffff16145b949350505050565b8273ffffffffffffffffffffffffffffffffffffffff16610d378261071f565b73ffffffffffffffffffffffffffffffffffffffff1614610dc05760405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201527f6f776e657200000000000000000000000000000000000000000000000000000060648201526084016104a1565b73ffffffffffffffffffffffffffffffffffffffff8216610e485760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f2061646460448201527f726573730000000000000000000000000000000000000000000000000000000060648201526084016104a1565b610e53600082610b07565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600360205260408120805460019290610e899084906126ff565b909155505073ffffffffffffffffffffffffffffffffffffffff82166000908152600360205260408120805460019290610ec4908490612716565b909155505060008181526002602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff86811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610fc55760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c65720000000000000060448201526064016104a1565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526005602090815260408083209487168084529482529182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b611068848484610d17565b611074848484846113f7565b6109995760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e746572000000000000000000000000000060648201526084016104a1565b60608160000361112957505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115611153578061113d8161272e565b915061114c9050600a83612766565b915061112d565b60008167ffffffffffffffff81111561116e5761116e61193b565b6040519080825280601f01601f191660200182016040528015611198576020820181803683370190505b5090505b8415610d0f576111ad6001836126ff565b91506111ba600a86611b19565b6111c5906030612716565b60f81b8183815181106111da576111da61277a565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350611214600a86612766565b945061119c565b6060815160000361123a57505060408051602081019091526000815290565b600060405180606001604052806040815260200161284d60409139905060006003845160026112699190612716565b6112739190612766565b61127e9060046127a9565b67ffffffffffffffff8111156112965761129661193b565b6040519080825280601f01601f1916602001820160405280156112c0576020820181803683370190505b509050600182016020820185865187015b8082101561132c576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f81168501518453506001830192506112d1565b5050600386510660018114611348576002811461135b57611363565b603d6001830353603d6002830353611363565b603d60018303535b509195945050505050565b61137883836115d0565b61138560008484846113f7565b6106265760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e746572000000000000000000000000000060648201526084016104a1565b600073ffffffffffffffffffffffffffffffffffffffff84163b156115c5576040517f150b7a0200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85169063150b7a029061146e9033908990889088906004016127e6565b6020604051808303816000875af19250505080156114c7575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682019092526114c49181019061282f565b60015b61157a573d8080156114f5576040519150601f19603f3d011682016040523d82523d6000602084013e6114fa565b606091505b5080516000036115725760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e746572000000000000000000000000000060648201526084016104a1565b805181602001fd5b7fffffffff00000000000000000000000000000000000000000000000000000000167f150b7a0200000000000000000000000000000000000000000000000000000000149050610d0f565b506001949350505050565b73ffffffffffffffffffffffffffffffffffffffff82166116335760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f206164647265737360448201526064016104a1565b60008181526002602052604090205473ffffffffffffffffffffffffffffffffffffffff16156116a55760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000060448201526064016104a1565b73ffffffffffffffffffffffffffffffffffffffff821660009081526003602052604081208054600192906116db908490612716565b909155505060008181526002602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b7fffffffff000000000000000000000000000000000000000000000000000000008116811461178c57600080fd5b50565b6000602082840312156117a157600080fd5b81356117ac8161175e565b9392505050565b60005b838110156117ce5781810151838201526020016117b6565b838111156109995750506000910152565b600081518084526117f78160208601602086016117b3565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006117ac60208301846117df565b60006020828403121561184e57600080fd5b5035919050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461187957600080fd5b919050565b6000806040838503121561189157600080fd5b61189a83611855565b946020939093013593505050565b6000806000606084860312156118bd57600080fd5b6118c684611855565b92506118d460208501611855565b9150604084013590509250925092565b6000602082840312156118f657600080fd5b6117ac82611855565b6000806040838503121561191257600080fd5b61191b83611855565b91506020830135801515811461193057600080fd5b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000806000806080858703121561198057600080fd5b61198985611855565b935061199760208601611855565b925060408501359150606085013567ffffffffffffffff808211156119bb57600080fd5b818701915087601f8301126119cf57600080fd5b8135818111156119e1576119e161193b565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715611a2757611a2761193b565b816040528281528a6020848701011115611a4057600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b60008060408385031215611a7757600080fd5b611a8083611855565b9150611a8e60208401611855565b90509250929050565b600181811c90821680611aab57607f821691505b602082108103611ae4577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082611b2857611b28611aea565b500690565b7f3c73766720786d6c6e733d22687474703a2f2f7777772e77332e6f72672f323081527f30302f737667222077696474683d223130323422206865696768743d2231303260208201527f34222066696c6c3d226e6f6e65223e3c706174682066696c6c3d2268736c2800604082015260008351611bb181605f8501602088016117b3565b7f2c20313030252c20313025292220643d224d3020306831303234763130323448605f918401918201527f307a22202f3e3c672066696c6c3d2268736c2800000000000000000000000000607f8201528351611c148160928401602088016117b3565b7f2c20313030252c2039302529223e3c7061746820643d224d393033203433372e609292909101918201527f35633020392e3131332d372e3338382031362e352d31362e352031362e35732d60b28201527f31362e352d372e3338372d31362e352d31362e3520372e3338382d31362e352060d28201527f31362e352d31362e352031362e3520372e3338372031362e352031362e357a4d60f28201527f3639382e3532392035363663362e39323120302031322e35332d352e353936206101128201527f31322e35332d31322e35762d353063302d362e39303420352e3630392d31322e6101328201527f352031322e3532392d31322e356832352e30353963362e393220302031322e356101528201527f323920352e3539362031322e3532392031322e35763530633020362e393034206101728201527f352e3630392031322e352031322e35332031322e357331322e3532392d352e356101928201527f39362031322e3532392d31322e35762d353063302d362e39303420352e3630396101b28201527f2d31322e352031322e35332d31322e356832352e30353963362e3932203020316101d28201527f322e35323920352e3539362031322e3532392031322e35763530633020362e396101f28201527f303420352e3630392031322e352031322e3532392031322e356833372e3538396102128201527f63362e393220302031322e3532392d352e3539362031322e3532392d31322e356102328201527f762d373563302d362e3930342d352e3630392d31322e352d31322e3532392d316102528201527f322e35732d31322e353320352e3539362d31322e35332031322e357635362e326102728201527f3561362e32363420362e3236342030203120312d31322e3532392030563437386102928201527f2e3563302d362e3930342d352e3630392d31322e352d31322e35332d31322e356102b28201527f483639382e353239632d362e393220302d31322e35323920352e3539362d31326102d28201527f2e3532392031322e35763735633020362e39303420352e3630392031322e35206102f28201527f31322e3532392031322e357a22202f3e3c7061746820643d224d3135372e36356103128201527f3520353431632d362e39333220302d31322e3535322d352e3539362d31322e356103328201527f35322d31322e35762d353063302d362e3930342d352e3631392d31322e352d316103528201527f322e3535312d31322e3553313230203437312e35393620313230203437382e356103728201527f763735633020362e39303420352e36322031322e352031322e3535322031322e6103928201527f35683135302e363263362e39333320302031322e3535322d352e3539362031326103b28201527f2e3535322d31322e35762d353063302d362e39303420352e3631392d31322e356103d28201527f2031322e3535322d31322e35683134342e33343563332e343635203020362e326103f28201527f373620322e37393820362e32373620362e3235732d322e38313120362e32352d6104128201527f362e32373620362e3235483332302e383238632d362e39333320302d31322e356104328201527f353220352e3539362d31322e3535322031322e357633372e35633020362e39306104528201527f3420352e3631392031322e352031322e3535322031322e35683135302e3632636104728201527f362e39333320302031322e3535322d352e3539362031322e3535322d31322e356104928201527f762d373563302d362e3930342d352e3631392d31322e352d31322e3535322d316104b28201527f322e35483238332e313732632d362e39333220302d31322e35353120352e35396104d28201527f362d31322e3535312031322e35763530633020362e3930342d352e36313920316104f28201527f322e352d31322e3535322031322e35682d32352e313033632d362e39333320306105128201527f2d31322e3535322d352e3539362d31322e3535322d31322e35762d353063302d6105328201527f362e3930342d352e36322d31322e352d31322e3535322d31322e35732d31322e6105528201527f35353220352e3539362d31322e3535322031322e35763530633020362e3930346105728201527f2d352e3631392031322e352d31322e3535312031322e35682d32352e3130347a6105928201527f6d3330312e3234322d362e3235633020332e3435322d322e38313120362e32356105b28201527f2d362e32373620362e3235483333392e363535632d332e34363520302d362e326105d28201527f37362d322e3739382d362e3237362d362e323573322e3831312d362e323520366105f28201527f2e3237362d362e3235683131322e39363663332e343635203020362e323736206106128201527f322e37393820362e32373620362e32357a4d343937203535332e3831386330206106328201527f362e39323920352e3632382031322e3534362031322e3537312031322e3534366106528201527f6831333261362e323820362e323820302030203120362e32383620362e3237326106728201527f20362e323820362e32382030203020312d362e32383620362e323733682d31336106928201527f32632d362e39343320302d31322e35373120352e3631362d31322e35373120316106b28201527f322e3534364131322e35362031322e3536203020302030203530392e353731206106d28201527f363034683135302e38353863362e39343320302031322e3537312d352e3631366106f28201527f2031322e3537312d31322e353435762d3131322e393163302d362e3932382d356107128201527f2e3632382d31322e3534352d31322e3537312d31322e353435483530392e35376107328201527f31632d362e39343320302d31322e35373120352e3631372d31322e35373120316107528201527f322e3534357637352e3237337a6d33372e3731342d36322e373237632d362e396107728201527f343320302d31322e35373120352e3631372d31322e3537312031322e353435766107928201527f32352e303931633020362e39323920352e3632382031322e3534362031322e356107b28201527f37312031322e353436683130302e35373263362e39343320302031322e3537316107d28201527f2d352e3631372031322e3537312d31322e353436762d32352e30393163302d366107f28201527f2e3932382d352e3632382d31322e3534352d31322e3537312d31322e353435486108128201527f3533342e3731347a222066696c6c2d72756c653d226576656e6f646422202f3e6108328201527f3c2f673e3c2f7376673e0000000000000000000000000000000000000000000061085282015261085c01949350505050565b7f7b226e616d65223a20227761676d6920230000000000000000000000000000008152600083516125f28160118501602088016117b3565b7f222c2022696d616765223a2022646174613a696d6167652f7376672b786d6c3b6011918401918201527f6261736536342c00000000000000000000000000000000000000000000000000603182015283516126558160388401602088016117b3565b7f227d00000000000000000000000000000000000000000000000000000000000060389290910191820152603a01949350505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c0000008152600082516126c381601d8501602087016117b3565b91909101601d0192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015612711576127116126d0565b500390565b60008219821115612729576127296126d0565b500190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361275f5761275f6126d0565b5060010190565b60008261277557612775611aea565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156127e1576127e16126d0565b500290565b600073ffffffffffffffffffffffffffffffffffffffff80871683528086166020840152508360408301526080606083015261282560808301846117df565b9695505050505050565b60006020828403121561284157600080fd5b81516117ac8161175e56fe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fa26469706673582212201665a4f9111990d7529375848d3fd02c0121091a940da59e763eba826e7b077064736f6c634300080d0033", + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "getBytecode", + { + "address": undefined, + "chainId": 1, + }, + ], + "refetch": [Function], + "status": "success", + "suspense": [Function], + } + `) +}) + +test('behavior: disabled when properties missing', async () => { + const [result] = renderComposable(() => useBytecode()) + + await wait(100) + expect(result.isPending.value).toBe(true) +}) diff --git a/wagmi-project/packages/vue/src/composables/useBytecode.ts b/wagmi-project/packages/vue/src/composables/useBytecode.ts new file mode 100644 index 000000000..a697ff1a9 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useBytecode.ts @@ -0,0 +1,72 @@ +import type { + Config, + GetBytecodeErrorType, + ResolvedRegister, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type GetBytecodeData, + type GetBytecodeOptions, + type GetBytecodeQueryKey, + getBytecodeQueryOptions, +} from '@wagmi/core/query' +import type { GetBytecodeQueryFnData } from '@wagmi/core/query' + +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' + +import { computed } from 'vue' +import type { DeepMaybeRef } from '../types/ref.js' +import { deepUnref } from '../utils/cloneDeep.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseBytecodeParameters< + config extends Config = Config, + selectData = GetBytecodeData, +> = Compute< + DeepMaybeRef< + GetBytecodeOptions & + ConfigParameter & + QueryParameter< + GetBytecodeQueryFnData, + GetBytecodeErrorType, + selectData, + GetBytecodeQueryKey + > + > +> + +export type UseBytecodeReturnType = + UseQueryReturnType + +/** https://wagmi.sh/vue/api/hooks/useBytecode */ +export function useBytecode< + config extends Config = ResolvedRegister['config'], + selectData = GetBytecodeData, +>( + parameters_: UseBytecodeParameters = {}, +): UseBytecodeReturnType { + const parameters = computed(() => deepUnref(parameters_)) + + const config = useConfig(parameters) + const chainId = useChainId({ config }) + + const queryOptions = computed(() => { + const { + address: contractAddress, + chainId: parametersChainId, + query = {}, + } = parameters.value + + const options = getBytecodeQueryOptions(config, { + ...parameters.value, + address: contractAddress, + chainId: parametersChainId ?? chainId.value, + }) + const enabled = Boolean(contractAddress && (query.enabled ?? true)) + return { ...query, ...options, enabled } + }) + + return useQuery(queryOptions as any) as UseBytecodeReturnType +} diff --git a/wagmi-project/packages/vue/src/composables/useChainId.test-d.ts b/wagmi-project/packages/vue/src/composables/useChainId.test-d.ts new file mode 100644 index 000000000..9f7d060c5 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useChainId.test-d.ts @@ -0,0 +1,14 @@ +import { config } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' + +import { useChainId } from './useChainId.js' + +test('default', () => { + const chainId = useChainId() + expectTypeOf(chainId.value).toEqualTypeOf() +}) + +test('parameters: config', () => { + const chainId = useChainId({ config }) + expectTypeOf(chainId.value).toEqualTypeOf<1 | 456 | 10>() +}) diff --git a/wagmi-project/packages/vue/src/composables/useChainId.test.ts b/wagmi-project/packages/vue/src/composables/useChainId.test.ts new file mode 100644 index 000000000..0a14370fc --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useChainId.test.ts @@ -0,0 +1,22 @@ +import { config } from '@wagmi/test' +import { renderComposable } from '@wagmi/test/vue' +import { expect, test } from 'vitest' + +import { useChainId } from './useChainId.js' + +test('default', () => { + const [chainId] = renderComposable(() => useChainId()) + + expect(chainId.value).toMatchInlineSnapshot('1') + + config.setState((x) => ({ ...x, chainId: 456 })) + + expect(chainId.value).toMatchInlineSnapshot('456') +}) + +test('parameters: config', () => { + const [chainId] = renderComposable(() => useChainId({ config }), { + attach() {}, + }) + expect(chainId.value).toBeDefined() +}) diff --git a/wagmi-project/packages/vue/src/composables/useChainId.ts b/wagmi-project/packages/vue/src/composables/useChainId.ts new file mode 100644 index 000000000..f459857ca --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useChainId.ts @@ -0,0 +1,35 @@ +import { + type Config, + type GetChainIdReturnType, + type ResolvedRegister, + getChainId, + watchChainId, +} from '@wagmi/core' +import { type Ref, onScopeDispose, readonly, ref } from 'vue' + +import type { ConfigParameter } from '../types/properties.js' +import { useConfig } from './useConfig.js' + +export type UseChainIdParameters = + ConfigParameter + +export type UseChainIdReturnType = Ref< + GetChainIdReturnType +> + +/** https://wagmi.sh/vue/api/composables/useChainId */ +export function useChainId( + parameters: UseChainIdParameters = {}, +): UseChainIdReturnType { + const config = useConfig(parameters) + + const chainId = ref(getChainId(config)) + const unsubscribe = watchChainId(config, { + onChange(data) { + chainId.value = data + }, + }) + onScopeDispose(() => unsubscribe()) + + return readonly(chainId) +} diff --git a/wagmi-project/packages/vue/src/composables/useChains.test.ts b/wagmi-project/packages/vue/src/composables/useChains.test.ts new file mode 100644 index 000000000..4ef51405a --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useChains.test.ts @@ -0,0 +1,16 @@ +import { config } from '@wagmi/test' +import { renderComposable } from '@wagmi/test/vue' +import { celo } from 'viem/chains' +import { expect, test } from 'vitest' + +import { useChains } from './useChains.js' + +test('default', async () => { + const [chains] = renderComposable(() => useChains()) + + expect(chains.value.length).toBe(3) + + config._internal.chains.setState((x) => [...x, celo]) + + expect(chains.value.length).toBe(4) +}) diff --git a/wagmi-project/packages/vue/src/composables/useChains.ts b/wagmi-project/packages/vue/src/composables/useChains.ts new file mode 100644 index 000000000..6cbada538 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useChains.ts @@ -0,0 +1,35 @@ +import { + type Config, + type GetChainsReturnType, + type ResolvedRegister, + getChains, +} from '@wagmi/core' +import { watchChains } from '@wagmi/core/internal' + +import { type Ref, onScopeDispose, readonly, ref } from 'vue' +import type { ConfigParameter } from '../types/properties.js' +import { useConfig } from './useConfig.js' + +export type UseChainsParameters = + ConfigParameter + +export type UseChainsReturnType = Ref< + GetChainsReturnType +> + +/** https://wagmi.sh/vue/api/composables/useChains */ +export function useChains( + parameters: UseChainsParameters = {}, +): UseChainsReturnType { + const config = useConfig(parameters) + + const chains = ref>(getChains(config)) + const unsubscribe = watchChains(config, { + onChange(data) { + chains.value = data as any + }, + }) + onScopeDispose(() => unsubscribe()) + + return readonly(chains) as UseChainsReturnType +} diff --git a/wagmi-project/packages/vue/src/composables/useClient.test-d.ts b/wagmi-project/packages/vue/src/composables/useClient.test-d.ts new file mode 100644 index 000000000..3500f2a40 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useClient.test-d.ts @@ -0,0 +1,42 @@ +import { chain, config } from '@wagmi/test' +import type { Chain } from 'viem' +import { expectTypeOf, test } from 'vitest' + +import { useClient } from './useClient.js' + +test('default', () => { + const client = useClient({ config }) + expectTypeOf(client.value.chain).toEqualTypeOf< + (typeof config)['chains'][number] + >() + expectTypeOf(client.value.transport.type).toEqualTypeOf<'http'>() +}) + +test('parameters: chainId', () => { + const client = useClient({ + config, + chainId: chain.mainnet.id, + }) + expectTypeOf(client.value.chain).toEqualTypeOf() + expectTypeOf(client.value.chain).not.toEqualTypeOf() + expectTypeOf(client.value.transport.type).toEqualTypeOf<'http'>() +}) + +test('behavior: unconfigured chain', () => { + { + const client = useClient({ chainId: 123456 }) + if (client.value) { + expectTypeOf(client.value.chain).toEqualTypeOf() + expectTypeOf(client.value.transport.type).toEqualTypeOf() + } else { + expectTypeOf(client.value).toEqualTypeOf() + } + } + + const client = useClient({ + config, + // @ts-expect-error + chainId: 123456, + }) + expectTypeOf(client.value).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/vue/src/composables/useClient.test.ts b/wagmi-project/packages/vue/src/composables/useClient.test.ts new file mode 100644 index 000000000..0d9d2325b --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useClient.test.ts @@ -0,0 +1,41 @@ +import { switchChain } from '@wagmi/core' +import { config } from '@wagmi/test' +import { renderComposable, waitFor } from '@wagmi/test/vue' +import { expect, test } from 'vitest' +import { ref } from 'vue' + +import { useClient } from './useClient.js' + +test('default', async () => { + const [client] = renderComposable(() => useClient()) + + expect(client?.value?.chain.id).toEqual(1) + + await switchChain(config, { chainId: 456 }) + + expect(client.value?.chain?.id).toEqual(456) +}) + +test('parameters: config', () => { + const [chainId] = renderComposable(() => useClient({ config }), { + attach() {}, + }) + expect(chainId.value).toBeDefined() +}) + +test('behavior: controlled chainId', async () => { + const chainId = ref(456) + + const [client] = renderComposable(() => useClient({ chainId })) + + expect(client?.value?.chain.id).toEqual(456) + + chainId.value = 1 + + await waitFor(client, (client) => client?.chain.id === 1) +}) + +test('behavior: unconfigured chain', () => { + const [client] = renderComposable(() => useClient({ chainId: 123456 })) + expect(client.value).toBeUndefined() +}) diff --git a/wagmi-project/packages/vue/src/composables/useClient.ts b/wagmi-project/packages/vue/src/composables/useClient.ts new file mode 100644 index 000000000..e29b38826 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useClient.ts @@ -0,0 +1,66 @@ +import { + type Config, + type GetClientParameters, + type GetClientReturnType, + type ResolvedRegister, + getClient, + watchClient, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type Ref, + computed, + onScopeDispose, + readonly, + ref, + watchEffect, +} from 'vue' + +import type { ConfigParameter } from '../types/properties.js' +import type { DeepMaybeRef } from '../types/ref.js' +import { deepUnref } from '../utils/cloneDeep.js' +import { useConfig } from './useConfig.js' + +export type UseClientParameters< + config extends Config = Config, + chainId extends config['chains'][number]['id'] | number | undefined = + | config['chains'][number]['id'] + | undefined, +> = Compute< + DeepMaybeRef & ConfigParameter> +> + +export type UseClientReturnType< + config extends Config = Config, + chainId extends config['chains'][number]['id'] | number | undefined = + | config['chains'][number]['id'] + | undefined, +> = Ref> + +/** https://wagmi.sh/vue/api/composables/useClient */ +export function useClient< + config extends Config = ResolvedRegister['config'], + chainId extends config['chains'][number]['id'] | number | undefined = + | config['chains'][number]['id'] + | undefined, +>( + parameters: UseClientParameters = {}, +): UseClientReturnType { + const params = computed(() => deepUnref(parameters)) + + const config = useConfig(params) + + const client = ref(getClient(config, params.value as GetClientParameters)) + watchEffect(() => { + client.value = getClient(config, params.value as GetClientParameters) + }) + const unsubscribe = watchClient(config, { + onChange(data) { + if (client.value?.uid === data?.uid) return + client.value = data + }, + }) + onScopeDispose(() => unsubscribe()) + + return readonly(client) as UseClientReturnType +} diff --git a/wagmi-project/packages/vue/src/composables/useConfig.test-d.ts b/wagmi-project/packages/vue/src/composables/useConfig.test-d.ts new file mode 100644 index 000000000..f2b9d2bb3 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useConfig.test-d.ts @@ -0,0 +1,16 @@ +import type { Config } from '@wagmi/core' +import { config } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' + +import { useConfig } from './useConfig.js' + +test('default', async () => { + const result = useConfig() + expectTypeOf(result).toEqualTypeOf() +}) + +test('parameters: config', async () => { + const result = useConfig({ config }) + expectTypeOf(result).not.toEqualTypeOf() + expectTypeOf(result).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/vue/src/composables/useConfig.test.ts b/wagmi-project/packages/vue/src/composables/useConfig.test.ts new file mode 100644 index 000000000..a7036b65e --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useConfig.test.ts @@ -0,0 +1,24 @@ +import { renderComposable } from '@wagmi/test/vue' +import { expect, test, vi } from 'vitest' + +import { useConfig } from './useConfig.js' + +test('default', () => { + const [config] = renderComposable(() => useConfig()) + expect(config).toBeDefined() +}) + +test('behavior: throws when not provided via WagmiPlugin', () => { + vi.spyOn(console, 'error').mockImplementation(() => {}) + + try { + renderComposable(() => useConfig(), { attach() {} }) + } catch (error) { + expect(error).toMatchInlineSnapshot(` + [WagmiPluginNotFoundError: No \`config\` found in Vue context, use \`WagmiPlugin\` to properly initialize the library. + + Docs: https://wagmi.sh/vue/api/TODO.html + Version: @wagmi/vue@x.y.z] + `) + } +}) diff --git a/wagmi-project/packages/vue/src/composables/useConfig.ts b/wagmi-project/packages/vue/src/composables/useConfig.ts new file mode 100644 index 000000000..a827f818a --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useConfig.ts @@ -0,0 +1,34 @@ +import type { Config, ResolvedRegister } from '@wagmi/core' +import { hasInjectionContext, inject, unref } from 'vue' + +import { + WagmiInjectionContextError, + WagmiPluginNotFoundError, +} from '../errors/plugin.js' +import { configKey } from '../plugin.js' +import type { ConfigParameter } from '../types/properties.js' +import type { DeepMaybeRef } from '../types/ref.js' + +export type UseConfigParameters = DeepMaybeRef< + ConfigParameter +> + +export type UseConfigReturnType = config + +/** https://wagmi.sh/vue/api/composables/useConfig */ +export function useConfig( + parameters_: UseConfigParameters = {}, +): UseConfigReturnType { + const parameters = unref(parameters_) + + // passthrough config if provided + if (parameters.config) return parameters.config as UseConfigReturnType + + // ensures that `inject()` can be used + if (!hasInjectionContext()) throw new WagmiInjectionContextError() + + const config = inject(configKey) + if (!config) throw new WagmiPluginNotFoundError() + + return config as UseConfigReturnType +} diff --git a/wagmi-project/packages/vue/src/composables/useConnect.test-d.ts b/wagmi-project/packages/vue/src/composables/useConnect.test-d.ts new file mode 100644 index 000000000..44c7b6fda --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useConnect.test-d.ts @@ -0,0 +1,121 @@ +import type { + ConnectErrorType, + Connector, + CreateConnectorFn, +} from '@wagmi/core' +import { config } from '@wagmi/test' +import type { Address } from 'viem' +import { expectTypeOf, test } from 'vitest' + +import { useConnect } from './useConnect.js' + +const connector = config.connectors[0]! +const contextValue = { foo: 'bar' } as const + +test('context', () => { + const { connect, context, data, error, variables } = useConnect({ + mutation: { + onMutate(variables) { + expectTypeOf(variables).toEqualTypeOf<{ + chainId?: number | undefined + connector: Connector | CreateConnectorFn + }>() + return contextValue + }, + onError(error, variables, context) { + expectTypeOf(variables).toEqualTypeOf<{ + chainId?: number | undefined + connector: Connector | CreateConnectorFn + }>() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSuccess(data, variables, context) { + expectTypeOf(variables).toEqualTypeOf<{ + chainId?: number | undefined + connector: Connector | CreateConnectorFn + }>() + expectTypeOf(data).toEqualTypeOf<{ + accounts: readonly [Address, ...Address[]] + chainId: number + }>() + expectTypeOf(context).toEqualTypeOf() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf< + | { + accounts: readonly [Address, ...Address[]] + chainId: number + } + | undefined + >() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toEqualTypeOf<{ + chainId?: number | undefined + connector: Connector | CreateConnectorFn + }>() + expectTypeOf(context).toEqualTypeOf() + }, + }, + }) + + expectTypeOf(data.value).toEqualTypeOf< + | { + accounts: readonly [Address, ...Address[]] + chainId: number + } + | undefined + >() + expectTypeOf(error.value).toEqualTypeOf() + expectTypeOf(variables.value).toMatchTypeOf< + | { + chainId?: number | undefined + connector: Connector | CreateConnectorFn + } + | undefined + >() + expectTypeOf(context.value).toEqualTypeOf() + + connect( + { connector }, + { + onError(error, variables, context) { + expectTypeOf(variables).toEqualTypeOf<{ + chainId?: number | undefined + connector: typeof connector | CreateConnectorFn + foo?: string | undefined + }>() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSuccess(data, variables, context) { + expectTypeOf(variables).toEqualTypeOf<{ + chainId?: number | undefined + connector: typeof connector | CreateConnectorFn + foo?: string | undefined + }>() + expectTypeOf(data).toEqualTypeOf<{ + accounts: readonly [Address, ...Address[]] + chainId: number + }>() + expectTypeOf(context).toEqualTypeOf() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf< + | { + accounts: readonly [Address, ...Address[]] + chainId: number + } + | undefined + >() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toEqualTypeOf<{ + chainId?: number | undefined + connector: typeof connector | CreateConnectorFn + foo?: string | undefined + }>() + expectTypeOf(context).toEqualTypeOf() + }, + }, + ) +}) diff --git a/wagmi-project/packages/vue/src/composables/useConnect.test.ts b/wagmi-project/packages/vue/src/composables/useConnect.test.ts new file mode 100644 index 000000000..206abd41e --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useConnect.test.ts @@ -0,0 +1,31 @@ +import { disconnect } from '@wagmi/core' +import { config } from '@wagmi/test' +import { renderComposable, waitFor } from '@wagmi/test/vue' +import { afterEach, expect, test } from 'vitest' + +import { useAccount } from './useAccount.js' +import { useConnect } from './useConnect.js' + +const connector = config.connectors[0]! + +afterEach(async () => { + if (config.state.current === connector.uid) + await disconnect(config, { connector }) +}) + +test('default', async () => { + const [account] = renderComposable(() => useAccount()) + const [connect] = renderComposable(() => useConnect()) + + expect(account.address.value).not.toBeDefined() + expect(account.status.value).toEqual('disconnected') + + connect.connect({ + connector: connect.connectors[0]!, + }) + + await waitFor(account.isConnected, (isConnected) => Boolean(isConnected)) + + expect(account.address.value).toBeDefined() + expect(account.status.value).toEqual('connected') +}) diff --git a/wagmi-project/packages/vue/src/composables/useConnect.ts b/wagmi-project/packages/vue/src/composables/useConnect.ts new file mode 100644 index 000000000..7659dc341 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useConnect.ts @@ -0,0 +1,92 @@ +import { useMutation } from '@tanstack/vue-query' +import type { + Config, + ConnectErrorType, + GetConnectorsReturnType, + ResolvedRegister, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type ConnectData, + type ConnectMutate, + type ConnectMutateAsync, + type ConnectVariables, + connectMutationOptions, +} from '@wagmi/core/query' +import { onScopeDispose } from 'vue' + +import type { ConfigParameter } from '../types/properties.js' +import type { + UseMutationParameters, + UseMutationReturnType, +} from '../utils/query.js' +import { useConfig } from './useConfig.js' +import { useConnectors } from './useConnectors.js' + +export type UseConnectParameters< + config extends Config = Config, + context = unknown, +> = Compute< + ConfigParameter & { + mutation?: + | UseMutationParameters< + ConnectData, + ConnectErrorType, + ConnectVariables, + context + > + | undefined + } +> + +export type UseConnectReturnType< + config extends Config = Config, + context = unknown, +> = Compute< + UseMutationReturnType< + ConnectData, + ConnectErrorType, + ConnectVariables, + context + > & { + connect: ConnectMutate + connectAsync: ConnectMutateAsync + connectors: Compute | config['connectors'] + } +> + +/** https://wagmi.sh/vue/api/composables/useConnect */ +export function useConnect< + config extends Config = ResolvedRegister['config'], + context = unknown, +>( + parameters: UseConnectParameters = {}, +): UseConnectReturnType { + const { mutation } = parameters + + const config = useConfig(parameters) + + const mutationOptions = connectMutationOptions(config) + const { mutate, mutateAsync, ...result } = useMutation({ + ...mutation, + ...mutationOptions, + }) + + // Reset mutation back to an idle state when the connector disconnects. + const unsubscribe = config.subscribe( + ({ status }) => status, + (status, previousStatus) => { + if (previousStatus === 'connected' && status === 'disconnected') + result.reset() + }, + ) + onScopeDispose(() => unsubscribe()) + + type Return = UseConnectReturnType + return { + ...(result as Return), + connect: mutate as Return['connect'], + connectAsync: mutateAsync as Return['connectAsync'], + connectors: useConnectors({ config }).value, + } +} diff --git a/wagmi-project/packages/vue/src/composables/useConnections.test.ts b/wagmi-project/packages/vue/src/composables/useConnections.test.ts new file mode 100644 index 000000000..d51401b42 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useConnections.test.ts @@ -0,0 +1,16 @@ +import { connect } from '@wagmi/core' +import { config } from '@wagmi/test' +import { renderComposable } from '@wagmi/test/vue' +import { expect, test } from 'vitest' + +import { useConnections } from './useConnections.js' + +test('default', async () => { + const [connections] = renderComposable(() => useConnections()) + + expect(connections.value).toEqual([]) + + await connect(config, { connector: config.connectors[0]! }) + + expect(connections.value.length).toBe(1) +}) diff --git a/wagmi-project/packages/vue/src/composables/useConnections.ts b/wagmi-project/packages/vue/src/composables/useConnections.ts new file mode 100644 index 000000000..7bcc49949 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useConnections.ts @@ -0,0 +1,30 @@ +import { + type GetConnectionsReturnType, + getConnections, + watchConnections, +} from '@wagmi/core' +import { type Ref, onScopeDispose, readonly, ref } from 'vue' + +import type { ConfigParameter } from '../types/properties.js' +import { useConfig } from './useConfig.js' + +export type UseConnectionsParameters = ConfigParameter + +export type UseConnectionsReturnType = Ref + +/** https://wagmi.sh/vue/api/composables/useConnections */ +export function useConnections( + parameters: UseConnectionsParameters = {}, +): UseConnectionsReturnType { + const config = useConfig(parameters) + + const connections = ref(getConnections(config)) + const unsubscribe = watchConnections(config, { + onChange(data) { + connections.value = data + }, + }) + onScopeDispose(() => unsubscribe()) + + return readonly(connections) as UseConnectionsReturnType +} diff --git a/wagmi-project/packages/vue/src/composables/useConnectorClient.test-d.ts b/wagmi-project/packages/vue/src/composables/useConnectorClient.test-d.ts new file mode 100644 index 000000000..710d8260d --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useConnectorClient.test-d.ts @@ -0,0 +1,12 @@ +import { config } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' + +import { useConnectorClient } from './useConnectorClient.js' + +test('parameters: config', async () => { + const client = useConnectorClient({ config }) + expectTypeOf(client.data?.value?.chain?.id!).toEqualTypeOf<1 | 456 | 10>() + + const client2 = useConnectorClient({ config, chainId: 1 }) + expectTypeOf(client2.data?.value?.chain?.id!).toEqualTypeOf<1>() +}) diff --git a/wagmi-project/packages/vue/src/composables/useConnectorClient.test.ts b/wagmi-project/packages/vue/src/composables/useConnectorClient.test.ts new file mode 100644 index 000000000..7a361702a --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useConnectorClient.test.ts @@ -0,0 +1,156 @@ +import { connect, disconnect } from '@wagmi/core' +import { config, wait } from '@wagmi/test' +import { renderComposable, waitFor } from '@wagmi/test/vue' +import { expect, test } from 'vitest' + +import { deepUnref } from '../utils/cloneDeep.js' +import { useConnect } from './useConnect.js' +import { useConnectorClient } from './useConnectorClient.js' +import { useDisconnect } from './useDisconnect.js' +import { useSwitchChain } from './useSwitchChain.js' + +const connector = config.connectors[0]! + +test('default', async () => { + const [client] = renderComposable(() => useConnectorClient()) + + expect(deepUnref(client)).toMatchInlineSnapshot(` + { + "data": undefined, + "dataUpdatedAt": 0, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": false, + "isFetchedAfterMount": false, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": true, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": false, + "isSuccess": false, + "queryKey": [ + "connectorClient", + { + "chainId": 1, + "connectorUid": undefined, + }, + ], + "refetch": [Function], + "status": "pending", + "suspense": [Function], + } + `) +}) + +test('behavior: connected on mount', async () => { + await connect(config, { connector }) + + const [client] = renderComposable(() => useConnectorClient()) + + await waitFor(client.isSuccess, (isSuccess) => isSuccess === true) + + const { data, queryKey: _, ...rest } = deepUnref(client) + expect(data).toMatchObject( + expect.objectContaining({ + account: expect.any(Object), + chain: expect.any(Object), + }), + ) + expect(rest).toMatchInlineSnapshot(` + { + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": false, + "isSuccess": true, + "refetch": [Function], + "status": "success", + "suspense": [Function], + } + `) + + await disconnect(config, { connector }) +}) + +test('behavior: connect and disconnect', async () => { + const [connect] = renderComposable(() => useConnect()) + const [client] = renderComposable(() => useConnectorClient()) + const [disconnect] = renderComposable(() => useDisconnect()) + + expect(client.data.value).not.toBeDefined() + + connect.connect({ + connector: connect.connectors[0]!, + }) + + await waitFor(client.data, (data) => data !== undefined) + + disconnect.disconnect() + + await waitFor(client.data, (data) => data === undefined) +}) + +test('behavior: switch chains', async () => { + await connect(config, { connector }) + + const [connectorClient] = renderComposable(() => useConnectorClient()) + const [switchChain] = renderComposable(() => useSwitchChain()) + + expect(connectorClient.data.value).not.toBeDefined() + + await waitFor(connectorClient.data, (data) => data !== undefined) + + switchChain.switchChain({ chainId: 456 }) + await waitFor(switchChain.isSuccess, (isSuccess) => isSuccess === true) + await waitFor(connectorClient.data, (data) => data !== undefined) + expect(connectorClient.data?.value?.chain.id).toEqual(456) + + switchChain.switchChain({ chainId: 1 }) + await waitFor(switchChain.isSuccess, (isSuccess) => isSuccess === true) + await waitFor(connectorClient.data, (data) => data !== undefined) + expect(connectorClient.data?.value?.chain.id).toEqual(1) + + await disconnect(config, { connector }) +}) + +test('behavior: disabled when properties missing', async () => { + const [connectorClient] = renderComposable(() => useConnectorClient()) + + await wait(100) + expect(connectorClient.isPending.value).toBe(true) +}) + +test('behavior: disabled when connecting', async () => { + const [connectorClient] = renderComposable(() => useConnectorClient()) + + config.setState((x) => ({ ...x, status: 'connecting' })) + + await wait(100) + expect(connectorClient.isLoading.value).not.toBeTruthy() +}) diff --git a/wagmi-project/packages/vue/src/composables/useConnectorClient.ts b/wagmi-project/packages/vue/src/composables/useConnectorClient.ts new file mode 100644 index 000000000..08735718b --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useConnectorClient.ts @@ -0,0 +1,132 @@ +import { useQueryClient } from '@tanstack/vue-query' +import type { + Config, + Connector, + GetConnectorClientErrorType, + ResolvedRegister, +} from '@wagmi/core' +import type { Compute, Omit } from '@wagmi/core/internal' +import { + type GetConnectorClientData, + type GetConnectorClientOptions, + type GetConnectorClientQueryFnData, + type GetConnectorClientQueryKey, + getConnectorClientQueryOptions, +} from '@wagmi/core/query' +import { computed, ref, watchEffect } from 'vue' + +import type { ConfigParameter } from '../types/properties.js' +import type { DeepMaybeRef, DeepUnwrapRef } from '../types/ref.js' +import { deepUnref } from '../utils/cloneDeep.js' +import { + type UseQueryParameters, + type UseQueryReturnType, + useQuery, +} from '../utils/query.js' +import { useAccount } from './useAccount.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseConnectorClientParameters< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = GetConnectorClientData, +> = Compute< + DeepMaybeRef< + GetConnectorClientOptions & + ConfigParameter & { + query?: + | Compute< + Omit< + DeepUnwrapRef< + UseQueryParameters< + GetConnectorClientQueryFnData, + GetConnectorClientErrorType, + selectData, + GetConnectorClientQueryKey + > + >, + 'gcTime' | 'staleTime' + > + > + | undefined + } + > +> + +export type UseConnectorClientReturnType< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = GetConnectorClientData, +> = UseQueryReturnType + +/** https://wagmi.sh/vue/api/composables/useConnectorClient */ +export function useConnectorClient< + config extends Config = ResolvedRegister['config'], + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = GetConnectorClientData, +>( + parameters_: UseConnectorClientParameters = {}, +): UseConnectorClientReturnType { + const parameters = computed(() => deepUnref(parameters_)) + + const config = useConfig(parameters) + const queryClient = useQueryClient() + const { + address, + connector: accountConnector, + status, + } = useAccount({ config }) + const configChainId = useChainId({ config }) + + const queryOptions = computed(() => { + const { + chainId = configChainId.value, + connector = accountConnector.value, + query = {}, + } = parameters.value + const { queryKey, ...options } = getConnectorClientQueryOptions< + config, + chainId + >(config as config, { + ...deepUnref(parameters), + chainId: chainId as chainId, + connector: connector as Connector, + }) + const enabled = Boolean( + (status.value === 'connected' || + (status.value === 'reconnecting' && connector?.getProvider)) && + (query.enabled ?? true), + ) + return { + ...query, + ...options, + queryKey, + enabled, + staleTime: Number.POSITIVE_INFINITY, + } + }) + + const addressRef = ref(address) + watchEffect(() => { + const previousAddress = addressRef.value + if (!address && previousAddress) { + // remove when account is disconnected + queryClient.removeQueries({ queryKey: queryOptions.value.queryKey }) + addressRef.value = undefined + } else if (address.value !== previousAddress) { + // invalidate when address changes + queryClient.invalidateQueries({ queryKey: queryOptions.value.queryKey }) + addressRef.value = address.value + } + }) + + return useQuery(queryOptions as any) as UseConnectorClientReturnType< + config, + chainId, + selectData + > +} diff --git a/wagmi-project/packages/vue/src/composables/useConnectors.test.ts b/wagmi-project/packages/vue/src/composables/useConnectors.test.ts new file mode 100644 index 000000000..16fec78df --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useConnectors.test.ts @@ -0,0 +1,21 @@ +import { mock } from '@wagmi/connectors' +import { accounts, config } from '@wagmi/test' +import { renderComposable } from '@wagmi/test/vue' +import { expect, test } from 'vitest' + +import { useConnectors } from './useConnectors.js' + +test('default', async () => { + const [connectors] = renderComposable(() => useConnectors()) + + const count = config.connectors.length + expect(connectors.value.length).toBe(count) + expect(connectors.value).toEqual(config.connectors) + + config._internal.connectors.setState(() => [ + ...config.connectors, + config._internal.connectors.setup(mock({ accounts })), + ]) + + expect(connectors.value.length).toBe(count + 1) +}) diff --git a/wagmi-project/packages/vue/src/composables/useConnectors.ts b/wagmi-project/packages/vue/src/composables/useConnectors.ts new file mode 100644 index 000000000..4d12d8180 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useConnectors.ts @@ -0,0 +1,37 @@ +import { + type Config, + type GetConnectorsReturnType, + type ResolvedRegister, + getConnectors, + watchConnectors, +} from '@wagmi/core' +import { type Ref, onScopeDispose, ref } from 'vue' + +import type { ConfigParameter } from '../types/properties.js' +import { useConfig } from './useConfig.js' + +export type UseConnectorsParameters = + ConfigParameter + +export type UseConnectorsReturnType = Ref< + GetConnectorsReturnType +> + +/** https://wagmi.sh/vue/api/composables/useConnectors */ +export function useConnectors< + config extends Config = ResolvedRegister['config'], +>( + parameters: UseConnectorsParameters = {}, +): UseConnectorsReturnType { + const config = useConfig(parameters) + + const connectors = ref(getConnectors(config)) + const unsubscribe = watchConnectors(config, { + onChange(data) { + connectors.value = data as never + }, + }) + onScopeDispose(() => unsubscribe()) + + return connectors +} diff --git a/wagmi-project/packages/vue/src/composables/useDisconnect.test-d.ts b/wagmi-project/packages/vue/src/composables/useDisconnect.test-d.ts new file mode 100644 index 000000000..3be3fe948 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useDisconnect.test-d.ts @@ -0,0 +1,87 @@ +import type { Connector, DisconnectErrorType } from '@wagmi/core' +import { config } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' + +import { useDisconnect } from './useDisconnect.js' + +const connector = config.connectors[0]! +const contextValue = { foo: 'bar' } as const + +test('parameter', () => { + expectTypeOf(useDisconnect().disconnect) + .parameter(0) + .toEqualTypeOf<{ connector?: Connector | undefined } | undefined>() + expectTypeOf(useDisconnect().disconnect) + .parameter(0) + .toEqualTypeOf<{ connector?: Connector | undefined } | undefined>() +}) + +test('context', () => { + const { context, data, disconnect, error, variables } = useDisconnect({ + mutation: { + onMutate(variables) { + expectTypeOf(variables).toEqualTypeOf< + { connector?: Connector | undefined } | undefined + >() + return contextValue + }, + onError(error, variables, context) { + expectTypeOf(variables).toEqualTypeOf< + { connector?: Connector | undefined } | undefined + >() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSuccess(data, variables, context) { + expectTypeOf(variables).toEqualTypeOf< + { connector?: Connector | undefined } | undefined + >() + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toEqualTypeOf< + { connector?: Connector | undefined } | undefined + >() + expectTypeOf(context).toEqualTypeOf() + }, + }, + }) + + expectTypeOf(data.value).toEqualTypeOf() + expectTypeOf(error.value).toEqualTypeOf() + expectTypeOf(variables.value).toEqualTypeOf< + { connector?: Connector | undefined } | undefined + >() + expectTypeOf(context.value).toEqualTypeOf() + + disconnect( + { connector }, + { + onError(error, variables, context) { + expectTypeOf(variables).toEqualTypeOf< + { connector?: Connector | undefined } | undefined + >() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSuccess(data, variables, context) { + expectTypeOf(variables).toEqualTypeOf< + { connector?: Connector | undefined } | undefined + >() + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toEqualTypeOf< + { connector?: Connector | undefined } | undefined + >() + expectTypeOf(context).toEqualTypeOf() + }, + }, + ) +}) diff --git a/wagmi-project/packages/vue/src/composables/useDisconnect.test.ts b/wagmi-project/packages/vue/src/composables/useDisconnect.test.ts new file mode 100644 index 000000000..935c75827 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useDisconnect.test.ts @@ -0,0 +1,30 @@ +import { connect } from '@wagmi/core' +import { config } from '@wagmi/test' +import { renderComposable, waitFor } from '@wagmi/test/vue' +import { beforeEach, expect, test } from 'vitest' + +import { useAccount } from './useAccount.js' +import { useDisconnect } from './useDisconnect.js' + +const connector = config.connectors[0]! + +beforeEach(async () => { + await connect(config, { connector }) +}) + +test('default', async () => { + const [account] = renderComposable(() => useAccount()) + const [disconnect] = renderComposable(() => useDisconnect()) + + expect(account.address.value).toBeDefined() + expect(account.status.value).toEqual('connected') + + disconnect.disconnect() + + await waitFor(account.isDisconnected, (isDisconnected) => + Boolean(isDisconnected), + ) + + expect(account.address.value).not.toBeDefined() + expect(account.status.value).toEqual('disconnected') +}) diff --git a/wagmi-project/packages/vue/src/composables/useDisconnect.ts b/wagmi-project/packages/vue/src/composables/useDisconnect.ts new file mode 100644 index 000000000..540e58812 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useDisconnect.ts @@ -0,0 +1,70 @@ +import { useMutation } from '@tanstack/vue-query' +import type { Connector, DisconnectErrorType } from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type DisconnectData, + type DisconnectMutate, + type DisconnectMutateAsync, + type DisconnectVariables, + disconnectMutationOptions, +} from '@wagmi/core/query' +import { type Ref, computed } from 'vue' + +import type { ConfigParameter } from '../types/properties.js' +import type { + UseMutationParameters, + UseMutationReturnType, +} from '../utils/query.js' +import { useConfig } from './useConfig.js' +import { useConnections } from './useConnections.js' + +export type UseDisconnectParameters = Compute< + ConfigParameter & { + mutation?: + | UseMutationParameters< + DisconnectData, + DisconnectErrorType, + DisconnectVariables, + context + > + | undefined + } +> + +export type UseDisconnectReturnType = Compute< + UseMutationReturnType< + DisconnectData, + DisconnectErrorType, + DisconnectVariables, + context + > & { + connectors: Ref + disconnect: DisconnectMutate + disconnectAsync: DisconnectMutateAsync + } +> + +/** https://wagmi.sh/vue/api/composables/useDisconnect */ +export function useDisconnect( + parameters: UseDisconnectParameters = {}, +): UseDisconnectReturnType { + const { mutation } = parameters + + const config = useConfig(parameters) + const connections = useConnections({ config }) + + const mutationOptions = disconnectMutationOptions(config) + const { mutate, mutateAsync, ...result } = useMutation({ + ...mutation, + ...mutationOptions, + }) + + return { + ...result, + connectors: computed(() => + connections.value.map((connection) => connection.connector), + ), + disconnect: mutate, + disconnectAsync: mutateAsync, + } +} diff --git a/wagmi-project/packages/vue/src/composables/useEnsAddress.test.ts b/wagmi-project/packages/vue/src/composables/useEnsAddress.test.ts new file mode 100644 index 000000000..01d35769b --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useEnsAddress.test.ts @@ -0,0 +1,52 @@ +import { renderComposable, waitFor } from '@wagmi/test/vue' +import { expect, test } from 'vitest' + +import { deepUnref } from '../utils/cloneDeep.js' +import { useEnsAddress } from './useEnsAddress.js' + +test('default', async () => { + const [result] = renderComposable(() => + useEnsAddress({ + name: 'wevm.eth', + }), + ) + + await waitFor(result.isSuccess) + + expect(deepUnref(result)).toMatchInlineSnapshot(` + { + "data": "0xd2135CfB216b74109775236E36d4b433F1DF507B", + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "ensAddress", + { + "chainId": 1, + "name": "wevm.eth", + }, + ], + "refetch": [Function], + "status": "success", + "suspense": [Function], + } + `) +}) diff --git a/wagmi-project/packages/vue/src/composables/useEnsAddress.ts b/wagmi-project/packages/vue/src/composables/useEnsAddress.ts new file mode 100644 index 000000000..ecb27ac14 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useEnsAddress.ts @@ -0,0 +1,65 @@ +import type { + Config, + GetEnsAddressErrorType, + ResolvedRegister, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type GetEnsAddressData, + type GetEnsAddressOptions, + type GetEnsAddressQueryFnData, + type GetEnsAddressQueryKey, + getEnsAddressQueryOptions, +} from '@wagmi/core/query' +import { computed } from 'vue' + +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import type { DeepMaybeRef } from '../types/ref.js' +import { deepUnref } from '../utils/cloneDeep.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseEnsAddressParameters< + config extends Config = Config, + selectData = GetEnsAddressData, +> = Compute< + DeepMaybeRef< + GetEnsAddressOptions & + ConfigParameter & + QueryParameter< + GetEnsAddressQueryFnData, + GetEnsAddressErrorType, + selectData, + GetEnsAddressQueryKey + > + > +> + +export type UseEnsAddressReturnType = + UseQueryReturnType + +/** https://wagmi.sh/vue/api/composables/useEnsAddress */ +export function useEnsAddress< + config extends Config = ResolvedRegister['config'], + selectData = GetEnsAddressData, +>( + parameters_: UseEnsAddressParameters = {}, +): UseEnsAddressReturnType { + const parameters = computed(() => deepUnref(parameters_)) + + const config = useConfig(parameters) + const configChainId = useChainId({ config }) + + const queryOptions = computed(() => { + const { chainId = configChainId.value, name, query = {} } = parameters.value + const options = getEnsAddressQueryOptions(config, { + ...parameters.value, + chainId, + }) + const enabled = Boolean(name && (query.enabled ?? true)) + return { ...query, ...options, enabled } + }) + + return useQuery(queryOptions as any) as UseEnsAddressReturnType +} diff --git a/wagmi-project/packages/vue/src/composables/useEnsAvatar.test.ts b/wagmi-project/packages/vue/src/composables/useEnsAvatar.test.ts new file mode 100644 index 000000000..ab024c89b --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useEnsAvatar.test.ts @@ -0,0 +1,52 @@ +import { renderComposable, waitFor } from '@wagmi/test/vue' +import { expect, test } from 'vitest' + +import { deepUnref } from '../utils/cloneDeep.js' +import { useEnsAvatar } from './useEnsAvatar.js' + +test('default', async () => { + const [result] = renderComposable(() => + useEnsAvatar({ + name: 'wevm.eth', + }), + ) + + await waitFor(result.isSuccess) + + expect(deepUnref(result)).toMatchInlineSnapshot(` + { + "data": "https://euc.li/wevm.eth", + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "ensAvatar", + { + "chainId": 1, + "name": "wevm.eth", + }, + ], + "refetch": [Function], + "status": "success", + "suspense": [Function], + } + `) +}) diff --git a/wagmi-project/packages/vue/src/composables/useEnsAvatar.ts b/wagmi-project/packages/vue/src/composables/useEnsAvatar.ts new file mode 100644 index 000000000..ff328ad87 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useEnsAvatar.ts @@ -0,0 +1,65 @@ +import type { + Config, + GetEnsAvatarErrorType, + ResolvedRegister, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type GetEnsAvatarData, + type GetEnsAvatarOptions, + type GetEnsAvatarQueryFnData, + type GetEnsAvatarQueryKey, + getEnsAvatarQueryOptions, +} from '@wagmi/core/query' +import { computed } from 'vue' + +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import type { DeepMaybeRef } from '../types/ref.js' +import { deepUnref } from '../utils/cloneDeep.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseEnsAvatarParameters< + config extends Config = Config, + selectData = GetEnsAvatarData, +> = Compute< + DeepMaybeRef< + GetEnsAvatarOptions & + ConfigParameter & + QueryParameter< + GetEnsAvatarQueryFnData, + GetEnsAvatarErrorType, + selectData, + GetEnsAvatarQueryKey + > + > +> + +export type UseEnsAvatarReturnType = + UseQueryReturnType + +/** https://wagmi.sh/vue/api/composables/useEnsAvatar */ +export function useEnsAvatar< + config extends Config = ResolvedRegister['config'], + selectData = GetEnsAvatarData, +>( + parameters_: UseEnsAvatarParameters = {}, +): UseEnsAvatarReturnType { + const parameters = computed(() => deepUnref(parameters_)) + + const config = useConfig(parameters) + const configChainId = useChainId({ config }) + + const queryOptions = computed(() => { + const { chainId = configChainId.value, name, query = {} } = parameters.value + const options = getEnsAvatarQueryOptions(config, { + ...parameters.value, + chainId, + }) + const enabled = Boolean(name && (query.enabled ?? true)) + return { ...query, ...options, enabled } + }) + + return useQuery(queryOptions as any) as UseEnsAvatarReturnType +} diff --git a/wagmi-project/packages/vue/src/composables/useEnsName.test.ts b/wagmi-project/packages/vue/src/composables/useEnsName.test.ts new file mode 100644 index 000000000..ee5b8cfab --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useEnsName.test.ts @@ -0,0 +1,52 @@ +import { renderComposable, waitFor } from '@wagmi/test/vue' +import { expect, test } from 'vitest' + +import { deepUnref } from '../utils/cloneDeep.js' +import { useEnsName } from './useEnsName.js' + +test('default', async () => { + const [result] = renderComposable(() => + useEnsName({ + address: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + }), + ) + + await waitFor(result.isSuccess) + + expect(deepUnref(result)).toMatchInlineSnapshot(` + { + "data": "wevm.eth", + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "ensName", + { + "address": "0xd2135CfB216b74109775236E36d4b433F1DF507B", + "chainId": 1, + }, + ], + "refetch": [Function], + "status": "success", + "suspense": [Function], + } + `) +}) diff --git a/wagmi-project/packages/vue/src/composables/useEnsName.ts b/wagmi-project/packages/vue/src/composables/useEnsName.ts new file mode 100644 index 000000000..ba251aa5a --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useEnsName.ts @@ -0,0 +1,65 @@ +import type { Config, GetEnsNameErrorType, ResolvedRegister } from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type GetEnsNameData, + type GetEnsNameOptions, + type GetEnsNameQueryFnData, + type GetEnsNameQueryKey, + getEnsNameQueryOptions, +} from '@wagmi/core/query' + +import { computed } from 'vue' +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import type { DeepMaybeRef } from '../types/ref.js' +import { deepUnref } from '../utils/cloneDeep.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseEnsNameParameters< + config extends Config = Config, + selectData = GetEnsNameData, +> = Compute< + DeepMaybeRef< + GetEnsNameOptions & + ConfigParameter & + QueryParameter< + GetEnsNameQueryFnData, + GetEnsNameErrorType, + selectData, + GetEnsNameQueryKey + > + > +> + +export type UseEnsNameReturnType = + UseQueryReturnType + +/** https://wagmi.sh/vue/api/composables/useEnsName */ +export function useEnsName< + config extends Config = ResolvedRegister['config'], + selectData = GetEnsNameData, +>( + parameters_: UseEnsNameParameters = {}, +): UseEnsNameReturnType { + const parameters = computed(() => deepUnref(parameters_)) + + const config = useConfig(parameters) + const configChainId = useChainId({ config }) + + const queryOptions = computed(() => { + const { + address, + chainId = configChainId.value, + query = {}, + } = parameters.value + const options = getEnsNameQueryOptions(config, { + ...parameters.value, + chainId, + }) + const enabled = Boolean(address && (query.enabled ?? true)) + return { ...query, ...options, enabled } + }) + + return useQuery(queryOptions as any) as UseEnsNameReturnType +} diff --git a/wagmi-project/packages/vue/src/composables/useEstimateGas.test-d.ts b/wagmi-project/packages/vue/src/composables/useEstimateGas.test-d.ts new file mode 100644 index 000000000..ba084419d --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useEstimateGas.test-d.ts @@ -0,0 +1,14 @@ +import { expectTypeOf, test } from 'vitest' + +import { useEstimateGas } from './useEstimateGas.js' + +test('select data', () => { + const result = useEstimateGas({ + query: { + select(data) { + return data.toString() + }, + }, + }) + expectTypeOf(result.data.value).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/vue/src/composables/useEstimateGas.test.ts b/wagmi-project/packages/vue/src/composables/useEstimateGas.test.ts new file mode 100644 index 000000000..f8212f11d --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useEstimateGas.test.ts @@ -0,0 +1,117 @@ +import { accounts, wait } from '@wagmi/test' +import { renderComposable, waitFor } from '@wagmi/test/vue' +import { parseEther } from 'viem' +import { expect, test } from 'vitest' + +import { ref } from 'vue' +import { deepUnref } from '../utils/cloneDeep.js' +import { useEstimateGas } from './useEstimateGas.js' + +test('default', async () => { + const [result] = renderComposable(() => + useEstimateGas({ + account: accounts[0], + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), + }), + ) + + await waitFor(result.isSuccess) + + expect(deepUnref(result)).toMatchInlineSnapshot(` + { + "data": 21000n, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "estimateGas", + { + "account": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "chainId": 1, + "to": "0xd2135CfB216b74109775236E36d4b433F1DF507B", + "value": 10000000000000000n, + }, + ], + "refetch": [Function], + "status": "success", + "suspense": [Function], + } + `) +}) + +test('behavior: address: undefined -> defined', async () => { + const address = ref() + + const [result] = renderComposable(() => + useEstimateGas({ + account: address, + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), + }), + ) + + await wait(100) + expect(result.fetchStatus.value).toBe('idle') + + address.value = accounts[0] + + await waitFor(result.isSuccess) + + expect(deepUnref(result)).toMatchInlineSnapshot(` + { + "data": 21000n, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "estimateGas", + { + "account": undefined, + "chainId": 1, + "to": "0xd2135CfB216b74109775236E36d4b433F1DF507B", + "value": 10000000000000000n, + }, + ], + "refetch": [Function], + "status": "success", + "suspense": [Function], + } + `) +}) diff --git a/wagmi-project/packages/vue/src/composables/useEstimateGas.ts b/wagmi-project/packages/vue/src/composables/useEstimateGas.ts new file mode 100644 index 000000000..fd885ec71 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useEstimateGas.ts @@ -0,0 +1,83 @@ +import type { + Config, + EstimateGasErrorType, + ResolvedRegister, +} from '@wagmi/core' +import { + type EstimateGasData, + type EstimateGasOptions, + type EstimateGasQueryFnData, + type EstimateGasQueryKey, + estimateGasQueryOptions, +} from '@wagmi/core/query' +import { computed } from 'vue' + +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import type { DeepMaybeRef } from '../types/ref.js' +import { deepUnref } from '../utils/cloneDeep.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' +import { useConnectorClient } from './useConnectorClient.js' + +export type UseEstimateGasParameters< + config extends Config = Config, + chainId extends config['chains'][number]['id'] | undefined = undefined, + selectData = EstimateGasData, +> = DeepMaybeRef< + EstimateGasOptions & + ConfigParameter & + QueryParameter< + EstimateGasQueryFnData, + EstimateGasErrorType, + selectData, + EstimateGasQueryKey + > +> + +export type UseEstimateGasReturnType = + UseQueryReturnType + +/** https://wagmi.sh/react/api/hooks/useEstimateGas */ +export function useEstimateGas< + config extends Config = ResolvedRegister['config'], + chainId extends config['chains'][number]['id'] | undefined = undefined, + selectData = EstimateGasData, +>( + parameters?: UseEstimateGasParameters, +): UseEstimateGasReturnType + +export function useEstimateGas( + parameters_: UseEstimateGasParameters = {}, +): UseEstimateGasReturnType { + const parameters = computed(() => deepUnref(parameters_)) + + const config = useConfig(parameters) + const { data: connectorClient } = useConnectorClient( + computed(() => ({ + connector: parameters.value.connector, + query: { enabled: parameters.value.account === undefined }, + })), + ) + + const configChainId = useChainId({ config }) + + const queryOptions = computed(() => { + const { + account = connectorClient?.value?.account, + chainId = configChainId.value, + connector, + query = {}, + } = parameters.value + const options = estimateGasQueryOptions(config, { + ...parameters.value, + account, + chainId, + connector, + }) + const enabled = Boolean((account || connector) && (query.enabled ?? true)) + return { ...query, ...options, enabled } + }) + + return useQuery(queryOptions) +} diff --git a/wagmi-project/packages/vue/src/composables/useReadContract.test-d.ts b/wagmi-project/packages/vue/src/composables/useReadContract.test-d.ts new file mode 100644 index 000000000..0685dde8f --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useReadContract.test-d.ts @@ -0,0 +1,99 @@ +import { abi } from '@wagmi/test' +import type { Address } from 'viem' +import { assertType, expectTypeOf, test } from 'vitest' + +import type { DeepUnwrapRef } from '../types/ref.js' +import { + type UseReadContractParameters, + type UseReadContractReturnType, + useReadContract, +} from './useReadContract.js' + +test('select data', () => { + const result = useReadContract({ + address: '0x', + abi: abi.erc20, + functionName: 'balanceOf', + args: ['0x'], + query: { + select(data) { + expectTypeOf(data).toEqualTypeOf() + return data?.toString() + }, + }, + }) + expectTypeOf(result.data.value).toEqualTypeOf() +}) + +test('UseReadContractParameters', () => { + type Result = DeepUnwrapRef< + UseReadContractParameters + > + expectTypeOf<{ + functionName?: + | 'symbol' + | 'name' + | 'allowance' + | 'balanceOf' + | 'decimals' + | 'totalSupply' + | undefined + args?: readonly [Address] | undefined + }>().toEqualTypeOf>() +}) + +test('UseReadContractReturnType', () => { + type Result = UseReadContractReturnType + expectTypeOf().toEqualTypeOf() +}) + +test('overloads', () => { + const result1 = useReadContract({ + address: '0x', + abi: abi.viewOverloads, + functionName: 'foo', + }) + assertType(result1.data.value) + + const result2 = useReadContract({ + address: '0x', + abi: abi.viewOverloads, + functionName: 'foo', + args: [], + }) + assertType(result2.data.value) + + const result3 = useReadContract({ + address: '0x', + abi: abi.viewOverloads, + functionName: 'foo', + args: ['0x'], + }) + // @ts-ignore – TODO: Fix https://github.com/wevm/viem/issues/1916 + assertType(result3.data) + + const result4 = useReadContract({ + address: '0x', + abi: abi.viewOverloads, + functionName: 'foo', + args: ['0x', '0x'], + }) + assertType< + | { + foo: `0x${string}` + bar: `0x${string}` + } + | undefined + // @ts-ignore – TODO: Fix https://github.com/wevm/viem/issues/1916 + >(result4.data) +}) + +test('deployless read (bytecode)', () => { + const result = useReadContract({ + code: '0x', + abi: abi.erc20, + functionName: 'balanceOf', + args: ['0x'], + }) + expectTypeOf(result.data.value).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/vue/src/composables/useReadContract.test.ts b/wagmi-project/packages/vue/src/composables/useReadContract.test.ts new file mode 100644 index 000000000..2fe2fb703 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useReadContract.test.ts @@ -0,0 +1,105 @@ +import { abi, address, bytecode, chain, wait } from '@wagmi/test' +import { renderComposable, waitFor } from '@wagmi/test/vue' +import { expect, test } from 'vitest' +import { ref } from 'vue' + +import { useReadContract } from './useReadContract.js' + +test('default', async () => { + const [result] = renderComposable(() => + useReadContract({ + address: address.wagmiMintExample, + abi: abi.wagmiMintExample, + functionName: 'balanceOf', + args: ['0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC'], + }), + ) + + await waitFor(result.isSuccess) + + expect(result.data.value).toBe(4n) + expect(result.queryKey).toMatchInlineSnapshot(` + [ + "readContract", + { + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "args": [ + "0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC", + ], + "chainId": 1, + "functionName": "balanceOf", + }, + ] + `) +}) + +test('parameters: chainId', async () => { + const [result] = renderComposable(() => + useReadContract({ + address: address.wagmiMintExample, + abi: abi.wagmiMintExample, + functionName: 'balanceOf', + args: ['0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC'], + chainId: chain.mainnet2.id, + }), + ) + + await waitFor(result.isSuccess) + + expect(result.data.value).toBe(4n) + expect(result.queryKey).toMatchInlineSnapshot(` + [ + "readContract", + { + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "args": [ + "0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC", + ], + "chainId": 456, + "functionName": "balanceOf", + }, + ] + `) +}) + +test('parameters: deployless read (bytecode)', async () => { + const [result] = renderComposable(() => + useReadContract({ + abi: abi.wagmiMintExample, + functionName: 'name', + code: bytecode.wagmiMintExample, + }), + ) + + await waitFor(result.isSuccess) + + expect(result.data.value).toMatchInlineSnapshot(`"wagmi"`) +}) + +test.skip('behavior: disabled when missing properties', async () => { + const addressRef = ref() + const abiRef = ref() + const functionNameRef = ref() + + const [result] = renderComposable(() => + useReadContract({ + abi: abiRef, + address: addressRef, + functionName: functionNameRef, + }), + ) + + await wait(100) + expect(result.fetchStatus.value).toBe('idle') + + addressRef.value = '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2' + + await wait(100) + expect(result.fetchStatus.value).toBe('idle') + + abiRef.value = abi.wagmiMintExample + functionNameRef.value = 'totalSupply' + + await wait(100) + expect(result.fetchStatus.value).toBe('fetching') +}) diff --git a/wagmi-project/packages/vue/src/composables/useReadContract.ts b/wagmi-project/packages/vue/src/composables/useReadContract.ts new file mode 100644 index 000000000..10ecc859f --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useReadContract.ts @@ -0,0 +1,116 @@ +import type { + Config, + ReadContractErrorType, + ResolvedRegister, +} from '@wagmi/core' +import type { UnionCompute } from '@wagmi/core/internal' +import { + type ReadContractData, + type ReadContractOptions, + type ReadContractQueryFnData, + type ReadContractQueryKey, + readContractQueryOptions, + structuralSharing, +} from '@wagmi/core/query' +import type { Abi, ContractFunctionArgs, ContractFunctionName } from 'viem' +import { computed } from 'vue' + +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import type { DeepMaybeRef } from '../types/ref.js' +import { deepUnref } from '../utils/cloneDeep.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseReadContractParameters< + abi extends Abi | readonly unknown[] = Abi, + functionName extends ContractFunctionName< + abi, + 'pure' | 'view' + > = ContractFunctionName, + args extends ContractFunctionArgs< + abi, + 'pure' | 'view', + functionName + > = ContractFunctionArgs, + config extends Config = Config, + selectData = ReadContractData, +> = UnionCompute< + DeepMaybeRef< + ReadContractOptions & + ConfigParameter & + QueryParameter< + ReadContractQueryFnData, + ReadContractErrorType, + selectData, + ReadContractQueryKey + > + > +> + +export type UseReadContractReturnType< + abi extends Abi | readonly unknown[] = Abi, + functionName extends ContractFunctionName< + abi, + 'pure' | 'view' + > = ContractFunctionName, + args extends ContractFunctionArgs< + abi, + 'pure' | 'view', + functionName + > = ContractFunctionArgs, + selectData = ReadContractData, +> = UseQueryReturnType + +/** https://wagmi.sh/vue/api/hooks/useReadContract */ +export function useReadContract< + const abi extends Abi | readonly unknown[], + functionName extends ContractFunctionName, + args extends ContractFunctionArgs, + config extends Config = ResolvedRegister['config'], + selectData = ReadContractData, +>( + parameters_: UseReadContractParameters< + abi, + functionName, + args, + config, + selectData + > = {} as any, +): UseReadContractReturnType { + const parameters = computed(() => deepUnref(parameters_)) as any + + const config = useConfig(parameters) + const configChainId = useChainId({ config }) + + const queryOptions = computed(() => { + const { + abi, + address, + chainId = configChainId.value, + code, + functionName, + query = {}, + } = parameters.value + const options = readContractQueryOptions( + config as any, + { ...parameters.value, chainId }, + ) + const enabled = Boolean( + (address || code) && abi && functionName && (query.enabled ?? true), + ) + return { + ...query, + ...options, + enabled, + structuralSharing: query.structuralSharing ?? structuralSharing, + } + }) + + return useQuery(queryOptions) as UseReadContractReturnType< + abi, + functionName, + args, + selectData + > +} diff --git a/wagmi-project/packages/vue/src/composables/useReconnect.test-d.ts b/wagmi-project/packages/vue/src/composables/useReconnect.test-d.ts new file mode 100644 index 000000000..bc4ecd8d8 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useReconnect.test-d.ts @@ -0,0 +1,154 @@ +import type { + Connector, + CreateConnectorFn, + ReconnectErrorType, +} from '@wagmi/core' +import { config } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' + +import type { Address } from 'viem' +import { useReconnect } from './useReconnect.js' + +const connectors = [config.connectors[0]!] +const contextValue = { foo: 'bar' } as const + +test('context', () => { + const { context, data, error, reconnect, variables } = useReconnect({ + mutation: { + onMutate(variables) { + expectTypeOf(variables).toEqualTypeOf< + | { + connectors?: + | readonly (CreateConnectorFn | Connector)[] + | undefined + } + | undefined + >() + return contextValue + }, + onError(error, variables, context) { + expectTypeOf(variables).toEqualTypeOf< + | { + connectors?: + | readonly (CreateConnectorFn | Connector)[] + | undefined + } + | undefined + >() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSuccess(data, variables, context) { + expectTypeOf(variables).toEqualTypeOf< + | { + connectors?: + | readonly (CreateConnectorFn | Connector)[] + | undefined + } + | undefined + >() + expectTypeOf(data).toEqualTypeOf< + { + accounts: readonly [Address, ...Address[]] + chainId: number + connector: Connector + }[] + >() + expectTypeOf(context).toEqualTypeOf() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf< + | { + accounts: readonly [Address, ...Address[]] + chainId: number + connector: Connector + }[] + | undefined + >() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toEqualTypeOf< + | { + connectors?: + | readonly (CreateConnectorFn | Connector)[] + | undefined + } + | undefined + >() + expectTypeOf(context).toEqualTypeOf() + }, + }, + }) + + expectTypeOf(data.value).toEqualTypeOf< + | { + accounts: readonly [Address, ...Address[]] + chainId: number + connector: Connector + }[] + | undefined + >() + expectTypeOf(error.value).toEqualTypeOf() + expectTypeOf(variables.value).toEqualTypeOf< + | { + connectors?: readonly (CreateConnectorFn | Connector)[] | undefined + } + | undefined + >() + expectTypeOf(context.value).toEqualTypeOf() + + reconnect( + { connectors }, + { + onError(error, variables, context) { + expectTypeOf(variables).toEqualTypeOf< + | { + connectors?: + | readonly (CreateConnectorFn | Connector)[] + | undefined + } + | undefined + >() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSuccess(data, variables, context) { + expectTypeOf(variables).toEqualTypeOf< + | { + connectors?: + | readonly (CreateConnectorFn | Connector)[] + | undefined + } + | undefined + >() + expectTypeOf(data).toEqualTypeOf< + { + accounts: readonly [Address, ...Address[]] + chainId: number + connector: Connector + }[] + >() + expectTypeOf(context).toEqualTypeOf() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf< + | { + accounts: readonly [Address, ...Address[]] + chainId: number + connector: Connector + }[] + | undefined + >() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toEqualTypeOf< + | { + connectors?: + | readonly (CreateConnectorFn | Connector)[] + | undefined + } + | undefined + >() + expectTypeOf(context).toEqualTypeOf() + }, + }, + ) +}) diff --git a/wagmi-project/packages/vue/src/composables/useReconnect.test.ts b/wagmi-project/packages/vue/src/composables/useReconnect.test.ts new file mode 100644 index 000000000..49cf7f73e --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useReconnect.test.ts @@ -0,0 +1,81 @@ +import { mock } from '@wagmi/connectors' +import { connect, disconnect } from '@wagmi/core' +import { accounts, config } from '@wagmi/test' +import { renderComposable, waitFor } from '@wagmi/test/vue' +import { afterEach, expect, test } from 'vitest' + +import { useReconnect } from './useReconnect.js' + +const connector = config._internal.connectors.setup( + mock({ + accounts, + features: { reconnect: true }, + }), +) + +afterEach(async () => { + if (config.state.current) await disconnect(config) +}) + +test('default', async () => { + await connect(config, { connector }) + + const [reconnect] = renderComposable(() => useReconnect()) + + reconnect.reconnect() + await waitFor(reconnect.isSuccess) + + expect(reconnect.data.value).toStrictEqual([]) +}) + +test('parameters: connectors (Connector)', async () => { + await connect(config, { connector }) + + const [reconnect] = renderComposable(() => useReconnect()) + + reconnect.reconnect({ connectors: [connector] }) + await waitFor(reconnect.isSuccess) + + expect(reconnect.data.value).toMatchObject( + expect.arrayContaining([ + expect.objectContaining({ + accounts: expect.any(Array), + chainId: expect.any(Number), + }), + ]), + ) +}) + +test('parameters: connectors (CreateConnectorFn)', async () => { + const connector = mock({ + accounts, + features: { reconnect: true }, + }) + await connect(config, { connector }) + + const [reconnect] = renderComposable(() => useReconnect()) + + reconnect.reconnect({ connectors: [connector] }) + await waitFor(reconnect.isSuccess) + + expect(reconnect.data.value).toMatchObject( + expect.arrayContaining([ + expect.objectContaining({ + accounts: expect.any(Array), + chainId: expect.any(Number), + }), + ]), + ) +}) + +test("behavior: doesn't reconnect if already reconnecting", async () => { + const previousStatus = config.state.status + config.setState((x) => ({ ...x, status: 'reconnecting' })) + + const [reconnect] = renderComposable(() => useReconnect()) + + await expect( + reconnect.reconnectAsync({ connectors: [connector] }), + ).resolves.toStrictEqual([]) + config.setState((x) => ({ ...x, status: previousStatus })) +}) diff --git a/wagmi-project/packages/vue/src/composables/useReconnect.ts b/wagmi-project/packages/vue/src/composables/useReconnect.ts new file mode 100644 index 000000000..cfab97d85 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useReconnect.ts @@ -0,0 +1,65 @@ +import { useMutation } from '@tanstack/vue-query' +import type { Connector, ReconnectErrorType } from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type ReconnectData, + type ReconnectMutate, + type ReconnectMutateAsync, + type ReconnectVariables, + reconnectMutationOptions, +} from '@wagmi/core/query' + +import type { ConfigParameter } from '../types/properties.js' +import type { + UseMutationParameters, + UseMutationReturnType, +} from '../utils/query.js' +import { useConfig } from './useConfig.js' + +export type UseReconnectParameters = Compute< + ConfigParameter & { + mutation?: + | UseMutationParameters< + ReconnectData, + ReconnectErrorType, + ReconnectVariables, + context + > + | undefined + } +> + +export type UseReconnectReturnType = Compute< + UseMutationReturnType< + ReconnectData, + ReconnectErrorType, + ReconnectVariables, + context + > & { + connectors: readonly Connector[] + reconnect: ReconnectMutate + reconnectAsync: ReconnectMutateAsync + } +> + +/** https://wagmi.sh/vue/api/composables/useReconnect */ +export function useReconnect( + parameters: UseReconnectParameters = {}, +): UseReconnectReturnType { + const { mutation } = parameters + + const config = useConfig(parameters) + + const mutationOptions = reconnectMutationOptions(config) + const { mutate, mutateAsync, ...result } = useMutation({ + ...mutation, + ...mutationOptions, + }) + + return { + ...result, + connectors: config.connectors, + reconnect: mutate, + reconnectAsync: mutateAsync, + } +} diff --git a/wagmi-project/packages/vue/src/composables/useSendTransaction.test-d.ts b/wagmi-project/packages/vue/src/composables/useSendTransaction.test-d.ts new file mode 100644 index 000000000..4670e879c --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useSendTransaction.test-d.ts @@ -0,0 +1,78 @@ +import type { SendTransactionErrorType } from '@wagmi/core' +import type { Hash } from 'viem' +import { expectTypeOf, test } from 'vitest' + +import { useSendTransaction } from './useSendTransaction.js' + +const contextValue = { foo: 'bar' } as const + +test('context', () => { + const { context, data, error, sendTransaction, variables } = + useSendTransaction({ + mutation: { + onMutate(variables) { + expectTypeOf(variables).toMatchTypeOf< + { chainId?: number | undefined } | undefined + >() + return contextValue + }, + onError(error, variables, context) { + expectTypeOf(variables).toMatchTypeOf<{ + chainId?: number | undefined + }>() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSuccess(data, variables, context) { + expectTypeOf(variables).toMatchTypeOf<{ + chainId?: number | undefined + }>() + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toMatchTypeOf<{ + chainId?: number | undefined + }>() + expectTypeOf(context).toEqualTypeOf() + }, + }, + }) + + expectTypeOf(data.value).toEqualTypeOf() + expectTypeOf(error.value).toEqualTypeOf() + expectTypeOf(variables.value).toMatchTypeOf< + { chainId?: number | undefined } | undefined + >() + expectTypeOf(context.value).toEqualTypeOf() + + sendTransaction( + { to: '0x' }, + { + onError(error, variables, context) { + expectTypeOf(variables).toMatchTypeOf<{ + chainId?: number | undefined + }>() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSuccess(data, variables, context) { + expectTypeOf(variables).toMatchTypeOf<{ + chainId?: number | undefined + }>() + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toMatchTypeOf<{ + chainId?: number | undefined + }>() + expectTypeOf(context).toEqualTypeOf() + }, + }, + ) +}) diff --git a/wagmi-project/packages/vue/src/composables/useSendTransaction.test.ts b/wagmi-project/packages/vue/src/composables/useSendTransaction.test.ts new file mode 100644 index 000000000..ae069766e --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useSendTransaction.test.ts @@ -0,0 +1,25 @@ +import { connect, disconnect } from '@wagmi/core' +import { config, transactionHashRegex } from '@wagmi/test' +import { renderComposable, waitFor } from '@wagmi/test/vue' +import { parseEther } from 'viem' +import { expect, test } from 'vitest' + +import { useSendTransaction } from './useSendTransaction.js' + +const connector = config.connectors[0]! + +test('default', async () => { + await connect(config, { connector }) + + const [result] = renderComposable(() => useSendTransaction()) + + result.sendTransaction({ + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), + }) + await waitFor(result.isSuccess) + + expect(result.data.value).toMatch(transactionHashRegex) + + await disconnect(config, { connector }) +}) diff --git a/wagmi-project/packages/vue/src/composables/useSendTransaction.ts b/wagmi-project/packages/vue/src/composables/useSendTransaction.ts new file mode 100644 index 000000000..d5bc71833 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useSendTransaction.ts @@ -0,0 +1,76 @@ +import { useMutation } from '@tanstack/vue-query' +import type { + Config, + ResolvedRegister, + SendTransactionErrorType, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type SendTransactionData, + type SendTransactionMutate, + type SendTransactionMutateAsync, + type SendTransactionVariables, + sendTransactionMutationOptions, +} from '@wagmi/core/query' + +import type { ConfigParameter } from '../types/properties.js' +import type { + UseMutationParameters, + UseMutationReturnType, +} from '../utils/query.js' +import { useConfig } from './useConfig.js' + +export type UseSendTransactionParameters< + config extends Config = Config, + context = unknown, +> = Compute< + ConfigParameter & { + mutation?: + | UseMutationParameters< + SendTransactionData, + SendTransactionErrorType, + SendTransactionVariables, + context + > + | undefined + } +> + +export type UseSendTransactionReturnType< + config extends Config = Config, + context = unknown, +> = Compute< + UseMutationReturnType< + SendTransactionData, + SendTransactionErrorType, + SendTransactionVariables, + context + > & { + sendTransaction: SendTransactionMutate + sendTransactionAsync: SendTransactionMutateAsync + } +> + +/** https://wagmi.sh/vue/api/composables/useSendTransaction */ +export function useSendTransaction< + config extends Config = ResolvedRegister['config'], + context = unknown, +>( + parameters: UseSendTransactionParameters = {}, +): UseSendTransactionReturnType { + const { mutation } = parameters + + const config = useConfig(parameters) + + const mutationOptions = sendTransactionMutationOptions(config) + const { mutate, mutateAsync, ...result } = useMutation({ + ...mutation, + ...mutationOptions, + }) + + return { + ...result, + sendTransaction: mutate, + sendTransactionAsync: mutateAsync, + } as UseSendTransactionReturnType +} diff --git a/wagmi-project/packages/vue/src/composables/useSignMessage.test-d.ts b/wagmi-project/packages/vue/src/composables/useSignMessage.test-d.ts new file mode 100644 index 000000000..5c8da53bb --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useSignMessage.test-d.ts @@ -0,0 +1,64 @@ +import type { SignMessageErrorType } from '@wagmi/core' +import type { SignMessageVariables } from '@wagmi/core/query' +import { expectTypeOf, test } from 'vitest' + +import { useSignMessage } from './useSignMessage.js' + +const message = 'hello world' +const contextValue = { foo: 'bar' } as const + +test('context', () => { + const { context, data, error, signMessage, variables } = useSignMessage({ + mutation: { + onMutate(variables) { + expectTypeOf(variables).toEqualTypeOf() + return contextValue + }, + onError(error, variables, context) { + expectTypeOf(variables).toEqualTypeOf() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSuccess(data, variables, context) { + expectTypeOf(variables).toEqualTypeOf() + expectTypeOf(data).toEqualTypeOf<`0x${string}`>() + expectTypeOf(context).toEqualTypeOf() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf<`0x${string}` | undefined>() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + }, + }) + + expectTypeOf(data.value).toEqualTypeOf<`0x${string}` | undefined>() + expectTypeOf(error.value).toEqualTypeOf() + expectTypeOf(variables.value).toEqualTypeOf< + SignMessageVariables | undefined + >() + expectTypeOf(context.value).toEqualTypeOf() + + signMessage( + { message }, + { + onError(error, variables, context) { + expectTypeOf(variables).toEqualTypeOf() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSuccess(data, variables, context) { + expectTypeOf(variables).toEqualTypeOf() + expectTypeOf(data).toEqualTypeOf<`0x${string}`>() + expectTypeOf(context).toEqualTypeOf() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf<`0x${string}` | undefined>() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + }, + ) +}) diff --git a/wagmi-project/packages/vue/src/composables/useSignMessage.test.ts b/wagmi-project/packages/vue/src/composables/useSignMessage.test.ts new file mode 100644 index 000000000..a00691fb7 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useSignMessage.test.ts @@ -0,0 +1,43 @@ +import { connect, disconnect, getAccount } from '@wagmi/core' +import { config, privateKey } from '@wagmi/test' +import { renderComposable, waitFor } from '@wagmi/test/vue' +import { recoverMessageAddress } from 'viem' +import { expect, test } from 'vitest' + +import { privateKeyToAccount } from 'viem/accounts' +import { useSignMessage } from './useSignMessage.js' + +const connector = config.connectors[0]! + +test('default', async () => { + await connect(config, { connector }) + + const [result] = renderComposable(() => useSignMessage()) + + result.signMessage({ message: 'foo bar baz' }) + await waitFor(result.isSuccess) + + await expect( + recoverMessageAddress({ + message: 'foo bar baz', + signature: result.data.value!, + }), + ).resolves.toEqual(getAccount(config).address) + + await disconnect(config, { connector }) +}) + +test('behavior: local account', async () => { + const [result] = renderComposable(() => useSignMessage()) + + const account = privateKeyToAccount(privateKey) + result.signMessage({ account, message: 'foo bar baz' }) + await waitFor(result.isSuccess) + + await expect( + recoverMessageAddress({ + message: 'foo bar baz', + signature: result.data.value!, + }), + ).resolves.toEqual(account.address) +}) diff --git a/wagmi-project/packages/vue/src/composables/useSignMessage.ts b/wagmi-project/packages/vue/src/composables/useSignMessage.ts new file mode 100644 index 000000000..2f7222b6a --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useSignMessage.ts @@ -0,0 +1,63 @@ +import type { SignMessageErrorType } from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type SignMessageData, + type SignMessageMutate, + type SignMessageMutateAsync, + type SignMessageVariables, + signMessageMutationOptions, +} from '@wagmi/core/query' + +import type { ConfigParameter } from '../types/properties.js' +import { + type UseMutationParameters, + type UseMutationReturnType, + useMutation, +} from '../utils/query.js' +import { useConfig } from './useConfig.js' + +export type UseSignMessageParameters = Compute< + ConfigParameter & { + mutation?: + | UseMutationParameters< + SignMessageData, + SignMessageErrorType, + SignMessageVariables, + context + > + | undefined + } +> + +export type UseSignMessageReturnType = Compute< + UseMutationReturnType< + SignMessageData, + SignMessageErrorType, + SignMessageVariables, + context + > & { + signMessage: SignMessageMutate + signMessageAsync: SignMessageMutateAsync + } +> + +/** https://wagmi.sh/vue/api/composables/useSignMessage */ +export function useSignMessage( + parameters: UseSignMessageParameters = {}, +): UseSignMessageReturnType { + const { mutation } = parameters + + const config = useConfig(parameters) + + const mutationOptions = signMessageMutationOptions(config) + const { mutate, mutateAsync, ...result } = useMutation({ + ...mutation, + ...mutationOptions, + }) + + return { + ...result, + signMessage: mutate, + signMessageAsync: mutateAsync, + } +} diff --git a/wagmi-project/packages/vue/src/composables/useSignTypedData.test-d.ts b/wagmi-project/packages/vue/src/composables/useSignTypedData.test-d.ts new file mode 100644 index 000000000..ba5c253a8 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useSignTypedData.test-d.ts @@ -0,0 +1,95 @@ +import type { + SignTypedDataErrorType, + SignTypedDataReturnType, +} from '@wagmi/core' +import type { SignTypedDataVariables } from '@wagmi/core/query' +import { typedData } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' + +import { useSignTypedData } from './useSignTypedData.js' + +const contextValue = { foo: 'bar' } as const + +test('context', () => { + const { context, data, error, signTypedData, variables } = useSignTypedData({ + mutation: { + onMutate(variables) { + expectTypeOf(variables).toMatchTypeOf() + return contextValue + }, + onError(error, variables, context) { + expectTypeOf(variables).toMatchTypeOf() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSuccess(data, variables, context) { + expectTypeOf(variables).toMatchTypeOf() + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toMatchTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + }, + }) + + expectTypeOf(data.value).toEqualTypeOf() + expectTypeOf(error.value).toEqualTypeOf() + expectTypeOf(variables.value).toMatchTypeOf< + SignTypedDataVariables | undefined + >() + expectTypeOf(context.value).toEqualTypeOf() + + signTypedData( + { + types: typedData.basic.types, + primaryType: 'Person', + message: { + name: 'Bob', + wallet: '0x', + }, + }, + { + onError(error, variables, context) { + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toMatchTypeOf<{ + types: typeof typedData.basic.types + primaryType: 'Person' + message: { + name: string + wallet: `0x${string}` + } + }>() + expectTypeOf(context).toEqualTypeOf() + }, + onSuccess(data, variables, context) { + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(variables).toMatchTypeOf<{ + types: typeof typedData.basic.types + primaryType: 'Person' + message: { + name: string + wallet: `0x${string}` + } + }>() + expectTypeOf(context).toEqualTypeOf() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toMatchTypeOf<{ + types: typeof typedData.basic.types + primaryType: 'Person' + message: { + name: string + wallet: `0x${string}` + } + }>() + expectTypeOf(context).toEqualTypeOf() + }, + }, + ) +}) diff --git a/wagmi-project/packages/vue/src/composables/useSignTypedData.test.ts b/wagmi-project/packages/vue/src/composables/useSignTypedData.test.ts new file mode 100644 index 000000000..e3636d21e --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useSignTypedData.test.ts @@ -0,0 +1,56 @@ +import { connect, disconnect, getAccount } from '@wagmi/core' +import { config, privateKey, typedData } from '@wagmi/test' +import { renderComposable, waitFor } from '@wagmi/test/vue' +import { recoverTypedDataAddress } from 'viem' +import { expect, test } from 'vitest' + +import { privateKeyToAccount } from 'viem/accounts' +import { useSignTypedData } from './useSignTypedData.js' + +const connector = config.connectors[0]! + +test('default', async () => { + await connect(config, { connector }) + + const [result] = renderComposable(() => useSignTypedData()) + + result.signTypedData({ + types: typedData.basic.types, + primaryType: 'Mail', + message: typedData.basic.message, + }) + await waitFor(result.isSuccess) + + await expect( + recoverTypedDataAddress({ + types: typedData.basic.types, + primaryType: 'Mail', + message: typedData.basic.message, + signature: result.data.value!, + }), + ).resolves.toEqual(getAccount(config).address) + + await disconnect(config, { connector }) +}) + +test('behavior: local account', async () => { + const [result] = renderComposable(() => useSignTypedData()) + + const account = privateKeyToAccount(privateKey) + result.signTypedData({ + account, + types: typedData.basic.types, + primaryType: 'Mail', + message: typedData.basic.message, + }) + await waitFor(result.isSuccess) + + await expect( + recoverTypedDataAddress({ + types: typedData.basic.types, + primaryType: 'Mail', + message: typedData.basic.message, + signature: result.data.value!, + }), + ).resolves.toEqual(account.address) +}) diff --git a/wagmi-project/packages/vue/src/composables/useSignTypedData.ts b/wagmi-project/packages/vue/src/composables/useSignTypedData.ts new file mode 100644 index 000000000..f0bdbf6c6 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useSignTypedData.ts @@ -0,0 +1,64 @@ +import type { SignTypedDataErrorType } from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type SignTypedDataData, + type SignTypedDataMutate, + type SignTypedDataMutateAsync, + type SignTypedDataVariables, + signTypedDataMutationOptions, +} from '@wagmi/core/query' + +import type { ConfigParameter } from '../types/properties.js' +import { + type UseMutationParameters, + type UseMutationReturnType, + useMutation, +} from '../utils/query.js' +import { useConfig } from './useConfig.js' + +export type UseSignTypedDataParameters = Compute< + ConfigParameter & { + mutation?: + | UseMutationParameters< + SignTypedDataData, + SignTypedDataErrorType, + SignTypedDataVariables, + context + > + | undefined + } +> + +export type UseSignTypedDataReturnType = Compute< + UseMutationReturnType< + SignTypedDataData, + SignTypedDataErrorType, + SignTypedDataVariables, + context + > & { + signTypedData: SignTypedDataMutate + signTypedDataAsync: SignTypedDataMutateAsync + } +> + +/** https://wagmi.sh/vue/api/composables/useSignTypedData */ +export function useSignTypedData( + parameters: UseSignTypedDataParameters = {}, +): UseSignTypedDataReturnType { + const { mutation } = parameters + + const config = useConfig(parameters) + + const mutationOptions = signTypedDataMutationOptions(config) + const { mutate, mutateAsync, ...result } = useMutation({ + ...mutation, + ...mutationOptions, + }) + + type Return = UseSignTypedDataReturnType + return { + ...result, + signTypedData: mutate as Return['signTypedData'], + signTypedDataAsync: mutateAsync as Return['signTypedDataAsync'], + } +} diff --git a/wagmi-project/packages/vue/src/composables/useSimulateContract.test-d.ts b/wagmi-project/packages/vue/src/composables/useSimulateContract.test-d.ts new file mode 100644 index 000000000..e8d2451ca --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useSimulateContract.test-d.ts @@ -0,0 +1,96 @@ +import { abi, type config } from '@wagmi/test' +import type { Address } from 'viem' +import { expectTypeOf, test } from 'vitest' + +import { + type UseSimulateContractReturnType, + useSimulateContract, +} from './useSimulateContract.js' + +test('default', () => { + const result = useSimulateContract({ + address: '0x', + abi: abi.erc20, + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + }) + + expectTypeOf(result.data.value).toMatchTypeOf< + | { + result: boolean + request: { + chainId?: undefined + abi: readonly [ + { + readonly name: 'transferFrom' + readonly type: 'function' + readonly stateMutability: 'nonpayable' + readonly inputs: readonly [ + { readonly type: 'address'; readonly name: 'sender' }, + { readonly type: 'address'; readonly name: 'recipient' }, + { readonly type: 'uint256'; readonly name: 'amount' }, + ] + readonly outputs: readonly [{ type: 'bool' }] + }, + ] + functionName: 'transferFrom' + args: readonly [Address, Address, bigint] + } + } + | undefined + >() +}) + +test('select data', () => { + // @ts-ignore TODO: Type instantiation is excessively deep and possibly infinite. + const result = useSimulateContract({ + address: '0x', + abi: abi.erc20, + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + chainId: 1, + query: { + select(data) { + expectTypeOf(data.result).toEqualTypeOf() + return data.request.args + }, + }, + }) + expectTypeOf(result.data.value).toEqualTypeOf< + readonly [Address, Address, bigint] | undefined + >() +}) + +test('UseSimulateContractReturnType', () => { + type Result = UseSimulateContractReturnType< + typeof abi.erc20, + 'transferFrom', + ['0x', '0x', 123n], + typeof config, + 1 + > + expectTypeOf().toMatchTypeOf< + | { + result: boolean + request: { + chainId: number + abi: readonly [ + { + readonly name: 'transferFrom' + readonly type: 'function' + readonly stateMutability: 'nonpayable' + readonly inputs: readonly [ + { readonly type: 'address'; readonly name: 'sender' }, + { readonly type: 'address'; readonly name: 'recipient' }, + { readonly type: 'uint256'; readonly name: 'amount' }, + ] + readonly outputs: readonly [{ type: 'bool' }] + }, + ] + functionName: 'approve' | 'transfer' | 'transferFrom' + args: readonly [Address, Address, bigint] + } + } + | undefined + >() +}) diff --git a/wagmi-project/packages/vue/src/composables/useSimulateContract.test.ts b/wagmi-project/packages/vue/src/composables/useSimulateContract.test.ts new file mode 100644 index 000000000..1118a51d6 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useSimulateContract.test.ts @@ -0,0 +1,59 @@ +import { connect, disconnect } from '@wagmi/core' +import { abi, address, config, wait } from '@wagmi/test' +import { renderComposable, waitFor } from '@wagmi/test/vue' +import { expect, test } from 'vitest' + +import { useSimulateContract } from './useSimulateContract.js' + +const connector = config.connectors[0]! + +test('default', async () => { + await connect(config, { connector }) + + const [result] = renderComposable(() => + useSimulateContract({ + address: address.wagmiMintExample, + abi: abi.wagmiMintExample, + functionName: 'mint', + }), + ) + + await waitFor(result.isSuccess) + + expect(result.data.value).toMatchInlineSnapshot(` + { + "chainId": 1, + "request": { + "abi": [ + { + "inputs": [], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + ], + "account": { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "type": "json-rpc", + }, + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "args": undefined, + "chainId": 1, + "dataSuffix": undefined, + "functionName": "mint", + }, + "result": undefined, + } + `) + + await disconnect(config, { connector }) +}) + +test('behavior: disabled when properties missing', async () => { + const [result] = renderComposable(() => useSimulateContract()) + + await wait(100) + + expect(result.fetchStatus.value).toBe('idle') +}) diff --git a/wagmi-project/packages/vue/src/composables/useSimulateContract.ts b/wagmi-project/packages/vue/src/composables/useSimulateContract.ts new file mode 100644 index 000000000..7ffce57b8 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useSimulateContract.ts @@ -0,0 +1,145 @@ +import type { + Config, + ResolvedRegister, + SimulateContractErrorType, +} from '@wagmi/core' +import { + type SimulateContractData, + type SimulateContractOptions, + type SimulateContractQueryFnData, + type SimulateContractQueryKey, + simulateContractQueryOptions, +} from '@wagmi/core/query' +import type { Abi, ContractFunctionArgs, ContractFunctionName } from 'viem' +import { type MaybeRef, computed } from 'vue' + +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import type { DeepMaybeRef } from '../types/ref.js' +import { deepUnref } from '../utils/cloneDeep.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' +import { useConnectorClient } from './useConnectorClient.js' + +export type UseSimulateContractParameters< + abi extends Abi | readonly unknown[] = Abi, + functionName extends ContractFunctionName< + abi, + 'nonpayable' | 'payable' + > = ContractFunctionName, + args extends ContractFunctionArgs< + abi, + 'nonpayable' | 'payable', + functionName + > = ContractFunctionArgs, + config extends Config = Config, + chainId extends config['chains'][number]['id'] | undefined = undefined, + selectData = SimulateContractData, +> = MaybeRef< + DeepMaybeRef< + SimulateContractOptions + > & + ConfigParameter & + QueryParameter< + SimulateContractQueryFnData, + SimulateContractErrorType, + selectData, + SimulateContractQueryKey + > +> + +export type UseSimulateContractReturnType< + abi extends Abi | readonly unknown[] = Abi, + functionName extends ContractFunctionName< + abi, + 'nonpayable' | 'payable' + > = ContractFunctionName, + args extends ContractFunctionArgs< + abi, + 'nonpayable' | 'payable', + functionName + > = ContractFunctionArgs, + config extends Config = Config, + chainId extends config['chains'][number]['id'] | undefined = undefined, + selectData = SimulateContractData, +> = UseQueryReturnType + +/** https://wagmi.sh/vue/api/composables/useSimulateContract */ +export function useSimulateContract< + const abi extends Abi | readonly unknown[], + functionName extends ContractFunctionName, + args extends ContractFunctionArgs< + abi, + 'nonpayable' | 'payable', + functionName + >, + config extends Config = ResolvedRegister['config'], + chainId extends config['chains'][number]['id'] | undefined = undefined, + selectData = SimulateContractData, +>( + parameters_: UseSimulateContractParameters< + abi, + functionName, + args, + config, + chainId, + selectData + > = {} as any, +): UseSimulateContractReturnType< + abi, + functionName, + args, + config, + chainId, + selectData +> { + const parameters = computed(() => deepUnref(parameters_)) as any + + const config = useConfig(parameters) + const { data: connectorClient } = useConnectorClient( + computed(() => ({ + connector: parameters.value.connector, + query: { enabled: parameters.value.account === undefined }, + })), + ) + const configChainId = useChainId({ config }) + + const queryOptions = computed(() => { + const { + abi, + account = connectorClient?.value?.account, + address, + chainId = configChainId.value, + functionName, + query = {}, + } = parameters.value + const options = simulateContractQueryOptions< + config, + abi, + functionName, + args, + chainId + >(config as any, { + ...parameters.value, + account, + chainId, + }) + const enabled = Boolean( + abi && address && functionName && (query.enabled ?? true), + ) + return { + ...query, + ...options, + enabled, + } + }) + + return useQuery(queryOptions as any) as UseSimulateContractReturnType< + abi, + functionName, + args, + config, + chainId, + selectData + > +} diff --git a/wagmi-project/packages/vue/src/composables/useSwitchAccount.test-d.ts b/wagmi-project/packages/vue/src/composables/useSwitchAccount.test-d.ts new file mode 100644 index 000000000..d55e4b9d5 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useSwitchAccount.test-d.ts @@ -0,0 +1,89 @@ +import type { Connector, SwitchAccountErrorType } from '@wagmi/core' +import { config } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' + +import type { Address } from 'viem' +import { useSwitchAccount } from './useSwitchAccount.js' + +const connector = config.connectors[0]! +const contextValue = { foo: 'bar' } as const + +test('context', () => { + const { context, data, error, switchAccount, variables } = useSwitchAccount({ + mutation: { + onMutate(variables) { + expectTypeOf(variables).toEqualTypeOf<{ connector: Connector }>() + return contextValue + }, + onError(error, variables, context) { + expectTypeOf(variables).toEqualTypeOf<{ connector: Connector }>() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSuccess(data, variables, context) { + expectTypeOf(variables).toEqualTypeOf<{ connector: Connector }>() + expectTypeOf(data).toEqualTypeOf<{ + accounts: readonly [Address, ...Address[]] + chainId: number + }>() + expectTypeOf(context).toEqualTypeOf() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf< + | { + accounts: readonly [Address, ...Address[]] + chainId: number + } + | undefined + >() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toEqualTypeOf<{ connector: Connector }>() + expectTypeOf(context).toEqualTypeOf() + }, + }, + }) + + expectTypeOf(data.value).toEqualTypeOf< + | { + accounts: readonly [Address, ...Address[]] + chainId: number + } + | undefined + >() + expectTypeOf(error.value).toEqualTypeOf() + expectTypeOf(variables.value).toEqualTypeOf< + { connector: Connector } | undefined + >() + expectTypeOf(context.value).toEqualTypeOf() + + switchAccount( + { connector }, + { + onError(error, variables, context) { + expectTypeOf(variables).toEqualTypeOf<{ connector: Connector }>() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSuccess(data, variables, context) { + expectTypeOf(variables).toEqualTypeOf<{ connector: Connector }>() + expectTypeOf(data).toEqualTypeOf<{ + accounts: readonly [Address, ...Address[]] + chainId: number + }>() + expectTypeOf(context).toEqualTypeOf() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf< + | { + accounts: readonly [Address, ...Address[]] + chainId: number + } + | undefined + >() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toEqualTypeOf<{ connector: Connector }>() + expectTypeOf(context).toEqualTypeOf() + }, + }, + ) +}) diff --git a/wagmi-project/packages/vue/src/composables/useSwitchAccount.test.ts b/wagmi-project/packages/vue/src/composables/useSwitchAccount.test.ts new file mode 100644 index 000000000..aade28e3d --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useSwitchAccount.test.ts @@ -0,0 +1,42 @@ +import { connect, disconnect } from '@wagmi/core' +import { config } from '@wagmi/test' +import { renderComposable, waitFor } from '@wagmi/test/vue' +import { expect, test } from 'vitest' + +import { useAccount } from './useAccount.js' +import { useSwitchAccount } from './useSwitchAccount.js' + +const connector1 = config.connectors[0]! +const connector2 = config.connectors[1]! + +test('default', async () => { + const [account] = renderComposable(() => useAccount()) + const [switchAccount] = renderComposable(() => useSwitchAccount()) + + expect(switchAccount.connectors.value).toEqual([]) + + await connect(config, { connector: connector2 }) + await connect(config, { connector: connector1 }) + + expect(switchAccount.connectors.value.length).toEqual(2) + + const address1 = account.address.value + expect(address1).toBeDefined() + + switchAccount.switchAccount({ connector: connector2 }) + await waitFor(switchAccount.isSuccess) + + const address2 = account.address.value + expect(address2).toBeDefined() + expect(address1).not.toBe(address2) + + switchAccount.switchAccount({ connector: connector1 }) + await waitFor(switchAccount.isSuccess) + + const address3 = account.address.value + expect(address3).toBeDefined() + expect(address1).toBe(address3) + + await disconnect(config, { connector: connector1 }) + await disconnect(config, { connector: connector2 }) +}) diff --git a/wagmi-project/packages/vue/src/composables/useSwitchAccount.ts b/wagmi-project/packages/vue/src/composables/useSwitchAccount.ts new file mode 100644 index 000000000..0c8f76a48 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useSwitchAccount.ts @@ -0,0 +1,84 @@ +import { useMutation } from '@tanstack/vue-query' +import type { + Config, + Connector, + ResolvedRegister, + SwitchAccountErrorType, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type SwitchAccountData, + type SwitchAccountMutate, + type SwitchAccountMutateAsync, + type SwitchAccountVariables, + switchAccountMutationOptions, +} from '@wagmi/core/query' +import { type Ref, computed } from 'vue' + +import type { ConfigParameter } from '../types/properties.js' +import type { + UseMutationParameters, + UseMutationReturnType, +} from '../utils/query.js' +import { useConfig } from './useConfig.js' +import { useConnections } from './useConnections.js' + +export type UseSwitchAccountParameters< + config extends Config = Config, + context = unknown, +> = Compute< + ConfigParameter & { + mutation?: + | UseMutationParameters< + SwitchAccountData, + SwitchAccountErrorType, + SwitchAccountVariables, + context + > + | undefined + } +> + +export type UseSwitchAccountReturnType< + config extends Config = Config, + context = unknown, +> = Compute< + UseMutationReturnType< + SwitchAccountData, + SwitchAccountErrorType, + SwitchAccountVariables, + context + > & { + connectors: Ref + switchAccount: SwitchAccountMutate + switchAccountAsync: SwitchAccountMutateAsync + } +> + +/** https://wagmi.sh/vue/api/composables/useSwitchAccount */ +export function useSwitchAccount< + config extends Config = ResolvedRegister['config'], + context = unknown, +>( + parameters: UseSwitchAccountParameters = {}, +): UseSwitchAccountReturnType { + const { mutation } = parameters + + const config = useConfig(parameters) + const connections = useConnections({ config }) + + const mutationOptions = switchAccountMutationOptions(config) + const { mutate, mutateAsync, ...result } = useMutation({ + ...mutation, + ...mutationOptions, + }) + + return { + ...result, + connectors: computed(() => + connections.value.map((connection) => connection.connector), + ), + switchAccount: mutate, + switchAccountAsync: mutateAsync, + } +} diff --git a/wagmi-project/packages/vue/src/composables/useSwitchChain.test-d.ts b/wagmi-project/packages/vue/src/composables/useSwitchChain.test-d.ts new file mode 100644 index 000000000..e77046094 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useSwitchChain.test-d.ts @@ -0,0 +1,118 @@ +import type { Connector, SwitchChainErrorType } from '@wagmi/core' +import type { Chain } from '@wagmi/core/chains' +import type { Compute, ExactPartial } from '@wagmi/core/internal' +import { chain } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' + +import type { AddEthereumChainParameter } from 'viem' +import { useSwitchChain } from './useSwitchChain.js' + +const chainId = chain.mainnet.id +const contextValue = { foo: 'bar' } as const + +test('context', () => { + const { chains, context, data, error, switchChain, variables } = + useSwitchChain({ + mutation: { + onMutate(variables) { + expectTypeOf(variables).toEqualTypeOf<{ + addEthereumChainParameter?: + | ExactPartial> + | undefined + chainId: number + connector?: Connector | undefined + }>() + return contextValue + }, + onError(error, variables, context) { + expectTypeOf(variables).toEqualTypeOf<{ + addEthereumChainParameter?: + | ExactPartial> + | undefined + chainId: number + connector?: Connector | undefined + }>() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSuccess(data, variables, context) { + expectTypeOf(variables).toEqualTypeOf<{ + addEthereumChainParameter?: + | ExactPartial> + | undefined + chainId: number + connector?: Connector | undefined + }>() + expectTypeOf(data).toEqualTypeOf>() + expectTypeOf(context).toEqualTypeOf() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf | undefined>() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toEqualTypeOf<{ + addEthereumChainParameter?: + | ExactPartial> + | undefined + chainId: number + connector?: Connector | undefined + }>() + expectTypeOf(context).toEqualTypeOf() + }, + }, + }) + + expectTypeOf(chains.value).toEqualTypeOf() + expectTypeOf(data.value).toEqualTypeOf | undefined>() + expectTypeOf(error.value).toEqualTypeOf() + expectTypeOf(variables.value).toEqualTypeOf< + | { + addEthereumChainParameter?: + | ExactPartial> + | undefined + chainId: number + connector?: Connector | undefined + } + | undefined + >() + expectTypeOf(context.value).toEqualTypeOf() + + switchChain( + { chainId }, + { + onError(error, variables, context) { + expectTypeOf(variables).toEqualTypeOf<{ + addEthereumChainParameter?: + | ExactPartial> + | undefined + chainId: number + connector?: Connector | undefined + }>() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSuccess(data, variables, context) { + expectTypeOf(variables).toEqualTypeOf<{ + addEthereumChainParameter?: + | ExactPartial> + | undefined + chainId: number + connector?: Connector | undefined + }>() + expectTypeOf(data).toEqualTypeOf>() + expectTypeOf(context).toEqualTypeOf() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf | undefined>() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toEqualTypeOf<{ + addEthereumChainParameter?: + | ExactPartial> + | undefined + chainId: number + connector?: Connector | undefined + }>() + expectTypeOf(context).toEqualTypeOf() + }, + }, + ) +}) diff --git a/wagmi-project/packages/vue/src/composables/useSwitchChain.test.ts b/wagmi-project/packages/vue/src/composables/useSwitchChain.test.ts new file mode 100644 index 000000000..12e7c21c2 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useSwitchChain.test.ts @@ -0,0 +1,35 @@ +import { connect, disconnect } from '@wagmi/core' +import { chain, config } from '@wagmi/test' +import { renderComposable, waitFor } from '@wagmi/test/vue' +import { expect, test } from 'vitest' + +import { useAccount } from './useAccount.js' +import { useSwitchChain } from './useSwitchChain.js' + +const connector = config.connectors[0]! + +test('default', async () => { + await connect(config, { connector }) + + const [account] = renderComposable(() => useAccount()) + const [switchChain] = renderComposable(() => useSwitchChain()) + + const chainId1 = account.chainId.value + expect(chainId1).toBeDefined() + + switchChain.switchChain({ chainId: chain.mainnet2.id }) + await waitFor(switchChain.isSuccess) + + const chainId2 = account.chainId.value + expect(chainId2).toBeDefined() + expect(chainId1).not.toBe(chainId2) + + switchChain.switchChain({ chainId: chain.mainnet.id }) + await waitFor(switchChain.isSuccess) + + const chainId3 = account.chainId.value + expect(chainId3).toBeDefined() + expect(chainId1).toBe(chainId3) + + await disconnect(config, { connector }) +}) diff --git a/wagmi-project/packages/vue/src/composables/useSwitchChain.ts b/wagmi-project/packages/vue/src/composables/useSwitchChain.ts new file mode 100644 index 000000000..8ff43c0fa --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useSwitchChain.ts @@ -0,0 +1,81 @@ +import { useMutation } from '@tanstack/vue-query' +import type { + Config, + ResolvedRegister, + SwitchChainErrorType, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type SwitchChainData, + type SwitchChainMutate, + type SwitchChainMutateAsync, + type SwitchChainVariables, + switchChainMutationOptions, +} from '@wagmi/core/query' +import type { Ref } from 'vue' + +import type { ConfigParameter } from '../types/properties.js' +import type { + UseMutationParameters, + UseMutationReturnType, +} from '../utils/query.js' +import { useChains } from './useChains.js' +import { useConfig } from './useConfig.js' + +export type UseSwitchChainParameters< + config extends Config = Config, + context = unknown, +> = Compute< + ConfigParameter & { + mutation?: + | UseMutationParameters< + SwitchChainData, + SwitchChainErrorType, + SwitchChainVariables, + context + > + | undefined + } +> + +export type UseSwitchChainReturnType< + config extends Config = Config, + context = unknown, +> = Compute< + UseMutationReturnType< + SwitchChainData, + SwitchChainErrorType, + SwitchChainVariables, + context + > & { + chains: Ref + switchChain: SwitchChainMutate + switchChainAsync: SwitchChainMutateAsync + } +> + +/** https://wagmi.sh/vue/api/composables/useSwitchChain */ +export function useSwitchChain< + config extends Config = ResolvedRegister['config'], + context = unknown, +>( + parameters: UseSwitchChainParameters = {}, +): UseSwitchChainReturnType { + const { mutation } = parameters + + const config = useConfig(parameters) + + const mutationOptions = switchChainMutationOptions(config) + const { mutate, mutateAsync, ...result } = useMutation({ + ...mutation, + ...mutationOptions, + }) + + type Return = UseSwitchChainReturnType + return { + ...result, + chains: useChains({ config }) as unknown as Ref, + switchChain: mutate as Return['switchChain'], + switchChainAsync: mutateAsync as Return['switchChainAsync'], + } as Return +} diff --git a/wagmi-project/packages/vue/src/composables/useTransaction.test-d.ts b/wagmi-project/packages/vue/src/composables/useTransaction.test-d.ts new file mode 100644 index 000000000..bb795814e --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useTransaction.test-d.ts @@ -0,0 +1,14 @@ +import { expectTypeOf, test } from 'vitest' + +import { useTransaction } from './useTransaction.js' + +test('select data', () => { + const result = useTransaction({ + query: { + select(data) { + return data?.nonce + }, + }, + }) + expectTypeOf(result.data.value).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/vue/src/composables/useTransaction.test.ts b/wagmi-project/packages/vue/src/composables/useTransaction.test.ts new file mode 100644 index 000000000..06659958f --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useTransaction.test.ts @@ -0,0 +1,74 @@ +import { renderComposable, waitFor } from '@wagmi/test/vue' +import { expect, test } from 'vitest' + +import { deepUnref } from '../utils/cloneDeep.js' +import { useTransaction } from './useTransaction.js' + +test('default', async () => { + const [result] = renderComposable(() => + useTransaction({ + hash: '0x60668ed8c2dc110d61d945a936fcd45b8f13654e5c78481c8c825d1148c7ef30', + }), + ) + + await waitFor(result.isSuccess) + + expect(deepUnref(result)).toMatchInlineSnapshot(` + { + "data": { + "accessList": [], + "blockHash": "0xd725a38b51e5ceec8c5f6c9ccfdb2cc423af993bb650af5eedca5e4be7156ba7", + "blockNumber": 15189204n, + "chainId": 1, + "from": "0xa0cf798816d4b9b9866b5330eea46a18382f251e", + "gas": 21000n, + "gasPrice": 9371645552n, + "hash": "0x60668ed8c2dc110d61d945a936fcd45b8f13654e5c78481c8c825d1148c7ef30", + "input": "0x", + "maxFeePerGas": 13644824566n, + "maxPriorityFeePerGas": 1500000000n, + "nonce": 86, + "r": "0x40174f9a38df876c1a7ce2587848819d4082ccd6d67a88aa5cabe59bf594e14f", + "s": "0x7c0c82f62a8a5a9b0e9cf30a54a72fdae8fc54b5b79ddafef0acd30e94e83872", + "to": "0xd2135cfb216b74109775236e36d4b433f1df507b", + "transactionIndex": 144, + "type": "eip1559", + "typeHex": "0x2", + "v": 0n, + "value": 100000000000000000n, + "yParity": 0, + }, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "transaction", + { + "chainId": 1, + "hash": "0x60668ed8c2dc110d61d945a936fcd45b8f13654e5c78481c8c825d1148c7ef30", + }, + ], + "refetch": [Function], + "status": "success", + "suspense": [Function], + } + `) +}) diff --git a/wagmi-project/packages/vue/src/composables/useTransaction.ts b/wagmi-project/packages/vue/src/composables/useTransaction.ts new file mode 100644 index 000000000..eea49e68c --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useTransaction.ts @@ -0,0 +1,91 @@ +import type { + Config, + GetTransactionErrorType, + ResolvedRegister, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type GetTransactionData, + type GetTransactionOptions, + type GetTransactionQueryFnData, + type GetTransactionQueryKey, + getTransactionQueryOptions, +} from '@wagmi/core/query' + +import { computed } from 'vue' +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import type { DeepMaybeRef } from '../types/ref.js' +import { deepUnref } from '../utils/cloneDeep.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseTransactionParameters< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = GetTransactionData, +> = Compute< + DeepMaybeRef< + GetTransactionOptions & + ConfigParameter & + QueryParameter< + GetTransactionQueryFnData, + GetTransactionErrorType, + selectData, + GetTransactionQueryKey + > + > +> + +export type UseTransactionReturnType< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = GetTransactionData, +> = UseQueryReturnType + +/** https://wagmi.sh/vue/api/composables/useTransaction */ +export function useTransaction< + config extends Config = ResolvedRegister['config'], + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = GetTransactionData, +>( + parameters_: UseTransactionParameters = {}, +): UseTransactionReturnType { + const parameters = computed(() => deepUnref(parameters_)) + + const config = useConfig(parameters) + const configChainId = useChainId({ config }) + + const queryOptions = computed(() => { + const { + blockHash, + blockNumber, + blockTag, + chainId = configChainId.value, + hash, + query = {}, + } = parameters.value + const options = getTransactionQueryOptions(config, { + ...parameters.value, + chainId, + }) + const enabled = Boolean( + !(blockHash && blockNumber && blockTag && hash) && + (query.enabled ?? true), + ) + return { + ...query, + ...options, + enabled, + } + }) + + return useQuery(queryOptions as any) as UseTransactionReturnType< + config, + chainId, + selectData + > +} diff --git a/wagmi-project/packages/vue/src/composables/useTransactionReceipt.test-d.ts b/wagmi-project/packages/vue/src/composables/useTransactionReceipt.test-d.ts new file mode 100644 index 000000000..180d8354d --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useTransactionReceipt.test-d.ts @@ -0,0 +1,14 @@ +import { expectTypeOf, test } from 'vitest' + +import { useTransactionReceipt } from './useTransactionReceipt.js' + +test('select data', () => { + const result = useTransactionReceipt({ + query: { + select(data) { + return data?.blockNumber + }, + }, + }) + expectTypeOf(result.data.value).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/vue/src/composables/useTransactionReceipt.test.ts b/wagmi-project/packages/vue/src/composables/useTransactionReceipt.test.ts new file mode 100644 index 000000000..009267142 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useTransactionReceipt.test.ts @@ -0,0 +1,208 @@ +import { chain, wait } from '@wagmi/test' +import { renderComposable, waitFor } from '@wagmi/test/vue' +import { expect, test } from 'vitest' +import { ref } from 'vue' +import { deepUnref } from '../utils/cloneDeep.js' +import { useTransactionReceipt } from './useTransactionReceipt.js' + +test('default', async () => { + const [result] = renderComposable(() => + useTransactionReceipt({ + hash: '0xbf7d27700d053765c9638d3b9d39eb3c56bfc48377583e8be483d61f9f18a871', + }), + ) + + await waitFor(result.isSuccess) + + expect(deepUnref(result)).toMatchInlineSnapshot(` + { + "data": { + "blockHash": "0xb932f77cf770d1d1c8f861153eec1e990f5d56b6ffdb4ac06aef3cca51ef37d4", + "blockNumber": 16280769n, + "contractAddress": null, + "cumulativeGasUsed": 21000n, + "effectiveGasPrice": 33427926161n, + "from": "0x043022ef9fca1066024d19d681e2ccf44ff90de3", + "gasUsed": 21000n, + "logs": [], + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "status": "success", + "to": "0x318a5fb4f1604fc46375a1db9a9018b6e423b345", + "transactionHash": "0xbf7d27700d053765c9638d3b9d39eb3c56bfc48377583e8be483d61f9f18a871", + "transactionIndex": 0, + "type": "legacy", + }, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "getTransactionReceipt", + { + "chainId": 1, + "hash": "0xbf7d27700d053765c9638d3b9d39eb3c56bfc48377583e8be483d61f9f18a871", + }, + ], + "refetch": [Function], + "status": "success", + "suspense": [Function], + } + `) +}) + +test('parameters: chainId', async () => { + const [result] = renderComposable(() => + useTransactionReceipt({ + chainId: chain.mainnet2.id, + hash: '0xbf7d27700d053765c9638d3b9d39eb3c56bfc48377583e8be483d61f9f18a871', + }), + ) + + await waitFor(result.isSuccess) + + expect(deepUnref(result)).toMatchInlineSnapshot(` + { + "data": { + "blockHash": "0xb932f77cf770d1d1c8f861153eec1e990f5d56b6ffdb4ac06aef3cca51ef37d4", + "blockNumber": 16280769n, + "contractAddress": null, + "cumulativeGasUsed": 21000n, + "effectiveGasPrice": 33427926161n, + "from": "0x043022ef9fca1066024d19d681e2ccf44ff90de3", + "gasUsed": 21000n, + "logs": [], + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "status": "success", + "to": "0x318a5fb4f1604fc46375a1db9a9018b6e423b345", + "transactionHash": "0xbf7d27700d053765c9638d3b9d39eb3c56bfc48377583e8be483d61f9f18a871", + "transactionIndex": 0, + "type": "legacy", + }, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "getTransactionReceipt", + { + "chainId": 456, + "hash": "0xbf7d27700d053765c9638d3b9d39eb3c56bfc48377583e8be483d61f9f18a871", + }, + ], + "refetch": [Function], + "status": "success", + "suspense": [Function], + } + `) +}) + +test('behavior: hash: undefined -> defined', async () => { + const hash = ref() + + const [result] = renderComposable(() => + useTransactionReceipt({ + hash, + }), + ) + + await wait(100) + expect(result.fetchStatus.value).toBe('idle') + + hash.value = + '0xbf7d27700d053765c9638d3b9d39eb3c56bfc48377583e8be483d61f9f18a871' + + await waitFor(result.isSuccess) + + expect(deepUnref(result)).toMatchInlineSnapshot(` + { + "data": { + "blockHash": "0xb932f77cf770d1d1c8f861153eec1e990f5d56b6ffdb4ac06aef3cca51ef37d4", + "blockNumber": 16280769n, + "contractAddress": null, + "cumulativeGasUsed": 21000n, + "effectiveGasPrice": 33427926161n, + "from": "0x043022ef9fca1066024d19d681e2ccf44ff90de3", + "gasUsed": 21000n, + "logs": [], + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "status": "success", + "to": "0x318a5fb4f1604fc46375a1db9a9018b6e423b345", + "transactionHash": "0xbf7d27700d053765c9638d3b9d39eb3c56bfc48377583e8be483d61f9f18a871", + "transactionIndex": 0, + "type": "legacy", + }, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "getTransactionReceipt", + { + "chainId": 1, + "hash": undefined, + }, + ], + "refetch": [Function], + "status": "success", + "suspense": [Function], + } + `) +}) + +test('behavior: disabled when properties missing', async () => { + const [result] = renderComposable(() => useTransactionReceipt()) + + await wait(100) + expect(result.fetchStatus.value).toBe('idle') +}) diff --git a/wagmi-project/packages/vue/src/composables/useTransactionReceipt.ts b/wagmi-project/packages/vue/src/composables/useTransactionReceipt.ts new file mode 100644 index 000000000..cba5c232a --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useTransactionReceipt.ts @@ -0,0 +1,85 @@ +import type { + Config, + GetTransactionReceiptErrorType, + ResolvedRegister, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type GetTransactionReceiptData, + type GetTransactionReceiptOptions, + type GetTransactionReceiptQueryKey, + getTransactionReceiptQueryOptions, +} from '@wagmi/core/query' +import type { GetTransactionReceiptQueryFnData } from '@wagmi/core/query' + +import { computed } from 'vue' +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import type { DeepMaybeRef } from '../types/ref.js' +import { deepUnref } from '../utils/cloneDeep.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseTransactionReceiptParameters< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = GetTransactionReceiptData, +> = Compute< + DeepMaybeRef< + GetTransactionReceiptOptions & + ConfigParameter & + QueryParameter< + GetTransactionReceiptQueryFnData, + GetTransactionReceiptErrorType, + selectData, + GetTransactionReceiptQueryKey + > + > +> + +export type UseTransactionReceiptReturnType< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = GetTransactionReceiptData, +> = UseQueryReturnType + +/** https://wagmi.sh/vue/api/composables/useTransactionReceipt */ +export function useTransactionReceipt< + config extends Config = ResolvedRegister['config'], + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = GetTransactionReceiptData, +>( + parameters_: UseTransactionReceiptParameters< + config, + chainId, + selectData + > = {}, +): UseTransactionReceiptReturnType { + const parameters = computed(() => deepUnref(parameters_)) + + const config = useConfig(parameters) + const configChainId = useChainId({ config }) + + const queryOptions = computed(() => { + const { chainId = configChainId.value, hash, query = {} } = parameters.value + const options = getTransactionReceiptQueryOptions(config, { + ...parameters.value, + chainId, + }) + const enabled = Boolean(hash && (query.enabled ?? true)) + return { + ...(query as any), + ...options, + enabled, + } + }) + + return useQuery(queryOptions) as UseTransactionReceiptReturnType< + config, + chainId, + selectData + > +} diff --git a/wagmi-project/packages/vue/src/composables/useWaitForTransactionReceipt.test-d.ts b/wagmi-project/packages/vue/src/composables/useWaitForTransactionReceipt.test-d.ts new file mode 100644 index 000000000..aa5dcad64 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useWaitForTransactionReceipt.test-d.ts @@ -0,0 +1,14 @@ +import { expectTypeOf, test } from 'vitest' + +import { useWaitForTransactionReceipt } from './useWaitForTransactionReceipt.js' + +test('select data', () => { + const result = useWaitForTransactionReceipt({ + query: { + select(data) { + return data?.blockNumber + }, + }, + }) + expectTypeOf(result.data.value).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/vue/src/composables/useWaitForTransactionReceipt.test.ts b/wagmi-project/packages/vue/src/composables/useWaitForTransactionReceipt.test.ts new file mode 100644 index 000000000..3cfcbe0fe --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useWaitForTransactionReceipt.test.ts @@ -0,0 +1,46 @@ +import { renderComposable, waitFor } from '@wagmi/test/vue' +import { expect, test } from 'vitest' +import { wait } from '../../../test/src/utils.js' +import { useWaitForTransactionReceipt } from './useWaitForTransactionReceipt.js' + +test('default', async () => { + const [result] = renderComposable(() => + useWaitForTransactionReceipt({ + hash: '0x60668ed8c2dc110d61d945a936fcd45b8f13654e5c78481c8c825d1148c7ef30', + }), + ) + + await waitFor(result.isSuccess) + + expect(result.data.value).toMatchInlineSnapshot(` + { + "blockHash": "0xd725a38b51e5ceec8c5f6c9ccfdb2cc423af993bb650af5eedca5e4be7156ba7", + "blockNumber": 15189204n, + "chainId": 1, + "contractAddress": null, + "cumulativeGasUsed": 12949744n, + "effectiveGasPrice": 9371645552n, + "from": "0xa0cf798816d4b9b9866b5330eea46a18382f251e", + "gasUsed": 21000n, + "logs": [], + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "status": "success", + "to": "0xd2135cfb216b74109775236e36d4b433f1df507b", + "transactionHash": "0x60668ed8c2dc110d61d945a936fcd45b8f13654e5c78481c8c825d1148c7ef30", + "transactionIndex": 144, + "type": "eip1559", + } + `) +}) + +test('disabled when hash is undefined', async () => { + const [result] = renderComposable(() => + useWaitForTransactionReceipt({ + hash: undefined, + }), + ) + + await wait(100) + + expect(result.isPending.value).toBe(true) +}) diff --git a/wagmi-project/packages/vue/src/composables/useWaitForTransactionReceipt.ts b/wagmi-project/packages/vue/src/composables/useWaitForTransactionReceipt.ts new file mode 100644 index 000000000..6aea7d8e0 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useWaitForTransactionReceipt.ts @@ -0,0 +1,84 @@ +import type { + Config, + ResolvedRegister, + WaitForTransactionReceiptErrorType, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type WaitForTransactionReceiptData, + type WaitForTransactionReceiptOptions, + type WaitForTransactionReceiptQueryFnData, + type WaitForTransactionReceiptQueryKey, + waitForTransactionReceiptQueryOptions, +} from '@wagmi/core/query' +import { computed } from 'vue' + +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import type { DeepMaybeRef } from '../types/ref.js' +import { deepUnref } from '../utils/cloneDeep.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseWaitForTransactionReceiptParameters< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = WaitForTransactionReceiptData, +> = Compute< + DeepMaybeRef< + WaitForTransactionReceiptOptions & + ConfigParameter & + QueryParameter< + WaitForTransactionReceiptQueryFnData, + WaitForTransactionReceiptErrorType, + selectData, + WaitForTransactionReceiptQueryKey + > + > +> + +export type UseWaitForTransactionReceiptReturnType< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = WaitForTransactionReceiptData, +> = UseQueryReturnType + +/** https://wagmi.sh/vue/api/composables/useWaitForTransactionReceipt */ +export function useWaitForTransactionReceipt< + config extends Config = ResolvedRegister['config'], + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = WaitForTransactionReceiptData, +>( + parameters_: UseWaitForTransactionReceiptParameters< + config, + chainId, + selectData + > = {}, +): UseWaitForTransactionReceiptReturnType { + const parameters = computed(() => deepUnref(parameters_)) + const config = useConfig(parameters_) + const configChainId = useChainId() + + const queryOptions = computed(() => { + const { chainId = configChainId.value, hash, query = {} } = parameters.value + + const options = waitForTransactionReceiptQueryOptions(config, { + ...parameters.value, + chainId, + }) + const enabled = Boolean(hash && (query.enabled ?? true)) + + return { + ...query, + ...options, + enabled, + } + }) + + return useQuery( + queryOptions as any, + ) as UseWaitForTransactionReceiptReturnType +} diff --git a/wagmi-project/packages/vue/src/composables/useWatchBlockNumber.test-d.ts b/wagmi-project/packages/vue/src/composables/useWatchBlockNumber.test-d.ts new file mode 100644 index 000000000..6ab034716 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useWatchBlockNumber.test-d.ts @@ -0,0 +1,75 @@ +import { createConfig } from '@wagmi/core' +import { http, webSocket } from 'viem' +import { mainnet, optimism } from 'viem/chains' +import { expectTypeOf, test } from 'vitest' + +import type { DeepUnwrapRef } from '../types/ref.js' +import { + type UseWatchBlockNumberParameters, + useWatchBlockNumber, +} from './useWatchBlockNumber.js' + +test('default', () => { + useWatchBlockNumber({ + poll: false, + onBlockNumber() {}, + }) +}) + +test('differing transports', () => { + const config = createConfig({ + chains: [mainnet, optimism], + transports: { + [mainnet.id]: http(), + [optimism.id]: webSocket(), + }, + }) + + type Result = DeepUnwrapRef< + UseWatchBlockNumberParameters< + typeof config, + typeof mainnet.id | typeof optimism.id + > + > + expectTypeOf().toEqualTypeOf() + useWatchBlockNumber({ + config, + poll: false, + onBlockNumber() {}, + }) + + type Result2 = DeepUnwrapRef< + UseWatchBlockNumberParameters + > + expectTypeOf().toEqualTypeOf() + useWatchBlockNumber({ + config, + chainId: mainnet.id, + poll: true, + onBlockNumber() {}, + }) + useWatchBlockNumber({ + config, + chainId: mainnet.id, + // @ts-expect-error + poll: false, + onBlockNumber() {}, + }) + + type Result3 = DeepUnwrapRef< + UseWatchBlockNumberParameters + > + expectTypeOf().toEqualTypeOf() + useWatchBlockNumber({ + config, + chainId: optimism.id, + poll: true, + onBlockNumber() {}, + }) + useWatchBlockNumber({ + config, + chainId: optimism.id, + poll: false, + onBlockNumber() {}, + }) +}) diff --git a/wagmi-project/packages/vue/src/composables/useWatchBlockNumber.test.ts b/wagmi-project/packages/vue/src/composables/useWatchBlockNumber.test.ts new file mode 100644 index 000000000..1b074d766 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useWatchBlockNumber.test.ts @@ -0,0 +1,67 @@ +import { testClient, wait } from '@wagmi/test' +import { renderComposable } from '@wagmi/test/vue' +import { expect, test } from 'vitest' +import { ref } from 'vue' +import { useWatchBlockNumber } from './useWatchBlockNumber.js' + +test('default', async () => { + const blockNumbers: bigint[] = [] + renderComposable(() => + useWatchBlockNumber({ + onBlockNumber(blockNumber) { + blockNumbers.push(blockNumber) + }, + }), + ) + + await testClient.mainnet.mine({ blocks: 1 }) + await wait(100) + await testClient.mainnet.mine({ blocks: 1 }) + await wait(100) + await testClient.mainnet.mine({ blocks: 1 }) + await wait(100) + + expect(blockNumbers.length).toBe(3) + expect( + blockNumbers.map((blockNumber) => blockNumber - blockNumbers[0]!), + ).toEqual([0n, 1n, 2n]) +}) + +test('parameters: enabled', async () => { + const enabled = ref(true) + + const blockNumbers: bigint[] = [] + renderComposable(() => + useWatchBlockNumber({ + enabled, + onBlockNumber(blockNumber) { + blockNumbers.push(blockNumber) + }, + }), + ) + + await testClient.mainnet.mine({ blocks: 1 }) + await wait(100) + await testClient.mainnet.mine({ blocks: 1 }) + await wait(100) + await testClient.mainnet.mine({ blocks: 1 }) + await wait(100) + + expect(blockNumbers.length).toBe(3) + expect( + blockNumbers.map((blockNumber) => blockNumber - blockNumbers[0]!), + ).toEqual([0n, 1n, 2n]) + + enabled.value = false + + await testClient.mainnet.mine({ blocks: 1 }) + await wait(100) + await testClient.mainnet.mine({ blocks: 1 }) + await wait(100) + await testClient.mainnet.mine({ blocks: 1 }) + await wait(100) + + expect( + blockNumbers.map((blockNumber) => blockNumber - blockNumbers[0]!), + ).toEqual([0n, 1n, 2n]) +}) diff --git a/wagmi-project/packages/vue/src/composables/useWatchBlockNumber.ts b/wagmi-project/packages/vue/src/composables/useWatchBlockNumber.ts new file mode 100644 index 000000000..96dd437ec --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useWatchBlockNumber.ts @@ -0,0 +1,63 @@ +import { + type Config, + type ResolvedRegister, + type WatchBlockNumberParameters, + watchBlockNumber, +} from '@wagmi/core' +import type { UnionCompute, UnionExactPartial } from '@wagmi/core/internal' +import { computed, watchEffect } from 'vue' + +import type { ConfigParameter, EnabledParameter } from '../types/properties.js' +import type { DeepMaybeRef } from '../types/ref.js' +import { deepUnref } from '../utils/cloneDeep.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseWatchBlockNumberParameters< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +> = DeepMaybeRef< + UnionCompute< + UnionExactPartial> & + ConfigParameter & + EnabledParameter + > +> + +export type UseWatchBlockNumberReturnType = void + +/** https://wagmi.sh/vue/api/composables/useWatchBlockNumber */ +export function useWatchBlockNumber< + config extends Config = ResolvedRegister['config'], + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +>( + parameters_: UseWatchBlockNumberParameters = {} as any, +): UseWatchBlockNumberReturnType { + const parameters = computed(() => deepUnref(parameters_)) + + const config = useConfig(parameters) + const configChainId = useChainId({ config }) + + watchEffect((onCleanup) => { + const { + chainId = configChainId.value, + enabled = true, + onBlockNumber, + config: _, + ...rest + } = parameters.value + + if (!enabled) return + if (!onBlockNumber) return + + const unwatch = watchBlockNumber(config, { + ...(rest as any), + chainId, + onBlockNumber, + emitOnBegin: true, + }) + onCleanup(unwatch) + }) +} diff --git a/wagmi-project/packages/vue/src/composables/useWatchContractEvent.test-d.ts b/wagmi-project/packages/vue/src/composables/useWatchContractEvent.test-d.ts new file mode 100644 index 000000000..17568222d --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useWatchContractEvent.test-d.ts @@ -0,0 +1,126 @@ +import { http, createConfig, webSocket } from '@wagmi/core' +import { mainnet, optimism } from '@wagmi/core/chains' +import { abi } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' + +import { useWatchContractEvent } from './useWatchContractEvent.js' + +test('default', () => { + useWatchContractEvent({ + address: '0x', + abi: abi.erc20, + eventName: 'Transfer', + poll: false, + args: { + from: '0x', + to: '0x', + }, + onLogs(logs) { + expectTypeOf(logs[0]!.eventName).toEqualTypeOf<'Transfer'>() + expectTypeOf(logs[0]!.args).toEqualTypeOf<{ + from?: `0x${string}` | undefined + to?: `0x${string}` | undefined + value?: bigint | undefined + }>() + }, + }) +}) + +test('behavior: no eventName', () => { + useWatchContractEvent({ + address: '0x', + abi: abi.erc20, + args: { + // TODO: Figure out why this is not working + // @ts-ignore + from: '0x', + to: '0x', + }, + onLogs(logs) { + expectTypeOf(logs[0]!.eventName).toEqualTypeOf<'Transfer' | 'Approval'>() + expectTypeOf(logs[0]!.args).toEqualTypeOf< + | Record + | readonly unknown[] + | { + from?: `0x${string}` | undefined + to?: `0x${string}` | undefined + value?: bigint | undefined + } + | { + owner?: `0x${string}` | undefined + spender?: `0x${string}` | undefined + value?: bigint | undefined + } + >() + }, + }) +}) + +test('differing transports', () => { + const config = createConfig({ + chains: [mainnet, optimism], + transports: { + [mainnet.id]: http(), + [optimism.id]: webSocket(), + }, + }) + + // TODO: Fix inference for `poll` (`DeepMaybeRef` wrapping `UseWatchContractEventParameters` not working as expected) + // type Result = UseWatchContractEventParameters< + // typeof abi.erc20, + // 'Transfer' | 'Approval', + // true, + // typeof config, + // typeof mainnet.id | typeof optimism.id + // > + // expectTypeOf().toEqualTypeOf() + useWatchContractEvent({ + config, + poll: false, + address: '0x', + abi: abi.erc20, + onLogs() {}, + }) + + // type Result2 = UseWatchContractEventParameters< + // typeof abi.erc20, + // 'Transfer' | 'Approval', + // true, + // typeof config, + // typeof mainnet.id + // > + // expectTypeOf().toEqualTypeOf() + useWatchContractEvent({ + config, + chainId: mainnet.id, + poll: true, + address: '0x', + abi: abi.erc20, + onLogs() {}, + }) + + // type Result3 = UseWatchContractEventParameters< + // typeof abi.erc20, + // 'Transfer' | 'Approval', + // true, + // typeof config, + // typeof optimism.id + // > + // expectTypeOf().toEqualTypeOf() + useWatchContractEvent({ + config, + chainId: optimism.id, + poll: true, + address: '0x', + abi: abi.erc20, + onLogs() {}, + }) + useWatchContractEvent({ + config, + chainId: optimism.id, + poll: false, + address: '0x', + abi: abi.erc20, + onLogs() {}, + }) +}) diff --git a/wagmi-project/packages/vue/src/composables/useWatchContractEvent.test.ts b/wagmi-project/packages/vue/src/composables/useWatchContractEvent.test.ts new file mode 100644 index 000000000..968c46d0c --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useWatchContractEvent.test.ts @@ -0,0 +1,106 @@ +import { connect, disconnect, getBalance, writeContract } from '@wagmi/core' +import { + abi, + accounts, + address, + config, + testClient, + transactionHashRegex, + wait, +} from '@wagmi/test' +import { renderComposable } from '@wagmi/test/vue' +import { http, createWalletClient, parseEther } from 'viem' +import type { WatchEventOnLogsParameter } from 'viem/actions' +import { expect, test } from 'vitest' + +import { ref } from 'vue' +import { useWatchContractEvent } from './useWatchContractEvent.js' + +const connector = config.connectors[0]! + +test('default', async () => { + const data = await connect(config, { connector }) + const connectedAddress = data.accounts[0] + + // impersonate usdc holder account and transfer usdc to connected account + await testClient.mainnet.impersonateAccount({ address: address.usdcHolder }) + await testClient.mainnet.setBalance({ + address: address.usdcHolder, + value: 10000000000000000000000n, + }) + await createWalletClient({ + account: address.usdcHolder, + chain: testClient.mainnet.chain, + transport: http(), + }).writeContract({ + address: address.usdc, + abi: abi.erc20, + functionName: 'transfer', + args: [connectedAddress, parseEther('10', 'gwei')], + }) + await testClient.mainnet.mine({ blocks: 1 }) + await testClient.mainnet.stopImpersonatingAccount({ + address: address.usdcHolder, + }) + + const balance = await getBalance(config, { + address: connectedAddress, + token: address.usdc, + }) + expect(balance.value).toBeGreaterThan(0n) + + // start watching transfer events + let logs: WatchEventOnLogsParameter = [] + renderComposable(() => + useWatchContractEvent({ + address: address.usdc, + abi: abi.erc20, + eventName: 'Transfer', + onLogs(next) { + logs = logs.concat(next) + }, + }), + ) + + await writeContract(config, { + address: address.usdc, + abi: abi.erc20, + functionName: 'transfer', + args: [accounts[1], parseEther('1', 'gwei')], + }) + + await writeContract(config, { + address: address.usdc, + abi: abi.erc20, + functionName: 'transfer', + args: [accounts[3], parseEther('1', 'gwei')], + }) + + await testClient.mainnet.mine({ blocks: 1 }) + await wait(100) + await testClient.mainnet.mine({ blocks: 1 }) + await wait(100) + + expect(logs.length).toBe(2) + expect(logs[0]?.transactionHash).toMatch(transactionHashRegex) + + await disconnect(config, { connector }) +}) + +test('parameters: enabled', async () => { + const enabled = ref(true) + + renderComposable(() => + useWatchContractEvent({ + address: address.usdc, + abi: abi.erc20, + eventName: 'Transfer', + }), + ) + + renderComposable(() => + useWatchContractEvent({ + enabled, + }), + ) +}) diff --git a/wagmi-project/packages/vue/src/composables/useWatchContractEvent.ts b/wagmi-project/packages/vue/src/composables/useWatchContractEvent.ts new file mode 100644 index 000000000..ffd988b40 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useWatchContractEvent.ts @@ -0,0 +1,77 @@ +import { + type Config, + type ResolvedRegister, + type WatchContractEventParameters, + watchContractEvent, +} from '@wagmi/core' +import type { UnionCompute, UnionExactPartial } from '@wagmi/core/internal' +import type { Abi, ContractEventName } from 'viem' +import { computed, watchEffect } from 'vue' + +import type { ConfigParameter, EnabledParameter } from '../types/properties.js' +import type { DeepMaybeRef } from '../types/ref.js' +import { deepUnref } from '../utils/cloneDeep.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseWatchContractEventParameters< + abi extends Abi | readonly unknown[] = Abi, + eventName extends ContractEventName = ContractEventName, + strict extends boolean | undefined = undefined, + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +> = DeepMaybeRef< + UnionCompute< + UnionExactPartial< + WatchContractEventParameters + > & + ConfigParameter & + EnabledParameter + > +> + +export type UseWatchContractEventReturnType = void + +/** https://wagmi.sh/vue/api/composables/useWatchContractEvent */ +export function useWatchContractEvent< + const abi extends Abi | readonly unknown[], + eventName extends ContractEventName, + strict extends boolean | undefined = undefined, + config extends Config = ResolvedRegister['config'], + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +>( + parameters: UseWatchContractEventParameters< + abi, + eventName, + strict, + config, + chainId + > = {} as any, +): UseWatchContractEventReturnType { + const parameters_ = computed(() => deepUnref(parameters)) + + const config = useConfig(parameters_) + const configChainId = useChainId({ config }) + + watchEffect((onCleanup) => { + const { + chainId = configChainId.value, + enabled = true, + onLogs, + config: _, + ...rest + } = parameters_.value + + if (!enabled) return + if (!onLogs) return + + const unwatch = watchContractEvent(config, { + ...(rest as any), + chainId, + onLogs, + }) + onCleanup(unwatch) + }) +} diff --git a/wagmi-project/packages/vue/src/composables/useWriteContract.test-d.ts b/wagmi-project/packages/vue/src/composables/useWriteContract.test-d.ts new file mode 100644 index 000000000..33a9b1434 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useWriteContract.test-d.ts @@ -0,0 +1,136 @@ +import type { WriteContractErrorType } from '@wagmi/core' +import { abi } from '@wagmi/test' +import type { Abi, Address, Hash } from 'viem' +import { expectTypeOf, test } from 'vitest' + +import { useSimulateContract } from './useSimulateContract.js' +import { useWriteContract } from './useWriteContract.js' + +const contextValue = { foo: 'bar' } as const + +test('context', () => { + const { + context, + data, + error, + writeContract: write, + variables, + } = useWriteContract({ + mutation: { + onMutate(variables) { + expectTypeOf(variables).toMatchTypeOf<{ + chainId?: number | undefined + abi: Abi + functionName: string + args?: readonly unknown[] | undefined + }>() + return contextValue + }, + onError(error, variables, context) { + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + + expectTypeOf(variables).toMatchTypeOf<{ + chainId?: number | undefined + abi: Abi + functionName: string + args?: readonly unknown[] | undefined + }>() + }, + onSuccess(data, variables, context) { + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + + expectTypeOf(variables).toMatchTypeOf<{ + chainId?: number | undefined + abi: Abi + functionName: string + args?: readonly unknown[] | undefined + }>() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + + expectTypeOf(variables).toMatchTypeOf<{ + chainId?: number | undefined + abi: Abi + functionName: string + args?: readonly unknown[] | undefined + }>() + }, + }, + }) + + expectTypeOf(data.value).toEqualTypeOf() + expectTypeOf(error.value).toEqualTypeOf() + expectTypeOf(variables.value).toMatchTypeOf< + { chainId?: number | undefined } | undefined + >() + expectTypeOf(context.value).toEqualTypeOf() + + write( + { + address: '0x', + abi: abi.erc20, + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + chainId: 1, + }, + { + onError(error, variables, context) { + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + + expectTypeOf(variables).toMatchTypeOf<{ + chainId?: number | undefined + abi: typeof abi.erc20 + functionName: 'transferFrom' + args: readonly [Address, Address, bigint] + }>() + }, + onSuccess(data, variables, context) { + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + + expectTypeOf(variables.functionName).toEqualTypeOf<'transferFrom'>() + expectTypeOf(variables.args).toEqualTypeOf< + readonly [Address, Address, bigint] + >() + expectTypeOf(variables).toMatchTypeOf<{ + chainId?: number | undefined + abi: typeof abi.erc20 + functionName: 'transferFrom' + args: readonly [Address, Address, bigint] + }>() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + + expectTypeOf(variables).toMatchTypeOf<{ + chainId?: number | undefined + abi: typeof abi.erc20 + functionName: 'transferFrom' + args: readonly [Address, Address, bigint] + }>() + }, + }, + ) +}) + +test('useSimulateContract', () => { + const { data } = useSimulateContract({ + address: '0x', + abi: abi.erc20, + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + chainId: 1, + }) + const { writeContract } = useWriteContract() + + const request = data?.value?.request + if (request) writeContract(request) +}) diff --git a/wagmi-project/packages/vue/src/composables/useWriteContract.test.ts b/wagmi-project/packages/vue/src/composables/useWriteContract.test.ts new file mode 100644 index 000000000..ba7c8cb4c --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useWriteContract.test.ts @@ -0,0 +1,25 @@ +import { connect, disconnect } from '@wagmi/core' +import { abi, address, config } from '@wagmi/test' +import { renderComposable, waitFor } from '@wagmi/test/vue' +import { expect, test } from 'vitest' + +import { useWriteContract } from './useWriteContract.js' + +const connector = config.connectors[0]! + +test('default', async () => { + await connect(config, { connector }) + + const [result] = renderComposable(() => useWriteContract()) + + result.writeContract({ + abi: abi.wagmiMintExample, + address: address.wagmiMintExample, + functionName: 'mint', + }) + await waitFor(result.isSuccess) + + expect(result.data.value).toBeDefined() + + await disconnect(config, { connector }) +}) diff --git a/wagmi-project/packages/vue/src/composables/useWriteContract.ts b/wagmi-project/packages/vue/src/composables/useWriteContract.ts new file mode 100644 index 000000000..21ac3a82d --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useWriteContract.ts @@ -0,0 +1,85 @@ +import { useMutation } from '@tanstack/vue-query' +import type { + Config, + ResolvedRegister, + WriteContractErrorType, +} from '@wagmi/core' +import { + type WriteContractData, + type WriteContractMutate, + type WriteContractMutateAsync, + type WriteContractVariables, + writeContractMutationOptions, +} from '@wagmi/core/query' +import type { Abi } from 'viem' + +import type { ConfigParameter } from '../types/properties.js' +import type { + UseMutationParameters, + UseMutationReturnType, +} from '../utils/query.js' +import { useConfig } from './useConfig.js' + +export type UseWriteContractParameters< + config extends Config = Config, + context = unknown, +> = ConfigParameter & { + mutation?: + | UseMutationParameters< + WriteContractData, + WriteContractErrorType, + WriteContractVariables< + Abi, + string, + readonly unknown[], + config, + config['chains'][number]['id'] + >, + context + > + | undefined +} + +export type UseWriteContractReturnType< + config extends Config = Config, + context = unknown, +> = UseMutationReturnType< + WriteContractData, + WriteContractErrorType, + WriteContractVariables< + Abi, + string, + readonly unknown[], + config, + config['chains'][number]['id'] + >, + context +> & { + writeContract: WriteContractMutate + writeContractAsync: WriteContractMutateAsync +} + +/** https://wagmi.sh/vue/api/composables/useWriteContract */ +export function useWriteContract< + config extends Config = ResolvedRegister['config'], + context = unknown, +>( + parameters: UseWriteContractParameters = {}, +): UseWriteContractReturnType { + const { mutation } = parameters + + const config = useConfig(parameters) + + const mutationOptions = writeContractMutationOptions(config) + const { mutate, mutateAsync, ...result } = useMutation({ + ...mutation, + ...mutationOptions, + }) + + type Return = UseWriteContractReturnType + return { + ...result, + writeContract: mutate as Return['writeContract'], + writeContractAsync: mutateAsync as Return['writeContractAsync'], + } +} diff --git a/wagmi-project/packages/vue/src/errors/base.test.ts b/wagmi-project/packages/vue/src/errors/base.test.ts new file mode 100644 index 000000000..3457d4be1 --- /dev/null +++ b/wagmi-project/packages/vue/src/errors/base.test.ts @@ -0,0 +1,155 @@ +import { expect, test } from 'vitest' + +import { BaseError } from './base.js' + +test('BaseError', () => { + expect(new BaseError('An error occurred.')).toMatchInlineSnapshot(` + [WagmiError: An error occurred. + + Version: @wagmi/vue@x.y.z] + `) + + expect( + new BaseError('An error occurred.', { details: 'details' }), + ).toMatchInlineSnapshot(` + [WagmiError: An error occurred. + + Details: details + Version: @wagmi/vue@x.y.z] + `) + + expect(new BaseError('', { details: 'details' })).toMatchInlineSnapshot(` + [WagmiError: An error occurred. + + Details: details + Version: @wagmi/vue@x.y.z] + `) +}) + +test('BaseError (w/ docsPath)', () => { + expect( + new BaseError('An error occurred.', { + details: 'details', + docsPath: '/lol', + }), + ).toMatchInlineSnapshot(` + [WagmiError: An error occurred. + + Docs: https://wagmi.sh/vue/lol.html + Details: details + Version: @wagmi/vue@x.y.z] + `) + expect( + new BaseError('An error occurred.', { + cause: new BaseError('error', { docsPath: '/docs' }), + }), + ).toMatchInlineSnapshot(` + [WagmiError: An error occurred. + + Docs: https://wagmi.sh/vue/docs.html + Version: @wagmi/vue@x.y.z] + `) + expect( + new BaseError('An error occurred.', { + cause: new BaseError('error'), + docsPath: '/lol', + }), + ).toMatchInlineSnapshot(` + [WagmiError: An error occurred. + + Docs: https://wagmi.sh/vue/lol.html + Version: @wagmi/vue@x.y.z] + `) + expect( + new BaseError('An error occurred.', { + details: 'details', + docsPath: '/lol', + docsSlug: 'test', + }), + ).toMatchInlineSnapshot(` + [WagmiError: An error occurred. + + Docs: https://wagmi.sh/vue/lol.html#test + Details: details + Version: @wagmi/vue@x.y.z] + `) +}) + +test('BaseError (w/ metaMessages)', () => { + expect( + new BaseError('An error occurred.', { + details: 'details', + metaMessages: ['Reason: idk', 'Cause: lol'], + }), + ).toMatchInlineSnapshot(` + [WagmiError: An error occurred. + + Reason: idk + Cause: lol + + Details: details + Version: @wagmi/vue@x.y.z] + `) +}) + +test('inherited BaseError', () => { + const err = new BaseError('An error occurred.', { + details: 'details', + docsPath: '/lol', + }) + expect( + new BaseError('An internal error occurred.', { + cause: err, + }), + ).toMatchInlineSnapshot(` + [WagmiError: An internal error occurred. + + Docs: https://wagmi.sh/vue/lol.html + Details: details + Version: @wagmi/vue@x.y.z] + `) +}) + +test('inherited Error', () => { + const err = new Error('details') + expect( + new BaseError('An internal error occurred.', { + cause: err, + docsPath: '/lol', + }), + ).toMatchInlineSnapshot(` + [WagmiError: An internal error occurred. + + Docs: https://wagmi.sh/vue/lol.html + Details: details + Version: @wagmi/vue@x.y.z] + `) +}) + +test('walk: no predicate fn (walks to leaf)', () => { + class FooError extends BaseError {} + class BarError extends BaseError {} + + const err = new BaseError('test1', { + cause: new FooError('test2', { cause: new BarError('test3') }), + }) + expect(err.walk()).toMatchInlineSnapshot(` + [WagmiError: test3 + + Version: @wagmi/vue@x.y.z] + `) +}) + +test('walk: predicate fn', () => { + class FooError extends BaseError {} + class BarError extends BaseError {} + + const err = new BaseError('test1', { + cause: new FooError('test2', { cause: new BarError('test3') }), + }) + expect(err.walk((err) => err instanceof FooError)).toMatchInlineSnapshot(` + [WagmiError: test2 + + Version: @wagmi/vue@x.y.z] + `) +}) diff --git a/wagmi-project/packages/vue/src/errors/base.ts b/wagmi-project/packages/vue/src/errors/base.ts new file mode 100644 index 000000000..bb65ac5fe --- /dev/null +++ b/wagmi-project/packages/vue/src/errors/base.ts @@ -0,0 +1,14 @@ +import { BaseError as CoreError } from '@wagmi/core' + +import { getVersion } from '../utils/getVersion.js' + +export type BaseErrorType = BaseError & { name: 'WagmiError' } +export class BaseError extends CoreError { + override name = 'WagmiError' + override get docsBaseUrl() { + return 'https://wagmi.sh/vue' + } + override get version() { + return getVersion() + } +} diff --git a/wagmi-project/packages/vue/src/errors/plugin.test.ts b/wagmi-project/packages/vue/src/errors/plugin.test.ts new file mode 100644 index 000000000..64ff3acda --- /dev/null +++ b/wagmi-project/packages/vue/src/errors/plugin.test.ts @@ -0,0 +1,24 @@ +import { expect, test } from 'vitest' + +import { + WagmiInjectionContextError, + WagmiPluginNotFoundError, +} from './plugin.js' + +test('WagmiPluginNotFoundError', () => { + expect(new WagmiPluginNotFoundError()).toMatchInlineSnapshot(` + [WagmiPluginNotFoundError: No \`config\` found in Vue context, use \`WagmiPlugin\` to properly initialize the library. + + Docs: https://wagmi.sh/vue/api/TODO.html + Version: @wagmi/vue@x.y.z] + `) +}) + +test('WagmiInjectionContextError', () => { + expect(new WagmiInjectionContextError()).toMatchInlineSnapshot(` + [WagmiInjectionContextError: Wagmi composables can only be used inside \`setup()\` function or functions that support injection context. + + Docs: https://wagmi.sh/vue/api/TODO.html + Version: @wagmi/vue@x.y.z] + `) +}) diff --git a/wagmi-project/packages/vue/src/errors/plugin.ts b/wagmi-project/packages/vue/src/errors/plugin.ts new file mode 100644 index 000000000..bed7cda47 --- /dev/null +++ b/wagmi-project/packages/vue/src/errors/plugin.ts @@ -0,0 +1,31 @@ +import { BaseError } from './base.js' + +export type WagmiPluginNotFoundErrorType = WagmiPluginNotFoundError & { + name: 'WagmiPluginNotFoundError' +} +export class WagmiPluginNotFoundError extends BaseError { + override name = 'WagmiPluginNotFoundError' + constructor() { + super( + 'No `config` found in Vue context, use `WagmiPlugin` to properly initialize the library.', + { + docsPath: '/api/TODO', + }, + ) + } +} + +export type WagmiInjectionContextErrorType = WagmiInjectionContextError & { + name: 'WagmiInjectionContextError' +} +export class WagmiInjectionContextError extends BaseError { + override name = 'WagmiInjectionContextError' + constructor() { + super( + 'Wagmi composables can only be used inside `setup()` function or functions that support injection context.', + { + docsPath: '/api/TODO', + }, + ) + } +} diff --git a/wagmi-project/packages/vue/src/exports/actions.test.ts b/wagmi-project/packages/vue/src/exports/actions.test.ts new file mode 100644 index 000000000..eaaedba14 --- /dev/null +++ b/wagmi-project/packages/vue/src/exports/actions.test.ts @@ -0,0 +1,86 @@ +import { expect, test } from 'vitest' + +import * as actions from './actions.js' + +test('exports', () => { + expect(Object.keys(actions)).toMatchInlineSnapshot(` + [ + "call", + "connect", + "deployContract", + "disconnect", + "estimateGas", + "estimateFeesPerGas", + "estimateMaxPriorityFeePerGas", + "getAccount", + "getBalance", + "fetchBalance", + "getBlock", + "getBlockNumber", + "fetchBlockNumber", + "getBlockTransactionCount", + "getBytecode", + "getCallsStatus", + "getCapabilities", + "getChainId", + "getChains", + "getClient", + "getConnections", + "getConnectors", + "getConnectorClient", + "getEnsAddress", + "fetchEnsAddress", + "getEnsAvatar", + "fetchEnsAvatar", + "getEnsName", + "fetchEnsName", + "getEnsResolver", + "fetchEnsResolver", + "getEnsText", + "getFeeHistory", + "getGasPrice", + "getProof", + "getPublicClient", + "getStorageAt", + "getToken", + "fetchToken", + "getTransaction", + "fetchTransaction", + "getTransactionConfirmations", + "getTransactionCount", + "getTransactionReceipt", + "getWalletClient", + "multicall", + "prepareTransactionRequest", + "readContract", + "readContracts", + "reconnect", + "sendCalls", + "sendTransaction", + "showCallsStatus", + "signMessage", + "signTypedData", + "simulateContract", + "switchAccount", + "switchChain", + "switchNetwork", + "verifyMessage", + "verifyTypedData", + "waitForCallsStatus", + "watchAccount", + "watchAsset", + "watchBlocks", + "watchBlockNumber", + "watchChainId", + "watchClient", + "watchConnections", + "watchConnectors", + "watchContractEvent", + "watchPendingTransactions", + "watchPublicClient", + "waitForTransactionReceipt", + "waitForTransaction", + "writeContract", + ] + `) +}) diff --git a/wagmi-project/packages/vue/src/exports/actions.ts b/wagmi-project/packages/vue/src/exports/actions.ts new file mode 100644 index 000000000..3ff9c743c --- /dev/null +++ b/wagmi-project/packages/vue/src/exports/actions.ts @@ -0,0 +1,7 @@ +//////////////////////////////////////////////////////////////////////////////// +// @wagmi/core/actions +//////////////////////////////////////////////////////////////////////////////// + +// biome-ignore lint/performance/noBarrelFile: entrypoint module +// biome-ignore lint/performance/noReExportAll: entrypoint module +export * from '@wagmi/core/actions' diff --git a/wagmi-project/packages/vue/src/exports/actions/experimental.test.ts b/wagmi-project/packages/vue/src/exports/actions/experimental.test.ts new file mode 100644 index 000000000..7c4b92df8 --- /dev/null +++ b/wagmi-project/packages/vue/src/exports/actions/experimental.test.ts @@ -0,0 +1,25 @@ +import { expect, test } from 'vitest' + +import * as experimentalActions from './experimental.js' + +test('exports', () => { + expect(Object.keys(experimentalActions)).toMatchInlineSnapshot(` + [ + "getCallsStatus", + "getCapabilities", + "sendCalls", + "showCallsStatus", + "waitForCallsStatus", + "writeContracts", + "getCallsStatusQueryOptions", + "getCallsStatusQueryKey", + "getCapabilitiesQueryOptions", + "getCapabilitiesQueryKey", + "sendCallsMutationOptions", + "showCallsStatusMutationOptions", + "waitForCallsStatusQueryKey", + "waitForCallsStatusQueryOptions", + "writeContractsMutationOptions", + ] + `) +}) diff --git a/wagmi-project/packages/vue/src/exports/actions/experimental.ts b/wagmi-project/packages/vue/src/exports/actions/experimental.ts new file mode 100644 index 000000000..6ee0334af --- /dev/null +++ b/wagmi-project/packages/vue/src/exports/actions/experimental.ts @@ -0,0 +1,7 @@ +//////////////////////////////////////////////////////////////////////////////// +// @wagmi/core/experimental +//////////////////////////////////////////////////////////////////////////////// + +// biome-ignore lint/performance/noBarrelFile: entrypoint module +// biome-ignore lint/performance/noReExportAll: entrypoint module +export * from '@wagmi/core/experimental' diff --git a/wagmi-project/packages/vue/src/exports/chains.ts b/wagmi-project/packages/vue/src/exports/chains.ts new file mode 100644 index 000000000..1fca7f537 --- /dev/null +++ b/wagmi-project/packages/vue/src/exports/chains.ts @@ -0,0 +1,7 @@ +//////////////////////////////////////////////////////////////////////////////// +// viem/chains +//////////////////////////////////////////////////////////////////////////////// + +// biome-ignore lint/performance/noBarrelFile: entrypoint module +// biome-ignore lint/performance/noReExportAll: entrypoint module +export * from 'viem/chains' diff --git a/wagmi-project/packages/vue/src/exports/connectors.test.ts b/wagmi-project/packages/vue/src/exports/connectors.test.ts new file mode 100644 index 000000000..068db8227 --- /dev/null +++ b/wagmi-project/packages/vue/src/exports/connectors.test.ts @@ -0,0 +1,17 @@ +import { expect, test } from 'vitest' + +import * as connectors from './connectors.js' + +test('exports', () => { + expect(Object.keys(connectors)).toMatchInlineSnapshot(` + [ + "injected", + "mock", + "coinbaseWallet", + "metaMask", + "safe", + "walletConnect", + "version", + ] + `) +}) diff --git a/wagmi-project/packages/vue/src/exports/connectors.ts b/wagmi-project/packages/vue/src/exports/connectors.ts new file mode 100644 index 000000000..e10367e31 --- /dev/null +++ b/wagmi-project/packages/vue/src/exports/connectors.ts @@ -0,0 +1,7 @@ +//////////////////////////////////////////////////////////////////////////////// +// @wagmi/connectors +//////////////////////////////////////////////////////////////////////////////// + +// biome-ignore lint/performance/noBarrelFile: entrypoint module +// biome-ignore lint/performance/noReExportAll: entrypoint module +export * from '@wagmi/connectors' diff --git a/wagmi-project/packages/vue/src/exports/index.test.ts b/wagmi-project/packages/vue/src/exports/index.test.ts new file mode 100644 index 000000000..bb8fb0a1b --- /dev/null +++ b/wagmi-project/packages/vue/src/exports/index.test.ts @@ -0,0 +1,74 @@ +import { expect, test } from 'vitest' + +import * as vue from './index.js' + +test('exports', () => { + expect(Object.keys(vue)).toMatchInlineSnapshot(` + [ + "configKey", + "WagmiPlugin", + "BaseError", + "WagmiPluginNotFoundError", + "WagmiInjectionContextError", + "useAccount", + "useAccountEffect", + "useBalance", + "useBlockNumber", + "useBytecode", + "useChainId", + "useClient", + "useConnectorClient", + "useChains", + "useConfig", + "useConnect", + "useConnections", + "useConnectors", + "useDisconnect", + "useEnsAddress", + "useEnsAvatar", + "useEnsName", + "useEstimateGas", + "useReadContract", + "useReconnect", + "useSendTransaction", + "useSignMessage", + "useSignTypedData", + "useSimulateContract", + "useSwitchAccount", + "useSwitchChain", + "useTransaction", + "useTransactionReceipt", + "useWatchBlockNumber", + "useWatchContractEvent", + "useWaitForTransactionReceipt", + "useWriteContract", + "createConfig", + "createConnector", + "injected", + "mock", + "ChainNotConfiguredError", + "ConnectorAlreadyConnectedError", + "ConnectorNotFoundError", + "ConnectorAccountNotFoundError", + "ConnectorChainMismatchError", + "ConnectorUnavailableReconnectingError", + "ProviderNotFoundError", + "SwitchChainNotSupportedError", + "createStorage", + "noopStorage", + "custom", + "fallback", + "http", + "webSocket", + "unstable_connector", + "cookieStorage", + "cookieToInitialState", + "deepEqual", + "deserialize", + "normalizeChainId", + "parseCookie", + "serialize", + "version", + ] + `) +}) diff --git a/wagmi-project/packages/vue/src/exports/index.ts b/wagmi-project/packages/vue/src/exports/index.ts new file mode 100644 index 000000000..e7267878c --- /dev/null +++ b/wagmi-project/packages/vue/src/exports/index.ts @@ -0,0 +1,280 @@ +//////////////////////////////////////////////////////////////////////////////// +// Plugin +//////////////////////////////////////////////////////////////////////////////// + +// biome-ignore lint/performance/noBarrelFile: entrypoint module +export { configKey, type WagmiPluginOptions, WagmiPlugin } from '../plugin.js' + +//////////////////////////////////////////////////////////////////////////////// +// Errors +//////////////////////////////////////////////////////////////////////////////// + +export { type BaseErrorType, BaseError } from '../errors/base.js' + +export { + type WagmiPluginNotFoundErrorType, + WagmiPluginNotFoundError, + type WagmiInjectionContextErrorType, + WagmiInjectionContextError, +} from '../errors/plugin.js' + +//////////////////////////////////////////////////////////////////////////////// +// Composables +//////////////////////////////////////////////////////////////////////////////// + +export { + type UseAccountParameters, + type UseAccountReturnType, + useAccount, +} from '../composables/useAccount.js' + +export { + type UseAccountEffectParameters, + useAccountEffect, +} from '../composables/useAccountEffect.js' + +export { + type UseBalanceParameters, + type UseBalanceReturnType, + useBalance, +} from '../composables/useBalance.js' + +export { + type UseBlockNumberParameters, + type UseBlockNumberReturnType, + useBlockNumber, +} from '../composables/useBlockNumber.js' + +export { + type UseBytecodeParameters, + type UseBytecodeReturnType, + useBytecode, +} from '../composables/useBytecode.js' + +export { + type UseChainIdParameters, + type UseChainIdReturnType, + useChainId, +} from '../composables/useChainId.js' + +export { + type UseClientParameters, + type UseClientReturnType, + useClient, +} from '../composables/useClient.js' + +export { + type UseConnectorClientParameters, + type UseConnectorClientReturnType, + useConnectorClient, +} from '../composables/useConnectorClient.js' + +export { + type UseChainsParameters, + type UseChainsReturnType, + useChains, +} from '../composables/useChains.js' + +export { + type UseConfigParameters, + type UseConfigReturnType, + useConfig, +} from '../composables/useConfig.js' + +export { + type UseConnectParameters, + type UseConnectReturnType, + useConnect, +} from '../composables/useConnect.js' + +export { + type UseConnectionsParameters, + type UseConnectionsReturnType, + useConnections, +} from '../composables/useConnections.js' + +export { + type UseConnectorsParameters, + type UseConnectorsReturnType, + useConnectors, +} from '../composables/useConnectors.js' + +export { + type UseDisconnectParameters, + type UseDisconnectReturnType, + useDisconnect, +} from '../composables/useDisconnect.js' + +export { + type UseEnsAddressParameters, + type UseEnsAddressReturnType, + useEnsAddress, +} from '../composables/useEnsAddress.js' + +export { + type UseEnsAvatarParameters, + type UseEnsAvatarReturnType, + useEnsAvatar, +} from '../composables/useEnsAvatar.js' + +export { + type UseEnsNameParameters, + type UseEnsNameReturnType, + useEnsName, +} from '../composables/useEnsName.js' + +export { + type UseEstimateGasParameters, + type UseEstimateGasReturnType, + useEstimateGas, +} from '../composables/useEstimateGas.js' + +export { + type UseReadContractParameters, + type UseReadContractReturnType, + useReadContract, +} from '../composables/useReadContract.js' + +export { + type UseReconnectParameters, + type UseReconnectReturnType, + useReconnect, +} from '../composables/useReconnect.js' + +export { + type UseSendTransactionParameters, + type UseSendTransactionReturnType, + useSendTransaction, +} from '../composables/useSendTransaction.js' + +export { + type UseSignMessageParameters, + type UseSignMessageReturnType, + useSignMessage, +} from '../composables/useSignMessage.js' + +export { + type UseSignTypedDataParameters, + type UseSignTypedDataReturnType, + useSignTypedData, +} from '../composables/useSignTypedData.js' + +export { + type UseSimulateContractParameters, + type UseSimulateContractReturnType, + useSimulateContract, +} from '../composables/useSimulateContract.js' + +export { + type UseSwitchAccountParameters, + type UseSwitchAccountReturnType, + useSwitchAccount, +} from '../composables/useSwitchAccount.js' + +export { + type UseSwitchChainParameters, + type UseSwitchChainReturnType, + useSwitchChain, +} from '../composables/useSwitchChain.js' + +export { + type UseTransactionParameters, + type UseTransactionReturnType, + useTransaction, +} from '../composables/useTransaction.js' + +export { + type UseTransactionReceiptParameters, + type UseTransactionReceiptReturnType, + useTransactionReceipt, +} from '../composables/useTransactionReceipt.js' + +export { + type UseWatchBlockNumberParameters, + type UseWatchBlockNumberReturnType, + useWatchBlockNumber, +} from '../composables/useWatchBlockNumber.js' + +export { + type UseWatchContractEventParameters, + type UseWatchContractEventReturnType, + useWatchContractEvent, +} from '../composables/useWatchContractEvent.js' + +export { + type UseWaitForTransactionReceiptParameters, + type UseWaitForTransactionReceiptReturnType, + useWaitForTransactionReceipt, +} from '../composables/useWaitForTransactionReceipt.js' + +export { + type UseWriteContractParameters, + type UseWriteContractReturnType, + useWriteContract, +} from '../composables/useWriteContract.js' + +//////////////////////////////////////////////////////////////////////////////// +// @wagmi/core +//////////////////////////////////////////////////////////////////////////////// + +export { + // Config + type Connection, + type Connector, + type Config, + type CreateConfigParameters, + type PartializedState, + type State, + createConfig, + // Connector + type ConnectorEventMap, + type CreateConnectorFn, + createConnector, + injected, + mock, + // Errors + type ChainNotConfiguredErrorType, + ChainNotConfiguredError, + type ConnectorAlreadyConnectedErrorType, + ConnectorAlreadyConnectedError, + type ConnectorNotFoundErrorType, + ConnectorNotFoundError, + type ConnectorAccountNotFoundErrorType, + ConnectorAccountNotFoundError, + type ConnectorChainMismatchErrorType, + ConnectorChainMismatchError, + type ConnectorUnavailableReconnectingErrorType, + ConnectorUnavailableReconnectingError, + type ProviderNotFoundErrorType, + ProviderNotFoundError, + type SwitchChainNotSupportedErrorType, + SwitchChainNotSupportedError, + // Storage + type CreateStorageParameters, + type Storage, + createStorage, + noopStorage, + // Transports + custom, + fallback, + http, + webSocket, + unstable_connector, + // Types + type Register, + type ResolvedRegister, + // Utilities + cookieStorage, + cookieToInitialState, + deepEqual, + deserialize, + normalizeChainId, + parseCookie, + serialize, +} from '@wagmi/core' + +//////////////////////////////////////////////////////////////////////////////// +// Version +//////////////////////////////////////////////////////////////////////////////// + +export { version } from '../version.js' diff --git a/wagmi-project/packages/vue/src/exports/nuxt.test.ts b/wagmi-project/packages/vue/src/exports/nuxt.test.ts new file mode 100644 index 000000000..7e5ecf958 --- /dev/null +++ b/wagmi-project/packages/vue/src/exports/nuxt.test.ts @@ -0,0 +1,11 @@ +import { expect, test } from 'vitest' + +import * as nuxt from './nuxt.js' + +test('exports', () => { + expect(Object.keys(nuxt)).toMatchInlineSnapshot(` + [ + "default", + ] + `) +}) diff --git a/wagmi-project/packages/vue/src/exports/nuxt.ts b/wagmi-project/packages/vue/src/exports/nuxt.ts new file mode 100644 index 000000000..e3e2e184a --- /dev/null +++ b/wagmi-project/packages/vue/src/exports/nuxt.ts @@ -0,0 +1,4 @@ +import { wagmiModule } from '../nuxt/module.js' + +export type { WagmiModuleOptions } from '../nuxt/module.js' +export default wagmiModule diff --git a/wagmi-project/packages/vue/src/exports/query.test.ts b/wagmi-project/packages/vue/src/exports/query.test.ts new file mode 100644 index 000000000..758d45c90 --- /dev/null +++ b/wagmi-project/packages/vue/src/exports/query.test.ts @@ -0,0 +1,99 @@ +import { expect, test } from 'vitest' + +import * as query from './query.js' + +test('exports', () => { + expect(Object.keys(query)).toMatchInlineSnapshot(` + [ + "callQueryKey", + "callQueryOptions", + "connectMutationOptions", + "deployContractMutationOptions", + "disconnectMutationOptions", + "estimateFeesPerGasQueryKey", + "estimateFeesPerGasQueryOptions", + "estimateGasQueryKey", + "estimateGasQueryOptions", + "estimateMaxPriorityFeePerGasQueryKey", + "estimateMaxPriorityFeePerGasQueryOptions", + "getBalanceQueryKey", + "getBalanceQueryOptions", + "getBlockQueryKey", + "getBlockQueryOptions", + "getBlockNumberQueryKey", + "getBlockNumberQueryOptions", + "getBlockTransactionCountQueryKey", + "getBlockTransactionCountQueryOptions", + "getBytecodeQueryKey", + "getBytecodeQueryOptions", + "getCallsStatusQueryKey", + "getCallsStatusQueryOptions", + "getCapabilitiesQueryKey", + "getCapabilitiesQueryOptions", + "getConnectorClientQueryKey", + "getConnectorClientQueryOptions", + "getEnsAddressQueryKey", + "getEnsAddressQueryOptions", + "getEnsAvatarQueryKey", + "getEnsAvatarQueryOptions", + "getEnsNameQueryKey", + "getEnsNameQueryOptions", + "getEnsResolverQueryKey", + "getEnsResolverQueryOptions", + "getEnsTextQueryKey", + "getEnsTextQueryOptions", + "getFeeHistoryQueryKey", + "getFeeHistoryQueryOptions", + "getGasPriceQueryKey", + "getGasPriceQueryOptions", + "getProofQueryKey", + "getProofQueryOptions", + "getStorageAtQueryKey", + "getStorageAtQueryOptions", + "getTokenQueryKey", + "getTokenQueryOptions", + "getTransactionQueryKey", + "getTransactionQueryOptions", + "getTransactionConfirmationsQueryKey", + "getTransactionConfirmationsQueryOptions", + "getTransactionCountQueryKey", + "getTransactionCountQueryOptions", + "getTransactionReceiptQueryKey", + "getTransactionReceiptQueryOptions", + "getWalletClientQueryKey", + "getWalletClientQueryOptions", + "infiniteReadContractsQueryKey", + "infiniteReadContractsQueryOptions", + "prepareTransactionRequestQueryKey", + "prepareTransactionRequestQueryOptions", + "readContractQueryKey", + "readContractQueryOptions", + "readContractsQueryKey", + "readContractsQueryOptions", + "reconnectMutationOptions", + "sendCallsMutationOptions", + "showCallsStatusMutationOptions", + "sendTransactionMutationOptions", + "signMessageMutationOptions", + "signTypedDataMutationOptions", + "switchAccountMutationOptions", + "simulateContractQueryKey", + "simulateContractQueryOptions", + "switchChainMutationOptions", + "verifyMessageQueryKey", + "verifyMessageQueryOptions", + "verifyTypedDataQueryKey", + "verifyTypedDataQueryOptions", + "waitForCallsStatusQueryKey", + "waitForCallsStatusQueryOptions", + "waitForTransactionReceiptQueryKey", + "waitForTransactionReceiptQueryOptions", + "watchAssetMutationOptions", + "writeContractMutationOptions", + "hashFn", + "structuralSharing", + "useMutation", + "useQuery", + ] + `) +}) diff --git a/wagmi-project/packages/vue/src/exports/query.ts b/wagmi-project/packages/vue/src/exports/query.ts new file mode 100644 index 000000000..cd9169c0e --- /dev/null +++ b/wagmi-project/packages/vue/src/exports/query.ts @@ -0,0 +1,19 @@ +//////////////////////////////////////////////////////////////////////////////// +// @wagmi/core/query +//////////////////////////////////////////////////////////////////////////////// + +// biome-ignore lint/performance/noBarrelFile: entrypoint module +// biome-ignore lint/performance/noReExportAll: entrypoint module +export * from '@wagmi/core/query' + +export { + type UseMutationParameters, + type UseMutationReturnType, + useMutation, +} from '../utils/query.js' + +export { + type UseQueryParameters, + type UseQueryReturnType, + useQuery, +} from '../utils/query.js' diff --git a/wagmi-project/packages/vue/src/nuxt/module.ts b/wagmi-project/packages/vue/src/nuxt/module.ts new file mode 100644 index 000000000..452dcefac --- /dev/null +++ b/wagmi-project/packages/vue/src/nuxt/module.ts @@ -0,0 +1,60 @@ +import type { NuxtModule } from '@nuxt/schema' +import { addImports, createResolver, defineNuxtModule } from 'nuxt/kit' + +// biome-ignore lint/complexity/noBannedTypes: +export type WagmiModuleOptions = {} + +export const wagmiModule: NuxtModule = + defineNuxtModule({ + meta: { + name: '@wagmi/vue', + configKey: 'wagmi', + compatibility: { + nuxt: '^3.0.0', + }, + }, + setup(_options, nuxt) { + const { resolve } = createResolver(import.meta.url) + + // Add types + nuxt.hook('prepare:types', ({ references }) => { + references.push({ types: '@wagmi/vue/nuxt' }) + }) + + // Add auto imports + const composables = resolve('./runtime/composables') + const names = [ + 'useAccount', + 'useAccountEffect', + 'useBalance', + 'useBlockNumber', + 'useChainId', + 'useChains', + 'useClient', + 'useConfig', + 'useConnect', + 'useConnections', + 'useConnectorClient', + 'useConnectors', + 'useDisconnect', + 'useEnsAddress', + 'useEnsAvatar', + 'useEnsName', + 'useEstimateGas', + 'useReadContract', + 'useReconnect', + 'useSendTransaction', + 'useSignMessage', + 'useSignTypedData', + 'useSimulateContract', + 'useSwitchAccount', + 'useSwitchChain', + 'useTransaction', + 'useTransactionReceipt', + 'useWaitForTransactionReceipt', + 'useWatchBlockNumber', + 'useWriteContract', + ] + addImports(names.map((name) => ({ from: composables, name }))) + }, + }) diff --git a/wagmi-project/packages/vue/src/nuxt/runtime/composables.ts b/wagmi-project/packages/vue/src/nuxt/runtime/composables.ts new file mode 100644 index 000000000..234068935 --- /dev/null +++ b/wagmi-project/packages/vue/src/nuxt/runtime/composables.ts @@ -0,0 +1,3 @@ +// biome-ignore lint/performance/noBarrelFile: entrypoint module +// biome-ignore lint/performance/noReExportAll: entrypoint module +export * from '../../exports/index.js' diff --git a/wagmi-project/packages/vue/src/plugin.ts b/wagmi-project/packages/vue/src/plugin.ts new file mode 100644 index 000000000..ae0d7f919 --- /dev/null +++ b/wagmi-project/packages/vue/src/plugin.ts @@ -0,0 +1,22 @@ +import { type ResolvedRegister, type State, hydrate } from '@wagmi/core' +import type { Plugin } from 'vue' + +export const configKey = Symbol() + +export type WagmiPluginOptions = { + config: ResolvedRegister['config'] + initialState?: State | undefined + reconnectOnMount?: boolean | undefined +} + +export const WagmiPlugin = { + install(app, options) { + const { config, reconnectOnMount = true } = options + app.provide(configKey, config) + // TODO: check this works in SSR env. + // - reconnect on mount. + // - hydrate initial state. + const { onMount } = hydrate(config, { ...options, reconnectOnMount }) + onMount() + }, +} satisfies Plugin diff --git a/wagmi-project/packages/vue/src/types/properties.ts b/wagmi-project/packages/vue/src/types/properties.ts new file mode 100644 index 000000000..e09fdb015 --- /dev/null +++ b/wagmi-project/packages/vue/src/types/properties.ts @@ -0,0 +1,27 @@ +import type { DefaultError, QueryKey } from '@tanstack/vue-query' +import type { Config } from '@wagmi/core' +import type { MaybeRef } from 'vue' +import type { UseQueryParameters } from '../utils/query.js' +import type { DeepUnwrapRef } from './ref.js' + +export type ConfigParameter = { + config?: Config | config | undefined +} + +export type EnabledParameter = { + enabled?: MaybeRef | undefined +} + +export type QueryParameter< + queryFnData = unknown, + error = DefaultError, + data = queryFnData, + queryKey extends QueryKey = QueryKey, +> = { + query?: + | Omit< + DeepUnwrapRef>, + 'queryFn' | 'queryHash' | 'queryKey' | 'queryKeyHashFn' | 'throwOnError' + > + | undefined +} diff --git a/wagmi-project/packages/vue/src/types/ref.ts b/wagmi-project/packages/vue/src/types/ref.ts new file mode 100644 index 000000000..d9cd8120e --- /dev/null +++ b/wagmi-project/packages/vue/src/types/ref.ts @@ -0,0 +1,39 @@ +// Credit: https://github.com/TanStack/query/blob/01ce023826b81e6c41e354f27691f65c9725af67/packages/vue-query/src/types.ts + +import type { Config, Connector } from '@wagmi/core' +import type { MaybeRef, Ref, UnwrapRef } from 'vue' + +type Primitive = string | number | boolean | bigint | symbol | undefined | null +type UnwrapLeaf = + | Primitive + // biome-ignore lint/complexity/noBannedTypes: we need to support all types + | Function + | Date + | Error + | RegExp + | Map + | WeakMap + | Set + | WeakSet + +export type DeepMaybeRef = MaybeRef< + // biome-ignore lint/complexity/noBannedTypes: + value extends Function | Config | Connector + ? value + : value extends object | any[] + ? { + [key in keyof value]: DeepMaybeRef + } + : value +> + +export type DeepUnwrapRef = T extends UnwrapLeaf + ? T + : T extends Ref + ? DeepUnwrapRef + : // biome-ignore lint/complexity/noBannedTypes: + T extends {} + ? { + [Property in keyof T]: DeepUnwrapRef + } + : UnwrapRef diff --git a/wagmi-project/packages/vue/src/utils/cloneDeep.ts b/wagmi-project/packages/vue/src/utils/cloneDeep.ts new file mode 100644 index 000000000..0bbf48deb --- /dev/null +++ b/wagmi-project/packages/vue/src/utils/cloneDeep.ts @@ -0,0 +1,44 @@ +// Credit: https://github.com/TanStack/query/blob/01ce023826b81e6c41e354f27691f65c9725af67/packages/vue-query/src/utils.ts + +import { isRef, unref } from 'vue' + +import type { DeepMaybeRef, DeepUnwrapRef } from '../types/ref.js' + +function cloneDeep( + value: DeepMaybeRef, + customize?: (val: DeepMaybeRef) => value | undefined, +): value { + if (customize) { + const result = customize(value) + // If it's a ref of undefined, return undefined + if (result === undefined && isRef(value)) return result as value + if (result !== undefined) return result + } + + if (Array.isArray(value)) + return value.map((val) => cloneDeep(val, customize)) as unknown as value + + if (typeof value === 'object' && isPlainObject(value)) { + const entries = Object.entries(value).map(([key, val]) => [ + key, + cloneDeep(val, customize), + ]) + return Object.fromEntries(entries) + } + + return value as value +} + +export function deepUnref(value: value): DeepUnwrapRef { + return cloneDeep(value as any, (val) => { + if (isRef(val)) return deepUnref(unref(val)) + return undefined + }) +} + +// biome-ignore lint/complexity/noBannedTypes: +function isPlainObject(value: unknown): value is Object { + if (Object.prototype.toString.call(value) !== '[object Object]') return false + const prototype = Object.getPrototypeOf(value) + return prototype === null || prototype === Object.prototype +} diff --git a/wagmi-project/packages/vue/src/utils/getVersion.test.ts b/wagmi-project/packages/vue/src/utils/getVersion.test.ts new file mode 100644 index 000000000..a2ae6fb1c --- /dev/null +++ b/wagmi-project/packages/vue/src/utils/getVersion.test.ts @@ -0,0 +1,7 @@ +import { expect, test } from 'vitest' + +import { getVersion } from './getVersion.js' + +test('default', () => { + expect(getVersion()).toMatchInlineSnapshot(`"@wagmi/vue@x.y.z"`) +}) diff --git a/wagmi-project/packages/vue/src/utils/getVersion.ts b/wagmi-project/packages/vue/src/utils/getVersion.ts new file mode 100644 index 000000000..1c33c5302 --- /dev/null +++ b/wagmi-project/packages/vue/src/utils/getVersion.ts @@ -0,0 +1,3 @@ +import { version } from '../version.js' + +export const getVersion = () => `@wagmi/vue@${version}` diff --git a/wagmi-project/packages/vue/src/utils/query.ts b/wagmi-project/packages/vue/src/utils/query.ts new file mode 100644 index 000000000..0ea82af9b --- /dev/null +++ b/wagmi-project/packages/vue/src/utils/query.ts @@ -0,0 +1,161 @@ +import { + type DefaultError, + type MutationObserverOptions, + type QueryKey, + type UseQueryOptions, + type UseMutationReturnType as tanstack_UseMutationReturnType, + type UseQueryReturnType as tanstack_UseQueryReturnType, + useQuery as tanstack_useQuery, + useMutation, +} from '@tanstack/vue-query' +import type { + Compute, + ExactPartial, + Omit, + UnionStrictOmit, +} from '@wagmi/core/internal' +import { hashFn } from '@wagmi/core/query' +import { type MaybeRef, computed, unref } from 'vue' + +import type { DeepMaybeRef, DeepUnwrapRef } from '../types/ref.js' + +export type UseMutationParameters< + data = unknown, + error = Error, + variables = void, + context = unknown, +> = Compute< + DeepMaybeRef< + Omit< + DeepUnwrapRef< + MutationObserverOptions, context> + >, + 'mutationFn' | 'mutationKey' | 'throwOnError' + > + > +> + +export type UseMutationReturnType< + data = unknown, + error = Error, + variables = void, + context = unknown, +> = Compute< + UnionStrictOmit< + tanstack_UseMutationReturnType, + 'mutate' | 'mutateAsync' + > +> + +export { useMutation } + +//////////////////////////////////////////////////////////////////////////////// + +export type UseQueryParameters< + queryFnData = unknown, + error = DefaultError, + data = queryFnData, + queryKey extends QueryKey = QueryKey, +> = Compute< + DeepMaybeRef< + ExactPartial< + Omit< + DeepUnwrapRef< + UseQueryOptions + >, + 'initialData' + > + > & { + // Fix `initialData` type + initialData?: + | DeepUnwrapRef< + UseQueryOptions + >['initialData'] + | undefined + } + > +> + +export type UseQueryReturnType = Compute< + tanstack_UseQueryReturnType & { + queryKey: QueryKey + } +> + +// Adding some basic customization. +// Ideally we don't have this function, but `import('@tanstack/vue-query').useQuery` currently has some quirks where it is super hard to +// pass down the inferred `initialData` type because of it's discriminated overload in the on `useQuery`. +export function useQuery( + parameters: MaybeRef< + UseQueryParameters & { + queryKey: QueryKey + } + >, +): UseQueryReturnType { + const options = computed(() => ({ + ...(unref(parameters) as any), + queryKeyHashFn: hashFn, + })) + const result = tanstack_useQuery(options) as UseQueryReturnType + result.queryKey = unref(options).queryKey as QueryKey + return result +} + +//////////////////////////////////////////////////////////////////////////////// + +// export type UseInfiniteQueryParameters< +// queryFnData = unknown, +// error = DefaultError, +// data = queryFnData, +// queryData = queryFnData, +// queryKey extends QueryKey = QueryKey, +// pageParam = unknown, +// > = Compute< +// Omit< +// UseInfiniteQueryOptions< +// queryFnData, +// error, +// data, +// queryData, +// queryKey, +// pageParam +// >, +// 'initialData' +// > & { +// // Fix `initialData` type +// initialData?: +// | UseInfiniteQueryOptions< +// queryFnData, +// error, +// data, +// queryKey +// >['initialData'] +// | undefined +// } +// > + +// export type UseInfiniteQueryReturnType< +// data = unknown, +// error = DefaultError, +// > = import('@tanstack/vue-query').UseInfiniteQueryReturnType & { +// queryKey: QueryKey +// } + +// // Adding some basic customization. +// export function useInfiniteQuery< +// queryFnData, +// error, +// data, +// queryKey extends QueryKey, +// >( +// parameters: UseInfiniteQueryParameters & { +// queryKey: QueryKey +// }, +// ): UseInfiniteQueryReturnType { +// const result = tanstack_useInfiniteQuery({ +// ...(parameters as any), +// queryKeyHashFn: hashFn, // for bigint support +// }) as UseInfiniteQueryReturnType +// result.queryKey = parameters.queryKey +// return result +// } diff --git a/wagmi-project/packages/vue/src/utils/updateState.ts b/wagmi-project/packages/vue/src/utils/updateState.ts new file mode 100644 index 000000000..bcd53872d --- /dev/null +++ b/wagmi-project/packages/vue/src/utils/updateState.ts @@ -0,0 +1,10 @@ +// Credit: https://github.com/TanStack/query/blob/01ce023826b81e6c41e354f27691f65c9725af67/packages/vue-query/src/utils.ts#L11-L18 + +export function updateState( + state: Record, + update: Record, +): void { + for (const key of Object.keys(state)) { + state[key] = update[key] + } +} diff --git a/wagmi-project/packages/vue/src/version.ts b/wagmi-project/packages/vue/src/version.ts new file mode 100644 index 000000000..4a292eed4 --- /dev/null +++ b/wagmi-project/packages/vue/src/version.ts @@ -0,0 +1 @@ +export const version = '0.1.20' diff --git a/wagmi-project/packages/vue/test/setup.ts b/wagmi-project/packages/vue/test/setup.ts new file mode 100644 index 000000000..5c0dcc071 --- /dev/null +++ b/wagmi-project/packages/vue/test/setup.ts @@ -0,0 +1,8 @@ +import { vi } from 'vitest' + +// Make dates stable across runs +Date.now = vi.fn(() => new Date(Date.UTC(2023, 1, 1)).valueOf()) + +vi.mock('../src/version.ts', () => { + return { version: 'x.y.z' } +}) diff --git a/wagmi-project/packages/vue/tsconfig.build.json b/wagmi-project/packages/vue/tsconfig.build.json new file mode 100644 index 000000000..fbed2b103 --- /dev/null +++ b/wagmi-project/packages/vue/tsconfig.build.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.base.json", + "include": ["src/**/*.ts"], + "exclude": ["src/**/*.test.ts", "src/**/*.test-d.ts"], + "compilerOptions": { + "sourceMap": true + } +} diff --git a/wagmi-project/packages/vue/tsconfig.json b/wagmi-project/packages/vue/tsconfig.json new file mode 100644 index 000000000..bacbc9228 --- /dev/null +++ b/wagmi-project/packages/vue/tsconfig.json @@ -0,0 +1,5 @@ +{ + "extends": "./tsconfig.build.json", + "include": ["src/**/*.ts", "test/**/*.ts"], + "exclude": [] +} diff --git a/wagmi-project/playgrounds/next/.gitignore b/wagmi-project/playgrounds/next/.gitignore new file mode 100644 index 000000000..8f322f0d8 --- /dev/null +++ b/wagmi-project/playgrounds/next/.gitignore @@ -0,0 +1,35 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# local env files +.env*.local + +# vercel +.vercel + +# typescript +*.tsbuildinfo +next-env.d.ts diff --git a/wagmi-project/playgrounds/next/next.config.mjs b/wagmi-project/playgrounds/next/next.config.mjs new file mode 100644 index 000000000..8831ff653 --- /dev/null +++ b/wagmi-project/playgrounds/next/next.config.mjs @@ -0,0 +1,20 @@ +import bundleAnalyzer from '@next/bundle-analyzer' + +const withBundleAnalyzer = bundleAnalyzer({ + enabled: process.env.ANALYZE === 'true', +}) + +/** @type {import('next').NextConfig} */ +const nextConfig = { + experimental: { + externalDir: true, + }, + webpack(config) { + config.resolve.extensionAlias = { + '.js': ['.js', '.ts'], + } + return config + }, +} + +export default withBundleAnalyzer(nextConfig) diff --git a/wagmi-project/playgrounds/next/package.json b/wagmi-project/playgrounds/next/package.json new file mode 100644 index 000000000..0afbe99d3 --- /dev/null +++ b/wagmi-project/playgrounds/next/package.json @@ -0,0 +1,31 @@ +{ + "name": "next-app", + "private": true, + "scripts": { + "analyze": "ANALYZE=true next build", + "dev": "next dev", + "build": "next build", + "start": "next start", + "lint": "next lint" + }, + "dependencies": { + "@next/bundle-analyzer": "^15.2.4", + "@tanstack/react-query": ">=5.45.1", + "next": "15.3.3", + "react": ">=18.3.1", + "react-dom": ">=18.3.1", + "viem": "2.*", + "wagmi": "workspace:*" + }, + "devDependencies": { + "@types/node": "^22.14.1", + "@types/react": ">=18.3.1", + "@types/react-dom": ">=18.3.0", + "bufferutil": "^4.0.8", + "encoding": "^0.1.13", + "lokijs": "^1.5.12", + "pino-pretty": "^13.0.0", + "supports-color": "^9.4.0", + "utf-8-validate": "^6.0.5" + } +} diff --git a/wagmi-project/playgrounds/next/src/app/contracts.ts b/wagmi-project/playgrounds/next/src/app/contracts.ts new file mode 100644 index 000000000..d7d66754a --- /dev/null +++ b/wagmi-project/playgrounds/next/src/app/contracts.ts @@ -0,0 +1,202 @@ +export const wagmiContractConfig = { + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + abi: [ + { inputs: [], stateMutability: 'nonpayable', type: 'constructor' }, + { + anonymous: false, + inputs: [ + { + indexed: true, + name: 'owner', + type: 'address', + }, + { + indexed: true, + name: 'approved', + type: 'address', + }, + { + indexed: true, + name: 'tokenId', + type: 'uint256', + }, + ], + name: 'Approval', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + name: 'owner', + type: 'address', + }, + { + indexed: true, + name: 'operator', + type: 'address', + }, + { + indexed: false, + name: 'approved', + type: 'bool', + }, + ], + name: 'ApprovalForAll', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + name: 'from', + type: 'address', + }, + { indexed: true, name: 'to', type: 'address' }, + { + indexed: true, + name: 'tokenId', + type: 'uint256', + }, + ], + name: 'Transfer', + type: 'event', + }, + { + inputs: [ + { name: 'to', type: 'address' }, + { name: 'tokenId', type: 'uint256' }, + ], + name: 'approve', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ name: 'owner', type: 'address' }], + name: 'balanceOf', + outputs: [{ name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ name: 'tokenId', type: 'uint256' }], + name: 'getApproved', + outputs: [{ name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { name: 'owner', type: 'address' }, + { name: 'operator', type: 'address' }, + ], + name: 'isApprovedForAll', + outputs: [{ name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'mint', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'tokenId', type: 'uint256' }], + name: 'mint', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'name', + outputs: [{ name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ name: 'tokenId', type: 'uint256' }], + name: 'ownerOf', + outputs: [{ name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { name: 'from', type: 'address' }, + { name: 'to', type: 'address' }, + { name: 'tokenId', type: 'uint256' }, + ], + name: 'safeTransferFrom', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { name: 'from', type: 'address' }, + { name: 'to', type: 'address' }, + { name: 'tokenId', type: 'uint256' }, + { name: '_data', type: 'bytes' }, + ], + name: 'safeTransferFrom', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { name: 'operator', type: 'address' }, + { name: 'approved', type: 'bool' }, + ], + name: 'setApprovalForAll', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ name: 'interfaceId', type: 'bytes4' }], + name: 'supportsInterface', + outputs: [{ name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'symbol', + outputs: [{ name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ name: 'tokenId', type: 'uint256' }], + name: 'tokenURI', + outputs: [{ name: '', type: 'string' }], + stateMutability: 'pure', + type: 'function', + }, + { + inputs: [], + name: 'totalSupply', + outputs: [{ name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { name: 'from', type: 'address' }, + { name: 'to', type: 'address' }, + { name: 'tokenId', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + ], +} as const diff --git a/wagmi-project/playgrounds/next/src/app/globals.css b/wagmi-project/playgrounds/next/src/app/globals.css new file mode 100644 index 000000000..0733a7ee6 --- /dev/null +++ b/wagmi-project/playgrounds/next/src/app/globals.css @@ -0,0 +1,21 @@ +:root { + background-color: #181818; + color: rgba(255, 255, 255, 0.87); + color-scheme: light dark; + font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; + font-synthesis: none; + font-weight: 400; + line-height: 1.5; + text-rendering: optimizeLegibility; + + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + -webkit-text-size-adjust: 100%; +} + +@media (prefers-color-scheme: light) { + :root { + background-color: #f8f8f8; + color: #181818; + } +} diff --git a/wagmi-project/playgrounds/next/src/app/layout.tsx b/wagmi-project/playgrounds/next/src/app/layout.tsx new file mode 100644 index 000000000..72ec934a0 --- /dev/null +++ b/wagmi-project/playgrounds/next/src/app/layout.tsx @@ -0,0 +1,30 @@ +import type { Metadata } from 'next' +import { Inter } from 'next/font/google' +import { headers } from 'next/headers' +import type { ReactNode } from 'react' +import { cookieToInitialState } from 'wagmi' +import './globals.css' + +import { getConfig } from '../wagmi' +import { Providers } from './providers' + +const inter = Inter({ subsets: ['latin'] }) + +export const metadata: Metadata = { + title: 'Create Wagmi', + description: 'Generated by create-wagmi', +} + +export default async function RootLayout(props: { children: ReactNode }) { + const initialState = cookieToInitialState( + getConfig(), + (await headers()).get('cookie'), + ) + return ( + + + {props.children} + + + ) +} diff --git a/wagmi-project/playgrounds/next/src/app/page.tsx b/wagmi-project/playgrounds/next/src/app/page.tsx new file mode 100644 index 000000000..33c1bf0ab --- /dev/null +++ b/wagmi-project/playgrounds/next/src/app/page.tsx @@ -0,0 +1,412 @@ +'use client' + +import type { FormEvent } from 'react' +import { type Hex, formatEther, parseAbi, parseEther } from 'viem' +import { + type BaseError, + useAccount, + useAccountEffect, + useBalance, + useBlockNumber, + useChainId, + useConfig, + useConnect, + useConnections, + useConnectorClient, + useDisconnect, + useEnsName, + useReadContract, + useReadContracts, + useSendTransaction, + useSignMessage, + useSwitchAccount, + useSwitchChain, + useWaitForTransactionReceipt, + useWriteContract, +} from 'wagmi' +import { switchChain } from 'wagmi/actions' +import { optimism, sepolia } from 'wagmi/chains' + +import { wagmiContractConfig } from './contracts' + +export default function App() { + useAccountEffect({ + onConnect(_data) { + // console.log('onConnect', data) + }, + onDisconnect() { + // console.log('onDisconnect') + }, + }) + + return ( + <> + + + + + + + + + + + + + + + + ) +} + +function Account() { + const account = useAccount() + const { disconnect } = useDisconnect() + const { data: ensName } = useEnsName({ + address: account.address, + }) + + return ( +
+

Account

+ +
+ account: {account.address} {ensName} +
+ chainId: {account.chainId} +
+ status: {account.status} +
+ + {account.status === 'connected' && ( + + )} +
+ ) +} + +function Connect() { + const chainId = useChainId() + const { connectors, connect, status, error } = useConnect() + + return ( +
+

Connect

+ {connectors.map((connector) => ( + + ))} +
{status}
+
{error?.message}
+
+ ) +} + +function SwitchAccount() { + const account = useAccount() + const { connectors, switchAccount } = useSwitchAccount() + + return ( +
+

Switch Account

+ + {connectors.map((connector) => ( + + ))} +
+ ) +} + +function SwitchChain() { + const chainId = useChainId() + const { chains, switchChain, error } = useSwitchChain() + + return ( +
+

Switch Chain

+ + {chains.map((chain) => ( + + ))} + + {error?.message} +
+ ) +} + +function SignMessage() { + const { data, signMessage } = useSignMessage() + + return ( +
+

Sign Message

+ +
{ + event.preventDefault() + const formData = new FormData(event.target as HTMLFormElement) + signMessage({ message: formData.get('message') as string }) + }} + > + + +
+ + {data} +
+ ) +} + +function Connections() { + const connections = useConnections() + + return ( +
+

Connections

+ + {connections.map((connection) => ( +
+
connector {connection.connector.name}
+
accounts: {JSON.stringify(connection.accounts)}
+
chainId: {connection.chainId}
+
+ ))} +
+ ) +} + +function Balance() { + const { address } = useAccount() + + const { data: default_ } = useBalance({ address }) + const { data: account_ } = useBalance({ address }) + const { data: optimism_ } = useBalance({ + address, + chainId: optimism.id, + }) + + return ( +
+

Balance

+ +
+ Balance (Default Chain):{' '} + {!!default_?.value && formatEther(default_.value)} +
+
+ Balance (Account Chain):{' '} + {!!account_?.value && formatEther(account_.value)} +
+
+ Balance (Optimism Chain):{' '} + {!!optimism_?.value && formatEther(optimism_.value)} +
+
+ ) +} + +function BlockNumber() { + const { data: default_ } = useBlockNumber({ watch: true }) + const { data: account_ } = useBlockNumber({ + watch: true, + }) + const { data: optimism_ } = useBlockNumber({ + chainId: optimism.id, + watch: true, + }) + + return ( +
+

Block Number

+ +
Block Number (Default Chain): {default_?.toString()}
+
Block Number (Account Chain): {account_?.toString()}
+
Block Number (Optimism): {optimism_?.toString()}
+
+ ) +} + +function ConnectorClient() { + const { data, error } = useConnectorClient() + return ( +
+

Connector Client

+ client {data?.account?.address} {data?.chain?.id} + {error?.message} +
+ ) +} + +function SendTransaction() { + const { data: hash, error, isPending, sendTransaction } = useSendTransaction() + + async function submit(e: FormEvent) { + e.preventDefault() + const formData = new FormData(e.target as HTMLFormElement) + const to = formData.get('address') as Hex + const value = formData.get('value') as string + sendTransaction({ to, value: parseEther(value) }) + } + + const { isLoading: isConfirming, isSuccess: isConfirmed } = + useWaitForTransactionReceipt({ + hash, + }) + + return ( +
+

Send Transaction

+
+ + + +
+ {hash &&
Transaction Hash: {hash}
} + {isConfirming && 'Waiting for confirmation...'} + {isConfirmed && 'Transaction confirmed.'} + {error && ( +
Error: {(error as BaseError).shortMessage || error.message}
+ )} +
+ ) +} + +function ReadContract() { + const { data: balance } = useReadContract({ + ...wagmiContractConfig, + functionName: 'balanceOf', + args: ['0x03A71968491d55603FFe1b11A9e23eF013f75bCF'], + }) + + return ( +
+

Read Contract

+
Balance: {balance?.toString()}
+
+ ) +} + +function ReadContracts() { + const { data } = useReadContracts({ + allowFailure: false, + contracts: [ + { + ...wagmiContractConfig, + functionName: 'balanceOf', + args: ['0x03A71968491d55603FFe1b11A9e23eF013f75bCF'], + }, + { + ...wagmiContractConfig, + functionName: 'ownerOf', + args: [69n], + }, + { + ...wagmiContractConfig, + functionName: 'totalSupply', + }, + ], + }) + const [balance, ownerOf, totalSupply] = data || [] + + return ( +
+

Read Contract

+
Balance: {balance?.toString()}
+
Owner of Token 69: {ownerOf?.toString()}
+
Total Supply: {totalSupply?.toString()}
+
+ ) +} + +function WriteContract() { + const { data: hash, error, isPending, writeContract } = useWriteContract() + + async function submit(e: FormEvent) { + e.preventDefault() + const formData = new FormData(e.target as HTMLFormElement) + const tokenId = formData.get('tokenId') as string + writeContract({ + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + abi: parseAbi(['function mint(uint256 tokenId)']), + functionName: 'mint', + args: [BigInt(tokenId)], + }) + } + + const { isLoading: isConfirming, isSuccess: isConfirmed } = + useWaitForTransactionReceipt({ + hash, + }) + + return ( +
+

Write Contract

+
+ + +
+ {hash &&
Transaction Hash: {hash}
} + {isConfirming && 'Waiting for confirmation...'} + {isConfirmed && 'Transaction confirmed.'} + {error && ( +
Error: {(error as BaseError).shortMessage || error.message}
+ )} +
+ ) +} + +function Repro() { + const config = useConfig() + const chainId = useChainId() + + // biome-ignore lint/suspicious/noConsoleLog: + console.log('chainId from useChainId is', chainId) + return ( +
+ Current Chain Id: {chainId} + + +
+ ) +} diff --git a/wagmi-project/playgrounds/next/src/app/providers.tsx b/wagmi-project/playgrounds/next/src/app/providers.tsx new file mode 100644 index 000000000..3f0082dd2 --- /dev/null +++ b/wagmi-project/playgrounds/next/src/app/providers.tsx @@ -0,0 +1,23 @@ +'use client' + +import { QueryClient, QueryClientProvider } from '@tanstack/react-query' +import { type ReactNode, useState } from 'react' +import { type State, WagmiProvider } from 'wagmi' + +import { getConfig } from '../wagmi' + +export function Providers(props: { + children: ReactNode + initialState?: State +}) { + const [config] = useState(() => getConfig()) + const [queryClient] = useState(() => new QueryClient()) + + return ( + + + {props.children} + + + ) +} diff --git a/wagmi-project/playgrounds/next/src/wagmi.ts b/wagmi-project/playgrounds/next/src/wagmi.ts new file mode 100644 index 000000000..0c9db90a5 --- /dev/null +++ b/wagmi-project/playgrounds/next/src/wagmi.ts @@ -0,0 +1,31 @@ +import { http, cookieStorage, createConfig, createStorage } from 'wagmi' +import { mainnet, optimism, sepolia } from 'wagmi/chains' +import { injected, metaMask, walletConnect } from 'wagmi/connectors' + +export function getConfig() { + return createConfig({ + chains: [mainnet, sepolia, optimism], + connectors: [ + injected(), + walletConnect({ + projectId: process.env.NEXT_PUBLIC_WC_PROJECT_ID!, + }), + metaMask(), + ], + storage: createStorage({ + storage: cookieStorage, + }), + ssr: true, + transports: { + [mainnet.id]: http(), + [sepolia.id]: http(), + [optimism.id]: http(), + }, + }) +} + +declare module 'wagmi' { + interface Register { + config: ReturnType + } +} diff --git a/wagmi-project/playgrounds/next/tsconfig.json b/wagmi-project/playgrounds/next/tsconfig.json new file mode 100644 index 000000000..9eb40a20d --- /dev/null +++ b/wagmi-project/playgrounds/next/tsconfig.json @@ -0,0 +1,24 @@ +{ + "compilerOptions": { + "target": "ESNext", + "lib": ["dom", "dom.iterable", "esnext"], + "allowJs": true, + "skipLibCheck": true, + "strict": true, + "noEmit": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "bundler", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "preserve", + "incremental": true, + "plugins": [ + { + "name": "next" + } + ] + }, + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], + "exclude": ["node_modules"] +} diff --git a/wagmi-project/playgrounds/nuxt/.gitignore b/wagmi-project/playgrounds/nuxt/.gitignore new file mode 100644 index 000000000..4a7f73a2e --- /dev/null +++ b/wagmi-project/playgrounds/nuxt/.gitignore @@ -0,0 +1,24 @@ +# Nuxt dev/build outputs +.output +.data +.nuxt +.nitro +.cache +dist + +# Node dependencies +node_modules + +# Logs +logs +*.log + +# Misc +.DS_Store +.fleet +.idea + +# Local env files +.env +.env.* +!.env.example diff --git a/wagmi-project/playgrounds/nuxt/app.vue b/wagmi-project/playgrounds/nuxt/app.vue new file mode 100644 index 000000000..98b46bf52 --- /dev/null +++ b/wagmi-project/playgrounds/nuxt/app.vue @@ -0,0 +1,28 @@ + + + diff --git a/wagmi-project/playgrounds/nuxt/components/Account.vue b/wagmi-project/playgrounds/nuxt/components/Account.vue new file mode 100644 index 000000000..33f1491da --- /dev/null +++ b/wagmi-project/playgrounds/nuxt/components/Account.vue @@ -0,0 +1,22 @@ + + + diff --git a/wagmi-project/playgrounds/nuxt/components/Connect.vue b/wagmi-project/playgrounds/nuxt/components/Connect.vue new file mode 100644 index 000000000..93320448c --- /dev/null +++ b/wagmi-project/playgrounds/nuxt/components/Connect.vue @@ -0,0 +1,19 @@ + + + diff --git a/wagmi-project/playgrounds/nuxt/nuxt.config.ts b/wagmi-project/playgrounds/nuxt/nuxt.config.ts new file mode 100644 index 000000000..adfe7fd2d --- /dev/null +++ b/wagmi-project/playgrounds/nuxt/nuxt.config.ts @@ -0,0 +1,7 @@ +import { defineNuxtConfig } from 'nuxt/config' + +// https://nuxt.com/docs/api/configuration/nuxt-config +export default defineNuxtConfig({ + devtools: { enabled: true }, + modules: ['@wagmi/vue/nuxt'], +}) diff --git a/wagmi-project/playgrounds/nuxt/package.json b/wagmi-project/playgrounds/nuxt/package.json new file mode 100644 index 000000000..512a1be27 --- /dev/null +++ b/wagmi-project/playgrounds/nuxt/package.json @@ -0,0 +1,20 @@ +{ + "name": "nuxt-app", + "private": true, + "type": "module", + "scripts": { + "build": "nuxt build", + "dev": "nuxt dev", + "generate": "nuxt generate", + "preview": "nuxt preview", + "_postinstall": "nuxt prepare" + }, + "dependencies": { + "@tanstack/vue-query": ">=5.45.0", + "@wagmi/vue": "workspace:*", + "nuxt": "^3.16.0", + "viem": "2.*", + "vue": ">=3.4.21", + "vue-router": "^4.3.2" + } +} diff --git a/wagmi-project/playgrounds/nuxt/plugins/wagmi.ts b/wagmi-project/playgrounds/nuxt/plugins/wagmi.ts new file mode 100644 index 000000000..b6abe5bcd --- /dev/null +++ b/wagmi-project/playgrounds/nuxt/plugins/wagmi.ts @@ -0,0 +1,10 @@ +import { VueQueryPlugin } from '@tanstack/vue-query' +import { WagmiPlugin } from '@wagmi/vue' +import { defineNuxtPlugin } from 'nuxt/app' + +import { config } from '../wagmi' + +// TODO: Move to @wagmi/vue/nuxt nitro plugin +export default defineNuxtPlugin((nuxtApp) => { + nuxtApp.vueApp.use(WagmiPlugin, { config }).use(VueQueryPlugin, {}) +}) diff --git a/wagmi-project/playgrounds/nuxt/public/favicon.ico b/wagmi-project/playgrounds/nuxt/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..18993ad91cfd43e03b074dd0b5cc3f37ab38e49c GIT binary patch literal 4286 zcmeHLOKuuL5PjK%MHWVi6lD zOGiREbCw`xmFozJ^aNatJY>w+g ze6a2@u~m#^BZm@8wco9#Crlli0uLb^3E$t2-WIc^#(?t)*@`UpuofJ(Uyh@F>b3Ph z$D^m8Xq~pTkGJ4Q`Q2)te3mgkWYZ^Ijq|hkiP^9`De={bQQ%heZC$QU2UpP(-tbl8 zPWD2abEew;oat@w`uP3J^YpsgT%~jT(Dk%oU}sa$7|n6hBjDj`+I;RX(>)%lm_7N{+B7Mu%H?422lE%MBJH!!YTN2oT7xr>>N-8OF$C&qU^ z>vLsa{$0X%q1fjOe3P1mCv#lN{xQ4_*HCSAZjTb1`}mlc+9rl8$B3OP%VT@mch_~G z7Y+4b{r>9e=M+7vSI;BgB?ryZDY4m>&wcHSn81VH1N~`0gvwH{ z8dv#hG|OK`>1;j7tM#B)Z7zDN?{6=dUal}$e + + + + + Vite Core + + +
+ + + diff --git a/wagmi-project/playgrounds/vite-core/package.json b/wagmi-project/playgrounds/vite-core/package.json new file mode 100644 index 000000000..07a606dc3 --- /dev/null +++ b/wagmi-project/playgrounds/vite-core/package.json @@ -0,0 +1,24 @@ +{ + "name": "vite-core", + "private": true, + "type": "module", + "scripts": { + "dev": "vite", + "build": "tsc && vite build", + "preview": "vite preview" + }, + "dependencies": { + "@wagmi/connectors": "workspace:*", + "@wagmi/core": "workspace:*", + "react": ">=18.3.1", + "react-dom": ">=18.3.1", + "viem": "2.*" + }, + "devDependencies": { + "@types/react": ">=18.3.1", + "@types/react-dom": ">=18.3.0", + "@vitejs/plugin-react": "^4.2.1", + "buffer": "^6.0.3", + "vite": "^5.4.19" + } +} diff --git a/wagmi-project/playgrounds/vite-core/src/App.tsx b/wagmi-project/playgrounds/vite-core/src/App.tsx new file mode 100644 index 000000000..3c8646be3 --- /dev/null +++ b/wagmi-project/playgrounds/vite-core/src/App.tsx @@ -0,0 +1,186 @@ +import { + type GetBalanceReturnType, + type GetBlockNumberReturnType, + connect, + disconnect, + getAccount, + getBalance, + getBlockNumber, + reconnect, + switchAccount, + watchAccount, + watchBlockNumber, +} from '@wagmi/core' +import { useEffect, useReducer, useState } from 'react' + +import { formatEther } from 'viem' +import { config } from './wagmi' + +function App() { + useEffect(() => { + reconnect(config) + }, []) + + return ( + <> + + + + + + + ) +} + +function Account() { + const [account, setAccount] = useState(getAccount(config)) + + useEffect(() => { + return watchAccount(config, { + onChange(data) { + setAccount(data) + }, + }) + }, []) + + return ( +
+

Account

+ +
+ account: {account.address} +
+ chainId: {account.chainId} +
+ status: {account.status} +
+ + {account.status === 'connected' && ( + + )} +
+ ) +} + +function Connect() { + const [, rerender] = useReducer((count) => count + 1, 0) + + useEffect(() => { + return config.subscribe(({ connections }) => connections, rerender) + }, []) + + return ( +
+

Connect

+ + {config.connectors.map((connector) => ( + + ))} +
+ ) +} + +function SwitchAccount() { + const [, rerender] = useReducer((count) => count + 1, 0) + + useEffect(() => { + return config.subscribe( + ({ connections, current }) => ({ connections, current }), + rerender, + ) + }, []) + + return ( +
+

SwitchAccount

+ + {config.connectors + .filter((connector) => config.state.connections.has(connector.uid)) + .map((connector) => ( + + ))} +
+ ) +} + +function Balance() { + const [account, setAccount] = useState(getAccount(config)) + + useEffect(() => { + return watchAccount(config, { + onChange(data) { + setAccount(data) + }, + }) + }, []) + + ///////////////////////////////////////////////////////// + + const [balance, setBalance] = useState() + + useEffect(() => { + if (!account.address) return + return watchBlockNumber(config, { + async onBlockNumber() { + try { + const balance = await getBalance(config, { + address: account.address!, + }) + setBalance(balance) + } catch (error) { + console.error('Error fetching balance', error) + } + }, + }) + }, [account.address]) + + return ( +
+

Balance

+ +
Balance: {!!balance?.value && formatEther(balance.value)}
+
+ ) +} + +function BlockNumber() { + const [blockNumber, setBlockNumber] = useState< + GetBlockNumberReturnType | undefined + >() + + useEffect(() => { + ;(async () => { + setBlockNumber(await getBlockNumber(config)) + + watchBlockNumber(config, { onBlockNumber: setBlockNumber }) + })() + }, []) + + return ( +
+

Block Number

+ +
Block Number (Default Chain): {blockNumber?.toString()}
+
+ ) +} + +export default App diff --git a/wagmi-project/playgrounds/vite-core/src/index.css b/wagmi-project/playgrounds/vite-core/src/index.css new file mode 100644 index 000000000..0733a7ee6 --- /dev/null +++ b/wagmi-project/playgrounds/vite-core/src/index.css @@ -0,0 +1,21 @@ +:root { + background-color: #181818; + color: rgba(255, 255, 255, 0.87); + color-scheme: light dark; + font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; + font-synthesis: none; + font-weight: 400; + line-height: 1.5; + text-rendering: optimizeLegibility; + + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + -webkit-text-size-adjust: 100%; +} + +@media (prefers-color-scheme: light) { + :root { + background-color: #f8f8f8; + color: #181818; + } +} diff --git a/wagmi-project/playgrounds/vite-core/src/main.tsx b/wagmi-project/playgrounds/vite-core/src/main.tsx new file mode 100644 index 000000000..180d9e1fc --- /dev/null +++ b/wagmi-project/playgrounds/vite-core/src/main.tsx @@ -0,0 +1,16 @@ +import React from 'react' +import ReactDOM from 'react-dom/client' +import './index.css' + +import { Buffer } from 'buffer' + +// `@coinbase-wallet/sdk` uses `Buffer` +globalThis.Buffer = Buffer + +import App from './App.tsx' + +ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render( + + + , +) diff --git a/wagmi-project/playgrounds/vite-core/src/vite-env.d.ts b/wagmi-project/playgrounds/vite-core/src/vite-env.d.ts new file mode 100644 index 000000000..11f02fe2a --- /dev/null +++ b/wagmi-project/playgrounds/vite-core/src/vite-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/wagmi-project/playgrounds/vite-core/src/wagmi.ts b/wagmi-project/playgrounds/vite-core/src/wagmi.ts new file mode 100644 index 000000000..d6152f9d2 --- /dev/null +++ b/wagmi-project/playgrounds/vite-core/src/wagmi.ts @@ -0,0 +1,22 @@ +import { coinbaseWallet, metaMask, walletConnect } from '@wagmi/connectors' +import { http, createConfig, createStorage } from '@wagmi/core' +import { mainnet, optimism, sepolia } from '@wagmi/core/chains' + +export const config = createConfig({ + chains: [mainnet, sepolia, optimism], + connectors: [ + walletConnect({ projectId: import.meta.env.VITE_WC_PROJECT_ID }), + coinbaseWallet(), + metaMask(), + ], + storage: createStorage({ storage: localStorage, key: 'vite-core' }), + transports: { + [mainnet.id]: http( + 'https://eth-mainnet.g.alchemy.com/v2/StF61Ht3J9nXAojZX-b21LVt9l0qDL38', + ), + [sepolia.id]: http( + 'https://eth-sepolia.g.alchemy.com/v2/roJyEHxkj7XWg1T9wmYnxvktDodQrFAS', + ), + [optimism.id]: http(), + }, +}) diff --git a/wagmi-project/playgrounds/vite-core/tsconfig.json b/wagmi-project/playgrounds/vite-core/tsconfig.json new file mode 100644 index 000000000..36d04ef37 --- /dev/null +++ b/wagmi-project/playgrounds/vite-core/tsconfig.json @@ -0,0 +1,28 @@ +{ + "compilerOptions": { + "target": "ESNext", + "lib": ["DOM", "DOM.Iterable", "ESNext"], + "module": "ESNext", + "skipLibCheck": true, + + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "react-jsx", + + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true, + + "paths": { + "@wagmi/connectors": ["../../packages/connectors/src/exports"], + "@wagmi/core": ["../../packages/core/src/exports"], + "@wagmi/core/*": ["../../packages/core/src/exports/*"] + } + }, + "include": ["src"], + "references": [{ "path": "./tsconfig.node.json" }] +} diff --git a/wagmi-project/playgrounds/vite-core/tsconfig.node.json b/wagmi-project/playgrounds/vite-core/tsconfig.node.json new file mode 100644 index 000000000..42872c59f --- /dev/null +++ b/wagmi-project/playgrounds/vite-core/tsconfig.node.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "composite": true, + "skipLibCheck": true, + "module": "ESNext", + "moduleResolution": "bundler", + "allowSyntheticDefaultImports": true + }, + "include": ["vite.config.ts"] +} diff --git a/wagmi-project/playgrounds/vite-core/vite.config.ts b/wagmi-project/playgrounds/vite-core/vite.config.ts new file mode 100644 index 000000000..36f7f4e1b --- /dev/null +++ b/wagmi-project/playgrounds/vite-core/vite.config.ts @@ -0,0 +1,7 @@ +import react from '@vitejs/plugin-react' +import { defineConfig } from 'vite' + +// https://vitejs.dev/config/ +export default defineConfig({ + plugins: [react()], +}) diff --git a/wagmi-project/playgrounds/vite-react/.gitignore b/wagmi-project/playgrounds/vite-react/.gitignore new file mode 100644 index 000000000..1b226cc61 --- /dev/null +++ b/wagmi-project/playgrounds/vite-react/.gitignore @@ -0,0 +1,26 @@ +src/generated.ts + +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/wagmi-project/playgrounds/vite-react/index.html b/wagmi-project/playgrounds/vite-react/index.html new file mode 100644 index 000000000..c29681356 --- /dev/null +++ b/wagmi-project/playgrounds/vite-react/index.html @@ -0,0 +1,12 @@ + + + + + + Vite React + + +
+ + + diff --git a/wagmi-project/playgrounds/vite-react/package.json b/wagmi-project/playgrounds/vite-react/package.json new file mode 100644 index 000000000..8b09e075f --- /dev/null +++ b/wagmi-project/playgrounds/vite-react/package.json @@ -0,0 +1,29 @@ +{ + "name": "vite-react", + "private": true, + "type": "module", + "scripts": { + "dev": "vite", + "build": "tsc && vite build", + "preview": "vite preview" + }, + "dependencies": { + "@tanstack/query-sync-storage-persister": "5.0.5", + "@tanstack/react-query": ">=5.45.1", + "@tanstack/react-query-persist-client": "5.0.5", + "idb-keyval": "^6.2.1", + "react": ">=18.3.1", + "react-dom": ">=18.3.1", + "viem": "2.*", + "wagmi": "workspace:*" + }, + "devDependencies": { + "@tanstack/react-query-devtools": "5.0.5", + "@types/react": ">=18.3.1", + "@types/react-dom": ">=18.3.0", + "@vitejs/plugin-react": "^4.2.1", + "@wagmi/cli": "workspace:*", + "buffer": "^6.0.3", + "vite": "^5.4.19" + } +} diff --git a/wagmi-project/playgrounds/vite-react/public/manifest.json b/wagmi-project/playgrounds/vite-react/public/manifest.json new file mode 100644 index 000000000..c5d451711 --- /dev/null +++ b/wagmi-project/playgrounds/vite-react/public/manifest.json @@ -0,0 +1,5 @@ +{ + "name": "vite-react", + "description": "vite-react playground", + "iconPath": "favicon.ico" +} diff --git a/wagmi-project/playgrounds/vite-react/src/App.tsx b/wagmi-project/playgrounds/vite-react/src/App.tsx new file mode 100644 index 000000000..ad2e36b06 --- /dev/null +++ b/wagmi-project/playgrounds/vite-react/src/App.tsx @@ -0,0 +1,389 @@ +import type { FormEvent } from 'react' +import { type Hex, formatEther, parseAbi, parseEther } from 'viem' +import { + type BaseError, + useAccount, + useAccountEffect, + useBalance, + useBlockNumber, + useChainId, + useConnect, + useConnections, + useConnectorClient, + useDisconnect, + useEnsName, + useReadContract, + useReadContracts, + useSendTransaction, + useSignMessage, + useSwitchAccount, + useSwitchChain, + useWaitForTransactionReceipt, + useWriteContract, +} from 'wagmi' +import { optimism } from 'wagmi/chains' + +import { wagmiContractConfig } from './contracts' + +function App() { + useAccountEffect({ + onConnect(_data) { + // console.log('onConnect', data) + }, + onDisconnect() { + // console.log('onDisconnect') + }, + }) + + return ( + <> + + + + + + + + + + + + + + + ) +} + +function Account() { + const account = useAccount() + const { disconnect } = useDisconnect() + const { data: ensName } = useEnsName({ + address: account.address, + }) + + return ( +
+

Account

+ +
+ account: {account.address} {ensName} +
+ chainId: {account.chainId} +
+ status: {account.status} +
+ + {account.status !== 'disconnected' && ( + + )} +
+ ) +} + +function Connect() { + const chainId = useChainId() + const { connectors, connect, status, error } = useConnect() + + return ( +
+

Connect

+ {connectors.map((connector) => ( + + ))} +
{status}
+
{error?.message}
+
+ ) +} + +function SwitchAccount() { + const account = useAccount() + const { connectors, switchAccount } = useSwitchAccount() + + return ( +
+

Switch Account

+ + {connectors.map((connector) => ( + + ))} +
+ ) +} + +function SwitchChain() { + const chainId = useChainId() + const { chains, switchChain, error } = useSwitchChain() + + return ( +
+

Switch Chain

+ + {chains.map((chain) => ( + + ))} + + {error?.message} +
+ ) +} + +function SignMessage() { + const { data, signMessage } = useSignMessage() + + return ( +
+

Sign Message

+ +
{ + event.preventDefault() + const formData = new FormData(event.target as HTMLFormElement) + signMessage({ message: formData.get('message') as string }) + }} + > + + +
+ + {data} +
+ ) +} + +function Connections() { + const connections = useConnections() + + return ( +
+

Connections

+ + {connections.map((connection) => ( +
+
connector {connection.connector.name}
+
accounts: {JSON.stringify(connection.accounts)}
+
chainId: {connection.chainId}
+
+ ))} +
+ ) +} + +function Balance() { + const { address } = useAccount() + + const { data: default_ } = useBalance({ address }) + const { data: account_ } = useBalance({ address }) + const { data: optimism_ } = useBalance({ + address, + chainId: optimism.id, + }) + + return ( +
+

Balance

+ +
+ Balance (Default Chain):{' '} + {!!default_?.value && formatEther(default_.value)} +
+
+ Balance (Account Chain):{' '} + {!!account_?.value && formatEther(account_.value)} +
+
+ Balance (Optimism Chain):{' '} + {!!optimism_?.value && formatEther(optimism_.value)} +
+
+ ) +} + +function BlockNumber() { + const { data: default_ } = useBlockNumber({ watch: true }) + const { data: account_ } = useBlockNumber({ + watch: true, + }) + const { data: optimism_ } = useBlockNumber({ + chainId: optimism.id, + watch: true, + }) + + return ( +
+

Block Number

+ +
Block Number (Default Chain): {default_?.toString()}
+
Block Number (Account Chain): {account_?.toString()}
+
Block Number (Optimism): {optimism_?.toString()}
+
+ ) +} + +function ConnectorClient() { + const { data, error } = useConnectorClient() + return ( +
+

Connector Client

+ client {data?.account?.address} {data?.chain?.id} + {error?.message} +
+ ) +} + +function SendTransaction() { + const { data: hash, error, isPending, sendTransaction } = useSendTransaction() + + async function submit(e: FormEvent) { + e.preventDefault() + const formData = new FormData(e.target as HTMLFormElement) + const to = formData.get('address') as Hex + const value = formData.get('value') as string + sendTransaction({ to, value: parseEther(value) }) + } + + const { isLoading: isConfirming, isSuccess: isConfirmed } = + useWaitForTransactionReceipt({ + hash, + }) + + return ( +
+

Send Transaction

+
+ + + +
+ {hash &&
Transaction Hash: {hash}
} + {isConfirming && 'Waiting for confirmation...'} + {isConfirmed && 'Transaction confirmed.'} + {error && ( +
Error: {(error as BaseError).shortMessage || error.message}
+ )} +
+ ) +} + +function ReadContract() { + const { data: balance } = useReadContract({ + ...wagmiContractConfig, + functionName: 'balanceOf', + args: ['0x03A71968491d55603FFe1b11A9e23eF013f75bCF'], + }) + + return ( +
+

Read Contract

+
Balance: {balance?.toString()}
+
+ ) +} + +function ReadContracts() { + const { data } = useReadContracts({ + allowFailure: false, + contracts: [ + { + ...wagmiContractConfig, + functionName: 'balanceOf', + args: ['0x03A71968491d55603FFe1b11A9e23eF013f75bCF'], + }, + { + ...wagmiContractConfig, + functionName: 'ownerOf', + args: [69n], + }, + { + ...wagmiContractConfig, + functionName: 'totalSupply', + }, + ], + }) + const [balance, ownerOf, totalSupply] = data || [] + + return ( +
+

Read Contract

+
Balance: {balance?.toString()}
+
Owner of Token 69: {ownerOf?.toString()}
+
Total Supply: {totalSupply?.toString()}
+
+ ) +} + +function WriteContract() { + const { data: hash, error, isPending, writeContract } = useWriteContract() + + async function submit(e: FormEvent) { + e.preventDefault() + const formData = new FormData(e.target as HTMLFormElement) + const tokenId = formData.get('tokenId') as string + writeContract({ + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + abi: parseAbi(['function mint(uint256 tokenId)']), + functionName: 'mint', + args: [BigInt(tokenId)], + }) + } + + const { isLoading: isConfirming, isSuccess: isConfirmed } = + useWaitForTransactionReceipt({ + hash, + }) + + return ( +
+

Write Contract

+
+ + +
+ {hash &&
Transaction Hash: {hash}
} + {isConfirming && 'Waiting for confirmation...'} + {isConfirmed && 'Transaction confirmed.'} + {error && ( +
Error: {(error as BaseError).shortMessage || error.message}
+ )} +
+ ) +} + +export default App diff --git a/wagmi-project/playgrounds/vite-react/src/contracts.ts b/wagmi-project/playgrounds/vite-react/src/contracts.ts new file mode 100644 index 000000000..d7d66754a --- /dev/null +++ b/wagmi-project/playgrounds/vite-react/src/contracts.ts @@ -0,0 +1,202 @@ +export const wagmiContractConfig = { + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + abi: [ + { inputs: [], stateMutability: 'nonpayable', type: 'constructor' }, + { + anonymous: false, + inputs: [ + { + indexed: true, + name: 'owner', + type: 'address', + }, + { + indexed: true, + name: 'approved', + type: 'address', + }, + { + indexed: true, + name: 'tokenId', + type: 'uint256', + }, + ], + name: 'Approval', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + name: 'owner', + type: 'address', + }, + { + indexed: true, + name: 'operator', + type: 'address', + }, + { + indexed: false, + name: 'approved', + type: 'bool', + }, + ], + name: 'ApprovalForAll', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + name: 'from', + type: 'address', + }, + { indexed: true, name: 'to', type: 'address' }, + { + indexed: true, + name: 'tokenId', + type: 'uint256', + }, + ], + name: 'Transfer', + type: 'event', + }, + { + inputs: [ + { name: 'to', type: 'address' }, + { name: 'tokenId', type: 'uint256' }, + ], + name: 'approve', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ name: 'owner', type: 'address' }], + name: 'balanceOf', + outputs: [{ name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ name: 'tokenId', type: 'uint256' }], + name: 'getApproved', + outputs: [{ name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { name: 'owner', type: 'address' }, + { name: 'operator', type: 'address' }, + ], + name: 'isApprovedForAll', + outputs: [{ name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'mint', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'tokenId', type: 'uint256' }], + name: 'mint', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'name', + outputs: [{ name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ name: 'tokenId', type: 'uint256' }], + name: 'ownerOf', + outputs: [{ name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { name: 'from', type: 'address' }, + { name: 'to', type: 'address' }, + { name: 'tokenId', type: 'uint256' }, + ], + name: 'safeTransferFrom', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { name: 'from', type: 'address' }, + { name: 'to', type: 'address' }, + { name: 'tokenId', type: 'uint256' }, + { name: '_data', type: 'bytes' }, + ], + name: 'safeTransferFrom', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { name: 'operator', type: 'address' }, + { name: 'approved', type: 'bool' }, + ], + name: 'setApprovalForAll', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ name: 'interfaceId', type: 'bytes4' }], + name: 'supportsInterface', + outputs: [{ name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'symbol', + outputs: [{ name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ name: 'tokenId', type: 'uint256' }], + name: 'tokenURI', + outputs: [{ name: '', type: 'string' }], + stateMutability: 'pure', + type: 'function', + }, + { + inputs: [], + name: 'totalSupply', + outputs: [{ name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { name: 'from', type: 'address' }, + { name: 'to', type: 'address' }, + { name: 'tokenId', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + ], +} as const diff --git a/wagmi-project/playgrounds/vite-react/src/index.css b/wagmi-project/playgrounds/vite-react/src/index.css new file mode 100644 index 000000000..0733a7ee6 --- /dev/null +++ b/wagmi-project/playgrounds/vite-react/src/index.css @@ -0,0 +1,21 @@ +:root { + background-color: #181818; + color: rgba(255, 255, 255, 0.87); + color-scheme: light dark; + font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; + font-synthesis: none; + font-weight: 400; + line-height: 1.5; + text-rendering: optimizeLegibility; + + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + -webkit-text-size-adjust: 100%; +} + +@media (prefers-color-scheme: light) { + :root { + background-color: #f8f8f8; + color: #181818; + } +} diff --git a/wagmi-project/playgrounds/vite-react/src/main.tsx b/wagmi-project/playgrounds/vite-react/src/main.tsx new file mode 100644 index 000000000..ad801a958 --- /dev/null +++ b/wagmi-project/playgrounds/vite-react/src/main.tsx @@ -0,0 +1,49 @@ +import { Buffer } from 'buffer' +import { createSyncStoragePersister } from '@tanstack/query-sync-storage-persister' +import { QueryClient } from '@tanstack/react-query' +import { ReactQueryDevtools } from '@tanstack/react-query-devtools' +import { PersistQueryClientProvider } from '@tanstack/react-query-persist-client' +import React from 'react' +import ReactDOM from 'react-dom/client' +import { WagmiProvider, deserialize, serialize } from 'wagmi' + +import './index.css' + +// `@coinbase-wallet/sdk` uses `Buffer` +globalThis.Buffer = Buffer + +import App from './App.tsx' +import { config } from './wagmi.ts' + +const queryClient = new QueryClient({ + defaultOptions: { + queries: { + gcTime: 1_000 * 60 * 60 * 24, // 24 hours + networkMode: 'offlineFirst', + refetchOnWindowFocus: false, + retry: 0, + }, + mutations: { networkMode: 'offlineFirst' }, + }, +}) + +const persister = createSyncStoragePersister({ + key: 'vite-react.cache', + serialize, + storage: window.localStorage, + deserialize, +}) + +ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render( + + + + + + + + , +) diff --git a/wagmi-project/playgrounds/vite-react/src/vite-env.d.ts b/wagmi-project/playgrounds/vite-react/src/vite-env.d.ts new file mode 100644 index 000000000..11f02fe2a --- /dev/null +++ b/wagmi-project/playgrounds/vite-react/src/vite-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/wagmi-project/playgrounds/vite-react/src/wagmi.ts b/wagmi-project/playgrounds/vite-react/src/wagmi.ts new file mode 100644 index 000000000..94b86f6fd --- /dev/null +++ b/wagmi-project/playgrounds/vite-react/src/wagmi.ts @@ -0,0 +1,40 @@ +import { del, get, set } from 'idb-keyval' +import { http, createConfig } from 'wagmi' +import { celo, mainnet, optimism, sepolia } from 'wagmi/chains' +import { coinbaseWallet, metaMask, walletConnect } from 'wagmi/connectors' + +// biome-ignore lint/correctness/noUnusedVariables: +const indexedDBStorage = { + async getItem(name: string) { + return get(name) + }, + async setItem(name: string, value: string) { + await set(name, value) + }, + async removeItem(name: string) { + await del(name) + }, +} + +export const config = createConfig({ + chains: [mainnet, sepolia, optimism, celo], + connectors: [ + walletConnect({ + projectId: import.meta.env.VITE_WC_PROJECT_ID, + }), + coinbaseWallet(), + metaMask(), + ], + transports: { + [mainnet.id]: http(), + [sepolia.id]: http(), + [optimism.id]: http(), + [celo.id]: http(), + }, +}) + +declare module 'wagmi' { + interface Register { + config: typeof config + } +} diff --git a/wagmi-project/playgrounds/vite-react/tsconfig.json b/wagmi-project/playgrounds/vite-react/tsconfig.json new file mode 100644 index 000000000..2a91e18f4 --- /dev/null +++ b/wagmi-project/playgrounds/vite-react/tsconfig.json @@ -0,0 +1,30 @@ +{ + "compilerOptions": { + "target": "ESNext", + "lib": ["DOM", "DOM.Iterable", "ESNext"], + "module": "ESNext", + "skipLibCheck": true, + + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "react-jsx", + + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true, + + "paths": { + "@wagmi/connectors": ["../../packages/connectors/src/exports"], + "@wagmi/core": ["../../packages/core/src/exports"], + "@wagmi/core/*": ["../../packages/core/src/exports/*"], + "wagmi": ["../../packages/react/src/exports"], + "wagmi/*": ["../../packages/react/src/exports/*"] + } + }, + "include": ["src"], + "references": [{ "path": "./tsconfig.node.json" }] +} diff --git a/wagmi-project/playgrounds/vite-react/tsconfig.node.json b/wagmi-project/playgrounds/vite-react/tsconfig.node.json new file mode 100644 index 000000000..42872c59f --- /dev/null +++ b/wagmi-project/playgrounds/vite-react/tsconfig.node.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "composite": true, + "skipLibCheck": true, + "module": "ESNext", + "moduleResolution": "bundler", + "allowSyntheticDefaultImports": true + }, + "include": ["vite.config.ts"] +} diff --git a/wagmi-project/playgrounds/vite-react/vite.config.ts b/wagmi-project/playgrounds/vite-react/vite.config.ts new file mode 100644 index 000000000..36f7f4e1b --- /dev/null +++ b/wagmi-project/playgrounds/vite-react/vite.config.ts @@ -0,0 +1,7 @@ +import react from '@vitejs/plugin-react' +import { defineConfig } from 'vite' + +// https://vitejs.dev/config/ +export default defineConfig({ + plugins: [react()], +}) diff --git a/wagmi-project/playgrounds/vite-react/wagmi.config.ts b/wagmi-project/playgrounds/vite-react/wagmi.config.ts new file mode 100644 index 000000000..d524220b0 --- /dev/null +++ b/wagmi-project/playgrounds/vite-react/wagmi.config.ts @@ -0,0 +1,17 @@ +import { defineConfig } from '@wagmi/cli' +import { foundry, hardhat } from '@wagmi/cli/plugins' + +export default defineConfig({ + out: 'src/generated.ts', + contracts: [], + plugins: [ + foundry({ + namePrefix: 'foundry', + project: '../../packages/cli/src/plugins/__fixtures__/foundry', + }), + hardhat({ + namePrefix: 'hardhat', + project: '../../packages/cli/src/plugins/__fixtures__/hardhat', + }), + ], +}) diff --git a/wagmi-project/playgrounds/vite-vue/.gitignore b/wagmi-project/playgrounds/vite-vue/.gitignore new file mode 100644 index 000000000..a547bf36d --- /dev/null +++ b/wagmi-project/playgrounds/vite-vue/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/wagmi-project/playgrounds/vite-vue/index.html b/wagmi-project/playgrounds/vite-vue/index.html new file mode 100644 index 000000000..3f59f5911 --- /dev/null +++ b/wagmi-project/playgrounds/vite-vue/index.html @@ -0,0 +1,13 @@ + + + + + + + Vite Vue + + +
+ + + diff --git a/wagmi-project/playgrounds/vite-vue/package.json b/wagmi-project/playgrounds/vite-vue/package.json new file mode 100644 index 000000000..bd4b1938a --- /dev/null +++ b/wagmi-project/playgrounds/vite-vue/package.json @@ -0,0 +1,22 @@ +{ + "name": "vite-vue", + "private": true, + "type": "module", + "scripts": { + "dev": "vite", + "build": "vue-tsc && vite build", + "preview": "vite preview" + }, + "dependencies": { + "@tanstack/vue-query": ">=5.45.0", + "@wagmi/vue": "workspace:*", + "viem": "2.*", + "vue": ">=3.4.21" + }, + "devDependencies": { + "@vitejs/plugin-vue": "^5.0.4", + "buffer": "^6.0.3", + "vite": "^5.4.19", + "vue-tsc": "^2.0.6" + } +} diff --git a/wagmi-project/playgrounds/vite-vue/public/vite.svg b/wagmi-project/playgrounds/vite-vue/public/vite.svg new file mode 100644 index 000000000..e7b8dfb1b --- /dev/null +++ b/wagmi-project/playgrounds/vite-vue/public/vite.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/wagmi-project/playgrounds/vite-vue/src/App.vue b/wagmi-project/playgrounds/vite-vue/src/App.vue new file mode 100644 index 000000000..5a7f194a0 --- /dev/null +++ b/wagmi-project/playgrounds/vite-vue/src/App.vue @@ -0,0 +1,29 @@ + + + diff --git a/wagmi-project/playgrounds/vite-vue/src/components/Account.vue b/wagmi-project/playgrounds/vite-vue/src/components/Account.vue new file mode 100644 index 000000000..33f1491da --- /dev/null +++ b/wagmi-project/playgrounds/vite-vue/src/components/Account.vue @@ -0,0 +1,22 @@ + + + diff --git a/wagmi-project/playgrounds/vite-vue/src/components/Balance.vue b/wagmi-project/playgrounds/vite-vue/src/components/Balance.vue new file mode 100644 index 000000000..b064d45e9 --- /dev/null +++ b/wagmi-project/playgrounds/vite-vue/src/components/Balance.vue @@ -0,0 +1,12 @@ + + + diff --git a/wagmi-project/playgrounds/vite-vue/src/components/BlockNumber.vue b/wagmi-project/playgrounds/vite-vue/src/components/BlockNumber.vue new file mode 100644 index 000000000..25f8744a7 --- /dev/null +++ b/wagmi-project/playgrounds/vite-vue/src/components/BlockNumber.vue @@ -0,0 +1,17 @@ + + + diff --git a/wagmi-project/playgrounds/vite-vue/src/components/Client.vue b/wagmi-project/playgrounds/vite-vue/src/components/Client.vue new file mode 100644 index 000000000..52e7f12f7 --- /dev/null +++ b/wagmi-project/playgrounds/vite-vue/src/components/Client.vue @@ -0,0 +1,14 @@ + + + diff --git a/wagmi-project/playgrounds/vite-vue/src/components/Connect.vue b/wagmi-project/playgrounds/vite-vue/src/components/Connect.vue new file mode 100644 index 000000000..93320448c --- /dev/null +++ b/wagmi-project/playgrounds/vite-vue/src/components/Connect.vue @@ -0,0 +1,19 @@ + + + diff --git a/wagmi-project/playgrounds/vite-vue/src/components/Connections.vue b/wagmi-project/playgrounds/vite-vue/src/components/Connections.vue new file mode 100644 index 000000000..21405f248 --- /dev/null +++ b/wagmi-project/playgrounds/vite-vue/src/components/Connections.vue @@ -0,0 +1,15 @@ + + + diff --git a/wagmi-project/playgrounds/vite-vue/src/components/ConnectorClient.vue b/wagmi-project/playgrounds/vite-vue/src/components/ConnectorClient.vue new file mode 100644 index 000000000..157156d3e --- /dev/null +++ b/wagmi-project/playgrounds/vite-vue/src/components/ConnectorClient.vue @@ -0,0 +1,14 @@ + + + diff --git a/wagmi-project/playgrounds/vite-vue/src/components/ReadContract.vue b/wagmi-project/playgrounds/vite-vue/src/components/ReadContract.vue new file mode 100644 index 000000000..2f236ac9e --- /dev/null +++ b/wagmi-project/playgrounds/vite-vue/src/components/ReadContract.vue @@ -0,0 +1,16 @@ + + + diff --git a/wagmi-project/playgrounds/vite-vue/src/components/SendTransaction.vue b/wagmi-project/playgrounds/vite-vue/src/components/SendTransaction.vue new file mode 100644 index 000000000..8a509b5e5 --- /dev/null +++ b/wagmi-project/playgrounds/vite-vue/src/components/SendTransaction.vue @@ -0,0 +1,35 @@ + + + diff --git a/wagmi-project/playgrounds/vite-vue/src/components/SwitchAccount.vue b/wagmi-project/playgrounds/vite-vue/src/components/SwitchAccount.vue new file mode 100644 index 000000000..bc1814bfa --- /dev/null +++ b/wagmi-project/playgrounds/vite-vue/src/components/SwitchAccount.vue @@ -0,0 +1,20 @@ + + + diff --git a/wagmi-project/playgrounds/vite-vue/src/components/SwitchChain.vue b/wagmi-project/playgrounds/vite-vue/src/components/SwitchChain.vue new file mode 100644 index 000000000..b38505204 --- /dev/null +++ b/wagmi-project/playgrounds/vite-vue/src/components/SwitchChain.vue @@ -0,0 +1,22 @@ + + + diff --git a/wagmi-project/playgrounds/vite-vue/src/components/WriteContract.vue b/wagmi-project/playgrounds/vite-vue/src/components/WriteContract.vue new file mode 100644 index 000000000..aa3102b3f --- /dev/null +++ b/wagmi-project/playgrounds/vite-vue/src/components/WriteContract.vue @@ -0,0 +1,28 @@ + + + diff --git a/wagmi-project/playgrounds/vite-vue/src/contracts.ts b/wagmi-project/playgrounds/vite-vue/src/contracts.ts new file mode 100644 index 000000000..d7d66754a --- /dev/null +++ b/wagmi-project/playgrounds/vite-vue/src/contracts.ts @@ -0,0 +1,202 @@ +export const wagmiContractConfig = { + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + abi: [ + { inputs: [], stateMutability: 'nonpayable', type: 'constructor' }, + { + anonymous: false, + inputs: [ + { + indexed: true, + name: 'owner', + type: 'address', + }, + { + indexed: true, + name: 'approved', + type: 'address', + }, + { + indexed: true, + name: 'tokenId', + type: 'uint256', + }, + ], + name: 'Approval', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + name: 'owner', + type: 'address', + }, + { + indexed: true, + name: 'operator', + type: 'address', + }, + { + indexed: false, + name: 'approved', + type: 'bool', + }, + ], + name: 'ApprovalForAll', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + name: 'from', + type: 'address', + }, + { indexed: true, name: 'to', type: 'address' }, + { + indexed: true, + name: 'tokenId', + type: 'uint256', + }, + ], + name: 'Transfer', + type: 'event', + }, + { + inputs: [ + { name: 'to', type: 'address' }, + { name: 'tokenId', type: 'uint256' }, + ], + name: 'approve', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ name: 'owner', type: 'address' }], + name: 'balanceOf', + outputs: [{ name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ name: 'tokenId', type: 'uint256' }], + name: 'getApproved', + outputs: [{ name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { name: 'owner', type: 'address' }, + { name: 'operator', type: 'address' }, + ], + name: 'isApprovedForAll', + outputs: [{ name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'mint', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'tokenId', type: 'uint256' }], + name: 'mint', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'name', + outputs: [{ name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ name: 'tokenId', type: 'uint256' }], + name: 'ownerOf', + outputs: [{ name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { name: 'from', type: 'address' }, + { name: 'to', type: 'address' }, + { name: 'tokenId', type: 'uint256' }, + ], + name: 'safeTransferFrom', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { name: 'from', type: 'address' }, + { name: 'to', type: 'address' }, + { name: 'tokenId', type: 'uint256' }, + { name: '_data', type: 'bytes' }, + ], + name: 'safeTransferFrom', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { name: 'operator', type: 'address' }, + { name: 'approved', type: 'bool' }, + ], + name: 'setApprovalForAll', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ name: 'interfaceId', type: 'bytes4' }], + name: 'supportsInterface', + outputs: [{ name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'symbol', + outputs: [{ name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ name: 'tokenId', type: 'uint256' }], + name: 'tokenURI', + outputs: [{ name: '', type: 'string' }], + stateMutability: 'pure', + type: 'function', + }, + { + inputs: [], + name: 'totalSupply', + outputs: [{ name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { name: 'from', type: 'address' }, + { name: 'to', type: 'address' }, + { name: 'tokenId', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + ], +} as const diff --git a/wagmi-project/playgrounds/vite-vue/src/main.ts b/wagmi-project/playgrounds/vite-vue/src/main.ts new file mode 100644 index 000000000..820eed372 --- /dev/null +++ b/wagmi-project/playgrounds/vite-vue/src/main.ts @@ -0,0 +1,17 @@ +import { Buffer } from 'buffer' +import { VueQueryPlugin } from '@tanstack/vue-query' +import { WagmiPlugin } from '@wagmi/vue' +import { createApp } from 'vue' + +// `@coinbase-wallet/sdk` uses `Buffer` +globalThis.Buffer = Buffer + +import App from './App.vue' +import './style.css' +import { config } from './wagmi' + +const app = createApp(App) + +app.use(WagmiPlugin, { config }).use(VueQueryPlugin, {}) + +app.mount('#app') diff --git a/wagmi-project/playgrounds/vite-vue/src/style.css b/wagmi-project/playgrounds/vite-vue/src/style.css new file mode 100644 index 000000000..0733a7ee6 --- /dev/null +++ b/wagmi-project/playgrounds/vite-vue/src/style.css @@ -0,0 +1,21 @@ +:root { + background-color: #181818; + color: rgba(255, 255, 255, 0.87); + color-scheme: light dark; + font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; + font-synthesis: none; + font-weight: 400; + line-height: 1.5; + text-rendering: optimizeLegibility; + + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + -webkit-text-size-adjust: 100%; +} + +@media (prefers-color-scheme: light) { + :root { + background-color: #f8f8f8; + color: #181818; + } +} diff --git a/wagmi-project/playgrounds/vite-vue/src/vite-env.d.ts b/wagmi-project/playgrounds/vite-vue/src/vite-env.d.ts new file mode 100644 index 000000000..11f02fe2a --- /dev/null +++ b/wagmi-project/playgrounds/vite-vue/src/vite-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/wagmi-project/playgrounds/vite-vue/src/wagmi.ts b/wagmi-project/playgrounds/vite-vue/src/wagmi.ts new file mode 100644 index 000000000..f5b3f286c --- /dev/null +++ b/wagmi-project/playgrounds/vite-vue/src/wagmi.ts @@ -0,0 +1,26 @@ +import { http, createConfig, createStorage } from '@wagmi/vue' +import { mainnet, optimism, sepolia } from '@wagmi/vue/chains' +import { coinbaseWallet, metaMask, walletConnect } from '@wagmi/vue/connectors' + +export const config = createConfig({ + chains: [mainnet, sepolia, optimism], + connectors: [ + walletConnect({ + projectId: import.meta.env.VITE_WC_PROJECT_ID, + }), + coinbaseWallet({ appName: 'Vite Vue Playground', darkMode: true }), + metaMask(), + ], + storage: createStorage({ storage: localStorage, key: 'vite-vue' }), + transports: { + [mainnet.id]: http(), + [sepolia.id]: http(), + [optimism.id]: http(), + }, +}) + +declare module '@wagmi/vue' { + interface Register { + config: typeof config + } +} diff --git a/wagmi-project/playgrounds/vite-vue/tsconfig.json b/wagmi-project/playgrounds/vite-vue/tsconfig.json new file mode 100644 index 000000000..18f095cd2 --- /dev/null +++ b/wagmi-project/playgrounds/vite-vue/tsconfig.json @@ -0,0 +1,23 @@ +{ + "compilerOptions": { + "target": "ES2020", + "useDefineForClassFields": true, + "module": "ESNext", + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "skipLibCheck": true, + + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "preserve", + + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true + }, + "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"], + "references": [{ "path": "./tsconfig.node.json" }] +} diff --git a/wagmi-project/playgrounds/vite-vue/tsconfig.node.json b/wagmi-project/playgrounds/vite-vue/tsconfig.node.json new file mode 100644 index 000000000..97ede7ee6 --- /dev/null +++ b/wagmi-project/playgrounds/vite-vue/tsconfig.node.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "composite": true, + "skipLibCheck": true, + "module": "ESNext", + "moduleResolution": "bundler", + "allowSyntheticDefaultImports": true, + "strict": true + }, + "include": ["vite.config.ts"] +} diff --git a/wagmi-project/playgrounds/vite-vue/vite.config.ts b/wagmi-project/playgrounds/vite-vue/vite.config.ts new file mode 100644 index 000000000..c3fa62d86 --- /dev/null +++ b/wagmi-project/playgrounds/vite-vue/vite.config.ts @@ -0,0 +1,7 @@ +import vue from '@vitejs/plugin-vue' +import { defineConfig } from 'vite' + +// https://vitejs.dev/config/ +export default defineConfig({ + plugins: [vue()], +}) diff --git a/wagmi-project/pnpm-lock.yaml b/wagmi-project/pnpm-lock.yaml new file mode 100644 index 000000000..161a4d590 --- /dev/null +++ b/wagmi-project/pnpm-lock.yaml @@ -0,0 +1,19645 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: false + excludeLinksFromLockfile: false + +catalogs: + default: + '@tanstack/query-core': + specifier: 5.49.1 + version: 5.49.1 + '@tanstack/react-query': + specifier: 5.49.2 + version: 5.49.2 + '@tanstack/vue-query': + specifier: 5.49.1 + version: 5.49.1 + '@testing-library/dom': + specifier: 10.4.0 + version: 10.4.0 + '@testing-library/react': + specifier: 16.0.1 + version: 16.0.1 + '@types/react': + specifier: 18.3.1 + version: 18.3.1 + '@types/react-dom': + specifier: 18.3.0 + version: 18.3.0 + react: + specifier: 18.3.1 + version: 18.3.1 + react-dom: + specifier: 18.3.1 + version: 18.3.1 + vue: + specifier: 3.4.27 + version: 3.4.27 + +importers: + + .: + devDependencies: + '@arethetypeswrong/cli': + specifier: ^0.16.4 + version: 0.16.4 + '@biomejs/biome': + specifier: ^1.9.4 + version: 1.9.4 + '@changesets/changelog-github': + specifier: 0.4.6 + version: 0.4.6(encoding@0.1.13) + '@changesets/cli': + specifier: ^2.27.8 + version: 2.27.8 + '@types/bun': + specifier: ^1.1.10 + version: 1.1.10 + '@vitest/coverage-v8': + specifier: ^2.1.1 + version: 2.1.1(vitest@2.1.9(@types/node@24.0.1)(happy-dom@15.10.2)(msw@2.4.9(typescript@5.8.3))(terser@5.39.2)) + '@wagmi/test': + specifier: workspace:* + version: link:packages/test + bun: + specifier: ^1.1.30 + version: 1.1.30 + happy-dom: + specifier: ^15.10.2 + version: 15.10.2 + knip: + specifier: ^5.30.6 + version: 5.30.6(@types/node@24.0.1)(typescript@5.8.3) + prool: + specifier: ^0.0.23 + version: 0.0.23 + publint: + specifier: ^0.3.0 + version: 0.3.12 + sherif: + specifier: ^1.0.0 + version: 1.0.0 + simple-git-hooks: + specifier: ^2.11.1 + version: 2.11.1 + typescript: + specifier: 5.8.3 + version: 5.8.3 + viem: + specifier: 2.29.2 + version: 2.29.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@6.0.5)(zod@3.25.20) + vitest: + specifier: ^2.1.9 + version: 2.1.9(@types/node@24.0.1)(happy-dom@15.10.2)(msw@2.4.9(typescript@5.8.3))(terser@5.39.2) + + packages/cli: + dependencies: + abitype: + specifier: ^1.0.4 + version: 1.0.4(typescript@5.8.3)(zod@3.25.20) + bundle-require: + specifier: ^5.1.0 + version: 5.1.0(esbuild@0.25.5) + cac: + specifier: ^6.7.14 + version: 6.7.14 + change-case: + specifier: ^5.4.4 + version: 5.4.4 + chokidar: + specifier: 4.0.3 + version: 4.0.3 + dedent: + specifier: ^1.5.3 + version: 1.6.0 + dotenv: + specifier: ^16.3.1 + version: 16.3.1 + dotenv-expand: + specifier: ^10.0.0 + version: 10.0.0 + esbuild: + specifier: ~0.25.5 + version: 0.25.5 + escalade: + specifier: 3.2.0 + version: 3.2.0 + fdir: + specifier: ^6.1.1 + version: 6.1.1(picomatch@4.0.2) + nanospinner: + specifier: 1.2.2 + version: 1.2.2 + pathe: + specifier: ^2.0.3 + version: 2.0.3 + picocolors: + specifier: ^1.0.0 + version: 1.0.0 + picomatch: + specifier: ^4.0.2 + version: 4.0.2 + prettier: + specifier: ^3.0.3 + version: 3.0.3 + viem: + specifier: 2.x + version: 2.10.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@6.0.5)(zod@3.25.20) + zod: + specifier: ^3.22.3 + version: 3.25.20 + devDependencies: + '@types/dedent': + specifier: ^0.7.2 + version: 0.7.2 + '@types/node': + specifier: ^22.14.0 + version: 22.15.31 + fixturez: + specifier: ^1.1.0 + version: 1.1.0 + msw: + specifier: ^2.4.9 + version: 2.4.9(typescript@5.8.3) + + packages/cli/src/plugins/__fixtures__/hardhat: + devDependencies: + hardhat: + specifier: ^2.22.3 + version: 2.22.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10) + + packages/connectors: + dependencies: + '@coinbase/wallet-sdk': + specifier: 4.3.0 + version: 4.3.0 + '@metamask/sdk': + specifier: 0.32.1 + version: 0.32.1(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) + '@safe-global/safe-apps-provider': + specifier: 0.18.6 + version: 0.18.6(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + '@safe-global/safe-apps-sdk': + specifier: 9.1.0 + version: 9.1.0(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + '@walletconnect/ethereum-provider': + specifier: 2.20.2 + version: 2.20.2(@types/react@18.3.1)(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + cbw-sdk: + specifier: npm:@coinbase/wallet-sdk@3.9.3 + version: '@coinbase/wallet-sdk@3.9.3' + devDependencies: + '@wagmi/core': + specifier: workspace:* + version: link:../core + msw: + specifier: ^2.4.9 + version: 2.4.9(typescript@5.8.3) + + packages/core: + dependencies: + eventemitter3: + specifier: 5.0.1 + version: 5.0.1 + mipd: + specifier: 0.0.7 + version: 0.0.7(typescript@5.8.3) + zustand: + specifier: 5.0.0 + version: 5.0.0(@types/react@18.3.1)(react@18.3.1)(use-sync-external-store@1.4.0(react@18.3.1)) + devDependencies: + '@tanstack/query-core': + specifier: 'catalog:' + version: 5.49.1 + + packages/create-wagmi: + dependencies: + cac: + specifier: ^6.7.14 + version: 6.7.14 + cross-spawn: + specifier: ^7.0.5 + version: 7.0.6 + picocolors: + specifier: ^1.0.0 + version: 1.0.0 + prompts: + specifier: ^2.4.2 + version: 2.4.2 + devDependencies: + '@types/cross-spawn': + specifier: ^6.0.6 + version: 6.0.6 + '@types/node': + specifier: ^20.12.10 + version: 20.12.10 + '@types/prompts': + specifier: ^2.4.9 + version: 2.4.9 + + packages/react: + dependencies: + '@wagmi/connectors': + specifier: workspace:* + version: link:../connectors + '@wagmi/core': + specifier: workspace:* + version: link:../core + use-sync-external-store: + specifier: 1.4.0 + version: 1.4.0(react@18.3.1) + devDependencies: + '@tanstack/react-query': + specifier: 'catalog:' + version: 5.49.2(react@18.3.1) + '@testing-library/dom': + specifier: 'catalog:' + version: 10.4.0 + '@testing-library/react': + specifier: 'catalog:' + version: 16.0.1(@testing-library/dom@10.4.0)(@types/react-dom@18.3.0)(@types/react@18.3.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@types/react': + specifier: 'catalog:' + version: 18.3.1 + '@types/react-dom': + specifier: 'catalog:' + version: 18.3.0 + '@types/use-sync-external-store': + specifier: ^0.0.6 + version: 0.0.6 + react: + specifier: 'catalog:' + version: 18.3.1 + react-dom: + specifier: 'catalog:' + version: 18.3.1(react@18.3.1) + + packages/register-tests/react: + dependencies: + '@tanstack/react-query': + specifier: 'catalog:' + version: 5.49.2(react@18.3.1) + react: + specifier: 'catalog:' + version: 18.3.1 + wagmi: + specifier: workspace:* + version: link:../../react + devDependencies: + '@types/react': + specifier: 'catalog:' + version: 18.3.1 + + packages/register-tests/vue: + dependencies: + '@tanstack/vue-query': + specifier: 'catalog:' + version: 5.49.1(vue@3.4.27(typescript@5.8.3)) + '@wagmi/vue': + specifier: workspace:* + version: link:../../vue + vue: + specifier: 'catalog:' + version: 3.4.27(typescript@5.8.3) + + packages/test: + devDependencies: + '@tanstack/react-query': + specifier: 'catalog:' + version: 5.49.2(react@18.3.1) + '@tanstack/vue-query': + specifier: 'catalog:' + version: 5.49.1(vue@3.4.27(typescript@5.8.3)) + '@testing-library/dom': + specifier: 'catalog:' + version: 10.4.0 + '@testing-library/react': + specifier: 'catalog:' + version: 16.0.1(@testing-library/dom@10.4.0)(@types/react-dom@18.3.0)(@types/react@18.3.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@types/react': + specifier: 'catalog:' + version: 18.3.1 + '@types/react-dom': + specifier: 'catalog:' + version: 18.3.0 + '@wagmi/core': + specifier: workspace:* + version: link:../core + '@wagmi/vue': + specifier: workspace:* + version: link:../vue + react: + specifier: 'catalog:' + version: 18.3.1 + react-dom: + specifier: 'catalog:' + version: 18.3.1(react@18.3.1) + vue: + specifier: 'catalog:' + version: 3.4.27(typescript@5.8.3) + wagmi: + specifier: workspace:* + version: link:../react + + packages/vue: + dependencies: + '@wagmi/connectors': + specifier: workspace:* + version: link:../connectors + '@wagmi/core': + specifier: workspace:* + version: link:../core + devDependencies: + '@nuxt/schema': + specifier: ^3.11.2 + version: 3.11.2(rollup@4.41.0) + '@tanstack/vue-query': + specifier: 'catalog:' + version: 5.49.1(vue@3.4.27(typescript@5.8.3)) + '@vue/test-utils': + specifier: ^2.4.6 + version: 2.4.6 + nuxt: + specifier: ^3.16.0 + version: 3.16.0(@biomejs/biome@1.9.4)(@parcel/watcher@2.5.1)(@types/node@24.0.1)(bufferutil@4.0.9)(db0@0.3.2)(encoding@0.1.13)(idb-keyval@6.2.1)(ioredis@5.6.1)(magicast@0.3.5)(rollup@4.41.0)(terser@5.39.2)(typescript@5.8.3)(utf-8-validate@6.0.5)(vite@6.3.5(@types/node@24.0.1)(jiti@2.4.2)(terser@5.39.2)(yaml@2.8.0))(yaml@2.8.0) + vue: + specifier: 'catalog:' + version: 3.4.27(typescript@5.8.3) + + playgrounds/next: + dependencies: + '@next/bundle-analyzer': + specifier: ^15.2.4 + version: 15.3.3(bufferutil@4.0.8)(utf-8-validate@6.0.5) + '@tanstack/react-query': + specifier: '>=5.45.1' + version: 5.49.2(react@18.3.1) + next: + specifier: 15.3.3 + version: 15.3.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: + specifier: '>=18.3.1' + version: 18.3.1 + react-dom: + specifier: '>=18.3.1' + version: 18.3.1(react@18.3.1) + viem: + specifier: 2.* + version: 2.10.8(bufferutil@4.0.8)(typescript@5.8.3)(utf-8-validate@6.0.5)(zod@3.25.20) + wagmi: + specifier: workspace:* + version: link:../../packages/react + devDependencies: + '@types/node': + specifier: ^22.14.1 + version: 22.15.31 + '@types/react': + specifier: '>=18.3.1' + version: 18.3.1 + '@types/react-dom': + specifier: '>=18.3.0' + version: 18.3.0 + bufferutil: + specifier: ^4.0.8 + version: 4.0.8 + encoding: + specifier: ^0.1.13 + version: 0.1.13 + lokijs: + specifier: ^1.5.12 + version: 1.5.12 + pino-pretty: + specifier: ^13.0.0 + version: 13.0.0 + supports-color: + specifier: ^9.4.0 + version: 9.4.0 + utf-8-validate: + specifier: ^6.0.5 + version: 6.0.5 + + playgrounds/nuxt: + dependencies: + '@tanstack/vue-query': + specifier: '>=5.45.0' + version: 5.49.1(vue@3.4.27(typescript@5.8.3)) + '@wagmi/vue': + specifier: workspace:* + version: link:../../packages/vue + nuxt: + specifier: ^3.16.0 + version: 3.16.0(@biomejs/biome@1.9.4)(@parcel/watcher@2.5.1)(@types/node@24.0.1)(bufferutil@4.0.9)(db0@0.3.2)(encoding@0.1.13)(idb-keyval@6.2.1)(ioredis@5.6.1)(magicast@0.3.5)(rollup@4.41.0)(terser@5.39.2)(typescript@5.8.3)(utf-8-validate@6.0.5)(vite@6.3.5(@types/node@24.0.1)(jiti@2.4.2)(terser@5.39.2)(yaml@2.8.0))(yaml@2.8.0) + viem: + specifier: 2.* + version: 2.10.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@6.0.5)(zod@3.25.20) + vue: + specifier: '>=3.4.21' + version: 3.4.27(typescript@5.8.3) + vue-router: + specifier: ^4.3.2 + version: 4.3.2(vue@3.4.27(typescript@5.8.3)) + + playgrounds/vite-core: + dependencies: + '@wagmi/connectors': + specifier: workspace:* + version: link:../../packages/connectors + '@wagmi/core': + specifier: workspace:* + version: link:../../packages/core + react: + specifier: '>=18.3.1' + version: 18.3.1 + react-dom: + specifier: '>=18.3.1' + version: 18.3.1(react@18.3.1) + viem: + specifier: 2.* + version: 2.10.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@6.0.5)(zod@3.25.20) + devDependencies: + '@types/react': + specifier: '>=18.3.1' + version: 18.3.1 + '@types/react-dom': + specifier: '>=18.3.0' + version: 18.3.0 + '@vitejs/plugin-react': + specifier: ^4.2.1 + version: 4.2.1(vite@5.4.19(@types/node@24.0.1)(terser@5.39.2)) + buffer: + specifier: ^6.0.3 + version: 6.0.3 + vite: + specifier: ^5.4.19 + version: 5.4.19(@types/node@24.0.1)(terser@5.39.2) + + playgrounds/vite-react: + dependencies: + '@tanstack/query-sync-storage-persister': + specifier: 5.0.5 + version: 5.0.5 + '@tanstack/react-query': + specifier: '>=5.45.1' + version: 5.49.2(react@18.3.1) + '@tanstack/react-query-persist-client': + specifier: 5.0.5 + version: 5.0.5(@tanstack/react-query@5.49.2(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + idb-keyval: + specifier: ^6.2.1 + version: 6.2.1 + react: + specifier: '>=18.3.1' + version: 18.3.1 + react-dom: + specifier: '>=18.3.1' + version: 18.3.1(react@18.3.1) + viem: + specifier: 2.* + version: 2.10.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@6.0.5)(zod@3.25.20) + wagmi: + specifier: workspace:* + version: link:../../packages/react + devDependencies: + '@tanstack/react-query-devtools': + specifier: 5.0.5 + version: 5.0.5(@tanstack/react-query@5.49.2(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@types/react': + specifier: '>=18.3.1' + version: 18.3.1 + '@types/react-dom': + specifier: '>=18.3.0' + version: 18.3.0 + '@vitejs/plugin-react': + specifier: ^4.2.1 + version: 4.2.1(vite@5.4.19(@types/node@24.0.1)(terser@5.39.2)) + '@wagmi/cli': + specifier: workspace:* + version: link:../../packages/cli + buffer: + specifier: ^6.0.3 + version: 6.0.3 + vite: + specifier: ^5.4.19 + version: 5.4.19(@types/node@24.0.1)(terser@5.39.2) + + playgrounds/vite-vue: + dependencies: + '@tanstack/vue-query': + specifier: '>=5.45.0' + version: 5.49.1(vue@3.4.27(typescript@5.8.3)) + '@wagmi/vue': + specifier: workspace:* + version: link:../../packages/vue + viem: + specifier: 2.* + version: 2.10.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@6.0.5)(zod@3.25.20) + vue: + specifier: '>=3.4.21' + version: 3.4.27(typescript@5.8.3) + devDependencies: + '@vitejs/plugin-vue': + specifier: ^5.0.4 + version: 5.0.4(vite@5.4.19(@types/node@24.0.1)(terser@5.39.2))(vue@3.4.27(typescript@5.8.3)) + buffer: + specifier: ^6.0.3 + version: 6.0.3 + vite: + specifier: ^5.4.19 + version: 5.4.19(@types/node@24.0.1)(terser@5.39.2) + vue-tsc: + specifier: ^2.0.6 + version: 2.0.16(typescript@5.8.3) + + site: + devDependencies: + '@shikijs/vitepress-twoslash': + specifier: 1.22.2 + version: 1.22.2(@nuxt/kit@3.17.4(magicast@0.3.5))(typescript@5.8.3) + '@tanstack/query-core': + specifier: 'catalog:' + version: 5.49.1 + '@tanstack/react-query': + specifier: 'catalog:' + version: 5.49.2(react@18.3.1) + '@tanstack/vue-query': + specifier: 'catalog:' + version: 5.49.1(vue@3.4.27(typescript@5.8.3)) + '@types/react': + specifier: 'catalog:' + version: 18.3.1 + '@wagmi/connectors': + specifier: workspace:* + version: link:../packages/connectors + '@wagmi/core': + specifier: workspace:* + version: link:../packages/core + '@wagmi/vue': + specifier: workspace:* + version: link:../packages/vue + abitype: + specifier: '*' + version: 1.0.2(typescript@5.8.3)(zod@3.25.20) + nuxt: + specifier: ^3.16.0 + version: 3.16.0(@biomejs/biome@1.9.4)(@parcel/watcher@2.5.1)(@types/node@24.0.1)(bufferutil@4.0.9)(db0@0.3.2)(encoding@0.1.13)(idb-keyval@6.2.1)(ioredis@5.6.1)(magicast@0.3.5)(rollup@4.41.0)(terser@5.39.2)(typescript@5.8.3)(utf-8-validate@6.0.5)(vite@6.3.5(@types/node@24.0.1)(jiti@2.4.2)(terser@5.39.2)(yaml@2.8.0))(yaml@2.8.0) + react: + specifier: 'catalog:' + version: 18.3.1 + unocss: + specifier: ^0.59.4 + version: 0.59.4(rollup@4.41.0) + viem: + specifier: 2.* + version: 2.10.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@6.0.5)(zod@3.25.20) + vitepress: + specifier: 1.5.0 + version: 1.5.0(@algolia/client-search@5.12.0)(@types/node@24.0.1)(@types/react@18.3.1)(change-case@5.4.4)(fuse.js@7.1.0)(idb-keyval@6.2.1)(jwt-decode@4.0.0)(postcss@8.5.5)(qrcode@1.5.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(terser@5.39.2)(typescript@5.8.3) + vue: + specifier: 'catalog:' + version: 3.4.27(typescript@5.8.3) + wagmi: + specifier: workspace:* + version: link:../packages/react + +packages: + + '@adraffy/ens-normalize@1.10.0': + resolution: {integrity: sha512-nA9XHtlAkYfJxY7bce8DcN7eKxWWCWkU+1GR9d+U6MbNpfwQp8TI7vqOsBsMcHoT4mBu2kypKoSKnghEzOOq5Q==} + + '@adraffy/ens-normalize@1.11.0': + resolution: {integrity: sha512-/3DDPKHqqIqxUULp8yP4zODUY1i+2xvVWsv8A79xGWdCAG+8sb0hRh0Rk2QyOJUnnbyPUAZYcpBuRe3nS2OIUg==} + + '@algolia/autocomplete-core@1.9.3': + resolution: {integrity: sha512-009HdfugtGCdC4JdXUbVJClA0q0zh24yyePn+KUGk3rP7j8FEe/m5Yo/z65gn6nP/cM39PxpzqKrL7A6fP6PPw==} + + '@algolia/autocomplete-plugin-algolia-insights@1.9.3': + resolution: {integrity: sha512-a/yTUkcO/Vyy+JffmAnTWbr4/90cLzw+CC3bRbhnULr/EM0fGNvM13oQQ14f2moLMcVDyAx/leczLlAOovhSZg==} + peerDependencies: + search-insights: '>= 1 < 3' + + '@algolia/autocomplete-preset-algolia@1.17.6': + resolution: {integrity: sha512-Cvg5JENdSCMuClwhJ1ON1/jSuojaYMiUW2KePm18IkdCzPJj/NXojaOxw58RFtQFpJgfVW8h2E8mEoDtLlMdeA==} + peerDependencies: + '@algolia/client-search': '>= 4.9.1 < 6' + algoliasearch: '>= 4.9.1 < 6' + + '@algolia/autocomplete-shared@1.17.6': + resolution: {integrity: sha512-aq/3V9E00Tw2GC/PqgyPGXtqJUlVc17v4cn1EUhSc+O/4zd04Uwb3UmPm8KDaYQQOrkt1lwvCj2vG2wRE5IKhw==} + peerDependencies: + '@algolia/client-search': '>= 4.9.1 < 6' + algoliasearch: '>= 4.9.1 < 6' + + '@algolia/autocomplete-shared@1.9.3': + resolution: {integrity: sha512-Wnm9E4Ye6Rl6sTTqjoymD+l8DjSTHsHboVRYrKgEt8Q7UHm9nYbqhN/i0fhUYA3OAEH7WA8x3jfpnmJm3rKvaQ==} + peerDependencies: + '@algolia/client-search': '>= 4.9.1 < 6' + algoliasearch: '>= 4.9.1 < 6' + + '@algolia/client-abtesting@5.12.0': + resolution: {integrity: sha512-hx4eVydkm3yrFCFxmcBtSzI/ykt0cZ6sDWch+v3JTgKpD2WtosMJU3Upv1AjQ4B6COSHCOWEX3vfFxW6OoH6aA==} + engines: {node: '>= 14.0.0'} + + '@algolia/client-analytics@5.12.0': + resolution: {integrity: sha512-EpTsSv6IW8maCfXCDIptgT7+mQJj7pImEkcNUnxR8yUKAHzTogTXv9yGm2WXOZFVuwstd2i0sImhQ1Vz8RH/hA==} + engines: {node: '>= 14.0.0'} + + '@algolia/client-common@5.12.0': + resolution: {integrity: sha512-od3WmO8qxyfNhKc+K3D17tvun3IMs/xMNmxCG9MiElAkYVbPPTRUYMkRneCpmJyQI0hNx2/EA4kZgzVfQjO86Q==} + engines: {node: '>= 14.0.0'} + + '@algolia/client-insights@5.12.0': + resolution: {integrity: sha512-8alajmsYUd+7vfX5lpRNdxqv3Xx9clIHLUItyQK0Z6gwGMbVEFe6YYhgDtwslMAP0y6b0WeJEIZJMLgT7VYpRw==} + engines: {node: '>= 14.0.0'} + + '@algolia/client-personalization@5.12.0': + resolution: {integrity: sha512-bUV9HtfkTBgpoVhxFrMkmVPG03ZN1Rtn51kiaEtukucdk3ggjR9Qu1YUfRSU2lFgxr9qJc8lTxwfvhjCeJRcqw==} + engines: {node: '>= 14.0.0'} + + '@algolia/client-query-suggestions@5.12.0': + resolution: {integrity: sha512-Q5CszzGWfxbIDs9DJ/QJsL7bP6h+lJMg27KxieEnI9KGCu0Jt5iFA3GkREkgRZxRdzlHbZKkrIzhtHVbSHw/rg==} + engines: {node: '>= 14.0.0'} + + '@algolia/client-search@5.12.0': + resolution: {integrity: sha512-R3qzEytgVLHOGNri+bpta6NtTt7YtkvUe/QBcAmMDjW4Jk1P0eBYIPfvnzIPbINRsLxIq9fZs9uAYBgsrts4Zg==} + engines: {node: '>= 14.0.0'} + + '@algolia/ingestion@1.12.0': + resolution: {integrity: sha512-zpHo6qhR22tL8FsdSI4DvEraPDi/019HmMrCFB/TUX98yzh5ooAU7sNW0qPL1I7+S++VbBmNzJOEU9VI8tEC8A==} + engines: {node: '>= 14.0.0'} + + '@algolia/monitoring@1.12.0': + resolution: {integrity: sha512-i2AJZED/zf4uhxezAJUhMKoL5QoepCBp2ynOYol0N76+TSoohaMADdPnWCqOULF4RzOwrG8wWynAwBlXsAI1RQ==} + engines: {node: '>= 14.0.0'} + + '@algolia/recommend@5.12.0': + resolution: {integrity: sha512-0jmZyKvYnB/Bj5c7WKsKedOUjnr0UtXm0LVFUdQrxXfqOqvWv9n6Vpr65UjdYG4Q49kRQxhlwtal9WJYrYymXg==} + engines: {node: '>= 14.0.0'} + + '@algolia/requester-browser-xhr@5.12.0': + resolution: {integrity: sha512-KxwleraFuVoEGCoeW6Y1RAEbgBMS7SavqeyzWdtkJc6mXeCOJXn1iZitb8Tyn2FcpMNUKlSm0adrUTt7G47+Ow==} + engines: {node: '>= 14.0.0'} + + '@algolia/requester-fetch@5.12.0': + resolution: {integrity: sha512-FuDZXUGU1pAg2HCnrt8+q1VGHKChV/LhvjvZlLOT7e56GJie6p+EuLu4/hMKPOVuQQ8XXtrTHKIU3Lw+7O5/bQ==} + engines: {node: '>= 14.0.0'} + + '@algolia/requester-node-http@5.12.0': + resolution: {integrity: sha512-ncDDY7CxZhMs6LIoPl+vHFQceIBhYPY5EfuGF1V7beO0U38xfsCYEyutEFB2kRzf4D9Gqppn3iWX71sNtrKcuw==} + engines: {node: '>= 14.0.0'} + + '@ampproject/remapping@2.2.1': + resolution: {integrity: sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==} + engines: {node: '>=6.0.0'} + + '@ampproject/remapping@2.3.0': + resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} + engines: {node: '>=6.0.0'} + + '@andrewbranch/untar.js@1.0.3': + resolution: {integrity: sha512-Jh15/qVmrLGhkKJBdXlK1+9tY4lZruYjsgkDFj08ZmDiWVBLJcqkok7Z0/R0In+i1rScBpJlSvrTS2Lm41Pbnw==} + + '@antfu/install-pkg@0.1.1': + resolution: {integrity: sha512-LyB/8+bSfa0DFGC06zpCEfs89/XoWZwws5ygEa5D+Xsm3OfI+aXQ86VgVG7Acyef+rSZ5HE7J8rrxzrQeM3PjQ==} + + '@antfu/utils@0.7.7': + resolution: {integrity: sha512-gFPqTG7otEJ8uP6wrhDv6mqwGWYZKNvAcCq6u9hOj0c+IKCEsY4L1oC9trPq2SaWIzAfHvqfBDxF591JkMf+kg==} + + '@arethetypeswrong/cli@0.16.4': + resolution: {integrity: sha512-qMmdVlJon5FtA+ahn0c1oAVNxiq4xW5lqFiTZ21XHIeVwAVIQ+uRz4UEivqRMsjVV1grzRgJSKqaOrq1MvlVyQ==} + engines: {node: '>=18'} + hasBin: true + + '@arethetypeswrong/core@0.16.4': + resolution: {integrity: sha512-RI3HXgSuKTfcBf1hSEg1P9/cOvmI0flsMm6/QL3L3wju4AlHDqd55JFPfXs4pzgEAgy5L9pul4/HPPz99x2GvA==} + engines: {node: '>=18'} + + '@babel/code-frame@7.24.2': + resolution: {integrity: sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==} + engines: {node: '>=6.9.0'} + + '@babel/code-frame@7.27.1': + resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} + engines: {node: '>=6.9.0'} + + '@babel/compat-data@7.24.4': + resolution: {integrity: sha512-vg8Gih2MLK+kOkHJp4gBEIkyaIi00jgWot2D9QOmmfLC8jINSOzmCLta6Bvz/JSBCqnegV0L80jhxkol5GWNfQ==} + engines: {node: '>=6.9.0'} + + '@babel/compat-data@7.27.2': + resolution: {integrity: sha512-TUtMJYRPyUb/9aU8f3K0mjmjf6M9N5Woshn2CS6nqJSeJtTtQcpLUXjGt9vbF8ZGff0El99sWkLgzwW3VXnxZQ==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.24.5': + resolution: {integrity: sha512-tVQRucExLQ02Boi4vdPp49svNGcfL2GhdTCT9aldhXgCJVAI21EtRfBettiuLUwce/7r6bFdgs6JFkcdTiFttA==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.27.1': + resolution: {integrity: sha512-IaaGWsQqfsQWVLqMn9OB92MNN7zukfVA4s7KKAI0KfrrDsZ0yhi5uV4baBuLuN7n3vsZpwP8asPPcVwApxvjBQ==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.24.5': + resolution: {integrity: sha512-x32i4hEXvr+iI0NEoEfDKzlemF8AmtOP8CcrRaEcpzysWuoEb1KknpcvMsHKPONoKZiDuItklgWhB18xEhr9PA==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.27.1': + resolution: {integrity: sha512-UnJfnIpc/+JO0/+KRVQNGU+y5taA5vCbwN8+azkX6beii/ZF+enZJSOKo11ZSzGJjlNfJHfQtmQT8H+9TXPG2w==} + engines: {node: '>=6.9.0'} + + '@babel/helper-annotate-as-pure@7.22.5': + resolution: {integrity: sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-annotate-as-pure@7.27.1': + resolution: {integrity: sha512-WnuuDILl9oOBbKnb4L+DyODx7iC47XfzmNCpTttFsSp6hTG7XZxu60+4IO+2/hPfcGOoKbFiwoI/+zwARbNQow==} + engines: {node: '>=6.9.0'} + + '@babel/helper-compilation-targets@7.23.6': + resolution: {integrity: sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-compilation-targets@7.27.2': + resolution: {integrity: sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-create-class-features-plugin@7.24.5': + resolution: {integrity: sha512-uRc4Cv8UQWnE4NXlYTIIdM7wfFkOqlFztcC/gVXDKohKoVB3OyonfelUBaJzSwpBntZ2KYGF/9S7asCHsXwW6g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-create-class-features-plugin@7.27.1': + resolution: {integrity: sha512-QwGAmuvM17btKU5VqXfb+Giw4JcN0hjuufz3DYnpeVDvZLAObloM77bhMXiqry3Iio+Ai4phVRDwl6WU10+r5A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-environment-visitor@7.22.20': + resolution: {integrity: sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-function-name@7.23.0': + resolution: {integrity: sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-hoist-variables@7.22.5': + resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-member-expression-to-functions@7.24.5': + resolution: {integrity: sha512-4owRteeihKWKamtqg4JmWSsEZU445xpFRXPEwp44HbgbxdWlUV1b4Agg4lkA806Lil5XM/e+FJyS0vj5T6vmcA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-member-expression-to-functions@7.27.1': + resolution: {integrity: sha512-E5chM8eWjTp/aNoVpcbfM7mLxu9XGLWYise2eBKGQomAk/Mb4XoxyqXTZbuTohbsl8EKqdlMhnDI2CCLfcs9wA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@7.24.3': + resolution: {integrity: sha512-viKb0F9f2s0BCS22QSF308z/+1YWKV/76mwt61NBzS5izMzDPwdq1pTrzf+Li3npBWX9KdQbkeCt1jSAM7lZqg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@7.27.1': + resolution: {integrity: sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-transforms@7.24.5': + resolution: {integrity: sha512-9GxeY8c2d2mdQUP1Dye0ks3VDyIMS98kt/llQ2nUId8IsWqTF0l1LkSX0/uP7l7MCDrzXS009Hyhe2gzTiGW8A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-module-transforms@7.27.1': + resolution: {integrity: sha512-9yHn519/8KvTU5BjTVEEeIM3w9/2yXNKoD82JifINImhpKkARMJKPP59kLo+BafpdN5zgNeIcS4jsGDmd3l58g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-optimise-call-expression@7.22.5': + resolution: {integrity: sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-optimise-call-expression@7.27.1': + resolution: {integrity: sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-plugin-utils@7.24.5': + resolution: {integrity: sha512-xjNLDopRzW2o6ba0gKbkZq5YWEBaK3PCyTOY1K2P/O07LGMhMqlMXPxwN4S5/RhWuCobT8z0jrlKGlYmeR1OhQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-plugin-utils@7.27.1': + resolution: {integrity: sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-replace-supers@7.24.1': + resolution: {integrity: sha512-QCR1UqC9BzG5vZl8BMicmZ28RuUBnHhAMddD8yHFHDRH9lLTZ9uUPehX8ctVPT8l0TKblJidqcgUUKGVrePleQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-replace-supers@7.27.1': + resolution: {integrity: sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-simple-access@7.24.5': + resolution: {integrity: sha512-uH3Hmf5q5n7n8mz7arjUlDOCbttY/DW4DYhE6FUsjKJ/oYC1kQQUvwEQWxRwUpX9qQKRXeqLwWxrqilMrf32sQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-skip-transparent-expression-wrappers@7.27.1': + resolution: {integrity: sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-split-export-declaration@7.24.5': + resolution: {integrity: sha512-5CHncttXohrHk8GWOFCcCl4oRD9fKosWlIRgWm4ql9VYioKm52Mk2xsmoohvm7f3JoiLSM5ZgJuRaf5QZZYd3Q==} + engines: {node: '>=6.9.0'} + + '@babel/helper-string-parser@7.24.1': + resolution: {integrity: sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-string-parser@7.25.9': + resolution: {integrity: sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-string-parser@7.27.1': + resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.24.5': + resolution: {integrity: sha512-3q93SSKX2TWCG30M2G2kwaKeTYgEUp5Snjuj8qm729SObL6nbtUldAi37qbxkD5gg3xnBio+f9nqpSepGZMvxA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.25.9': + resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.27.1': + resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-option@7.23.5': + resolution: {integrity: sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-option@7.27.1': + resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} + engines: {node: '>=6.9.0'} + + '@babel/helpers@7.24.5': + resolution: {integrity: sha512-CiQmBMMpMQHwM5m01YnrM6imUG1ebgYJ+fAIW4FZe6m4qHTPaRHti+R8cggAwkdz4oXhtO4/K9JWlh+8hIfR2Q==} + engines: {node: '>=6.9.0'} + + '@babel/helpers@7.27.1': + resolution: {integrity: sha512-FCvFTm0sWV8Fxhpp2McP5/W53GPllQ9QeQ7SiqGWjMf/LVG07lFa5+pgK05IRhVwtvafT22KF+ZSnM9I545CvQ==} + engines: {node: '>=6.9.0'} + + '@babel/highlight@7.24.5': + resolution: {integrity: sha512-8lLmua6AVh/8SLJRRVD6V8p73Hir9w5mJrhE+IPpILG31KKlI9iz5zmBYKcWPS59qSfgP9RaSBQSHHE81WKuEw==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.24.5': + resolution: {integrity: sha512-EOv5IK8arwh3LI47dz1b0tKUb/1uhHAnHJOrjgtQMIpu1uXd9mlFrJg9IUgGUgZ41Ch0K8REPTYpO7B76b4vJg==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/parser@7.26.2': + resolution: {integrity: sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/parser@7.27.2': + resolution: {integrity: sha512-QYLs8299NA7WM/bZAdp+CviYYkVoYXlDW2rzliy3chxd1PQjej7JORuMJDJXJUb9g0TT+B99EwaVLKmX+sPXWw==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/plugin-syntax-jsx@7.24.1': + resolution: {integrity: sha512-2eCtxZXf+kbkMIsXS4poTvT4Yu5rXiRa+9xGVT56raghjmBTKMpFNc9R4IDiB4emao9eO22Ox7CxuJG7BgExqA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-jsx@7.27.1': + resolution: {integrity: sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-typescript@7.24.1': + resolution: {integrity: sha512-Yhnmvy5HZEnHUty6i++gcfH1/l68AHnItFHnaCv6hn9dNh0hQvvQJsxpi4BMBFN5DLeHBuucT/0DgzXif/OyRw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-typescript@7.27.1': + resolution: {integrity: sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-modules-commonjs@7.24.1': + resolution: {integrity: sha512-szog8fFTUxBfw0b98gEWPaEqF42ZUD/T3bkynW/wtgx2p/XCP55WEsb+VosKceRSd6njipdZvNogqdtI4Q0chw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-react-jsx-self@7.24.5': + resolution: {integrity: sha512-RtCJoUO2oYrYwFPtR1/jkoBEcFuI1ae9a9IMxeyAVa3a1Ap4AnxmyIKG2b2FaJKqkidw/0cxRbWN+HOs6ZWd1w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-react-jsx-source@7.24.1': + resolution: {integrity: sha512-1v202n7aUq4uXAieRTKcwPzNyphlCuqHHDcdSNc+vdhoTEZcFMh+L5yZuCmGaIO7bs1nJUNfHB89TZyoL48xNA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-typescript@7.24.5': + resolution: {integrity: sha512-E0VWu/hk83BIFUWnsKZ4D81KXjN5L3MobvevOHErASk9IPwKHOkTgvqzvNo1yP/ePJWqqK2SpUR5z+KQbl6NVw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-typescript@7.27.1': + resolution: {integrity: sha512-Q5sT5+O4QUebHdbwKedFBEwRLb02zJ7r4A5Gg2hUoLuU3FjdMcyqcywqUrLCaDsFCxzokf7u9kuy7qz51YUuAg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/preset-typescript@7.24.1': + resolution: {integrity: sha512-1DBaMmRDpuYQBPWD8Pf/WEwCrtgRHxsZnP4mIy9G/X+hFfbI47Q2G4t1Paakld84+qsk2fSsUPMKg71jkoOOaQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/runtime@7.26.0': + resolution: {integrity: sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==} + engines: {node: '>=6.9.0'} + + '@babel/runtime@7.27.6': + resolution: {integrity: sha512-vbavdySgbTTrmFE+EsiqUTzlOr5bzlnJtUv9PynGCAKvfQqjIXbvFdumPM/GxMDfyuGMJaJAU6TO4zc1Jf1i8Q==} + engines: {node: '>=6.9.0'} + + '@babel/standalone@7.24.5': + resolution: {integrity: sha512-Sl8oN9bGfRlNUA2jzfzoHEZxFBDliBlwi5mPVCAWKSlBNkXXJOHpu7SDOqjF6mRoTa6GNX/1kAWG3Tr+YQ3N7A==} + engines: {node: '>=6.9.0'} + + '@babel/template@7.24.0': + resolution: {integrity: sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==} + engines: {node: '>=6.9.0'} + + '@babel/template@7.27.2': + resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.24.5': + resolution: {integrity: sha512-7aaBLeDQ4zYcUFDUD41lJc1fG8+5IU9DaNSJAgal866FGvmD5EbWQgnEC6kO1gGLsX0esNkfnJSndbTXA3r7UA==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.27.1': + resolution: {integrity: sha512-ZCYtZciz1IWJB4U61UPu4KEaqyfj+r5T1Q5mqPo+IBpcG9kHv30Z0aD8LXPgC1trYa6rK0orRyAhqUgk4MjmEg==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.24.5': + resolution: {integrity: sha512-6mQNsaLeXTw0nxYUYu+NSa4Hx4BlF1x1x8/PMFbiR+GBSr+2DkECc69b8hgy2frEodNcvPffeH8YfWd3LI6jhQ==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.26.0': + resolution: {integrity: sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.27.1': + resolution: {integrity: sha512-+EzkxvLNfiUeKMgy/3luqfsCWFRXLb7U6wNQTk60tovuckwB15B191tJWvpp4HjiQWdJkCxO3Wbvc6jlk3Xb2Q==} + engines: {node: '>=6.9.0'} + + '@bcoe/v8-coverage@0.2.3': + resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} + + '@biomejs/biome@1.9.4': + resolution: {integrity: sha512-1rkd7G70+o9KkTn5KLmDYXihGoTaIGO9PIIN2ZB7UJxFrWw04CZHPYiMRjYsaDvVV7hP1dYNRLxSANLaBFGpog==} + engines: {node: '>=14.21.3'} + hasBin: true + + '@biomejs/cli-darwin-arm64@1.9.4': + resolution: {integrity: sha512-bFBsPWrNvkdKrNCYeAp+xo2HecOGPAy9WyNyB/jKnnedgzl4W4Hb9ZMzYNbf8dMCGmUdSavlYHiR01QaYR58cw==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [darwin] + + '@biomejs/cli-darwin-x64@1.9.4': + resolution: {integrity: sha512-ngYBh/+bEedqkSevPVhLP4QfVPCpb+4BBe2p7Xs32dBgs7rh9nY2AIYUL6BgLw1JVXV8GlpKmb/hNiuIxfPfZg==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [darwin] + + '@biomejs/cli-linux-arm64-musl@1.9.4': + resolution: {integrity: sha512-v665Ct9WCRjGa8+kTr0CzApU0+XXtRgwmzIf1SeKSGAv+2scAlW6JR5PMFo6FzqqZ64Po79cKODKf3/AAmECqA==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [linux] + + '@biomejs/cli-linux-arm64@1.9.4': + resolution: {integrity: sha512-fJIW0+LYujdjUgJJuwesP4EjIBl/N/TcOX3IvIHJQNsAqvV2CHIogsmA94BPG6jZATS4Hi+xv4SkBBQSt1N4/g==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [linux] + + '@biomejs/cli-linux-x64-musl@1.9.4': + resolution: {integrity: sha512-gEhi/jSBhZ2m6wjV530Yy8+fNqG8PAinM3oV7CyO+6c3CEh16Eizm21uHVsyVBEB6RIM8JHIl6AGYCv6Q6Q9Tg==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [linux] + + '@biomejs/cli-linux-x64@1.9.4': + resolution: {integrity: sha512-lRCJv/Vi3Vlwmbd6K+oQ0KhLHMAysN8lXoCI7XeHlxaajk06u7G+UsFSO01NAs5iYuWKmVZjmiOzJ0OJmGsMwg==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [linux] + + '@biomejs/cli-win32-arm64@1.9.4': + resolution: {integrity: sha512-tlbhLk+WXZmgwoIKwHIHEBZUwxml7bRJgk0X2sPyNR3S93cdRq6XulAZRQJ17FYGGzWne0fgrXBKpl7l4M87Hg==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [win32] + + '@biomejs/cli-win32-x64@1.9.4': + resolution: {integrity: sha512-8Y5wMhVIPaWe6jw2H+KlEm4wP/f7EW3810ZLmDlrEEy5KvBsb9ECEfu/kMWD484ijfQ8+nIi0giMgu9g1UAuuA==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [win32] + + '@bundled-es-modules/cookie@2.0.0': + resolution: {integrity: sha512-Or6YHg/kamKHpxULAdSqhGqnWFneIXu1NKvvfBBzKGwpVsYuFIQ5aBPHDnnoR3ghW1nvSkALd+EF9iMtY7Vjxw==} + + '@bundled-es-modules/statuses@1.0.1': + resolution: {integrity: sha512-yn7BklA5acgcBr+7w064fGV+SGIFySjCKpqjcWgBAIfrAkY+4GQTJJHQMeT3V/sgz23VTEVV8TtOmkvJAhFVfg==} + + '@bundled-es-modules/tough-cookie@0.1.6': + resolution: {integrity: sha512-dvMHbL464C0zI+Yqxbz6kZ5TOEp7GLW+pry/RWndAR8MJQAXZ2rPmIs8tziTZjeIyhSNZgZbCePtfSbdWqStJw==} + + '@changesets/apply-release-plan@7.0.5': + resolution: {integrity: sha512-1cWCk+ZshEkSVEZrm2fSj1Gz8sYvxgUL4Q78+1ZZqeqfuevPTPk033/yUZ3df8BKMohkqqHfzj0HOOrG0KtXTw==} + + '@changesets/assemble-release-plan@6.0.4': + resolution: {integrity: sha512-nqICnvmrwWj4w2x0fOhVj2QEGdlUuwVAwESrUo5HLzWMI1rE5SWfsr9ln+rDqWB6RQ2ZyaMZHUcU7/IRaUJS+Q==} + + '@changesets/changelog-git@0.2.0': + resolution: {integrity: sha512-bHOx97iFI4OClIT35Lok3sJAwM31VbUM++gnMBV16fdbtBhgYu4dxsphBF/0AZZsyAHMrnM0yFcj5gZM1py6uQ==} + + '@changesets/changelog-github@0.4.6': + resolution: {integrity: sha512-ahR/+o3OPodzfG9kucEMU/tEtBgwy6QoJiWi1sDBPme8n3WjT6pBlbhqNYpWAJKilomwfjBGY0MTUTs6r9d1RQ==} + + '@changesets/cli@2.27.8': + resolution: {integrity: sha512-gZNyh+LdSsI82wBSHLQ3QN5J30P4uHKJ4fXgoGwQxfXwYFTJzDdvIJasZn8rYQtmKhyQuiBj4SSnLuKlxKWq4w==} + hasBin: true + + '@changesets/config@3.0.3': + resolution: {integrity: sha512-vqgQZMyIcuIpw9nqFIpTSNyc/wgm/Lu1zKN5vECy74u95Qx/Wa9g27HdgO4NkVAaq+BGA8wUc/qvbvVNs93n6A==} + + '@changesets/errors@0.2.0': + resolution: {integrity: sha512-6BLOQUscTpZeGljvyQXlWOItQyU71kCdGz7Pi8H8zdw6BI0g3m43iL4xKUVPWtG+qrrL9DTjpdn8eYuCQSRpow==} + + '@changesets/get-dependents-graph@2.1.2': + resolution: {integrity: sha512-sgcHRkiBY9i4zWYBwlVyAjEM9sAzs4wYVwJUdnbDLnVG3QwAaia1Mk5P8M7kraTOZN+vBET7n8KyB0YXCbFRLQ==} + + '@changesets/get-github-info@0.5.2': + resolution: {integrity: sha512-JppheLu7S114aEs157fOZDjFqUDpm7eHdq5E8SSR0gUBTEK0cNSHsrSR5a66xs0z3RWuo46QvA3vawp8BxDHvg==} + + '@changesets/get-release-plan@4.0.4': + resolution: {integrity: sha512-SicG/S67JmPTrdcc9Vpu0wSQt7IiuN0dc8iR5VScnnTVPfIaLvKmEGRvIaF0kcn8u5ZqLbormZNTO77bCEvyWw==} + + '@changesets/get-version-range-type@0.4.0': + resolution: {integrity: sha512-hwawtob9DryoGTpixy1D3ZXbGgJu1Rhr+ySH2PvTLHvkZuQ7sRT4oQwMh0hbqZH1weAooedEjRsbrWcGLCeyVQ==} + + '@changesets/git@3.0.1': + resolution: {integrity: sha512-pdgHcYBLCPcLd82aRcuO0kxCDbw/yISlOtkmwmE8Odo1L6hSiZrBOsRl84eYG7DRCab/iHnOkWqExqc4wxk2LQ==} + + '@changesets/logger@0.1.1': + resolution: {integrity: sha512-OQtR36ZlnuTxKqoW4Sv6x5YIhOmClRd5pWsjZsddYxpWs517R0HkyiefQPIytCVh4ZcC5x9XaG8KTdd5iRQUfg==} + + '@changesets/parse@0.4.0': + resolution: {integrity: sha512-TS/9KG2CdGXS27S+QxbZXgr8uPsP4yNJYb4BC2/NeFUj80Rni3TeD2qwWmabymxmrLo7JEsytXH1FbpKTbvivw==} + + '@changesets/pre@2.0.1': + resolution: {integrity: sha512-vvBJ/If4jKM4tPz9JdY2kGOgWmCowUYOi5Ycv8dyLnEE8FgpYYUo1mgJZxcdtGGP3aG8rAQulGLyyXGSLkIMTQ==} + + '@changesets/read@0.6.1': + resolution: {integrity: sha512-jYMbyXQk3nwP25nRzQQGa1nKLY0KfoOV7VLgwucI0bUO8t8ZLCr6LZmgjXsiKuRDc+5A6doKPr9w2d+FEJ55zQ==} + + '@changesets/should-skip-package@0.1.1': + resolution: {integrity: sha512-H9LjLbF6mMHLtJIc/eHR9Na+MifJ3VxtgP/Y+XLn4BF7tDTEN1HNYtH6QMcjP1uxp9sjaFYmW8xqloaCi/ckTg==} + + '@changesets/types@4.1.0': + resolution: {integrity: sha512-LDQvVDv5Kb50ny2s25Fhm3d9QSZimsoUGBsUioj6MC3qbMUCuC8GPIvk/M6IvXx3lYhAs0lwWUQLb+VIEUCECw==} + + '@changesets/types@5.2.1': + resolution: {integrity: sha512-myLfHbVOqaq9UtUKqR/nZA/OY7xFjQMdfgfqeZIBK4d0hA6pgxArvdv8M+6NUzzBsjWLOtvApv8YHr4qM+Kpfg==} + + '@changesets/types@6.0.0': + resolution: {integrity: sha512-b1UkfNulgKoWfqyHtzKS5fOZYSJO+77adgL7DLRDr+/7jhChN+QcHnbjiQVOz/U+Ts3PGNySq7diAItzDgugfQ==} + + '@changesets/write@0.3.2': + resolution: {integrity: sha512-kDxDrPNpUgsjDbWBvUo27PzKX4gqeKOlhibaOXDJA6kuBisGqNHv/HwGJrAu8U/dSf8ZEFIeHIPtvSlZI1kULw==} + + '@cloudflare/kv-asset-handler@0.4.0': + resolution: {integrity: sha512-+tv3z+SPp+gqTIcImN9o0hqE9xyfQjI1XD9pL6NuKjua9B1y7mNYv0S9cP+QEbA4ppVgGZEmKOvHX5G5Ei1CVA==} + engines: {node: '>=18.0.0'} + + '@coinbase/wallet-sdk@3.9.3': + resolution: {integrity: sha512-N/A2DRIf0Y3PHc1XAMvbBUu4zisna6qAdqABMZwBMNEfWrXpAwx16pZGkYCLGE+Rvv1edbcB2LYDRnACNcmCiw==} + + '@coinbase/wallet-sdk@4.3.0': + resolution: {integrity: sha512-T3+SNmiCw4HzDm4we9wCHCxlP0pqCiwKe4sOwPH3YAK2KSKjxPRydKu6UQJrdONFVLG7ujXvbd/6ZqmvJb8rkw==} + + '@colors/colors@1.5.0': + resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} + engines: {node: '>=0.1.90'} + + '@colors/colors@1.6.0': + resolution: {integrity: sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==} + engines: {node: '>=0.1.90'} + + '@dabh/diagnostics@2.0.3': + resolution: {integrity: sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==} + + '@dependents/detective-less@4.1.0': + resolution: {integrity: sha512-KrkT6qO5NxqNfy68sBl6CTSoJ4SNDIS5iQArkibhlbGU4LaDukZ3q2HIkh8aUKDio6o4itU4xDR7t82Y2eP1Bg==} + engines: {node: '>=14'} + + '@discoveryjs/json-ext@0.5.7': + resolution: {integrity: sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==} + engines: {node: '>=10.0.0'} + + '@docsearch/css@3.6.3': + resolution: {integrity: sha512-3uvbg8E7rhqE1C4oBAK3tGlS2qfhi9zpfZgH/yjDPF73vd9B41urVIKujF4rczcF4E3qs34SedhehiDJ4UdNBA==} + + '@docsearch/js@3.6.3': + resolution: {integrity: sha512-2mBFomaN6VijyQQGwieERDu9GeE0hlv9TQRZBTOYsPQW7/vqtd4hnHEkbBbaBRiS4PYcy+UhikbMuDExJs63UA==} + + '@docsearch/react@3.6.3': + resolution: {integrity: sha512-2munr4uBuZq1PG+Ge+F+ldIdxb3Wi8OmEIv2tQQb4RvEvvph+xtQkxwHzVIEnt5s+HecwucuXwB+3JhcZboFLg==} + peerDependencies: + '@types/react': '>= 16.8.0 < 19.0.0' + react: '>= 16.8.0 < 19.0.0' + react-dom: '>= 16.8.0 < 19.0.0' + search-insights: '>= 1 < 3' + peerDependenciesMeta: + '@types/react': + optional: true + react: + optional: true + react-dom: + optional: true + search-insights: + optional: true + + '@ecies/ciphers@0.2.3': + resolution: {integrity: sha512-tapn6XhOueMwht3E2UzY0ZZjYokdaw9XtL9kEyjhQ/Fb9vL9xTFbOaI+fV0AWvTpYu4BNloC6getKW6NtSg4mA==} + engines: {bun: '>=1', deno: '>=2', node: '>=16'} + peerDependencies: + '@noble/ciphers': ^1.0.0 + + '@emnapi/core@1.4.3': + resolution: {integrity: sha512-4m62DuCE07lw01soJwPiBGC0nAww0Q+RY70VZ+n49yDIO13yyinhbWCeNnaob0lakDtWQzSdtNWzJeOJt2ma+g==} + + '@emnapi/runtime@1.4.3': + resolution: {integrity: sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ==} + + '@emnapi/wasi-threads@1.0.2': + resolution: {integrity: sha512-5n3nTJblwRi8LlXkJ9eBzu+kZR8Yxcc7ubakyQTFzPMtIhFpUBRbsnc2Dv88IZDIbCDlBiWrknhB4Lsz7mg6BA==} + + '@esbuild/aix-ppc64@0.21.5': + resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + + '@esbuild/aix-ppc64@0.25.4': + resolution: {integrity: sha512-1VCICWypeQKhVbE9oW/sJaAmjLxhVqacdkvPLEjwlttjfwENRSClS8EjBz0KzRyFSCPDIkuXW34Je/vk7zdB7Q==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/aix-ppc64@0.25.5': + resolution: {integrity: sha512-9o3TMmpmftaCMepOdA5k/yDw8SfInyzWWTjYTFCX3kPSDJMROQTb8jg+h9Cnwnmm1vOzvxN7gIfB5V2ewpjtGA==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.21.5': + resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm64@0.25.4': + resolution: {integrity: sha512-bBy69pgfhMGtCnwpC/x5QhfxAz/cBgQ9enbtwjf6V9lnPI/hMyT9iWpR1arm0l3kttTr4L0KSLpKmLp/ilKS9A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm64@0.25.5': + resolution: {integrity: sha512-VGzGhj4lJO+TVGV1v8ntCZWJktV7SGCs3Pn1GRWI1SBFtRALoomm8k5E9Pmwg3HOAal2VDc2F9+PM/rEY6oIDg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.21.5': + resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + + '@esbuild/android-arm@0.25.4': + resolution: {integrity: sha512-QNdQEps7DfFwE3hXiU4BZeOV68HHzYwGd0Nthhd3uCkkEKK7/R6MTgM0P7H7FAs5pU/DIWsviMmEGxEoxIZ+ZQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-arm@0.25.5': + resolution: {integrity: sha512-AdJKSPeEHgi7/ZhuIPtcQKr5RQdo6OO2IL87JkianiMYMPbCtot9fxPbrMiBADOWWm3T2si9stAiVsGbTQFkbA==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.21.5': + resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + + '@esbuild/android-x64@0.25.4': + resolution: {integrity: sha512-TVhdVtQIFuVpIIR282btcGC2oGQoSfZfmBdTip2anCaVYcqWlZXGcdcKIUklfX2wj0JklNYgz39OBqh2cqXvcQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/android-x64@0.25.5': + resolution: {integrity: sha512-D2GyJT1kjvO//drbRT3Hib9XPwQeWd9vZoBJn+bu/lVsOZ13cqNdDeqIF/xQ5/VmWvMduP6AmXvylO/PIc2isw==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.21.5': + resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-arm64@0.25.4': + resolution: {integrity: sha512-Y1giCfM4nlHDWEfSckMzeWNdQS31BQGs9/rouw6Ub91tkK79aIMTH3q9xHvzH8d0wDru5Ci0kWB8b3up/nl16g==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-arm64@0.25.5': + resolution: {integrity: sha512-GtaBgammVvdF7aPIgH2jxMDdivezgFu6iKpmT+48+F8Hhg5J/sfnDieg0aeG/jfSvkYQU2/pceFPDKlqZzwnfQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.21.5': + resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + + '@esbuild/darwin-x64@0.25.4': + resolution: {integrity: sha512-CJsry8ZGM5VFVeyUYB3cdKpd/H69PYez4eJh1W/t38vzutdjEjtP7hB6eLKBoOdxcAlCtEYHzQ/PJ/oU9I4u0A==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/darwin-x64@0.25.5': + resolution: {integrity: sha512-1iT4FVL0dJ76/q1wd7XDsXrSW+oLoquptvh4CLR4kITDtqi2e/xwXwdCVH8hVHU43wgJdsq7Gxuzcs6Iq/7bxQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.21.5': + resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-arm64@0.25.4': + resolution: {integrity: sha512-yYq+39NlTRzU2XmoPW4l5Ifpl9fqSk0nAJYM/V/WUGPEFfek1epLHJIkTQM6bBs1swApjO5nWgvr843g6TjxuQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-arm64@0.25.5': + resolution: {integrity: sha512-nk4tGP3JThz4La38Uy/gzyXtpkPW8zSAmoUhK9xKKXdBCzKODMc2adkB2+8om9BDYugz+uGV7sLmpTYzvmz6Sw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.21.5': + resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.25.4': + resolution: {integrity: sha512-0FgvOJ6UUMflsHSPLzdfDnnBBVoCDtBTVyn/MrWloUNvq/5SFmh13l3dvgRPkDihRxb77Y17MbqbCAa2strMQQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.25.5': + resolution: {integrity: sha512-PrikaNjiXdR2laW6OIjlbeuCPrPaAl0IwPIaRv+SMV8CiM8i2LqVUHFC1+8eORgWyY7yhQY+2U2fA55mBzReaw==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.21.5': + resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm64@0.25.4': + resolution: {integrity: sha512-+89UsQTfXdmjIvZS6nUnOOLoXnkUTB9hR5QAeLrQdzOSWZvNSAXAtcRDHWtqAUtAmv7ZM1WPOOeSxDzzzMogiQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm64@0.25.5': + resolution: {integrity: sha512-Z9kfb1v6ZlGbWj8EJk9T6czVEjjq2ntSYLY2cw6pAZl4oKtfgQuS4HOq41M/BcoLPzrUbNd+R4BXFyH//nHxVg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.21.5': + resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-arm@0.25.4': + resolution: {integrity: sha512-kro4c0P85GMfFYqW4TWOpvmF8rFShbWGnrLqlzp4X1TNWjRY3JMYUfDCtOxPKOIY8B0WC8HN51hGP4I4hz4AaQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-arm@0.25.5': + resolution: {integrity: sha512-cPzojwW2okgh7ZlRpcBEtsX7WBuqbLrNXqLU89GxWbNt6uIg78ET82qifUy3W6OVww6ZWobWub5oqZOVtwolfw==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.21.5': + resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-ia32@0.25.4': + resolution: {integrity: sha512-yTEjoapy8UP3rv8dB0ip3AfMpRbyhSN3+hY8mo/i4QXFeDxmiYbEKp3ZRjBKcOP862Ua4b1PDfwlvbuwY7hIGQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-ia32@0.25.5': + resolution: {integrity: sha512-sQ7l00M8bSv36GLV95BVAdhJ2QsIbCuCjh/uYrWiMQSUuV+LpXwIqhgJDcvMTj+VsQmqAHL2yYaasENvJ7CDKA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.21.5': + resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-loong64@0.25.4': + resolution: {integrity: sha512-NeqqYkrcGzFwi6CGRGNMOjWGGSYOpqwCjS9fvaUlX5s3zwOtn1qwg1s2iE2svBe4Q/YOG1q6875lcAoQK/F4VA==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-loong64@0.25.5': + resolution: {integrity: sha512-0ur7ae16hDUC4OL5iEnDb0tZHDxYmuQyhKhsPBV8f99f6Z9KQM02g33f93rNH5A30agMS46u2HP6qTdEt6Q1kg==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.21.5': + resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-mips64el@0.25.4': + resolution: {integrity: sha512-IcvTlF9dtLrfL/M8WgNI/qJYBENP3ekgsHbYUIzEzq5XJzzVEV/fXY9WFPfEEXmu3ck2qJP8LG/p3Q8f7Zc2Xg==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-mips64el@0.25.5': + resolution: {integrity: sha512-kB/66P1OsHO5zLz0i6X0RxlQ+3cu0mkxS3TKFvkb5lin6uwZ/ttOkP3Z8lfR9mJOBk14ZwZ9182SIIWFGNmqmg==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.21.5': + resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-ppc64@0.25.4': + resolution: {integrity: sha512-HOy0aLTJTVtoTeGZh4HSXaO6M95qu4k5lJcH4gxv56iaycfz1S8GO/5Jh6X4Y1YiI0h7cRyLi+HixMR+88swag==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-ppc64@0.25.5': + resolution: {integrity: sha512-UZCmJ7r9X2fe2D6jBmkLBMQetXPXIsZjQJCjgwpVDz+YMcS6oFR27alkgGv3Oqkv07bxdvw7fyB71/olceJhkQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.21.5': + resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-riscv64@0.25.4': + resolution: {integrity: sha512-i8JUDAufpz9jOzo4yIShCTcXzS07vEgWzyX3NH2G7LEFVgrLEhjwL3ajFE4fZI3I4ZgiM7JH3GQ7ReObROvSUA==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-riscv64@0.25.5': + resolution: {integrity: sha512-kTxwu4mLyeOlsVIFPfQo+fQJAV9mh24xL+y+Bm6ej067sYANjyEw1dNHmvoqxJUCMnkBdKpvOn0Ahql6+4VyeA==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.21.5': + resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-s390x@0.25.4': + resolution: {integrity: sha512-jFnu+6UbLlzIjPQpWCNh5QtrcNfMLjgIavnwPQAfoGx4q17ocOU9MsQ2QVvFxwQoWpZT8DvTLooTvmOQXkO51g==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-s390x@0.25.5': + resolution: {integrity: sha512-K2dSKTKfmdh78uJ3NcWFiqyRrimfdinS5ErLSn3vluHNeHVnBAFWC8a4X5N+7FgVE1EjXS1QDZbpqZBjfrqMTQ==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.21.5': + resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + + '@esbuild/linux-x64@0.25.4': + resolution: {integrity: sha512-6e0cvXwzOnVWJHq+mskP8DNSrKBr1bULBvnFLpc1KY+d+irZSgZ02TGse5FsafKS5jg2e4pbvK6TPXaF/A6+CA==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/linux-x64@0.25.5': + resolution: {integrity: sha512-uhj8N2obKTE6pSZ+aMUbqq+1nXxNjZIIjCjGLfsWvVpy7gKCOL6rsY1MhRh9zLtUtAI7vpgLMK6DxjO8Qm9lJw==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-arm64@0.25.4': + resolution: {integrity: sha512-vUnkBYxZW4hL/ie91hSqaSNjulOnYXE1VSLusnvHg2u3jewJBz3YzB9+oCw8DABeVqZGg94t9tyZFoHma8gWZQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-arm64@0.25.5': + resolution: {integrity: sha512-pwHtMP9viAy1oHPvgxtOv+OkduK5ugofNTVDilIzBLpoWAM16r7b/mxBvfpuQDpRQFMfuVr5aLcn4yveGvBZvw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.21.5': + resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.25.4': + resolution: {integrity: sha512-XAg8pIQn5CzhOB8odIcAm42QsOfa98SBeKUdo4xa8OvX8LbMZqEtgeWE9P/Wxt7MlG2QqvjGths+nq48TrUiKw==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.25.5': + resolution: {integrity: sha512-WOb5fKrvVTRMfWFNCroYWWklbnXH0Q5rZppjq0vQIdlsQKuw6mdSihwSo4RV/YdQ5UCKKvBy7/0ZZYLBZKIbwQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.25.4': + resolution: {integrity: sha512-Ct2WcFEANlFDtp1nVAXSNBPDxyU+j7+tId//iHXU2f/lN5AmO4zLyhDcpR5Cz1r08mVxzt3Jpyt4PmXQ1O6+7A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-arm64@0.25.5': + resolution: {integrity: sha512-7A208+uQKgTxHd0G0uqZO8UjK2R0DDb4fDmERtARjSHWxqMTye4Erz4zZafx7Di9Cv+lNHYuncAkiGFySoD+Mw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.21.5': + resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.25.4': + resolution: {integrity: sha512-xAGGhyOQ9Otm1Xu8NT1ifGLnA6M3sJxZ6ixylb+vIUVzvvd6GOALpwQrYrtlPouMqd/vSbgehz6HaVk4+7Afhw==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.25.5': + resolution: {integrity: sha512-G4hE405ErTWraiZ8UiSoesH8DaCsMm0Cay4fsFWOOUcz8b8rC6uCvnagr+gnioEjWn0wC+o1/TAHt+It+MpIMg==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/sunos-x64@0.21.5': + resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + + '@esbuild/sunos-x64@0.25.4': + resolution: {integrity: sha512-Mw+tzy4pp6wZEK0+Lwr76pWLjrtjmJyUB23tHKqEDP74R3q95luY/bXqXZeYl4NYlvwOqoRKlInQialgCKy67Q==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/sunos-x64@0.25.5': + resolution: {integrity: sha512-l+azKShMy7FxzY0Rj4RCt5VD/q8mG/e+mDivgspo+yL8zW7qEwctQ6YqKX34DTEleFAvCIUviCFX1SDZRSyMQA==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.21.5': + resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-arm64@0.25.4': + resolution: {integrity: sha512-AVUP428VQTSddguz9dO9ngb+E5aScyg7nOeJDrF1HPYu555gmza3bDGMPhmVXL8svDSoqPCsCPjb265yG/kLKQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-arm64@0.25.5': + resolution: {integrity: sha512-O2S7SNZzdcFG7eFKgvwUEZ2VG9D/sn/eIiz8XRZ1Q/DO5a3s76Xv0mdBzVM5j5R639lXQmPmSo0iRpHqUUrsxw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.21.5': + resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-ia32@0.25.4': + resolution: {integrity: sha512-i1sW+1i+oWvQzSgfRcxxG2k4I9n3O9NRqy8U+uugaT2Dy7kLO9Y7wI72haOahxceMX8hZAzgGou1FhndRldxRg==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-ia32@0.25.5': + resolution: {integrity: sha512-onOJ02pqs9h1iMJ1PQphR+VZv8qBMQ77Klcsqv9CNW2w6yLqoURLcgERAIurY6QE63bbLuqgP9ATqajFLK5AMQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.21.5': + resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + + '@esbuild/win32-x64@0.25.4': + resolution: {integrity: sha512-nOT2vZNw6hJ+z43oP1SPea/G/6AbN6X+bGNhNuq8NtRHy4wsMhw765IKLNmnjek7GvjWBYQ8Q5VBoYTFg9y1UQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@esbuild/win32-x64@0.25.5': + resolution: {integrity: sha512-TXv6YnJ8ZMVdX+SXWVBo/0p8LTcrUYngpWjvm91TMjjBQii7Oz11Lw5lbDV5Y0TzuhSJHwiH4hEtC1I42mMS0g==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@ethereumjs/common@3.2.0': + resolution: {integrity: sha512-pksvzI0VyLgmuEF2FA/JR/4/y6hcPq8OUail3/AvycBaW1d5VSauOZzqGvJ3RTmR4MU35lWE8KseKOsEhrFRBA==} + + '@ethereumjs/rlp@4.0.1': + resolution: {integrity: sha512-tqsQiBQDQdmPWE1xkkBq4rlSW5QZpLOUJ5RJh2/9fug+q9tnUhuZoVLk7s0scUIKTOzEtR72DFBXI4WiZcMpvw==} + engines: {node: '>=14'} + hasBin: true + + '@ethereumjs/tx@4.2.0': + resolution: {integrity: sha512-1nc6VO4jtFd172BbSnTnDQVr9IYBFl1y4xPzZdtkrkKIncBCkdbgfdRV+MiTkJYAtTxvV12GRZLqBFT1PNK6Yw==} + engines: {node: '>=14'} + + '@ethereumjs/util@8.1.0': + resolution: {integrity: sha512-zQ0IqbdX8FZ9aw11vP+dZkKDkS+kgIvQPHnSAXzP9pLu+Rfu3D3XEeLbicvoXJTYnhZiPmsZUxgdzXwNKxRPbA==} + engines: {node: '>=14'} + + '@ethersproject/abi@5.7.0': + resolution: {integrity: sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA==} + + '@ethersproject/abstract-provider@5.7.0': + resolution: {integrity: sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw==} + + '@ethersproject/abstract-signer@5.7.0': + resolution: {integrity: sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ==} + + '@ethersproject/address@5.7.0': + resolution: {integrity: sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA==} + + '@ethersproject/base64@5.7.0': + resolution: {integrity: sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ==} + + '@ethersproject/bignumber@5.7.0': + resolution: {integrity: sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw==} + + '@ethersproject/bytes@5.7.0': + resolution: {integrity: sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A==} + + '@ethersproject/constants@5.7.0': + resolution: {integrity: sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA==} + + '@ethersproject/hash@5.7.0': + resolution: {integrity: sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g==} + + '@ethersproject/keccak256@5.7.0': + resolution: {integrity: sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg==} + + '@ethersproject/logger@5.7.0': + resolution: {integrity: sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig==} + + '@ethersproject/networks@5.7.1': + resolution: {integrity: sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ==} + + '@ethersproject/properties@5.7.0': + resolution: {integrity: sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw==} + + '@ethersproject/rlp@5.7.0': + resolution: {integrity: sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w==} + + '@ethersproject/signing-key@5.7.0': + resolution: {integrity: sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q==} + + '@ethersproject/strings@5.7.0': + resolution: {integrity: sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg==} + + '@ethersproject/transactions@5.7.0': + resolution: {integrity: sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ==} + + '@ethersproject/web@5.7.1': + resolution: {integrity: sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w==} + + '@fastify/busboy@2.1.0': + resolution: {integrity: sha512-+KpH+QxZU7O4675t3mnkQKcZZg56u+K/Ct2K+N2AZYNVK8kyeo/bI18tI8aPm3tvNNRyTWfj6s5tnGNlcbQRsA==} + engines: {node: '>=14'} + + '@fastify/busboy@3.1.1': + resolution: {integrity: sha512-5DGmA8FTdB2XbDeEwc/5ZXBl6UbBAyBOOLlPuBnZ/N1SwdH9Ii+cOX3tBROlDgcTXxjOYnLMVoKk9+FXAw0CJw==} + + '@floating-ui/core@1.6.1': + resolution: {integrity: sha512-42UH54oPZHPdRHdw6BgoBD6cg/eVTmVrFcgeRDM3jbO7uxSoipVcmcIGFcA5jmOHO5apcyvBhkSKES3fQJnu7A==} + + '@floating-ui/dom@1.1.1': + resolution: {integrity: sha512-TpIO93+DIujg3g7SykEAGZMDtbJRrmnYRCNYSjJlvIbGhBjRSNTLVbNeDQBrzy9qDgUbiWdc7KA0uZHZ2tJmiw==} + + '@floating-ui/utils@0.2.2': + resolution: {integrity: sha512-J4yDIIthosAsRZ5CPYP/jQvUAQtlZTTD/4suA08/FEnlxqW3sKS9iAhgsa9VYLZ6vDHn/ixJgIqRQPotoBjxIw==} + + '@iconify-json/simple-icons@1.2.10': + resolution: {integrity: sha512-9OK1dsSjXlH36lhu5n+BlSoXuqFjHUErGLtNdzHpq0vHq4YFBuGYWtZ+vZTHLreRQ8ijPRv/6EsgkV+nf6AReQ==} + + '@iconify/types@2.0.0': + resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==} + + '@iconify/utils@2.1.23': + resolution: {integrity: sha512-YGNbHKM5tyDvdWZ92y2mIkrfvm5Fvhe6WJSkWu7vvOFhMtYDP0casZpoRz0XEHZCrYsR4stdGT3cZ52yp5qZdQ==} + + '@img/sharp-darwin-arm64@0.34.2': + resolution: {integrity: sha512-OfXHZPppddivUJnqyKoi5YVeHRkkNE2zUFT2gbpKxp/JZCFYEYubnMg+gOp6lWfasPrTS+KPosKqdI+ELYVDtg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [darwin] + + '@img/sharp-darwin-x64@0.34.2': + resolution: {integrity: sha512-dYvWqmjU9VxqXmjEtjmvHnGqF8GrVjM2Epj9rJ6BUIXvk8slvNDJbhGFvIoXzkDhrJC2jUxNLz/GUjjvSzfw+g==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-darwin-arm64@1.1.0': + resolution: {integrity: sha512-HZ/JUmPwrJSoM4DIQPv/BfNh9yrOA8tlBbqbLz4JZ5uew2+o22Ik+tHQJcih7QJuSa0zo5coHTfD5J8inqj9DA==} + cpu: [arm64] + os: [darwin] + + '@img/sharp-libvips-darwin-x64@1.1.0': + resolution: {integrity: sha512-Xzc2ToEmHN+hfvsl9wja0RlnXEgpKNmftriQp6XzY/RaSfwD9th+MSh0WQKzUreLKKINb3afirxW7A0fz2YWuQ==} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-linux-arm64@1.1.0': + resolution: {integrity: sha512-IVfGJa7gjChDET1dK9SekxFFdflarnUB8PwW8aGwEoF3oAsSDuNUTYS+SKDOyOJxQyDC1aPFMuRYLoDInyV9Ew==} + cpu: [arm64] + os: [linux] + + '@img/sharp-libvips-linux-arm@1.1.0': + resolution: {integrity: sha512-s8BAd0lwUIvYCJyRdFqvsj+BJIpDBSxs6ivrOPm/R7piTs5UIwY5OjXrP2bqXC9/moGsyRa37eYWYCOGVXxVrA==} + cpu: [arm] + os: [linux] + + '@img/sharp-libvips-linux-ppc64@1.1.0': + resolution: {integrity: sha512-tiXxFZFbhnkWE2LA8oQj7KYR+bWBkiV2nilRldT7bqoEZ4HiDOcePr9wVDAZPi/Id5fT1oY9iGnDq20cwUz8lQ==} + cpu: [ppc64] + os: [linux] + + '@img/sharp-libvips-linux-s390x@1.1.0': + resolution: {integrity: sha512-xukSwvhguw7COyzvmjydRb3x/09+21HykyapcZchiCUkTThEQEOMtBj9UhkaBRLuBrgLFzQ2wbxdeCCJW/jgJA==} + cpu: [s390x] + os: [linux] + + '@img/sharp-libvips-linux-x64@1.1.0': + resolution: {integrity: sha512-yRj2+reB8iMg9W5sULM3S74jVS7zqSzHG3Ol/twnAAkAhnGQnpjj6e4ayUz7V+FpKypwgs82xbRdYtchTTUB+Q==} + cpu: [x64] + os: [linux] + + '@img/sharp-libvips-linuxmusl-arm64@1.1.0': + resolution: {integrity: sha512-jYZdG+whg0MDK+q2COKbYidaqW/WTz0cc1E+tMAusiDygrM4ypmSCjOJPmFTvHHJ8j/6cAGyeDWZOsK06tP33w==} + cpu: [arm64] + os: [linux] + + '@img/sharp-libvips-linuxmusl-x64@1.1.0': + resolution: {integrity: sha512-wK7SBdwrAiycjXdkPnGCPLjYb9lD4l6Ze2gSdAGVZrEL05AOUJESWU2lhlC+Ffn5/G+VKuSm6zzbQSzFX/P65A==} + cpu: [x64] + os: [linux] + + '@img/sharp-linux-arm64@0.34.2': + resolution: {integrity: sha512-D8n8wgWmPDakc83LORcfJepdOSN6MvWNzzz2ux0MnIbOqdieRZwVYY32zxVx+IFUT8er5KPcyU3XXsn+GzG/0Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + + '@img/sharp-linux-arm@0.34.2': + resolution: {integrity: sha512-0DZzkvuEOqQUP9mo2kjjKNok5AmnOr1jB2XYjkaoNRwpAYMDzRmAqUIa1nRi58S2WswqSfPOWLNOr0FDT3H5RQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm] + os: [linux] + + '@img/sharp-linux-s390x@0.34.2': + resolution: {integrity: sha512-EGZ1xwhBI7dNISwxjChqBGELCWMGDvmxZXKjQRuqMrakhO8QoMgqCrdjnAqJq/CScxfRn+Bb7suXBElKQpPDiw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [s390x] + os: [linux] + + '@img/sharp-linux-x64@0.34.2': + resolution: {integrity: sha512-sD7J+h5nFLMMmOXYH4DD9UtSNBD05tWSSdWAcEyzqW8Cn5UxXvsHAxmxSesYUsTOBmUnjtxghKDl15EvfqLFbQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + + '@img/sharp-linuxmusl-arm64@0.34.2': + resolution: {integrity: sha512-NEE2vQ6wcxYav1/A22OOxoSOGiKnNmDzCYFOZ949xFmrWZOVII1Bp3NqVVpvj+3UeHMFyN5eP/V5hzViQ5CZNA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + + '@img/sharp-linuxmusl-x64@0.34.2': + resolution: {integrity: sha512-DOYMrDm5E6/8bm/yQLCWyuDJwUnlevR8xtF8bs+gjZ7cyUNYXiSf/E8Kp0Ss5xasIaXSHzb888V1BE4i1hFhAA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + + '@img/sharp-wasm32@0.34.2': + resolution: {integrity: sha512-/VI4mdlJ9zkaq53MbIG6rZY+QRN3MLbR6usYlgITEzi4Rpx5S6LFKsycOQjkOGmqTNmkIdLjEvooFKwww6OpdQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [wasm32] + + '@img/sharp-win32-arm64@0.34.2': + resolution: {integrity: sha512-cfP/r9FdS63VA5k0xiqaNaEoGxBg9k7uE+RQGzuK9fHt7jib4zAVVseR9LsE4gJcNWgT6APKMNnCcnyOtmSEUQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [win32] + + '@img/sharp-win32-ia32@0.34.2': + resolution: {integrity: sha512-QLjGGvAbj0X/FXl8n1WbtQ6iVBpWU7JO94u/P2M4a8CFYsvQi4GW2mRy/JqkRx0qpBzaOdKJKw8uc930EX2AHw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ia32] + os: [win32] + + '@img/sharp-win32-x64@0.34.2': + resolution: {integrity: sha512-aUdT6zEYtDKCaxkofmmJDJYGCf0+pJg3eU9/oBuqvEeoB9dKI6ZLc/1iLJCTuJQDO4ptntAlkUmHgGjyuobZbw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [win32] + + '@inquirer/confirm@3.1.6': + resolution: {integrity: sha512-Mj4TU29g6Uy+37UtpA8UpEOI2icBfpCwSW1QDtfx60wRhUy90s/kHPif2OXSSvuwDQT1lhAYRWUfkNf9Tecxvg==} + engines: {node: '>=18'} + + '@inquirer/core@8.1.0': + resolution: {integrity: sha512-kfx0SU9nWgGe1f03ao/uXc85SFH1v2w3vQVH7QDGjKxdtJz+7vPitFtG++BTyJMYyYgH8MpXigutcXJeiQwVRw==} + engines: {node: '>=18'} + + '@inquirer/figures@1.0.1': + resolution: {integrity: sha512-mtup3wVKia3ZwULPHcbs4Mor8Voi+iIXEWD7wCNbIO6lYR62oPCTQyrddi5OMYVXHzeCSoneZwJuS8sBvlEwDw==} + engines: {node: '>=18'} + + '@inquirer/type@1.3.1': + resolution: {integrity: sha512-Pe3PFccjPVJV1vtlfVvm9OnlbxqdnP5QcscFEFEnK5quChf1ufZtM0r8mR5ToWHMxZOh0s8o/qp9ANGRTo/DAw==} + engines: {node: '>=18'} + + '@ioredis/commands@1.2.0': + resolution: {integrity: sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg==} + + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + + '@isaacs/fs-minipass@4.0.1': + resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==} + engines: {node: '>=18.0.0'} + + '@istanbuljs/schema@0.1.3': + resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} + engines: {node: '>=8'} + + '@jridgewell/gen-mapping@0.3.3': + resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==} + engines: {node: '>=6.0.0'} + + '@jridgewell/gen-mapping@0.3.5': + resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} + engines: {node: '>=6.0.0'} + + '@jridgewell/gen-mapping@0.3.8': + resolution: {integrity: sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==} + engines: {node: '>=6.0.0'} + + '@jridgewell/resolve-uri@3.1.0': + resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==} + engines: {node: '>=6.0.0'} + + '@jridgewell/set-array@1.1.2': + resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/set-array@1.2.1': + resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} + engines: {node: '>=6.0.0'} + + '@jridgewell/source-map@0.3.6': + resolution: {integrity: sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==} + + '@jridgewell/sourcemap-codec@1.4.14': + resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==} + + '@jridgewell/sourcemap-codec@1.4.15': + resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} + + '@jridgewell/sourcemap-codec@1.5.0': + resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + + '@jridgewell/trace-mapping@0.3.17': + resolution: {integrity: sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==} + + '@jridgewell/trace-mapping@0.3.25': + resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + + '@kwsites/file-exists@1.1.1': + resolution: {integrity: sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==} + + '@kwsites/promise-deferred@1.1.1': + resolution: {integrity: sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==} + + '@lit-labs/ssr-dom-shim@1.3.0': + resolution: {integrity: sha512-nQIWonJ6eFAvUUrSlwyHDm/aE8PBDu5kRpL0vHMg6K8fK3Diq1xdPjTnsJSwxABhaZ+5eBi1btQB5ShUTKo4nQ==} + + '@lit/reactive-element@2.1.0': + resolution: {integrity: sha512-L2qyoZSQClcBmq0qajBVbhYEcG6iK0XfLn66ifLe/RfC0/ihpc+pl0Wdn8bJ8o+hj38cG0fGXRgSS20MuXn7qA==} + + '@manypkg/find-root@1.1.0': + resolution: {integrity: sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==} + + '@manypkg/get-packages@1.1.3': + resolution: {integrity: sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==} + + '@mapbox/node-pre-gyp@1.0.11': + resolution: {integrity: sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==} + hasBin: true + + '@mapbox/node-pre-gyp@2.0.0': + resolution: {integrity: sha512-llMXd39jtP0HpQLVI37Bf1m2ADlEb35GYSh1SDSLsBhR+5iCxiNGlT31yqbNtVHygHAtMy6dWFERpU2JgufhPg==} + engines: {node: '>=18'} + hasBin: true + + '@metamask/eth-json-rpc-provider@1.0.1': + resolution: {integrity: sha512-whiUMPlAOrVGmX8aKYVPvlKyG4CpQXiNNyt74vE1xb5sPvmx5oA7B/kOi/JdBvhGQq97U1/AVdXEdk2zkP8qyA==} + engines: {node: '>=14.0.0'} + + '@metamask/eth-sig-util@4.0.1': + resolution: {integrity: sha512-tghyZKLHZjcdlDqCA3gNZmLeR0XvOE9U1qoQO9ohyAZT6Pya+H9vkBPcsyXytmYLNgVoin7CKCmweo/R43V+tQ==} + engines: {node: '>=12.0.0'} + + '@metamask/json-rpc-engine@7.3.3': + resolution: {integrity: sha512-dwZPq8wx9yV3IX2caLi9q9xZBw2XeIoYqdyihDDDpuHVCEiqadJLwqM3zy+uwf6F1QYQ65A8aOMQg1Uw7LMLNg==} + engines: {node: '>=16.0.0'} + + '@metamask/json-rpc-engine@8.0.2': + resolution: {integrity: sha512-IoQPmql8q7ABLruW7i4EYVHWUbF74yrp63bRuXV5Zf9BQwcn5H9Ww1eLtROYvI1bUXwOiHZ6qT5CWTrDc/t/AA==} + engines: {node: '>=16.0.0'} + + '@metamask/json-rpc-middleware-stream@7.0.2': + resolution: {integrity: sha512-yUdzsJK04Ev98Ck4D7lmRNQ8FPioXYhEUZOMS01LXW8qTvPGiRVXmVltj2p4wrLkh0vW7u6nv0mNl5xzC5Qmfg==} + engines: {node: '>=16.0.0'} + + '@metamask/object-multiplex@2.1.0': + resolution: {integrity: sha512-4vKIiv0DQxljcXwfpnbsXcfa5glMj5Zg9mqn4xpIWqkv6uJ2ma5/GtUfLFSxhlxnR8asRMv8dDmWya1Tc1sDFA==} + engines: {node: ^16.20 || ^18.16 || >=20} + + '@metamask/onboarding@1.0.1': + resolution: {integrity: sha512-FqHhAsCI+Vacx2qa5mAFcWNSrTcVGMNjzxVgaX8ECSny/BJ9/vgXP9V7WF/8vb9DltPeQkxr+Fnfmm6GHfmdTQ==} + + '@metamask/providers@16.1.0': + resolution: {integrity: sha512-znVCvux30+3SaUwcUGaSf+pUckzT5ukPRpcBmy+muBLC0yaWnBcvDqGfcsw6CBIenUdFrVoAFa8B6jsuCY/a+g==} + engines: {node: ^18.18 || >=20} + + '@metamask/rpc-errors@6.4.0': + resolution: {integrity: sha512-1ugFO1UoirU2esS3juZanS/Fo8C8XYocCuBpfZI5N7ECtoG+zu0wF+uWZASik6CkO6w9n/Iebt4iI4pT0vptpg==} + engines: {node: '>=16.0.0'} + + '@metamask/safe-event-emitter@2.0.0': + resolution: {integrity: sha512-/kSXhY692qiV1MXu6EeOZvg5nECLclxNXcKCxJ3cXQgYuRymRHpdx/t7JXfsK+JLjwA1e1c1/SBrlQYpusC29Q==} + + '@metamask/safe-event-emitter@3.0.0': + resolution: {integrity: sha512-j6Z47VOmVyGMlnKXZmL0fyvWfEYtKWCA9yGZkU3FCsGZUT5lHGmvaV9JA5F2Y+010y7+ROtR3WMXIkvl/nVzqQ==} + engines: {node: '>=12.0.0'} + + '@metamask/safe-event-emitter@3.1.2': + resolution: {integrity: sha512-5yb2gMI1BDm0JybZezeoX/3XhPDOtTbcFvpTXM9kxsoZjPZFh4XciqRbpD6N86HYZqWDhEaKUDuOyR0sQHEjMA==} + engines: {node: '>=12.0.0'} + + '@metamask/sdk-communication-layer@0.32.0': + resolution: {integrity: sha512-dmj/KFjMi1fsdZGIOtbhxdg3amxhKL/A5BqSU4uh/SyDKPub/OT+x5pX8bGjpTL1WPWY/Q0OIlvFyX3VWnT06Q==} + peerDependencies: + cross-fetch: ^4.0.0 + eciesjs: '*' + eventemitter2: ^6.4.9 + readable-stream: ^3.6.2 + socket.io-client: ^4.5.1 + + '@metamask/sdk-install-modal-web@0.32.1': + resolution: {integrity: sha512-MGmAo6qSjf1tuYXhCu2EZLftq+DSt5Z7fsIKr2P+lDgdTPWgLfZB1tJKzNcwKKOdf6q9Qmmxn7lJuI/gq5LrKw==} + + '@metamask/sdk@0.32.1': + resolution: {integrity: sha512-ulvScxyuX+A8VYgQ9FGugtpH5l2U8AF0lOjaw6XyqwnL7I/U0Lk9yyz9pns4Zyq356Z4+nIBzxmb6czWLzp8UQ==} + + '@metamask/superstruct@3.2.1': + resolution: {integrity: sha512-fLgJnDOXFmuVlB38rUN5SmU7hAFQcCjrg3Vrxz67KTY7YHFnSNEKvX4avmEBdOI0yTCxZjwMCFEqsC8k2+Wd3g==} + engines: {node: '>=16.0.0'} + + '@metamask/utils@5.0.2': + resolution: {integrity: sha512-yfmE79bRQtnMzarnKfX7AEJBwFTxvTyw3nBQlu/5rmGXrjAeAMltoGxO62TFurxrQAFMNa/fEjIHNvungZp0+g==} + engines: {node: '>=14.0.0'} + + '@metamask/utils@8.5.0': + resolution: {integrity: sha512-I6bkduevXb72TIM9q2LRO63JSsF9EXduh3sBr9oybNX2hNNpr/j1tEjXrsG0Uabm4MJ1xkGAQEMwifvKZIkyxQ==} + engines: {node: '>=16.0.0'} + + '@metamask/utils@9.3.0': + resolution: {integrity: sha512-w8CVbdkDrVXFJbfBSlDfafDR6BAkpDmv1bC1UJVCoVny5tW2RKAdn9i68Xf7asYT4TnUhl/hN4zfUiKQq9II4g==} + engines: {node: '>=16.0.0'} + + '@mswjs/interceptors@0.35.9': + resolution: {integrity: sha512-SSnyl/4ni/2ViHKkiZb8eajA/eN1DNFaHjhGiLUdZvDz6PKF4COSf/17xqSz64nOo2Ia29SA6B2KNCsyCbVmaQ==} + engines: {node: '>=18'} + + '@napi-rs/wasm-runtime@0.2.10': + resolution: {integrity: sha512-bCsCyeZEwVErsGmyPNSzwfwFn4OdxBj0mmv6hOFucB/k81Ojdu68RbZdxYsRQUPc9l6SU5F/cG+bXgWs3oUgsQ==} + + '@netlify/binary-info@1.0.0': + resolution: {integrity: sha512-4wMPu9iN3/HL97QblBsBay3E1etIciR84izI3U+4iALY+JHCrI+a2jO0qbAZ/nxKoegypYEaiiqWXylm+/zfrw==} + + '@netlify/blobs@9.1.1': + resolution: {integrity: sha512-hOrWBMOvdh9oa+8Z6ocvkY92q9YtfD+Vbh2i+Qs14cHsl9SYxRzPRQnBxU/H6PNtj6gtEJ7tv8RbBN8z7jH2jA==} + engines: {node: ^14.16.0 || >=16.0.0} + + '@netlify/dev-utils@2.1.1': + resolution: {integrity: sha512-0O4/eEcmZCNUkpSuN/yYRkX6BAcK/sbnH0YYNuK3HX193QXaSBT60TUpvTpiRxI6zvIfYCDRl3rz63w8m/lEMg==} + engines: {node: ^14.16.0 || >=16.0.0} + + '@netlify/functions@3.1.8': + resolution: {integrity: sha512-oAHPyybBx4oH8+3RfgihrTVhv6gseQw1pt0k4kZ/NDmGbEsgrr3gw+3ajzM5+fW5UnWiNuR5c+d7JgtRqjyMkw==} + engines: {node: '>=14.0.0'} + + '@netlify/open-api@2.37.0': + resolution: {integrity: sha512-zXnRFkxgNsalSgU8/vwTWnav3R+8KG8SsqHxqaoJdjjJtnZR7wo3f+qqu4z+WtZ/4V7fly91HFUwZ6Uz2OdW7w==} + engines: {node: '>=14.8.0'} + + '@netlify/runtime-utils@1.3.1': + resolution: {integrity: sha512-7/vIJlMYrPJPlEW84V2yeRuG3QBu66dmlv9neTmZ5nXzwylhBEOhy11ai+34A8mHCSZI4mKns25w3HM9kaDdJg==} + engines: {node: '>=16.0.0'} + + '@netlify/serverless-functions-api@1.41.1': + resolution: {integrity: sha512-swjyZEd8U1QVp01rZdHxpwWie7GkP1kS4+4n8kuNKA8+3G5tD0JXXf3a5d4tdwVvrU9k7a4GP1Bn792UPwecmw==} + engines: {node: '>=18.0.0'} + + '@netlify/zip-it-and-ship-it@10.1.1': + resolution: {integrity: sha512-MMXrty1NADxyMPgd7qZvDUYunhcPhxIA/jWP2joceOoPcAxOno/aS4jFuIHf2Dbb4HdhR+BlvgvDCy7QTXXyLQ==} + engines: {node: ^14.18.0 || >=16.0.0} + hasBin: true + + '@next/bundle-analyzer@15.3.3': + resolution: {integrity: sha512-9gddnjACK6yOa5IkmeFyzcwZh2rscsb6ZspTd7tymPYKQM96fJuKjn9HrRtPNKiMm7ExKNadAJqREmHdBgHZ9A==} + + '@next/env@15.3.3': + resolution: {integrity: sha512-OdiMrzCl2Xi0VTjiQQUK0Xh7bJHnOuET2s+3V+Y40WJBAXrJeGA3f+I8MZJ/YQ3mVGi5XGR1L66oFlgqXhQ4Vw==} + + '@next/swc-darwin-arm64@15.3.3': + resolution: {integrity: sha512-WRJERLuH+O3oYB4yZNVahSVFmtxRNjNF1I1c34tYMoJb0Pve+7/RaLAJJizyYiFhjYNGHRAE1Ri2Fd23zgDqhg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + + '@next/swc-darwin-x64@15.3.3': + resolution: {integrity: sha512-XHdzH/yBc55lu78k/XwtuFR/ZXUTcflpRXcsu0nKmF45U96jt1tsOZhVrn5YH+paw66zOANpOnFQ9i6/j+UYvw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + + '@next/swc-linux-arm64-gnu@15.3.3': + resolution: {integrity: sha512-VZ3sYL2LXB8znNGcjhocikEkag/8xiLgnvQts41tq6i+wql63SMS1Q6N8RVXHw5pEUjiof+II3HkDd7GFcgkzw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@next/swc-linux-arm64-musl@15.3.3': + resolution: {integrity: sha512-h6Y1fLU4RWAp1HPNJWDYBQ+e3G7sLckyBXhmH9ajn8l/RSMnhbuPBV/fXmy3muMcVwoJdHL+UtzRzs0nXOf9SA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@next/swc-linux-x64-gnu@15.3.3': + resolution: {integrity: sha512-jJ8HRiF3N8Zw6hGlytCj5BiHyG/K+fnTKVDEKvUCyiQ/0r5tgwO7OgaRiOjjRoIx2vwLR+Rz8hQoPrnmFbJdfw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@next/swc-linux-x64-musl@15.3.3': + resolution: {integrity: sha512-HrUcTr4N+RgiiGn3jjeT6Oo208UT/7BuTr7K0mdKRBtTbT4v9zJqCDKO97DUqqoBK1qyzP1RwvrWTvU6EPh/Cw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@next/swc-win32-arm64-msvc@15.3.3': + resolution: {integrity: sha512-SxorONgi6K7ZUysMtRF3mIeHC5aA3IQLmKFQzU0OuhuUYwpOBc1ypaLJLP5Bf3M9k53KUUUj4vTPwzGvl/NwlQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + + '@next/swc-win32-x64-msvc@15.3.3': + resolution: {integrity: sha512-4QZG6F8enl9/S2+yIiOiju0iCTFd93d8VC1q9LZS4p/Xuk81W2QDjCFeoogmrWWkAD59z8ZxepBQap2dKS5ruw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + + '@noble/ciphers@1.2.1': + resolution: {integrity: sha512-rONPWMC7PeExE077uLE4oqWrZ1IvAfz3oH9LibVAcVCopJiA9R62uavnbEzdkVmJYI6M6Zgkbeb07+tWjlq2XA==} + engines: {node: ^14.21.3 || >=16} + + '@noble/ciphers@1.3.0': + resolution: {integrity: sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw==} + engines: {node: ^14.21.3 || >=16} + + '@noble/curves@1.2.0': + resolution: {integrity: sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==} + + '@noble/curves@1.4.0': + resolution: {integrity: sha512-p+4cb332SFCrReJkCYe8Xzm0OWi4Jji5jVdIZRL/PmacmDkFNw6MrrV+gGpiPxLHbV+zKFRywUWbaseT+tZRXg==} + + '@noble/curves@1.4.2': + resolution: {integrity: sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw==} + + '@noble/curves@1.8.0': + resolution: {integrity: sha512-j84kjAbzEnQHaSIhRPUmB3/eVXu2k3dKPl2LOrR8fSOIL+89U+7lV117EWHtq/GHM3ReGHM46iRBdZfpc4HRUQ==} + engines: {node: ^14.21.3 || >=16} + + '@noble/curves@1.8.1': + resolution: {integrity: sha512-warwspo+UYUPep0Q+vtdVB4Ugn8GGQj8iyB3gnRWsztmUHTI3S1nhdiWNsPUGL0vud7JlRRk1XEu7Lq1KGTnMQ==} + engines: {node: ^14.21.3 || >=16} + + '@noble/curves@1.8.2': + resolution: {integrity: sha512-vnI7V6lFNe0tLAuJMu+2sX+FcL14TaCWy1qiczg1VwRmPrpQCdq5ESXQMqUc2tluRNf6irBXrWbl1mGN8uaU/g==} + engines: {node: ^14.21.3 || >=16} + + '@noble/curves@1.9.2': + resolution: {integrity: sha512-HxngEd2XUcg9xi20JkwlLCtYwfoFw4JGkuZpT+WlsPD4gB/cxkvTD8fSsoAnphGZhFdZYKeQIPCuFlWPm1uE0g==} + engines: {node: ^14.21.3 || >=16} + + '@noble/hashes@1.2.0': + resolution: {integrity: sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ==} + + '@noble/hashes@1.3.2': + resolution: {integrity: sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==} + engines: {node: '>= 16'} + + '@noble/hashes@1.4.0': + resolution: {integrity: sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==} + engines: {node: '>= 16'} + + '@noble/hashes@1.5.0': + resolution: {integrity: sha512-1j6kQFb7QRru7eKN3ZDvRcP13rugwdxZqCjbiAVZfIJwgj2A65UmT4TgARXGlXgnRkORLTDTrO19ZErt7+QXgA==} + engines: {node: ^14.21.3 || >=16} + + '@noble/hashes@1.7.0': + resolution: {integrity: sha512-HXydb0DgzTpDPwbVeDGCG1gIu7X6+AuU6Zl6av/E/KG8LMsvPntvq+w17CHRpKBmN6Ybdrt1eP3k4cj8DJa78w==} + engines: {node: ^14.21.3 || >=16} + + '@noble/hashes@1.7.1': + resolution: {integrity: sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ==} + engines: {node: ^14.21.3 || >=16} + + '@noble/hashes@1.7.2': + resolution: {integrity: sha512-biZ0NUSxyjLLqo6KxEJ1b+C2NAx0wtDoFvCaXHGgUkeHzf3Xc1xKumFKREuT7f7DARNZ/slvYUwFG6B0f2b6hQ==} + engines: {node: ^14.21.3 || >=16} + + '@noble/hashes@1.8.0': + resolution: {integrity: sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==} + engines: {node: ^14.21.3 || >=16} + + '@noble/secp256k1@1.7.1': + resolution: {integrity: sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw==} + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + '@nomicfoundation/edr-darwin-arm64@0.3.7': + resolution: {integrity: sha512-6tK9Lv/lSfyBvpEQ4nsTfgxyDT1y1Uv/x8Wa+aB+E8qGo3ToexQ1BMVjxJk6PChXCDOWxB3B4KhqaZFjdhl3Ow==} + engines: {node: '>= 18'} + cpu: [arm64] + os: [darwin] + + '@nomicfoundation/edr-darwin-x64@0.3.7': + resolution: {integrity: sha512-1RrQ/1JPwxrYO69e0tglFv5H+ggour5Ii3bb727+yBpBShrxtOTQ7fZyfxA5h62LCN+0Z9wYOPeQ7XFcVurMaQ==} + engines: {node: '>= 18'} + cpu: [x64] + os: [darwin] + + '@nomicfoundation/edr-linux-arm64-gnu@0.3.7': + resolution: {integrity: sha512-ds/CKlBoVXIihjhflhgPn13EdKWed6r5bgvMs/YwRqT5wldQAQJZWAfA2+nYm0Yi2gMGh1RUpBcfkyl4pq7G+g==} + engines: {node: '>= 18'} + cpu: [arm64] + os: [linux] + + '@nomicfoundation/edr-linux-arm64-musl@0.3.7': + resolution: {integrity: sha512-e29udiRaPujhLkM3+R6ju7QISrcyOqpcaxb2FsDWBkuD7H8uU9JPZEyyUIpEp5uIY0Jh1eEJPKZKIXQmQAEAuw==} + engines: {node: '>= 18'} + cpu: [arm64] + os: [linux] + + '@nomicfoundation/edr-linux-x64-gnu@0.3.7': + resolution: {integrity: sha512-/xkjmTyv+bbJ4akBCW0qzFKxPOV4AqLOmqurov+s9umHb16oOv72osSa3SdzJED2gHDaKmpMITT4crxbar4Axg==} + engines: {node: '>= 18'} + cpu: [x64] + os: [linux] + + '@nomicfoundation/edr-linux-x64-musl@0.3.7': + resolution: {integrity: sha512-QwBP9xlmsbf/ldZDGLcE4QiAb8Zt46E/+WLpxHBATFhGa7MrpJh6Zse+h2VlrT/SYLPbh2cpHgSmoSlqVxWG9g==} + engines: {node: '>= 18'} + cpu: [x64] + os: [linux] + + '@nomicfoundation/edr-win32-x64-msvc@0.3.7': + resolution: {integrity: sha512-j/80DEnkxrF2ewdbk/gQ2EOPvgF0XSsg8D0o4+6cKhUVAW6XwtWKzIphNL6dyD2YaWEPgIrNvqiJK/aln0ww4Q==} + engines: {node: '>= 18'} + cpu: [x64] + os: [win32] + + '@nomicfoundation/edr@0.3.7': + resolution: {integrity: sha512-v2JFWnFKRsnOa6PDUrD+sr8amcdhxnG/YbL7LzmgRGU1odWEyOF4/EwNeUajQr4ZNKVWrYnJ6XjydXtUge5OBQ==} + engines: {node: '>= 18'} + + '@nomicfoundation/ethereumjs-common@4.0.4': + resolution: {integrity: sha512-9Rgb658lcWsjiicr5GzNCjI1llow/7r0k50dLL95OJ+6iZJcVbi15r3Y0xh2cIO+zgX0WIHcbzIu6FeQf9KPrg==} + + '@nomicfoundation/ethereumjs-rlp@5.0.4': + resolution: {integrity: sha512-8H1S3s8F6QueOc/X92SdrA4RDenpiAEqMg5vJH99kcQaCy/a3Q6fgseo75mgWlbanGJXSlAPtnCeG9jvfTYXlw==} + engines: {node: '>=18'} + hasBin: true + + '@nomicfoundation/ethereumjs-tx@5.0.4': + resolution: {integrity: sha512-Xjv8wAKJGMrP1f0n2PeyfFCCojHd7iS3s/Ab7qzF1S64kxZ8Z22LCMynArYsVqiFx6rzYy548HNVEyI+AYN/kw==} + engines: {node: '>=18'} + peerDependencies: + c-kzg: ^2.1.2 + peerDependenciesMeta: + c-kzg: + optional: true + + '@nomicfoundation/ethereumjs-util@9.0.4': + resolution: {integrity: sha512-sLOzjnSrlx9Bb9EFNtHzK/FJFsfg2re6bsGqinFinH1gCqVfz9YYlXiMWwDM4C/L4ywuHFCYwfKTVr/QHQcU0Q==} + engines: {node: '>=18'} + peerDependencies: + c-kzg: ^2.1.2 + peerDependenciesMeta: + c-kzg: + optional: true + + '@nomicfoundation/solidity-analyzer-darwin-arm64@0.1.1': + resolution: {integrity: sha512-KcTodaQw8ivDZyF+D76FokN/HdpgGpfjc/gFCImdLUyqB6eSWVaZPazMbeAjmfhx3R0zm/NYVzxwAokFKgrc0w==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + + '@nomicfoundation/solidity-analyzer-darwin-x64@0.1.1': + resolution: {integrity: sha512-XhQG4BaJE6cIbjAVtzGOGbK3sn1BO9W29uhk9J8y8fZF1DYz0Doj8QDMfpMu+A6TjPDs61lbsmeYodIDnfveSA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + + '@nomicfoundation/solidity-analyzer-freebsd-x64@0.1.1': + resolution: {integrity: sha512-GHF1VKRdHW3G8CndkwdaeLkVBi5A9u2jwtlS7SLhBc8b5U/GcoL39Q+1CSO3hYqePNP+eV5YI7Zgm0ea6kMHoA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [freebsd] + + '@nomicfoundation/solidity-analyzer-linux-arm64-gnu@0.1.1': + resolution: {integrity: sha512-g4Cv2fO37ZsUENQ2vwPnZc2zRenHyAxHcyBjKcjaSmmkKrFr64yvzeNO8S3GBFCo90rfochLs99wFVGT/0owpg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@nomicfoundation/solidity-analyzer-linux-arm64-musl@0.1.1': + resolution: {integrity: sha512-WJ3CE5Oek25OGE3WwzK7oaopY8xMw9Lhb0mlYuJl/maZVo+WtP36XoQTb7bW/i8aAdHW5Z+BqrHMux23pvxG3w==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@nomicfoundation/solidity-analyzer-linux-x64-gnu@0.1.1': + resolution: {integrity: sha512-5WN7leSr5fkUBBjE4f3wKENUy9HQStu7HmWqbtknfXkkil+eNWiBV275IOlpXku7v3uLsXTOKpnnGHJYI2qsdA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@nomicfoundation/solidity-analyzer-linux-x64-musl@0.1.1': + resolution: {integrity: sha512-KdYMkJOq0SYPQMmErv/63CwGwMm5XHenEna9X9aB8mQmhDBrYrlAOSsIPgFCUSL0hjxE3xHP65/EPXR/InD2+w==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@nomicfoundation/solidity-analyzer-win32-arm64-msvc@0.1.1': + resolution: {integrity: sha512-VFZASBfl4qiBYwW5xeY20exWhmv6ww9sWu/krWSesv3q5hA0o1JuzmPHR4LPN6SUZj5vcqci0O6JOL8BPw+APg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + + '@nomicfoundation/solidity-analyzer-win32-ia32-msvc@0.1.1': + resolution: {integrity: sha512-JnFkYuyCSA70j6Si6cS1A9Gh1aHTEb8kOTBApp/c7NRTFGNMH8eaInKlyuuiIbvYFhlXW4LicqyYuWNNq9hkpQ==} + engines: {node: '>= 10'} + cpu: [ia32] + os: [win32] + + '@nomicfoundation/solidity-analyzer-win32-x64-msvc@0.1.1': + resolution: {integrity: sha512-HrVJr6+WjIXGnw3Q9u6KQcbZCtk0caVWhCdFADySvRyUxJ8PnzlaP+MhwNE8oyT8OZ6ejHBRrrgjSqDCFXGirw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + + '@nomicfoundation/solidity-analyzer@0.1.1': + resolution: {integrity: sha512-1LMtXj1puAxyFusBgUIy5pZk3073cNXYnXUpuNKFghHbIit/xZgbk0AokpUADbNm3gyD6bFWl3LRFh3dhVdREg==} + engines: {node: '>= 12'} + + '@nuxt/cli@3.25.1': + resolution: {integrity: sha512-7+Ut7IvAD4b5piikJFSgIqSPbHKFT5gq05JvCsEHRM0MPA5QR9QHkicklyMqSj0D/oEkDohen8qRgdxRie3oUA==} + engines: {node: ^16.10.0 || >=18.0.0} + hasBin: true + + '@nuxt/devalue@2.0.2': + resolution: {integrity: sha512-GBzP8zOc7CGWyFQS6dv1lQz8VVpz5C2yRszbXufwG/9zhStTIH50EtD87NmWbTMwXDvZLNg8GIpb1UFdH93JCA==} + + '@nuxt/devtools-kit@2.4.1': + resolution: {integrity: sha512-taA2Nm03JiV3I+SEYS/u1AfjvLm3V9PO8lh0xLsUk/2mlUnL6GZ9xLXrp8VRg11HHt7EPXERGQh8h4iSPU2bSQ==} + peerDependencies: + vite: '>=6.0' + + '@nuxt/devtools-wizard@2.4.1': + resolution: {integrity: sha512-2BaryhfribzQ95UxR7vLLV17Pk1Otxg9ryqH71M1Yp0mybBFs6Z3b0v+RXfCb4BwA10s/tXBhfF13DHSSJF1+A==} + hasBin: true + + '@nuxt/devtools@2.4.1': + resolution: {integrity: sha512-2gwjUF1J1Bp/V9ZTsYJe8sS9O3eg80gdf01fT8aEBcilR3wf0PSIxjEyYk+YENtrHPLXcnnUko89jHGq23MHPQ==} + hasBin: true + peerDependencies: + vite: '>=6.0' + + '@nuxt/kit@3.16.0': + resolution: {integrity: sha512-yPfhk58BG6wJhELkGOTCOlkMDbZkizk3IaINcyTKm+hBKiK3SheLt7S9HStNL+qZSfH2Cf7A8sYp6M72lOIEtA==} + engines: {node: '>=18.12.0'} + + '@nuxt/kit@3.17.4': + resolution: {integrity: sha512-l+hY8sy2XFfg3PigZj+PTu6+KIJzmbACTRimn1ew/gtCz+F38f6KTF4sMRTN5CUxiB8TRENgEonASmkAWfpO9Q==} + engines: {node: '>=18.12.0'} + + '@nuxt/schema@3.11.2': + resolution: {integrity: sha512-Z0bx7N08itD5edtpkstImLctWMNvxTArsKXzS35ZuqyAyKBPcRjO1CU01slH0ahO30Gg9kbck3/RKNZPwfOjJg==} + engines: {node: ^14.18.0 || >=16.10.0} + + '@nuxt/schema@3.16.0': + resolution: {integrity: sha512-uCpcqWO6C4P5c4vi1/sq5GyajO0EOp+ZWFtPrnKaJ1pXAhA+W1aMVxAjfi2f18QMJHuRXBz1TouFg1RmWA6FuA==} + engines: {node: ^14.18.0 || >=16.10.0} + + '@nuxt/schema@3.17.4': + resolution: {integrity: sha512-bsfJdWjKNYLkVQt7Ykr9YsAql1u8Tuo6iecSUOltTIhsvAIYsknRFPHoNKNmaiv/L6FgCQgUgQppPTPUAXiJQQ==} + engines: {node: ^14.18.0 || >=16.10.0} + + '@nuxt/telemetry@2.6.6': + resolution: {integrity: sha512-Zh4HJLjzvm3Cq9w6sfzIFyH9ozK5ePYVfCUzzUQNiZojFsI2k1QkSBrVI9BGc6ArKXj/O6rkI6w7qQ+ouL8Cag==} + engines: {node: '>=18.12.0'} + hasBin: true + + '@nuxt/ui-templates@1.3.3': + resolution: {integrity: sha512-3BG5doAREcD50dbKyXgmjD4b1GzY8CUy3T41jMhHZXNDdaNwOd31IBq+D6dV00OSrDVhzrTVj0IxsUsnMyHvIQ==} + + '@nuxt/vite-builder@3.16.0': + resolution: {integrity: sha512-H/mRrDmpWWLIiF1J9jguCKITF0ydFxmgcBcbveQac6vVhaOZunBAv9SsKHZgnH8CDM1v5BnuRNyIQ9y4Y9wW8g==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0.0} + peerDependencies: + vue: ^3.3.4 + + '@one-ini/wasm@0.1.1': + resolution: {integrity: sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==} + + '@open-draft/deferred-promise@2.2.0': + resolution: {integrity: sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA==} + + '@open-draft/logger@0.3.0': + resolution: {integrity: sha512-X2g45fzhxH238HKO4xbSr7+wBS8Fvw6ixhTDuvLd5mqh6bJJCFAPwU9mPDxbcrRtfxv4u5IHCEH77BmxvXmmxQ==} + + '@open-draft/until@2.1.0': + resolution: {integrity: sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==} + + '@oven/bun-darwin-aarch64@1.1.30': + resolution: {integrity: sha512-D07QioP+QXlouvIqQIS+7r2zq4lTNd6he79rhKsRQRZGFf9i3NPu87zspUpCaFEu//DZ35DYTt+5anQpAzpoxA==} + cpu: [arm64] + os: [darwin] + + '@oven/bun-darwin-x64-baseline@1.1.30': + resolution: {integrity: sha512-1kFUCxHx7WuEbLDmqm0m2UKBd3S4Ln6qKQ4gxU4umMLFkmvDJn6PszDruFInxGKFLoTAmbXNYNVWkkG/ekt/Lg==} + cpu: [x64] + os: [darwin] + + '@oven/bun-darwin-x64@1.1.30': + resolution: {integrity: sha512-xZ4gTehS6QwN6bsJfDycCNneKoUMaFUQhQg24bJzXS4JPDxeKg1W7PS5AE+U9apz5Dx6//+D4RwVpAPG2LXt0w==} + cpu: [x64] + os: [darwin] + + '@oven/bun-linux-aarch64@1.1.30': + resolution: {integrity: sha512-SfHHLlph6fptDXyyChcUkeDbEZr2ww1p2BucV6OrvzwTOPi8pVmXA4360YT8ggR/3AHPp4GO36VaD+FU2Ocbxw==} + cpu: [arm64] + os: [linux] + + '@oven/bun-linux-x64-baseline@1.1.30': + resolution: {integrity: sha512-/b/VuNOaAYmsVk9MvfwKcCYARJPUg78hebxNyD5DSajAf3dqtUSnf7QYcq/3mxWH++N+gM7uRTrGksGS63+ZUw==} + cpu: [x64] + os: [linux] + + '@oven/bun-linux-x64@1.1.30': + resolution: {integrity: sha512-1mC39jQSaECytEKAZdCZmv3ZreMsp7aoxnBwmJtVd2Z7urnw17PKi4dKkZd/R+AubsNYtXtW4jeM8SEa5sUJRw==} + cpu: [x64] + os: [linux] + + '@oven/bun-windows-x64-baseline@1.1.30': + resolution: {integrity: sha512-ERQ4/ogzbFvHjpyHcnruc8bnryvDvUoiWi6vczfQ4M/idJc+Kg5VSEJiF5k7946rIZGamG6QWgRxtpIglD4/Zw==} + cpu: [x64] + os: [win32] + + '@oven/bun-windows-x64@1.1.30': + resolution: {integrity: sha512-mdRjNtD9NIA8CiH6N1zrIVE6oAtDko/c29H1s00UA+5O/WhXhg95G8IyInD8hN3vAEz8H2lGBgLG2EGfSFxnGg==} + cpu: [x64] + os: [win32] + + '@oxc-parser/binding-darwin-arm64@0.56.5': + resolution: {integrity: sha512-rj4WZqQVJQgLnGnDu2ciIOC5SqcBPc4x11RN0NwuedSGzny5mtBdNVLwt0+8iB15lIjrOKg5pjYJ8GQVPca5HA==} + engines: {node: '>=14.0.0'} + cpu: [arm64] + os: [darwin] + + '@oxc-parser/binding-darwin-x64@0.56.5': + resolution: {integrity: sha512-Rr7aMkqcxGIM6fgkpaj9SJj0u1O1g+AT7mJwmdi5PLSQRPR4CkDKfztEnAj5k+d2blWvh9nPZH8G0OCwxIHk1Q==} + engines: {node: '>=14.0.0'} + cpu: [x64] + os: [darwin] + + '@oxc-parser/binding-linux-arm-gnueabihf@0.56.5': + resolution: {integrity: sha512-jcFCThrWUt5k1GM43tdmI1m2dEnWUPPHHTWKBJbZBXzXLrJJzkqv5OU87Spf1004rYj9swwpa13kIldFwMzglA==} + engines: {node: '>=14.0.0'} + cpu: [arm] + os: [linux] + + '@oxc-parser/binding-linux-arm64-gnu@0.56.5': + resolution: {integrity: sha512-zo/9RDgWvugKxCpHHcAC5EW0AqoEvODJ4Iv4aT1Xonv6kcydbyPSXJBQhhZUvTXTAFIlQKl6INHl+Xki9Qs3fw==} + engines: {node: '>=14.0.0'} + cpu: [arm64] + os: [linux] + + '@oxc-parser/binding-linux-arm64-musl@0.56.5': + resolution: {integrity: sha512-SCIqrL5apVbrtMoqOpKX/Ez+c46WmW0Tyhtu+Xby281biH+wYu70m+fux9ZsGmbHc2ojd4FxUcaUdCZtb5uTOQ==} + engines: {node: '>=14.0.0'} + cpu: [arm64] + os: [linux] + + '@oxc-parser/binding-linux-x64-gnu@0.56.5': + resolution: {integrity: sha512-I2mpX35NWo83hay4wrnzFLk3VuGK1BBwHaqvEdqsCode8iG8slYJRJPICVbCEWlkR3rotlTQ+608JcRU0VqZ5Q==} + engines: {node: '>=14.0.0'} + cpu: [x64] + os: [linux] + + '@oxc-parser/binding-linux-x64-musl@0.56.5': + resolution: {integrity: sha512-xfzUHGYOh3PGWZdBuY5r1czvE8EGWPAmhTWHqkw3/uAfUVWN/qrrLjMojiaiWyUgl/9XIFg05m5CJH9dnngh5Q==} + engines: {node: '>=14.0.0'} + cpu: [x64] + os: [linux] + + '@oxc-parser/binding-wasm32-wasi@0.56.5': + resolution: {integrity: sha512-+z3Ofmc1v5kcu8fXgG5vn7T1f52P47ceTTmTXsm5HPY7rq5EMYRUaBnxH6cesXwY1OVVCwYlIZbCiy8Pm1w8zQ==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + + '@oxc-parser/binding-win32-arm64-msvc@0.56.5': + resolution: {integrity: sha512-pRg8QrbMh8PgnXBreiONoJBR306u+JN19BXQC7oKIaG4Zxt9Mn8XIyuhUv3ytqjLudSiG2ERWQUoCGLs+yfW0A==} + engines: {node: '>=14.0.0'} + cpu: [arm64] + os: [win32] + + '@oxc-parser/binding-win32-x64-msvc@0.56.5': + resolution: {integrity: sha512-VALZNcuyw/6rwsxOACQ2YS6rey2d/ym4cNfXqJrHB/MZduAPj4xvij72gHGu3Ywm31KVGLVWk/mrMRiM9CINcA==} + engines: {node: '>=14.0.0'} + cpu: [x64] + os: [win32] + + '@oxc-parser/wasm@0.56.5': + resolution: {integrity: sha512-9vtn56ok7PHS0elihFP+Q+alveQuGR0vnF6OeZesxkKWLJr8mCk0kZJx5ZxLjibaPA/sxWTmOyn31UMM9jg9fg==} + deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. + + '@oxc-project/types@0.56.5': + resolution: {integrity: sha512-skY3kOJwp22W4RkaadH1hZ3hqFHjkRrIIE0uQ4VUg+/Chvbl+2pF+B55IrIk2dgsKXS57YEUsJuN6I6s4rgFjA==} + + '@parcel/watcher-android-arm64@2.4.1': + resolution: {integrity: sha512-LOi/WTbbh3aTn2RYddrO8pnapixAziFl6SMxHM69r3tvdSm94JtCenaKgk1GRg5FJ5wpMCpHeW+7yqPlvZv7kg==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [android] + + '@parcel/watcher-android-arm64@2.5.1': + resolution: {integrity: sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [android] + + '@parcel/watcher-darwin-arm64@2.4.1': + resolution: {integrity: sha512-ln41eihm5YXIY043vBrrHfn94SIBlqOWmoROhsMVTSXGh0QahKGy77tfEywQ7v3NywyxBBkGIfrWRHm0hsKtzA==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [darwin] + + '@parcel/watcher-darwin-arm64@2.5.1': + resolution: {integrity: sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [darwin] + + '@parcel/watcher-darwin-x64@2.4.1': + resolution: {integrity: sha512-yrw81BRLjjtHyDu7J61oPuSoeYWR3lDElcPGJyOvIXmor6DEo7/G2u1o7I38cwlcoBHQFULqF6nesIX3tsEXMg==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [darwin] + + '@parcel/watcher-darwin-x64@2.5.1': + resolution: {integrity: sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [darwin] + + '@parcel/watcher-freebsd-x64@2.4.1': + resolution: {integrity: sha512-TJa3Pex/gX3CWIx/Co8k+ykNdDCLx+TuZj3f3h7eOjgpdKM+Mnix37RYsYU4LHhiYJz3DK5nFCCra81p6g050w==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [freebsd] + + '@parcel/watcher-freebsd-x64@2.5.1': + resolution: {integrity: sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [freebsd] + + '@parcel/watcher-linux-arm-glibc@2.4.1': + resolution: {integrity: sha512-4rVYDlsMEYfa537BRXxJ5UF4ddNwnr2/1O4MHM5PjI9cvV2qymvhwZSFgXqbS8YoTk5i/JR0L0JDs69BUn45YA==} + engines: {node: '>= 10.0.0'} + cpu: [arm] + os: [linux] + + '@parcel/watcher-linux-arm-glibc@2.5.1': + resolution: {integrity: sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==} + engines: {node: '>= 10.0.0'} + cpu: [arm] + os: [linux] + + '@parcel/watcher-linux-arm-musl@2.5.1': + resolution: {integrity: sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==} + engines: {node: '>= 10.0.0'} + cpu: [arm] + os: [linux] + + '@parcel/watcher-linux-arm64-glibc@2.4.1': + resolution: {integrity: sha512-BJ7mH985OADVLpbrzCLgrJ3TOpiZggE9FMblfO65PlOCdG++xJpKUJ0Aol74ZUIYfb8WsRlUdgrZxKkz3zXWYA==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [linux] + + '@parcel/watcher-linux-arm64-glibc@2.5.1': + resolution: {integrity: sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [linux] + + '@parcel/watcher-linux-arm64-musl@2.4.1': + resolution: {integrity: sha512-p4Xb7JGq3MLgAfYhslU2SjoV9G0kI0Xry0kuxeG/41UfpjHGOhv7UoUDAz/jb1u2elbhazy4rRBL8PegPJFBhA==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [linux] + + '@parcel/watcher-linux-arm64-musl@2.5.1': + resolution: {integrity: sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [linux] + + '@parcel/watcher-linux-x64-glibc@2.4.1': + resolution: {integrity: sha512-s9O3fByZ/2pyYDPoLM6zt92yu6P4E39a03zvO0qCHOTjxmt3GHRMLuRZEWhWLASTMSrrnVNWdVI/+pUElJBBBg==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [linux] + + '@parcel/watcher-linux-x64-glibc@2.5.1': + resolution: {integrity: sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [linux] + + '@parcel/watcher-linux-x64-musl@2.4.1': + resolution: {integrity: sha512-L2nZTYR1myLNST0O632g0Dx9LyMNHrn6TOt76sYxWLdff3cB22/GZX2UPtJnaqQPdCRoszoY5rcOj4oMTtp5fQ==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [linux] + + '@parcel/watcher-linux-x64-musl@2.5.1': + resolution: {integrity: sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [linux] + + '@parcel/watcher-wasm@2.4.1': + resolution: {integrity: sha512-/ZR0RxqxU/xxDGzbzosMjh4W6NdYFMqq2nvo2b8SLi7rsl/4jkL8S5stIikorNkdR50oVDvqb/3JT05WM+CRRA==} + engines: {node: '>= 10.0.0'} + bundledDependencies: + - napi-wasm + + '@parcel/watcher-wasm@2.5.1': + resolution: {integrity: sha512-RJxlQQLkaMMIuWRozy+z2vEqbaQlCuaCgVZIUCzQLYggY22LZbP5Y1+ia+FD724Ids9e+XIyOLXLrLgQSHIthw==} + engines: {node: '>= 10.0.0'} + bundledDependencies: + - napi-wasm + + '@parcel/watcher-win32-arm64@2.4.1': + resolution: {integrity: sha512-Uq2BPp5GWhrq/lcuItCHoqxjULU1QYEcyjSO5jqqOK8RNFDBQnenMMx4gAl3v8GiWa59E9+uDM7yZ6LxwUIfRg==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [win32] + + '@parcel/watcher-win32-arm64@2.5.1': + resolution: {integrity: sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [win32] + + '@parcel/watcher-win32-ia32@2.4.1': + resolution: {integrity: sha512-maNRit5QQV2kgHFSYwftmPBxiuK5u4DXjbXx7q6eKjq5dsLXZ4FJiVvlcw35QXzk0KrUecJmuVFbj4uV9oYrcw==} + engines: {node: '>= 10.0.0'} + cpu: [ia32] + os: [win32] + + '@parcel/watcher-win32-ia32@2.5.1': + resolution: {integrity: sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ==} + engines: {node: '>= 10.0.0'} + cpu: [ia32] + os: [win32] + + '@parcel/watcher-win32-x64@2.4.1': + resolution: {integrity: sha512-+DvS92F9ezicfswqrvIRM2njcYJbd5mb9CUgtrHCHmvn7pPPa+nMDRu1o1bYYz/l5IB2NVGNJWiH7h1E58IF2A==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [win32] + + '@parcel/watcher-win32-x64@2.5.1': + resolution: {integrity: sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [win32] + + '@parcel/watcher@2.4.1': + resolution: {integrity: sha512-HNjmfLQEVRZmHRET336f20H/8kOozUGwk7yajvsonjNxbj2wBTK1WsQuHkD5yYh9RxFGL2EyDHryOihOwUoKDA==} + engines: {node: '>= 10.0.0'} + + '@parcel/watcher@2.5.1': + resolution: {integrity: sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==} + engines: {node: '>= 10.0.0'} + + '@paulmillr/qr@0.2.1': + resolution: {integrity: sha512-IHnV6A+zxU7XwmKFinmYjUcwlyK9+xkG3/s9KcQhI9BjQKycrJ1JRO+FbNYPwZiPKW3je/DR0k7w8/gLa5eaxQ==} + deprecated: 'The package is now available as "qr": npm install qr' + + '@pkgjs/parseargs@0.11.0': + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + + '@polka/url@1.0.0-next.29': + resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==} + + '@poppinss/colors@4.1.4': + resolution: {integrity: sha512-FA+nTU8p6OcSH4tLDY5JilGYr1bVWHpNmcLr7xmMEdbWmKHa+3QZ+DqefrXKmdjO/brHTnQZo20lLSjaO7ydog==} + engines: {node: '>=18.16.0'} + + '@poppinss/dumper@0.6.3': + resolution: {integrity: sha512-iombbn8ckOixMtuV1p3f8jN6vqhXefNjJttoPaJDMeIk/yIGhkkL3OrHkEjE9SRsgoAx1vBUU2GtgggjvA5hCA==} + + '@poppinss/exception@1.2.1': + resolution: {integrity: sha512-aQypoot0HPSJa6gDPEPTntc1GT6QINrSbgRlRhadGW2WaYqUK3tK4Bw9SBMZXhmxd3GeAlZjVcODHgiu+THY7A==} + engines: {node: '>=18'} + + '@publint/pack@0.1.2': + resolution: {integrity: sha512-S+9ANAvUmjutrshV4jZjaiG8XQyuJIZ8a4utWmN/vW1sgQ9IfBnPndwkmQYw53QmouOIytT874u65HEmu6H5jw==} + engines: {node: '>=18'} + + '@reown/appkit-common@1.7.3': + resolution: {integrity: sha512-wKTr6N3z8ly17cc51xBEVkZK4zAd8J1m7RubgsdQ1olFY9YJGe61RYoNv9yFjt6tUVeYT+z7iMUwPhX2PziefQ==} + + '@reown/appkit-controllers@1.7.3': + resolution: {integrity: sha512-aqAcX/nZe0gwqjncyCkVrAk3lEw0qZ9xGrdLOmA207RreO4J0Vxu8OJXCBn4C2AUI2OpBxCPah+vyuKTUJTeHQ==} + + '@reown/appkit-polyfills@1.7.3': + resolution: {integrity: sha512-vQUiAyI7WiNTUV4iNwv27iigdeg8JJTEo6ftUowIrKZ2/gtE2YdMtGpavuztT/qrXhrIlTjDGp5CIyv9WOTu4g==} + + '@reown/appkit-scaffold-ui@1.7.3': + resolution: {integrity: sha512-ssB15fcjmoKQ+VfoCo7JIIK66a4SXFpCH8uK1CsMmXmKIKqPN54ohLo291fniV6mKtnJxh5Xm68slGtGrO3bmA==} + + '@reown/appkit-ui@1.7.3': + resolution: {integrity: sha512-zKmFIjLp0X24pF9KtPtSHmdsh/RjEWIvz+faIbPGm4tQbwcxdg9A35HeoP0rMgKYx49SX51LgPwVXne2gYacqQ==} + + '@reown/appkit-utils@1.7.3': + resolution: {integrity: sha512-8/MNhmfri+2uu8WzBhZ5jm5llofOIa1dyXDXRC/hfrmGmCFJdrQKPpuqOFYoimo2s2g70pK4PYefvOKgZOWzgg==} + + '@reown/appkit-wallet@1.7.3': + resolution: {integrity: sha512-D0pExd0QUE71ursQPp3pq/0iFrz2oz87tOyFifrPANvH5X0RQCYn/34/kXr+BFVQzNFfCBDlYP+CniNA/S0KiQ==} + + '@reown/appkit@1.7.3': + resolution: {integrity: sha512-aA/UIwi/dVzxEB62xlw3qxHa3RK1YcPMjNxoGj/fHNCqL2qWmbcOXT7coCUa9RG7/Bh26FZ3vdVT2v71j6hebQ==} + + '@rolldown/pluginutils@1.0.0-beta.9': + resolution: {integrity: sha512-e9MeMtVWo186sgvFFJOPGy7/d2j2mZhLJIdVW0C/xDluuOvymEATqz6zKsP0ZmXGzQtqlyjz5sC1sYQUoJG98w==} + + '@rollup/plugin-alias@5.1.1': + resolution: {integrity: sha512-PR9zDb+rOzkRb2VD+EuKB7UC41vU5DIwZ5qqCpk0KJudcWAyi8rvYOhS7+L5aZCspw1stTViLgN5v6FF1p5cgQ==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/plugin-commonjs@28.0.3': + resolution: {integrity: sha512-pyltgilam1QPdn+Zd9gaCfOLcnjMEJ9gV+bTw6/r73INdvzf1ah9zLIJBm+kW7R6IUFIQ1YO+VqZtYxZNWFPEQ==} + engines: {node: '>=16.0.0 || 14 >= 14.17'} + peerDependencies: + rollup: ^2.68.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/plugin-inject@5.0.5': + resolution: {integrity: sha512-2+DEJbNBoPROPkgTDNe8/1YXWcqxbN5DTjASVIOx8HS+pITXushyNiBV56RB08zuptzz8gT3YfkqriTBVycepg==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/plugin-json@6.1.0': + resolution: {integrity: sha512-EGI2te5ENk1coGeADSIwZ7G2Q8CJS2sF120T7jLw4xFw9n7wIOXHo+kIYRAoVpJAN+kmqZSoO3Fp4JtoNF4ReA==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/plugin-node-resolve@16.0.1': + resolution: {integrity: sha512-tk5YCxJWIG81umIvNkSod2qK5KyQW19qcBF/B78n1bjtOON6gzKoVeSzAE8yHCZEDmqkHKkxplExA8KzdJLJpA==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^2.78.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/plugin-replace@6.0.2': + resolution: {integrity: sha512-7QaYCf8bqF04dOy7w/eHmJeNExxTYwvKAmlSAH/EaWWUzbT0h5sbF6bktFoX/0F/0qwng5/dWFMyf3gzaM8DsQ==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/plugin-terser@0.4.4': + resolution: {integrity: sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/pluginutils@5.1.0': + resolution: {integrity: sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/pluginutils@5.1.4': + resolution: {integrity: sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/rollup-android-arm-eabi@4.41.0': + resolution: {integrity: sha512-KxN+zCjOYHGwCl4UCtSfZ6jrq/qi88JDUtiEFk8LELEHq2Egfc/FgW+jItZiOLRuQfb/3xJSgFuNPC9jzggX+A==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.41.0': + resolution: {integrity: sha512-yDvqx3lWlcugozax3DItKJI5j05B0d4Kvnjx+5mwiUpWramVvmAByYigMplaoAQ3pvdprGCTCE03eduqE/8mPQ==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.41.0': + resolution: {integrity: sha512-2KOU574vD3gzcPSjxO0eyR5iWlnxxtmW1F5CkNOHmMlueKNCQkxR6+ekgWyVnz6zaZihpUNkGxjsYrkTJKhkaw==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.41.0': + resolution: {integrity: sha512-gE5ACNSxHcEZyP2BA9TuTakfZvULEW4YAOtxl/A/YDbIir/wPKukde0BNPlnBiP88ecaN4BJI2TtAd+HKuZPQQ==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.41.0': + resolution: {integrity: sha512-GSxU6r5HnWij7FoSo7cZg3l5GPg4HFLkzsFFh0N/b16q5buW1NAWuCJ+HMtIdUEi6XF0qH+hN0TEd78laRp7Dg==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.41.0': + resolution: {integrity: sha512-KGiGKGDg8qLRyOWmk6IeiHJzsN/OYxO6nSbT0Vj4MwjS2XQy/5emsmtoqLAabqrohbgLWJ5GV3s/ljdrIr8Qjg==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.41.0': + resolution: {integrity: sha512-46OzWeqEVQyX3N2/QdiU/CMXYDH/lSHpgfBkuhl3igpZiaB3ZIfSjKuOnybFVBQzjsLwkus2mjaESy8H41SzvA==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm-musleabihf@4.41.0': + resolution: {integrity: sha512-lfgW3KtQP4YauqdPpcUZHPcqQXmTmH4nYU0cplNeW583CMkAGjtImw4PKli09NFi2iQgChk4e9erkwlfYem6Lg==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm64-gnu@4.41.0': + resolution: {integrity: sha512-nn8mEyzMbdEJzT7cwxgObuwviMx6kPRxzYiOl6o/o+ChQq23gfdlZcUNnt89lPhhz3BYsZ72rp0rxNqBSfqlqw==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-arm64-musl@4.41.0': + resolution: {integrity: sha512-l+QK99je2zUKGd31Gh+45c4pGDAqZSuWQiuRFCdHYC2CSiO47qUWsCcenrI6p22hvHZrDje9QjwSMAFL3iwXwQ==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-loongarch64-gnu@4.41.0': + resolution: {integrity: sha512-WbnJaxPv1gPIm6S8O/Wg+wfE/OzGSXlBMbOe4ie+zMyykMOeqmgD1BhPxZQuDqwUN+0T/xOFtL2RUWBspnZj3w==} + cpu: [loong64] + os: [linux] + + '@rollup/rollup-linux-powerpc64le-gnu@4.41.0': + resolution: {integrity: sha512-eRDWR5t67/b2g8Q/S8XPi0YdbKcCs4WQ8vklNnUYLaSWF+Cbv2axZsp4jni6/j7eKvMLYCYdcsv8dcU+a6QNFg==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-riscv64-gnu@4.41.0': + resolution: {integrity: sha512-TWrZb6GF5jsEKG7T1IHwlLMDRy2f3DPqYldmIhnA2DVqvvhY2Ai184vZGgahRrg8k9UBWoSlHv+suRfTN7Ua4A==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-riscv64-musl@4.41.0': + resolution: {integrity: sha512-ieQljaZKuJpmWvd8gW87ZmSFwid6AxMDk5bhONJ57U8zT77zpZ/TPKkU9HpnnFrM4zsgr4kiGuzbIbZTGi7u9A==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-s390x-gnu@4.41.0': + resolution: {integrity: sha512-/L3pW48SxrWAlVsKCN0dGLB2bi8Nv8pr5S5ocSM+S0XCn5RCVCXqi8GVtHFsOBBCSeR+u9brV2zno5+mg3S4Aw==} + cpu: [s390x] + os: [linux] + + '@rollup/rollup-linux-x64-gnu@4.41.0': + resolution: {integrity: sha512-XMLeKjyH8NsEDCRptf6LO8lJk23o9wvB+dJwcXMaH6ZQbbkHu2dbGIUindbMtRN6ux1xKi16iXWu6q9mu7gDhQ==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-linux-x64-musl@4.41.0': + resolution: {integrity: sha512-m/P7LycHZTvSQeXhFmgmdqEiTqSV80zn6xHaQ1JSqwCtD1YGtwEK515Qmy9DcB2HK4dOUVypQxvhVSy06cJPEg==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-win32-arm64-msvc@4.41.0': + resolution: {integrity: sha512-4yodtcOrFHpbomJGVEqZ8fzD4kfBeCbpsUy5Pqk4RluXOdsWdjLnjhiKy2w3qzcASWd04fp52Xz7JKarVJ5BTg==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.41.0': + resolution: {integrity: sha512-tmazCrAsKzdkXssEc65zIE1oC6xPHwfy9d5Ta25SRCDOZS+I6RypVVShWALNuU9bxIfGA0aqrmzlzoM5wO5SPQ==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.41.0': + resolution: {integrity: sha512-h1J+Yzjo/X+0EAvR2kIXJDuTuyT7drc+t2ALY0nIcGPbTatNOf0VWdhEA2Z4AAjv6X1NJV7SYo5oCTYRJhSlVA==} + cpu: [x64] + os: [win32] + + '@safe-global/safe-apps-provider@0.18.6': + resolution: {integrity: sha512-4LhMmjPWlIO8TTDC2AwLk44XKXaK6hfBTWyljDm0HQ6TWlOEijVWNrt2s3OCVMSxlXAcEzYfqyu1daHZooTC2Q==} + + '@safe-global/safe-apps-sdk@9.1.0': + resolution: {integrity: sha512-N5p/ulfnnA2Pi2M3YeWjULeWbjo7ei22JwU/IXnhoHzKq3pYCN6ynL9mJBOlvDVv892EgLPCWCOwQk/uBT2v0Q==} + + '@safe-global/safe-gateway-typescript-sdk@3.8.0': + resolution: {integrity: sha512-CiGWIHgIaOdICpDxp05Jw3OPslWTu8AnL0PhrCT1xZgIO86NlMMLzkGbeycJ4FHpTjA999O791Oxp4bZPIjgHA==} + + '@scure/base@1.1.3': + resolution: {integrity: sha512-/+SgoRjLq7Xlf0CWuLHq2LUZeL/w65kfzAPG5NH9pcmBhs+nunQTn4gvdwgMTIXnt9b2C/1SeL2XiysZEyIC9Q==} + + '@scure/base@1.1.9': + resolution: {integrity: sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg==} + + '@scure/base@1.2.4': + resolution: {integrity: sha512-5Yy9czTO47mqz+/J8GM6GIId4umdCk1wc1q8rKERQulIoc8VP9pzDcghv10Tl2E7R96ZUx/PhND3ESYUQX8NuQ==} + + '@scure/base@1.2.6': + resolution: {integrity: sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg==} + + '@scure/bip32@1.1.5': + resolution: {integrity: sha512-XyNh1rB0SkEqd3tXcXMi+Xe1fvg+kUIcoRIEujP1Jgv7DqW2r9lg3Ah0NkFaCs9sTkQAQA8kw7xiRXzENi9Rtw==} + + '@scure/bip32@1.3.2': + resolution: {integrity: sha512-N1ZhksgwD3OBlwTv3R6KFEcPojl/W4ElJOeCZdi+vuI5QmTFwLq3OFf2zd2ROpKvxFdgZ6hUpb0dx9bVNEwYCA==} + + '@scure/bip32@1.4.0': + resolution: {integrity: sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg==} + + '@scure/bip32@1.6.2': + resolution: {integrity: sha512-t96EPDMbtGgtb7onKKqxRLfE5g05k7uHnHRM2xdE6BP/ZmxaLtPek4J4KfVn/90IQNrU1IOAqMgiDtUdtbe3nw==} + + '@scure/bip39@1.1.1': + resolution: {integrity: sha512-t+wDck2rVkh65Hmv280fYdVdY25J9YeEUIgn2LG1WM6gxFkGzcksoDiUkWVpVp3Oex9xGC68JU2dSbUfwZ2jPg==} + + '@scure/bip39@1.2.1': + resolution: {integrity: sha512-Z3/Fsz1yr904dduJD0NpiyRHhRYHdcnyh73FZWiV+/qhWi83wNJ3NWolYqCEN+ZWsUz2TWwajJggcRE9r1zUYg==} + + '@scure/bip39@1.3.0': + resolution: {integrity: sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ==} + + '@scure/bip39@1.5.4': + resolution: {integrity: sha512-TFM4ni0vKvCfBpohoh+/lY05i9gRbSwXWngAsF4CABQxoaOHijxuaZ2R6cStDQ5CHtHO9aGJTr4ksVJASRRyMA==} + + '@sec-ant/readable-stream@0.4.1': + resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==} + + '@sentry/core@5.30.0': + resolution: {integrity: sha512-TmfrII8w1PQZSZgPpUESqjB+jC6MvZJZdLtE/0hZ+SrnKhW3x5WlYLvTXZpcWePYBku7rl2wn1RZu6uT0qCTeg==} + engines: {node: '>=6'} + + '@sentry/hub@5.30.0': + resolution: {integrity: sha512-2tYrGnzb1gKz2EkMDQcfLrDTvmGcQPuWxLnJKXJvYTQDGLlEvi2tWz1VIHjunmOvJrB5aIQLhm+dcMRwFZDCqQ==} + engines: {node: '>=6'} + + '@sentry/minimal@5.30.0': + resolution: {integrity: sha512-BwWb/owZKtkDX+Sc4zCSTNcvZUq7YcH3uAVlmh/gtR9rmUvbzAA3ewLuB3myi4wWRAMEtny6+J/FN/x+2wn9Xw==} + engines: {node: '>=6'} + + '@sentry/node@5.30.0': + resolution: {integrity: sha512-Br5oyVBF0fZo6ZS9bxbJZG4ApAjRqAnqFFurMVJJdunNb80brh7a5Qva2kjhm+U6r9NJAB5OmDyPkA1Qnt+QVg==} + engines: {node: '>=6'} + + '@sentry/tracing@5.30.0': + resolution: {integrity: sha512-dUFowCr0AIMwiLD7Fs314Mdzcug+gBVo/+NCMyDw8tFxJkwWAKl7Qa2OZxLQ0ZHjakcj1hNKfCQJ9rhyfOl4Aw==} + engines: {node: '>=6'} + + '@sentry/types@5.30.0': + resolution: {integrity: sha512-R8xOqlSTZ+htqrfteCWU5Nk0CDN5ApUTvrlvBuiH1DyP6czDZ4ktbZB0hAgBlVcK0U+qpD3ag3Tqqpa5Q67rPw==} + engines: {node: '>=6'} + + '@sentry/utils@5.30.0': + resolution: {integrity: sha512-zaYmoH0NWWtvnJjC9/CBseXMtKHm/tm40sz3YfJRxeQjyzRqNQPgivpd9R/oDJCYj999mzdW382p/qi2ypjLww==} + engines: {node: '>=6'} + + '@shikijs/core@1.22.2': + resolution: {integrity: sha512-bvIQcd8BEeR1yFvOYv6HDiyta2FFVePbzeowf5pPS1avczrPK+cjmaxxh0nx5QzbON7+Sv0sQfQVciO7bN72sg==} + + '@shikijs/engine-javascript@1.22.2': + resolution: {integrity: sha512-iOvql09ql6m+3d1vtvP8fLCVCK7BQD1pJFmHIECsujB0V32BJ0Ab6hxk1ewVSMFA58FI0pR2Had9BKZdyQrxTw==} + + '@shikijs/engine-oniguruma@1.22.2': + resolution: {integrity: sha512-GIZPAGzQOy56mGvWMoZRPggn0dTlBf1gutV5TdceLCZlFNqWmuc7u+CzD0Gd9vQUTgLbrt0KLzz6FNprqYAxlA==} + + '@shikijs/transformers@1.22.2': + resolution: {integrity: sha512-8f78OiBa6pZDoZ53lYTmuvpFPlWtevn23bzG+azpPVvZg7ITax57o/K3TC91eYL3OMJOO0onPbgnQyZjRos8XQ==} + + '@shikijs/twoslash@1.22.2': + resolution: {integrity: sha512-4R3A7aH/toZgtlveXHKk01nIsvn8hjAfPJ1aT550zcV4qK6vK/tfaEyYtaljOaY1wig2l5+8sKjNSEz3PcSiEw==} + + '@shikijs/types@1.22.2': + resolution: {integrity: sha512-NCWDa6LGZqTuzjsGfXOBWfjS/fDIbDdmVDug+7ykVe1IKT4c1gakrvlfFYp5NhAXH/lyqLM8wsAPo5wNy73Feg==} + + '@shikijs/vitepress-twoslash@1.22.2': + resolution: {integrity: sha512-F4cS9l6QTt/ILlz+S871bOido2CK8Xwdnl4q9gHdnTuZlN1PHAMRZbAOvYAtokvouPp9aZ2W7NtNa+CNCn3yPQ==} + + '@shikijs/vscode-textmate@9.3.0': + resolution: {integrity: sha512-jn7/7ky30idSkd/O5yDBfAnVt+JJpepofP/POZ1iMOxK59cOfqIgg/Dj0eFsjOTMw+4ycJN0uhZH/Eb0bs/EUA==} + + '@sindresorhus/is@4.6.0': + resolution: {integrity: sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==} + engines: {node: '>=10'} + + '@sindresorhus/is@7.0.1': + resolution: {integrity: sha512-QWLl2P+rsCJeofkDNIT3WFmb6NrRud1SUYW8dIhXK/46XFV8Q/g7Bsvib0Askb0reRLe+WYPeeE+l5cH7SlkuQ==} + engines: {node: '>=18'} + + '@sindresorhus/merge-streams@2.3.0': + resolution: {integrity: sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==} + engines: {node: '>=18'} + + '@sindresorhus/merge-streams@4.0.0': + resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} + engines: {node: '>=18'} + + '@snyk/github-codeowners@1.1.0': + resolution: {integrity: sha512-lGFf08pbkEac0NYgVf4hdANpAgApRjNByLXB+WBip3qj1iendOIyAwP2GKkKbQMNVy2r1xxDf0ssfWscoiC+Vw==} + engines: {node: '>=8.10'} + hasBin: true + + '@socket.io/component-emitter@3.1.2': + resolution: {integrity: sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==} + + '@speed-highlight/core@1.2.7': + resolution: {integrity: sha512-0dxmVj4gxg3Jg879kvFS/msl4s9F3T9UXC1InxgOf7t5NvcPD97u/WTA5vL/IxWHMn7qSxBozqrnnE2wvl1m8g==} + + '@swc/counter@0.1.3': + resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} + + '@swc/helpers@0.5.15': + resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==} + + '@tanstack/match-sorter-utils@8.15.1': + resolution: {integrity: sha512-PnVV3d2poenUM31ZbZi/yXkBu3J7kd5k2u51CGwwNojag451AjTH9N6n41yjXz2fpLeewleyLBmNS6+HcGDlXw==} + engines: {node: '>=12'} + + '@tanstack/query-core@5.0.5': + resolution: {integrity: sha512-MThCETMkHDHTnFZHp71L+SqTtD5d6XHftFCVR1xRJdWM3qGrlQ2VCXaj0SKVcyJej2e1Opa2c7iknu1llxCDNQ==} + + '@tanstack/query-core@5.49.1': + resolution: {integrity: sha512-JnC9ndmD1KKS01Rt/ovRUB1tmwO7zkyXAyIxN9mznuJrcNtOrkmOnQqdJF2ib9oHzc2VxHomnEG7xyfo54Npkw==} + + '@tanstack/query-devtools@5.0.5': + resolution: {integrity: sha512-xjuOhOrrO50sPoJ4WG9yPe3imQ0Ds/nutnmwdTqjM2ZTIkflh//p7q2iB6IxFBY9sB106h+PULlma8sgTuOKAQ==} + + '@tanstack/query-persist-client-core@5.0.5': + resolution: {integrity: sha512-xdxDiSN/gBG1QJBiyNZPv2y1DOBMrILvhrEd9PgtOzE1AswmgVUh96KENiD7QiABKCVVIihDtSDvJGj0ukbudg==} + + '@tanstack/query-sync-storage-persister@5.0.5': + resolution: {integrity: sha512-uk2/mcNf+YYVza3XaU61RSPCcIi/p+0DfsZWMyIim1yCxF7hzZ17zWheM/2v3zZbeTY/C6m1NIO9KIRiPAM9Mg==} + + '@tanstack/react-query-devtools@5.0.5': + resolution: {integrity: sha512-vJyS7HXx2zw43TQjm3m4uyaNUgGizOpK2SZL9Lc+DZSuhFbuZ55UEYJTz8yudCbHdLXlkuVZwo6TWWOhXWJFeA==} + peerDependencies: + '@tanstack/react-query': ^5.0.5 + react: ^18.0.0 + react-dom: ^18.0.0 + + '@tanstack/react-query-persist-client@5.0.5': + resolution: {integrity: sha512-V/jIKdiw0WyJYpnzwnKS+O19jgJPWSBDzvx9qFaXAm98Jnt+lGWFBZdUR0MgY2ufM1fbeejXTjcorgwqjc3kaA==} + peerDependencies: + '@tanstack/react-query': ^5.0.5 + react: ^18.0.0 + react-dom: ^18.0.0 + + '@tanstack/react-query@5.49.2': + resolution: {integrity: sha512-6rfwXDK9BvmHISbNFuGd+wY3P44lyW7lWiA9vIFGT/T0P9aHD1VkjTvcM4SDAIbAQ9ygEZZoLt7dlU1o3NjMVA==} + peerDependencies: + react: ^18.0.0 + + '@tanstack/vue-query@5.49.1': + resolution: {integrity: sha512-/nTqP8PNCRzMcqTGEuFQE3ntUD3A+K05r6Dw/0hNwNS3PLEaKUKlxytmAhIoaoloQwbbAghjLyKRQZ+CMWv90A==} + peerDependencies: + '@vue/composition-api': ^1.1.2 + vue: ^2.6.0 || ^3.3.0 + peerDependenciesMeta: + '@vue/composition-api': + optional: true + + '@testing-library/dom@10.4.0': + resolution: {integrity: sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==} + engines: {node: '>=18'} + + '@testing-library/react@16.0.1': + resolution: {integrity: sha512-dSmwJVtJXmku+iocRhWOUFbrERC76TX2Mnf0ATODz8brzAZrMBbzLwQixlBSanZxR6LddK3eiwpSFZgDET1URg==} + engines: {node: '>=18'} + peerDependencies: + '@testing-library/dom': ^10.0.0 + '@types/react': ^18.0.0 + '@types/react-dom': ^18.0.0 + react: ^18.0.0 + react-dom: ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@trysound/sax@0.2.0': + resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==} + engines: {node: '>=10.13.0'} + + '@tybys/wasm-util@0.9.0': + resolution: {integrity: sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==} + + '@types/aria-query@5.0.4': + resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==} + + '@types/babel__core@7.20.5': + resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} + + '@types/babel__generator@7.6.5': + resolution: {integrity: sha512-h9yIuWbJKdOPLJTbmSpPzkF67e659PbQDba7ifWm5BJ8xTv+sDmS7rFmywkWOvXedGTivCdeGSIIX8WLcRTz8w==} + + '@types/babel__template@7.4.2': + resolution: {integrity: sha512-/AVzPICMhMOMYoSx9MoKpGDKdBRsIXMNByh1PXSZoa+v6ZoLa8xxtsT/uLQ/NJm0XVAWl/BvId4MlDeXJaeIZQ==} + + '@types/babel__traverse@7.20.2': + resolution: {integrity: sha512-ojlGK1Hsfce93J0+kn3H5R73elidKUaZonirN33GSmgTUMpzI/MIFfSpF3haANe3G1bEBS9/9/QEqwTzwqFsKw==} + + '@types/bn.js@4.11.6': + resolution: {integrity: sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==} + + '@types/bn.js@5.1.5': + resolution: {integrity: sha512-V46N0zwKRF5Q00AZ6hWtN0T8gGmDUaUzLWQvHFo5yThtVwK/VCenFY3wXVbOvNfajEpsTfQM4IN9k/d6gUVX3A==} + + '@types/bun@1.1.10': + resolution: {integrity: sha512-76KYVSwrHwr9zsnk6oLXOGs9KvyBg3U066GLO4rk6JZk1ypEPGCUDZ5yOiESyIHWs9cx9iC8r01utYN32XdmgA==} + + '@types/cookie@0.6.0': + resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==} + + '@types/cross-spawn@6.0.6': + resolution: {integrity: sha512-fXRhhUkG4H3TQk5dBhQ7m/JDdSNHKwR2BBia62lhwEIq9xGiQKLxd6LymNhn47SjXhsUEPmxi+PKw2OkW4LLjA==} + + '@types/debug@4.1.12': + resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} + + '@types/debug@4.1.7': + resolution: {integrity: sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg==} + + '@types/dedent@0.7.2': + resolution: {integrity: sha512-kRiitIeUg1mPV9yH4VUJ/1uk2XjyANfeL8/7rH1tsjvHeO9PJLBHJIYsFWmAvmGj5u8rj+1TZx7PZzW2qLw3Lw==} + + '@types/estree@1.0.5': + resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} + + '@types/estree@1.0.7': + resolution: {integrity: sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==} + + '@types/hast@3.0.4': + resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} + + '@types/linkify-it@5.0.0': + resolution: {integrity: sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==} + + '@types/lru-cache@5.1.1': + resolution: {integrity: sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw==} + + '@types/markdown-it@14.1.2': + resolution: {integrity: sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==} + + '@types/mdast@4.0.3': + resolution: {integrity: sha512-LsjtqsyF+d2/yFOYaN22dHZI1Cpwkrj+g06G8+qtUKlhovPW89YhqSnfKtMbkgmEtYpH2gydRNULd6y8mciAFg==} + + '@types/mdurl@2.0.0': + resolution: {integrity: sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==} + + '@types/ms@0.7.31': + resolution: {integrity: sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==} + + '@types/ms@2.1.0': + resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} + + '@types/mute-stream@0.0.4': + resolution: {integrity: sha512-CPM9nzrCPPJHQNA9keH9CVkVI+WR5kMa+7XEs5jcGQ0VoAGnLv242w8lIVgwAEfmE4oufJRaTc9PNLQl0ioAow==} + + '@types/node@12.20.55': + resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} + + '@types/node@20.12.10': + resolution: {integrity: sha512-Eem5pH9pmWBHoGAT8Dr5fdc5rYA+4NAovdM4EktRPVAAiJhmWWfQrA0cFhAbOsQdSfIHjAud6YdkbL69+zSKjw==} + + '@types/node@20.12.14': + resolution: {integrity: sha512-scnD59RpYD91xngrQQLGkE+6UrHUPzeKZWhhjBSa3HSkwjbQc38+q3RoIVEwxQGRw3M+j5hpNAM+lgV3cVormg==} + + '@types/node@20.19.0': + resolution: {integrity: sha512-hfrc+1tud1xcdVTABC2JiomZJEklMcXYNTVtZLAeqTVWD+qL5jkHKT+1lOtqDdGxt+mB53DTtiz673vfjU8D1Q==} + + '@types/node@22.15.31': + resolution: {integrity: sha512-jnVe5ULKl6tijxUhvQeNbQG/84fHfg+yMak02cT8QVhBx/F05rAVxCGBYYTh2EKz22D6JF5ktXuNwdx7b9iEGw==} + + '@types/node@24.0.1': + resolution: {integrity: sha512-MX4Zioh39chHlDJbKmEgydJDS3tspMP/lnQC67G3SWsTnb9NeYVWOjkxpOSy4oMfPs4StcWHwBrvUb4ybfnuaw==} + + '@types/normalize-package-data@2.4.4': + resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} + + '@types/parse-path@7.1.0': + resolution: {integrity: sha512-EULJ8LApcVEPbrfND0cRQqutIOdiIgJ1Mgrhpy755r14xMohPTEpkV/k28SJvuOs9bHRFW8x+KeDAEPiGQPB9Q==} + deprecated: This is a stub types definition. parse-path provides its own type definitions, so you do not need this installed. + + '@types/pbkdf2@3.1.2': + resolution: {integrity: sha512-uRwJqmiXmh9++aSu1VNEn3iIxWOhd8AHXNSdlaLfdAAdSTY9jYVeGWnzejM3dvrkbqE3/hyQkQQ29IFATEGlew==} + + '@types/prompts@2.4.9': + resolution: {integrity: sha512-qTxFi6Buiu8+50/+3DGIWLHM6QuWsEKugJnnP6iv2Mc4ncxE4A/OJkjuVOA+5X0X1S/nq5VJRa8Lu+nwcvbrKA==} + + '@types/prop-types@15.7.5': + resolution: {integrity: sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==} + + '@types/react-dom@18.3.0': + resolution: {integrity: sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==} + + '@types/react@18.3.1': + resolution: {integrity: sha512-V0kuGBX3+prX+DQ/7r2qsv1NsdfnCLnTgnRJ1pYnxykBhGMz+qj+box5lq7XsO5mtZsBqpjwwTu/7wszPfMBcw==} + + '@types/resolve@1.20.2': + resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==} + + '@types/secp256k1@4.0.3': + resolution: {integrity: sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w==} + + '@types/semver@7.5.3': + resolution: {integrity: sha512-OxepLK9EuNEIPxWNME+C6WwbRAOOI2o2BaQEGzz5Lu2e4Z5eDnEo+/aVEDMIXywoJitJ7xWd641wrGLZdtwRyw==} + + '@types/statuses@2.0.4': + resolution: {integrity: sha512-eqNDvZsCNY49OAXB0Firg/Sc2BgoWsntsLUdybGFOhAfCD6QJ2n9HXUIHGqt5qjrxmMv4wS8WLAw43ZkKcJ8Pw==} + + '@types/tough-cookie@4.0.5': + resolution: {integrity: sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==} + + '@types/triple-beam@1.3.5': + resolution: {integrity: sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==} + + '@types/trusted-types@2.0.3': + resolution: {integrity: sha512-NfQ4gyz38SL8sDNrSixxU2Os1a5xcdFxipAFxYEuLUlvU2uDwS4NUpsImcf1//SlWItCVMMLiylsxbmNMToV/g==} + + '@types/unist@3.0.2': + resolution: {integrity: sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==} + + '@types/use-sync-external-store@0.0.6': + resolution: {integrity: sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==} + + '@types/web-bluetooth@0.0.20': + resolution: {integrity: sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==} + + '@types/wrap-ansi@3.0.0': + resolution: {integrity: sha512-ltIpx+kM7g/MLRZfkbL7EsCEjfzCcScLpkg37eXEtx5kmrAKBkTJwd1GIAjDSL8wTpM6Hzn5YO4pSb91BEwu1g==} + + '@types/ws@8.5.10': + resolution: {integrity: sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==} + + '@types/yauzl@2.10.3': + resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} + + '@typescript-eslint/types@5.62.0': + resolution: {integrity: sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + '@typescript-eslint/typescript-estree@5.62.0': + resolution: {integrity: sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/visitor-keys@5.62.0': + resolution: {integrity: sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + '@typescript/vfs@1.6.0': + resolution: {integrity: sha512-hvJUjNVeBMp77qPINuUvYXj4FyWeeMMKZkxEATEU3hqBAQ7qdTBCUFT7Sp0Zu0faeEtFf+ldXxMEDr/bk73ISg==} + peerDependencies: + typescript: '*' + + '@ungap/structured-clone@1.2.0': + resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} + + '@unhead/vue@2.0.9': + resolution: {integrity: sha512-0t8YXVXvEgXkXhCb22hqPrsgun3Jqul/ZvydgBY0SlEfEbC1ioL15/1QuJwBFG3us6OnSewjbDagg4Jh478g8g==} + peerDependencies: + vue: '>=3.5.13' + + '@unocss/astro@0.59.4': + resolution: {integrity: sha512-DU3OR5MMR1Uvvec4/wB9EetDASHRg19Moy6z/MiIhn8JWJ0QzWYgSeJcfUX8exomMYv6WUEQJL+CyLI34Wmn8w==} + peerDependencies: + vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0 || ^5.0.0-0 + peerDependenciesMeta: + vite: + optional: true + + '@unocss/cli@0.59.4': + resolution: {integrity: sha512-TT+WKedSifhsRqnpoYD2LfyYipVzEbzIU4DDGIaDNeDxGXYOGpb876zzkPDcvZSpI37IJ/efkkV7PGYpPBcQBQ==} + engines: {node: '>=14'} + hasBin: true + + '@unocss/config@0.59.4': + resolution: {integrity: sha512-h3yhj+D5Ygn5R7gbK4wMrtXZX6FF5DF6YD517sSSb0XB3lxHD9PhhT4HaV1hpHknvu0cMFU3460M45+TN1TI0Q==} + engines: {node: '>=14'} + + '@unocss/core@0.59.4': + resolution: {integrity: sha512-bBZ1sgcAtezQVZ1BST9IS3jqcsTLyqKNjiIf7FTnX3DHpfpYuMDFzSOtmkZDzBleOLO/CtcRWjT0HwTSQAmV0A==} + + '@unocss/extractor-arbitrary-variants@0.59.4': + resolution: {integrity: sha512-RDe4FgMGJQ+tp9GLvhPHni7Cc2O0lHBRMElVlN8LoXJAdODMICdbrEPGJlEfrc+7x/QgVFoR895KpYJh3hIgGA==} + + '@unocss/inspector@0.59.4': + resolution: {integrity: sha512-QczJFNDiggmekkJyNcbcZIUVwlhvxz7ZwjnSf0w7K4znxfjKkZ1hNUbqLviM1HumkTKOdT27VISW7saN/ysO4w==} + + '@unocss/postcss@0.59.4': + resolution: {integrity: sha512-KVz+AD7McHKp7VEWHbFahhyyVEo0oP/e1vnuNSuPlHthe+1V2zfH6lps+iJcvfL2072r5J+0PvD/1kOp5ryUSg==} + engines: {node: '>=14'} + + '@unocss/preset-attributify@0.59.4': + resolution: {integrity: sha512-BeogWuYaIakC1gmOZFFCjFVWmu/m3AqEX8UYQS6tY6lAaK2L4Qf4AstYBlT2zAMxy9LNxPDxFQrvfSfFk5Klsg==} + + '@unocss/preset-icons@0.59.4': + resolution: {integrity: sha512-Afjwh5oC4KRE8TNZDUkRK6hvvV1wKLrS1e5trniE0B0AM9HK3PBolQaIU7QmzPv6WQrog+MZgIwafg1eqsPUCA==} + + '@unocss/preset-mini@0.59.4': + resolution: {integrity: sha512-ZLywGrXi1OCr4My5vX2rLUb5Xgx6ufR9WTQOvpQJGBdIV/jnZn/pyE5avCs476SnOq2K172lnd8mFmTK7/zArA==} + + '@unocss/preset-tagify@0.59.4': + resolution: {integrity: sha512-vWMdTUoghOSmTbdmZtERssffmdUdOuhh4vUdl0R8Kv6KxB0PkvEFCu2FItn97nRJdSPlZSFxxDkaOIg9w+STNQ==} + + '@unocss/preset-typography@0.59.4': + resolution: {integrity: sha512-ZX9bxZUqlXK1qEDzO5lkK96ICt9itR/oNyn/7mMc1JPqwj263LumQMn5silocgzoLSUXEeq//L6GylqYjkL8GA==} + + '@unocss/preset-uno@0.59.4': + resolution: {integrity: sha512-G1f8ZluplvXZ3bERj+sM/8zzY//XD++nNOlAQNKOANSVht3qEoJebrfEiMClNpA5qW5VWOZhEhPkh0M7GsXtnA==} + + '@unocss/preset-web-fonts@0.59.4': + resolution: {integrity: sha512-ehutTjKHnf2KPmdatN42N9a8+y+glKSU3UlcBRNsVIIXVIlaBQuPVGZSPhnMtrKD17IgWylXq2K6RJK+ab0hZA==} + + '@unocss/preset-wind@0.59.4': + resolution: {integrity: sha512-CNX6w0ZpSQg/i1oF0/WKWzto8PtLqoknC5h8JmmcGb7VsyBQeV0oNnhbURxpbuMEhbv1MWVIGvk8a+P6y0rFkQ==} + + '@unocss/reset@0.59.4': + resolution: {integrity: sha512-Upy4xzdWl4RChbLAXBq1BoR4WqxXMoIfjvtcwSZcZK2sylXCFAseSWnyzJFdSiXPqNfmMuNgPXgiSxiQB+cmNA==} + + '@unocss/rule-utils@0.59.4': + resolution: {integrity: sha512-1qoLJlBWAkS4D4sg73990S1MT7E8E5md/YhopKjTQuEC9SyeVmEg+5pR/Xd8xhPKMqbcuBPl/DS8b6l/GQO56A==} + engines: {node: '>=14'} + + '@unocss/scope@0.59.4': + resolution: {integrity: sha512-wBQJ39kw4Tfj4km7AoGvSIobPKVnRZVsgc0bema5Y0PL3g1NeVQ/LopBI2zEJWdpxGXUWxSDsXm7BZo6qVlD/A==} + + '@unocss/transformer-attributify-jsx-babel@0.59.4': + resolution: {integrity: sha512-xtCRSgeTaDBiNJLVX7oOSFe63JiFB5nrdK23PHn3IlZM9O7Bxx4ZxI3MQJtFZFQNE+INFko+DVyY1WiFEm1p/Q==} + + '@unocss/transformer-attributify-jsx@0.59.4': + resolution: {integrity: sha512-m4b83utzKMfUQH/45V2QkjJoXd8Tu2pRP1nic91Xf7QRceyKDD+BxoTneo2JNC2K274cQu7HqqotnCm2aFfEGw==} + + '@unocss/transformer-compile-class@0.59.4': + resolution: {integrity: sha512-Vgk2OCLPW0pU+Uzr1IgDtHVspSBb+gPrQFkV+5gxHk9ZdKi3oYKxLuufVWYDSwv7o9yfQGbYrMH9YLsjRsnA7Q==} + + '@unocss/transformer-directives@0.59.4': + resolution: {integrity: sha512-nXUTEclUbs0vQ4KfLhKt4J/5SLSEq1az2FNlJmiXMmqmn75X89OrtCu2OJu9sGXhn+YyBApxgcSSdxmtpqMi1Q==} + + '@unocss/transformer-variant-group@0.59.4': + resolution: {integrity: sha512-9XLixxn1NRgP62Kj4R/NC/rpqhql5F2s6ulJ8CAMTEbd/NylVhEANluPGDVUGcLJ4cj6E02hFa8C1PLGSm7/xw==} + + '@unocss/vite@0.59.4': + resolution: {integrity: sha512-q7GN7vkQYn79n7vYIUlaa7gXGwc7pk0Qo3z3ZFwWGE43/DtZnn2Hwl5UjgBAgi9McA+xqHJEHRsJnI7HJPHUYA==} + peerDependencies: + vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0 || ^5.0.0-0 + + '@vercel/nft@0.27.7': + resolution: {integrity: sha512-FG6H5YkP4bdw9Ll1qhmbxuE8KwW2E/g8fJpM183fWQLeVDGqzeywMIeJ9h2txdWZ03psgWMn6QymTxaDLmdwUg==} + engines: {node: '>=16'} + hasBin: true + + '@vercel/nft@0.29.3': + resolution: {integrity: sha512-aVV0E6vJpuvImiMwU1/5QKkw2N96BRFE7mBYGS7FhXUoS6V7SarQ+8tuj33o7ofECz8JtHpmQ9JW+oVzOoB7MA==} + engines: {node: '>=18'} + hasBin: true + + '@vitejs/plugin-react@4.2.1': + resolution: {integrity: sha512-oojO9IDc4nCUUi8qIR11KoQm0XFFLIwsRBwHRR4d/88IWghn1y6ckz/bJ8GHDCsYEJee8mDzqtJxh15/cisJNQ==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + vite: ^4.2.0 || ^5.0.0 + + '@vitejs/plugin-vue-jsx@4.2.0': + resolution: {integrity: sha512-DSTrmrdLp+0LDNF77fqrKfx7X0ErRbOcUAgJL/HbSesqQwoUvUQ4uYQqaex+rovqgGcoPqVk+AwUh3v9CuiYIw==} + engines: {node: ^18.0.0 || >=20.0.0} + peerDependencies: + vite: ^5.0.0 || ^6.0.0 + vue: ^3.0.0 + + '@vitejs/plugin-vue@5.0.4': + resolution: {integrity: sha512-WS3hevEszI6CEVEx28F8RjTX97k3KsrcY6kvTg7+Whm5y3oYvcqzVeGCU3hxSAn4uY2CLCkeokkGKpoctccilQ==} + engines: {node: ^18.0.0 || >=20.0.0} + peerDependencies: + vite: ^5.0.0 + vue: ^3.2.25 + + '@vitejs/plugin-vue@5.1.4': + resolution: {integrity: sha512-N2XSI2n3sQqp5w7Y/AN/L2XDjBIRGqXko+eDp42sydYSBeJuSm5a1sLf8zakmo8u7tA8NmBgoDLA1HeOESjp9A==} + engines: {node: ^18.0.0 || >=20.0.0} + peerDependencies: + vite: ^5.0.0 + vue: ^3.2.25 + + '@vitejs/plugin-vue@5.2.4': + resolution: {integrity: sha512-7Yx/SXSOcQq5HiiV3orevHUFn+pmMB4cgbEkDYgnkUWb0WfeQ/wa2yFv6D5ICiCQOVpjA7vYDXrC7AGO8yjDHA==} + engines: {node: ^18.0.0 || >=20.0.0} + peerDependencies: + vite: ^5.0.0 || ^6.0.0 + vue: ^3.2.25 + + '@vitest/coverage-v8@2.1.1': + resolution: {integrity: sha512-md/A7A3c42oTT8JUHSqjP5uKTWJejzUW4jalpvs+rZ27gsURsMU8DEb+8Jf8C6Kj2gwfSHJqobDNBuoqlm0cFw==} + peerDependencies: + '@vitest/browser': 2.1.1 + vitest: 2.1.1 + peerDependenciesMeta: + '@vitest/browser': + optional: true + + '@vitest/expect@2.1.9': + resolution: {integrity: sha512-UJCIkTBenHeKT1TTlKMJWy1laZewsRIzYighyYiJKZreqtdxSos/S1t+ktRMQWu2CKqaarrkeszJx1cgC5tGZw==} + + '@vitest/mocker@2.1.9': + resolution: {integrity: sha512-tVL6uJgoUdi6icpxmdrn5YNo3g3Dxv+IHJBr0GXHaEdTcw3F+cPKnsXFhli6nO+f/6SDKPHEK1UN+k+TQv0Ehg==} + peerDependencies: + msw: ^2.4.9 + vite: ^5.0.0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true + + '@vitest/pretty-format@2.1.9': + resolution: {integrity: sha512-KhRIdGV2U9HOUzxfiHmY8IFHTdqtOhIzCpd8WRdJiE7D/HUcZVD0EgQCVjm+Q9gkUXWgBvMmTtZgIG48wq7sOQ==} + + '@vitest/runner@2.1.9': + resolution: {integrity: sha512-ZXSSqTFIrzduD63btIfEyOmNcBmQvgOVsPNPe0jYtESiXkhd8u2erDLnMxmGrDCwHCCHE7hxwRDCT3pt0esT4g==} + + '@vitest/snapshot@2.1.9': + resolution: {integrity: sha512-oBO82rEjsxLNJincVhLhaxxZdEtV0EFHMK5Kmx5sJ6H9L183dHECjiefOAdnqpIgT5eZwT04PoggUnW88vOBNQ==} + + '@vitest/spy@2.1.9': + resolution: {integrity: sha512-E1B35FwzXXTs9FHNK6bDszs7mtydNi5MIfUWpceJ8Xbfb1gBMscAnwLbEu+B44ed6W3XjL9/ehLPHR1fkf1KLQ==} + + '@vitest/utils@2.1.9': + resolution: {integrity: sha512-v0psaMSkNJ3A2NMrUEHFRzJtDPFn+/VWZ5WxImB21T9fjucJRmS7xCS3ppEnARb9y11OAzaD+P2Ps+b+BGX5iQ==} + + '@volar/language-core@2.2.1': + resolution: {integrity: sha512-iHJAZKcYldZgyS8gx6DfIZApViVBeqbf6iPhqoZpG5A6F4zsZiFldKfwaKaBA3/wnOTWE2i8VUbXywI1WywCPg==} + + '@volar/language-core@2.4.8': + resolution: {integrity: sha512-K/GxMOXGq997bO00cdFhTNuR85xPxj0BEEAy+BaqqayTmy9Tmhfgmq2wpJcVspRhcwfgPoE2/mEJa26emUhG/g==} + + '@volar/source-map@2.2.1': + resolution: {integrity: sha512-w1Bgpguhbp7YTr7VUFu6gb4iAZjeEPsOX4zpgiuvlldbzvIWDWy4t0jVifsIsxZ99HAu+c3swiME7wt+GeNqhA==} + + '@volar/source-map@2.4.8': + resolution: {integrity: sha512-jeWJBkC/WivdelMwxKkpFL811uH/jJ1kVxa+c7OvG48DXc3VrP7pplSWPP2W1dLMqBxD+awRlg55FQQfiup4cA==} + + '@volar/typescript@2.2.1': + resolution: {integrity: sha512-Z/tqluR7Hz5/5dCqQp7wo9C/6tSv/IYl+tTzgzUt2NjTq95bKSsuO4E+V06D0c+3aP9x5S9jggLqw451hpnc6Q==} + + '@vue-macros/common@1.16.1': + resolution: {integrity: sha512-Pn/AWMTjoMYuquepLZP813BIcq8DTZiNCoaceuNlvaYuOTd8DqBZWc5u0uOMQZMInwME1mdSmmBAcTluiV9Jtg==} + engines: {node: '>=16.14.0'} + peerDependencies: + vue: ^2.7.0 || ^3.2.25 + peerDependenciesMeta: + vue: + optional: true + + '@vue/babel-helper-vue-transform-on@1.4.0': + resolution: {integrity: sha512-mCokbouEQ/ocRce/FpKCRItGo+013tHg7tixg3DUNS+6bmIchPt66012kBMm476vyEIJPafrvOf4E5OYj3shSw==} + + '@vue/babel-plugin-jsx@1.4.0': + resolution: {integrity: sha512-9zAHmwgMWlaN6qRKdrg1uKsBKHvnUU+Py+MOCTuYZBoZsopa90Di10QRjB+YPnVss0BZbG/H5XFwJY1fTxJWhA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + peerDependenciesMeta: + '@babel/core': + optional: true + + '@vue/babel-plugin-resolve-type@1.4.0': + resolution: {integrity: sha512-4xqDRRbQQEWHQyjlYSgZsWj44KfiF6D+ktCuXyZ8EnVDYV3pztmXJDf1HveAjUAXxAnR8daCQT51RneWWxtTyQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@vue/compiler-core@3.4.27': + resolution: {integrity: sha512-E+RyqY24KnyDXsCuQrI+mlcdW3ALND6U7Gqa/+bVwbcpcR3BRRIckFoz7Qyd4TTlnugtwuI7YgjbvsLmxb+yvg==} + + '@vue/compiler-core@3.5.12': + resolution: {integrity: sha512-ISyBTRMmMYagUxhcpyEH0hpXRd/KqDU4ymofPgl2XAkY9ZhQ+h0ovEZJIiPop13UmR/54oA2cgMDjgroRelaEw==} + + '@vue/compiler-core@3.5.14': + resolution: {integrity: sha512-k7qMHMbKvoCXIxPhquKQVw3Twid3Kg4s7+oYURxLGRd56LiuHJVrvFKI4fm2AM3c8apqODPfVJGoh8nePbXMRA==} + + '@vue/compiler-dom@3.4.27': + resolution: {integrity: sha512-kUTvochG/oVgE1w5ViSr3KUBh9X7CWirebA3bezTbB5ZKBQZwR2Mwj9uoSKRMFcz4gSMzzLXBPD6KpCLb9nvWw==} + + '@vue/compiler-dom@3.5.12': + resolution: {integrity: sha512-9G6PbJ03uwxLHKQ3P42cMTi85lDRvGLB2rSGOiQqtXELat6uI4n8cNz9yjfVHRPIu+MsK6TE418Giruvgptckg==} + + '@vue/compiler-dom@3.5.14': + resolution: {integrity: sha512-1aOCSqxGOea5I80U2hQJvXYpPm/aXo95xL/m/mMhgyPUsKe9jhjwWpziNAw7tYRnbz1I61rd9Mld4W9KmmRoug==} + + '@vue/compiler-sfc@3.4.27': + resolution: {integrity: sha512-nDwntUEADssW8e0rrmE0+OrONwmRlegDA1pD6QhVeXxjIytV03yDqTey9SBDiALsvAd5U4ZrEKbMyVXhX6mCGA==} + + '@vue/compiler-sfc@3.5.12': + resolution: {integrity: sha512-2k973OGo2JuAa5+ZlekuQJtitI5CgLMOwgl94BzMCsKZCX/xiqzJYzapl4opFogKHqwJk34vfsaKpfEhd1k5nw==} + + '@vue/compiler-sfc@3.5.14': + resolution: {integrity: sha512-9T6m/9mMr81Lj58JpzsiSIjBgv2LiVoWjIVa7kuXHICUi8LiDSIotMpPRXYJsXKqyARrzjT24NAwttrMnMaCXA==} + + '@vue/compiler-ssr@3.4.27': + resolution: {integrity: sha512-CVRzSJIltzMG5FcidsW0jKNQnNRYC8bT21VegyMMtHmhW3UOI7knmUehzswXLrExDLE6lQCZdrhD4ogI7c+vuw==} + + '@vue/compiler-ssr@3.5.12': + resolution: {integrity: sha512-eLwc7v6bfGBSM7wZOGPmRavSWzNFF6+PdRhE+VFJhNCgHiF8AM7ccoqcv5kBXA2eWUfigD7byekvf/JsOfKvPA==} + + '@vue/compiler-ssr@3.5.14': + resolution: {integrity: sha512-Y0G7PcBxr1yllnHuS/NxNCSPWnRGH4Ogrp0tsLA5QemDZuJLs99YjAKQ7KqkHE0vCg4QTKlQzXLKCMF7WPSl7Q==} + + '@vue/compiler-vue2@2.7.16': + resolution: {integrity: sha512-qYC3Psj9S/mfu9uVi5WvNZIzq+xnXMhOwbTFKKDD7b1lhpnn71jXSFdTQ+WsIEk0ONCd7VV2IMm7ONl6tbQ86A==} + + '@vue/devtools-api@6.6.1': + resolution: {integrity: sha512-LgPscpE3Vs0x96PzSSB4IGVSZXZBZHpfxs+ZA1d+VEPwHdOXowy/Y2CsvCAIFrf+ssVU1pD1jidj505EpUnfbA==} + + '@vue/devtools-api@6.6.4': + resolution: {integrity: sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==} + + '@vue/devtools-api@7.6.2': + resolution: {integrity: sha512-NCT0ujqlwAhoFvCsAG7G5qS8w/A/dhvFSt2BhmNxyqgpYDrf9CG1zYyWLQkE3dsZ+5lCT6ULUic2VKNaE07Vzg==} + + '@vue/devtools-core@7.7.6': + resolution: {integrity: sha512-ghVX3zjKPtSHu94Xs03giRIeIWlb9M+gvDRVpIZ/cRIxKHdW6HE/sm1PT3rUYS3aV92CazirT93ne+7IOvGUWg==} + peerDependencies: + vue: ^3.0.0 + + '@vue/devtools-kit@7.6.2': + resolution: {integrity: sha512-k61BxHRmcTtIQZFouF9QWt9nCCNtSdw12lhg8VNtHq5/XOBGD+ewiK27a40UJ8UPYoCJvi80hbvbYr5E/Zeu1g==} + + '@vue/devtools-kit@7.7.6': + resolution: {integrity: sha512-geu7ds7tem2Y7Wz+WgbnbZ6T5eadOvozHZ23Atk/8tksHMFOFylKi1xgGlQlVn0wlkEf4hu+vd5ctj1G4kFtwA==} + + '@vue/devtools-shared@7.6.2': + resolution: {integrity: sha512-lcjyJ7hCC0W0kNwnCGMLVTMvDLoZgjcq9BvboPgS+6jQyDul7fpzRSKTGtGhCHoxrDox7qBAKGbAl2Rcf7GE1A==} + + '@vue/devtools-shared@7.7.6': + resolution: {integrity: sha512-yFEgJZ/WblEsojQQceuyK6FzpFDx4kqrz2ohInxNj5/DnhoX023upTv4OD6lNPLAA5LLkbwPVb10o/7b+Y4FVA==} + + '@vue/language-core@2.0.16': + resolution: {integrity: sha512-Bc2sexRH99pznOph8mLw2BlRZ9edm7tW51kcBXgx8adAoOcZUWJj3UNSsdQ6H9Y8meGz7BoazVrVo/jUukIsPw==} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@vue/language-core@2.1.10': + resolution: {integrity: sha512-DAI289d0K3AB5TUG3xDp9OuQ71CnrujQwJrQnfuZDwo6eGNf0UoRlPuaVNO+Zrn65PC3j0oB2i7mNmVPggeGeQ==} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@vue/reactivity@3.4.27': + resolution: {integrity: sha512-kK0g4NknW6JX2yySLpsm2jlunZJl2/RJGZ0H9ddHdfBVHcNzxmQ0sS0b09ipmBoQpY8JM2KmUw+a6sO8Zo+zIA==} + + '@vue/reactivity@3.5.12': + resolution: {integrity: sha512-UzaN3Da7xnJXdz4Okb/BGbAaomRHc3RdoWqTzlvd9+WBR5m3J39J1fGcHes7U3za0ruYn/iYy/a1euhMEHvTAg==} + + '@vue/reactivity@3.5.14': + resolution: {integrity: sha512-7cK1Hp343Fu/SUCCO52vCabjvsYu7ZkOqyYu7bXV9P2yyfjUMUXHZafEbq244sP7gf+EZEz+77QixBTuEqkQQw==} + + '@vue/runtime-core@3.4.27': + resolution: {integrity: sha512-7aYA9GEbOOdviqVvcuweTLe5Za4qBZkUY7SvET6vE8kyypxVgaT1ixHLg4urtOlrApdgcdgHoTZCUuTGap/5WA==} + + '@vue/runtime-core@3.5.12': + resolution: {integrity: sha512-hrMUYV6tpocr3TL3Ad8DqxOdpDe4zuQY4HPY3X/VRh+L2myQO8MFXPAMarIOSGNu0bFAjh1yBkMPXZBqCk62Uw==} + + '@vue/runtime-core@3.5.14': + resolution: {integrity: sha512-w9JWEANwHXNgieAhxPpEpJa+0V5G0hz3NmjAZwlOebtfKyp2hKxKF0+qSh0Xs6/PhfGihuSdqMprMVcQU/E6ag==} + + '@vue/runtime-dom@3.4.27': + resolution: {integrity: sha512-ScOmP70/3NPM+TW9hvVAz6VWWtZJqkbdf7w6ySsws+EsqtHvkhxaWLecrTorFxsawelM5Ys9FnDEMt6BPBDS0Q==} + + '@vue/runtime-dom@3.5.12': + resolution: {integrity: sha512-q8VFxR9A2MRfBr6/55Q3umyoN7ya836FzRXajPB6/Vvuv0zOPL+qltd9rIMzG/DbRLAIlREmnLsplEF/kotXKA==} + + '@vue/runtime-dom@3.5.14': + resolution: {integrity: sha512-lCfR++IakeI35TVR80QgOelsUIdcKjd65rWAMfdSlCYnaEY5t3hYwru7vvcWaqmrK+LpI7ZDDYiGU5V3xjMacw==} + + '@vue/server-renderer@3.4.27': + resolution: {integrity: sha512-dlAMEuvmeA3rJsOMJ2J1kXU7o7pOxgsNHVr9K8hB3ImIkSuBrIdy0vF66h8gf8Tuinf1TK3mPAz2+2sqyf3KzA==} + peerDependencies: + vue: 3.4.27 + + '@vue/server-renderer@3.5.12': + resolution: {integrity: sha512-I3QoeDDeEPZm8yR28JtY+rk880Oqmj43hreIBVTicisFTx/Dl7JpG72g/X7YF8hnQD3IFhkky5i2bPonwrTVPg==} + peerDependencies: + vue: 3.5.12 + + '@vue/server-renderer@3.5.14': + resolution: {integrity: sha512-Rf/ISLqokIvcySIYnv3tNWq40PLpNLDLSJwwVWzG6MNtyIhfbcrAxo5ZL9nARJhqjZyWWa40oRb2IDuejeuv6w==} + peerDependencies: + vue: 3.5.14 + + '@vue/shared@3.4.27': + resolution: {integrity: sha512-DL3NmY2OFlqmYYrzp39yi3LDkKxa5vZVwxWdQ3rG0ekuWscHraeIbnI8t+aZK7qhYqEqWKTUdijadunb9pnrgA==} + + '@vue/shared@3.5.12': + resolution: {integrity: sha512-L2RPSAwUFbgZH20etwrXyVyCBu9OxRSi8T/38QsvnkJyvq2LufW2lDCOzm7t/U9C1mkhJGWYfCuFBCmIuNivrg==} + + '@vue/shared@3.5.14': + resolution: {integrity: sha512-oXTwNxVfc9EtP1zzXAlSlgARLXNC84frFYkS0HHz0h3E4WZSP9sywqjqzGCP9Y34M8ipNmd380pVgmMuwELDyQ==} + + '@vue/test-utils@2.4.6': + resolution: {integrity: sha512-FMxEjOpYNYiFe0GkaHsnJPXFHxQ6m4t8vI/ElPGpMWxZKpmRvQ33OIrvRXemy6yha03RxhOlQuy+gZMC3CQSow==} + + '@vueuse/core@11.2.0': + resolution: {integrity: sha512-JIUwRcOqOWzcdu1dGlfW04kaJhW3EXnnjJJfLTtddJanymTL7lF1C0+dVVZ/siLfc73mWn+cGP1PE1PKPruRSA==} + + '@vueuse/integrations@11.2.0': + resolution: {integrity: sha512-zGXz3dsxNHKwiD9jPMvR3DAxQEOV6VWIEYTGVSB9PNpk4pTWR+pXrHz9gvXWcP2sTk3W2oqqS6KwWDdntUvNVA==} + peerDependencies: + async-validator: ^4 + axios: ^1 + change-case: ^5 + drauu: ^0.4 + focus-trap: ^7 + fuse.js: ^7 + idb-keyval: ^6 + jwt-decode: ^4 + nprogress: ^0.2 + qrcode: ^1.5 + sortablejs: ^1 + universal-cookie: ^7 + peerDependenciesMeta: + async-validator: + optional: true + axios: + optional: true + change-case: + optional: true + drauu: + optional: true + focus-trap: + optional: true + fuse.js: + optional: true + idb-keyval: + optional: true + jwt-decode: + optional: true + nprogress: + optional: true + qrcode: + optional: true + sortablejs: + optional: true + universal-cookie: + optional: true + + '@vueuse/metadata@11.2.0': + resolution: {integrity: sha512-L0ZmtRmNx+ZW95DmrgD6vn484gSpVeRbgpWevFKXwqqQxW9hnSi2Ppuh2BzMjnbv4aJRiIw8tQatXT9uOB23dQ==} + + '@vueuse/shared@11.2.0': + resolution: {integrity: sha512-VxFjie0EanOudYSgMErxXfq6fo8vhr5ICI+BuE3I9FnX7ePllEsVrRQ7O6Q1TLgApeLuPKcHQxAXpP+KnlrJsg==} + + '@walletconnect/core@2.19.2': + resolution: {integrity: sha512-iu0mgLj51AXcKpdNj8+4EdNNBd/mkNjLEhZn6UMc/r7BM9WbmpPMEydA39WeRLbdLO4kbpmq4wTbiskI1rg+HA==} + engines: {node: '>=18'} + + '@walletconnect/core@2.20.2': + resolution: {integrity: sha512-48XnarxQQrpJ0KZJOjit56DxuzfVRYUdL8XVMvUh/ZNUiX2FB5w6YuljUUeTLfYOf04Et6qhVGEUkmX3W+9/8w==} + engines: {node: '>=18'} + + '@walletconnect/environment@1.0.1': + resolution: {integrity: sha512-T426LLZtHj8e8rYnKfzsw1aG6+M0BT1ZxayMdv/p8yM0MU+eJDISqNY3/bccxRr4LrF9csq02Rhqt08Ibl0VRg==} + + '@walletconnect/ethereum-provider@2.20.2': + resolution: {integrity: sha512-fGNJtytHuBWZcmMXRIG1djlfEiPMvPJ0R3JlfJjAx2VfVN+O+1xdF6QSWcZxFizviIUFJV+f1zWt0V2VVD61Rg==} + + '@walletconnect/events@1.0.1': + resolution: {integrity: sha512-NPTqaoi0oPBVNuLv7qPaJazmGHs5JGyO8eEAk5VGKmJzDR7AHzD4k6ilox5kxk1iwiOnFopBOOMLs86Oa76HpQ==} + + '@walletconnect/heartbeat@1.2.2': + resolution: {integrity: sha512-uASiRmC5MwhuRuf05vq4AT48Pq8RMi876zV8rr8cV969uTOzWdB/k+Lj5yI2PBtB1bGQisGen7MM1GcZlQTBXw==} + + '@walletconnect/jsonrpc-http-connection@1.0.8': + resolution: {integrity: sha512-+B7cRuaxijLeFDJUq5hAzNyef3e3tBDIxyaCNmFtjwnod5AGis3RToNqzFU33vpVcxFhofkpE7Cx+5MYejbMGw==} + + '@walletconnect/jsonrpc-provider@1.0.14': + resolution: {integrity: sha512-rtsNY1XqHvWj0EtITNeuf8PHMvlCLiS3EjQL+WOkxEOA4KPxsohFnBDeyPYiNm4ZvkQdLnece36opYidmtbmow==} + + '@walletconnect/jsonrpc-types@1.0.4': + resolution: {integrity: sha512-P6679fG/M+wuWg9TY8mh6xFSdYnFyFjwFelxyISxMDrlbXokorEVXYOxiqEbrU3x1BmBoCAJJ+vtEaEoMlpCBQ==} + + '@walletconnect/jsonrpc-utils@1.0.8': + resolution: {integrity: sha512-vdeb03bD8VzJUL6ZtzRYsFMq1eZQcM3EAzT0a3st59dyLfJ0wq+tKMpmGH7HlB7waD858UWgfIcudbPFsbzVdw==} + + '@walletconnect/jsonrpc-ws-connection@1.0.16': + resolution: {integrity: sha512-G81JmsMqh5nJheE1mPst1W0WfVv0SG3N7JggwLLGnI7iuDZJq8cRJvQwLGKHn5H1WTW7DEPCo00zz5w62AbL3Q==} + + '@walletconnect/keyvaluestorage@1.1.1': + resolution: {integrity: sha512-V7ZQq2+mSxAq7MrRqDxanTzu2RcElfK1PfNYiaVnJgJ7Q7G7hTVwF8voIBx92qsRyGHZihrwNPHuZd1aKkd0rA==} + peerDependencies: + '@react-native-async-storage/async-storage': 1.x + peerDependenciesMeta: + '@react-native-async-storage/async-storage': + optional: true + + '@walletconnect/logger@2.1.2': + resolution: {integrity: sha512-aAb28I3S6pYXZHQm5ESB+V6rDqIYfsnHaQyzFbwUUBFY4H0OXx/YtTl8lvhUNhMMfb9UxbwEBS253TlXUYJWSw==} + + '@walletconnect/relay-api@1.0.11': + resolution: {integrity: sha512-tLPErkze/HmC9aCmdZOhtVmYZq1wKfWTJtygQHoWtgg722Jd4homo54Cs4ak2RUFUZIGO2RsOpIcWipaua5D5Q==} + + '@walletconnect/relay-auth@1.1.0': + resolution: {integrity: sha512-qFw+a9uRz26jRCDgL7Q5TA9qYIgcNY8jpJzI1zAWNZ8i7mQjaijRnWFKsCHAU9CyGjvt6RKrRXyFtFOpWTVmCQ==} + + '@walletconnect/safe-json@1.0.2': + resolution: {integrity: sha512-Ogb7I27kZ3LPC3ibn8ldyUr5544t3/STow9+lzz7Sfo808YD7SBWk7SAsdBFlYgP2zDRy2hS3sKRcuSRM0OTmA==} + + '@walletconnect/sign-client@2.19.2': + resolution: {integrity: sha512-a/K5PRIFPCjfHq5xx3WYKHAAF8Ft2I1LtxloyibqiQOoUtNLfKgFB1r8sdMvXM7/PADNPe4iAw4uSE6PrARrfg==} + + '@walletconnect/sign-client@2.20.2': + resolution: {integrity: sha512-KyeDToypZ1OjCbij4Jx0cAg46bMwZ6zCKt0HzCkqENcex3Zchs7xBp9r8GtfEMGw+PUnXwqrhzmLBH0x/43oIQ==} + + '@walletconnect/time@1.0.2': + resolution: {integrity: sha512-uzdd9woDcJ1AaBZRhqy5rNC9laqWGErfc4dxA9a87mPdKOgWMD85mcFo9dIYIts/Jwocfwn07EC6EzclKubk/g==} + + '@walletconnect/types@2.19.2': + resolution: {integrity: sha512-/LZWhkVCUN+fcTgQUxArxhn2R8DF+LSd/6Wh9FnpjeK/Sdupx1EPS8okWG6WPAqq2f404PRoNAfQytQ82Xdl3g==} + + '@walletconnect/types@2.20.2': + resolution: {integrity: sha512-XPPbJM/mGU05i6jUxhC3yI/YvhSF6TYJQ5SXTWM53lVe6hs6ukvlEhPctu9ZBTGwGFhwPXIjtK/eWx+v4WY5iw==} + + '@walletconnect/universal-provider@2.19.2': + resolution: {integrity: sha512-LkKg+EjcSUpPUhhvRANgkjPL38wJPIWumAYD8OK/g4OFuJ4W3lS/XTCKthABQfFqmiNbNbVllmywiyE44KdpQg==} + + '@walletconnect/universal-provider@2.20.2': + resolution: {integrity: sha512-6uVu1E88tioaXEEJCbJKwCIQlOHif1nmfY092BznZEnBn2lli5ICzQh2bxtUDNmNNLKsMDI3FV1fODFeWMVJTQ==} + + '@walletconnect/utils@2.19.2': + resolution: {integrity: sha512-VU5CcUF4sZDg8a2/ov29OJzT3KfLuZqJUM0GemW30dlipI5fkpb0VPenZK7TcdLPXc1LN+Q+7eyTqHRoAu/BIA==} + + '@walletconnect/utils@2.20.2': + resolution: {integrity: sha512-2uRUDvpYSIJFYcr1WIuiFy6CEszLF030o6W8aDMkGk9/MfAZYEJQHMJcjWyaNMPHLJT0POR5lPaqkYOpuyPIQQ==} + + '@walletconnect/window-getters@1.0.1': + resolution: {integrity: sha512-vHp+HqzGxORPAN8gY03qnbTMnhqIwjeRJNOMOAzePRg4xVEEE2WvYsI9G2NMjOknA8hnuYbU3/hwLcKbjhc8+Q==} + + '@walletconnect/window-metadata@1.0.1': + resolution: {integrity: sha512-9koTqyGrM2cqFRW517BPY/iEtUDx2r1+Pwwu5m7sJ7ka79wi3EyqhqcICk/yDmv6jAS1rjKgTKXlEhanYjijcA==} + + '@whatwg-node/disposablestack@0.0.6': + resolution: {integrity: sha512-LOtTn+JgJvX8WfBVJtF08TGrdjuFzGJc4mkP8EdDI8ADbvO7kiexYep1o8dwnt0okb0jYclCDXF13xU7Ge4zSw==} + engines: {node: '>=18.0.0'} + + '@whatwg-node/fetch@0.10.8': + resolution: {integrity: sha512-Rw9z3ctmeEj8QIB9MavkNJqekiu9usBCSMZa+uuAvM0lF3v70oQVCXNppMIqaV6OTZbdaHF1M2HLow58DEw+wg==} + engines: {node: '>=18.0.0'} + + '@whatwg-node/node-fetch@0.7.21': + resolution: {integrity: sha512-QC16IdsEyIW7kZd77aodrMO7zAoDyyqRCTLg+qG4wqtP4JV9AA+p7/lgqMdD29XyiYdVvIdFrfI9yh7B1QvRvw==} + engines: {node: '>=18.0.0'} + + '@whatwg-node/promise-helpers@1.3.2': + resolution: {integrity: sha512-Nst5JdK47VIl9UcGwtv2Rcgyn5lWtZ0/mhRQ4G8NN2isxpq2TO30iqHzmwoJycjWuyUfg3GFXqP/gFHXeV57IA==} + engines: {node: '>=16.0.0'} + + '@whatwg-node/server@0.9.71': + resolution: {integrity: sha512-ueFCcIPaMgtuYDS9u0qlUoEvj6GiSsKrwnOLPp9SshqjtcRaR1IEHRjoReq3sXNydsF5i0ZnmuYgXq9dV53t0g==} + engines: {node: '>=18.0.0'} + + abbrev@1.1.1: + resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==} + + abbrev@2.0.0: + resolution: {integrity: sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + abbrev@3.0.1: + resolution: {integrity: sha512-AO2ac6pjRB3SJmGJo+v5/aK6Omggp6fsLrs6wN9bd35ulu4cCwaAU9+7ZhXjeqHVkaHThLuzH0nZr0YpCDhygg==} + engines: {node: ^18.17.0 || >=20.5.0} + + abitype@1.0.0: + resolution: {integrity: sha512-NMeMah//6bJ56H5XRj8QCV4AwuW6hB6zqz2LnhhLdcWVQOsXki6/Pn3APeqxCma62nXIcmZWdu1DlHWS74umVQ==} + peerDependencies: + typescript: '>=5.0.4' + zod: ^3 >=3.22.0 + peerDependenciesMeta: + typescript: + optional: true + zod: + optional: true + + abitype@1.0.2: + resolution: {integrity: sha512-aFt4k2H+eiAKy/zxtnORa9iIb10BMBeWL18l8v4+QuwYEBXPxxjSB1bFZCzQmKPoj8m7j68K705l3uY+E2gAjg==} + peerDependencies: + typescript: '>=5.0.4' + zod: ^3 >=3.22.0 + peerDependenciesMeta: + typescript: + optional: true + zod: + optional: true + + abitype@1.0.4: + resolution: {integrity: sha512-UivtYZOGJGE8rsrM/N5vdRkUpqEZVmuTumfTuolm7m/6O09wprd958rx8kUBwVAAAhQDveGAgD0GJdBuR8s6tw==} + peerDependencies: + typescript: '>=5.0.4' + zod: ^3 >=3.22.0 + peerDependenciesMeta: + typescript: + optional: true + zod: + optional: true + + abitype@1.0.5: + resolution: {integrity: sha512-YzDhti7cjlfaBhHutMaboYB21Ha3rXR9QTkNJFzYC4kC8YclaiwPBBBJY8ejFdu2wnJeZCVZSMlQJ7fi8S6hsw==} + peerDependencies: + typescript: '>=5.0.4' + zod: ^3 >=3.22.0 + peerDependenciesMeta: + typescript: + optional: true + zod: + optional: true + + abitype@1.0.8: + resolution: {integrity: sha512-ZeiI6h3GnW06uYDLx0etQtX/p8E24UaHHBj57RSjK7YBFe7iuVn07EDpOeP451D06sF27VOz9JJPlIKJmXgkEg==} + peerDependencies: + typescript: '>=5.0.4' + zod: ^3 >=3.22.0 + peerDependenciesMeta: + typescript: + optional: true + zod: + optional: true + + abort-controller@3.0.0: + resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} + engines: {node: '>=6.5'} + + acorn-import-attributes@1.9.5: + resolution: {integrity: sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==} + peerDependencies: + acorn: ^8 + + acorn-walk@8.3.4: + resolution: {integrity: sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==} + engines: {node: '>=0.4.0'} + + acorn@8.11.3: + resolution: {integrity: sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==} + engines: {node: '>=0.4.0'} + hasBin: true + + acorn@8.14.1: + resolution: {integrity: sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==} + engines: {node: '>=0.4.0'} + hasBin: true + + acorn@8.15.0: + resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} + engines: {node: '>=0.4.0'} + hasBin: true + + adm-zip@0.4.16: + resolution: {integrity: sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg==} + engines: {node: '>=0.3.0'} + + agent-base@6.0.2: + resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} + engines: {node: '>= 6.0.0'} + + agent-base@7.1.3: + resolution: {integrity: sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==} + engines: {node: '>= 14'} + + aggregate-error@3.1.0: + resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} + engines: {node: '>=8'} + + algoliasearch@5.12.0: + resolution: {integrity: sha512-psGBRYdGgik8I6m28iAB8xpubvjEt7UQU+w5MAJUA2324WHiGoHap5BPkkjB14rMaXeRts6pmOsrVIglGyOVwg==} + engines: {node: '>= 14.0.0'} + + alien-signals@0.2.0: + resolution: {integrity: sha512-StlonZhBBrsPPwrDjiPAiVTf/rolxffLxVPT60Qv/t88BZ81BvUVzHgGqEFvJ1ii8HXtm1+zU2Icr59tfWEcag==} + + ansi-align@3.0.1: + resolution: {integrity: sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==} + + ansi-colors@4.1.1: + resolution: {integrity: sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==} + engines: {node: '>=6'} + + ansi-colors@4.1.3: + resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} + engines: {node: '>=6'} + + ansi-escapes@4.3.2: + resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} + engines: {node: '>=8'} + + ansi-escapes@7.0.0: + resolution: {integrity: sha512-GdYO7a61mR0fOlAsvC9/rIHf7L96sBc6dEWzeOu+KAea5bZyQRPIpojrVoI4AXGJS/ycu/fBTdLrUkA4ODrvjw==} + engines: {node: '>=18'} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-regex@6.1.0: + resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==} + engines: {node: '>=12'} + + ansi-styles@3.2.1: + resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} + engines: {node: '>=4'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@5.2.0: + resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} + engines: {node: '>=10'} + + ansi-styles@6.2.1: + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + engines: {node: '>=12'} + + ansis@3.17.0: + resolution: {integrity: sha512-0qWUglt9JEqLFr3w1I1pbrChn1grhaiAR2ocX1PP/flRmxgtwTzPFFFnfIlD6aMOLQZgSuCRlidD70lvx8yhzg==} + engines: {node: '>=14'} + + any-promise@1.3.0: + resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} + + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + + aproba@2.0.0: + resolution: {integrity: sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==} + + archiver-utils@2.1.0: + resolution: {integrity: sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==} + engines: {node: '>= 6'} + + archiver-utils@3.0.4: + resolution: {integrity: sha512-KVgf4XQVrTjhyWmx6cte4RxonPLR9onExufI1jhvw/MQ4BB6IsZD5gT8Lq+u/+pRkWna/6JoHpiQioaqFP5Rzw==} + engines: {node: '>= 10'} + + archiver-utils@5.0.2: + resolution: {integrity: sha512-wuLJMmIBQYCsGZgYLTy5FIB2pF6Lfb6cXMSF8Qywwk3t20zWnAi7zLcQFdKQmIB8wyZpY5ER38x08GbwtR2cLA==} + engines: {node: '>= 14'} + + archiver@5.3.2: + resolution: {integrity: sha512-+25nxyyznAXF7Nef3y0EbBeqmGZgeN/BxHX29Rs39djAfaFalmQ89SE6CWyDCHzGL0yt/ycBtNOmGTW0FyGWNw==} + engines: {node: '>= 10'} + + archiver@7.0.1: + resolution: {integrity: sha512-ZcbTaIqJOfCc03QwD468Unz/5Ir8ATtvAHsK+FdXbDIbGfihqh9mrvdcYunQzqn4HrvWWaFyaxJhGZagaJJpPQ==} + engines: {node: '>= 14'} + + are-we-there-yet@2.0.0: + resolution: {integrity: sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==} + engines: {node: '>=10'} + deprecated: This package is no longer supported. + + argparse@1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + aria-query@5.3.0: + resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==} + + array-union@1.0.2: + resolution: {integrity: sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==} + engines: {node: '>=0.10.0'} + + array-union@2.1.0: + resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} + engines: {node: '>=8'} + + array-uniq@1.0.3: + resolution: {integrity: sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==} + engines: {node: '>=0.10.0'} + + assertion-error@2.0.1: + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} + engines: {node: '>=12'} + + ast-kit@1.4.3: + resolution: {integrity: sha512-MdJqjpodkS5J149zN0Po+HPshkTdUyrvF7CKTafUgv69vBSPtncrj+3IiUgqdd7ElIEkbeXCsEouBUwLrw9Ilg==} + engines: {node: '>=16.14.0'} + + ast-module-types@5.0.0: + resolution: {integrity: sha512-JvqziE0Wc0rXQfma0HZC/aY7URXHFuZV84fJRtP8u+lhp0JYCNd5wJzVXP45t0PH0Mej3ynlzvdyITYIu0G4LQ==} + engines: {node: '>=14'} + + ast-walker-scope@0.6.2: + resolution: {integrity: sha512-1UWOyC50xI3QZkRuDj6PqDtpm1oHWtYs+NQGwqL/2R11eN3Q81PHAHPM0SWW3BNQm53UDwS//Jv8L4CCVLM1bQ==} + engines: {node: '>=16.14.0'} + + async-mutex@0.2.6: + resolution: {integrity: sha512-Hs4R+4SPgamu6rSGW8C7cV9gaWUKEHykfzCCvIRuaVv636Ju10ZdeUbvb4TBEW0INuq2DHZqXbK4Nd3yG4RaRw==} + + async-sema@3.1.1: + resolution: {integrity: sha512-tLRNUXati5MFePdAk8dw7Qt7DpxPB60ofAgn8WRhW6a2rcimZnYBP9oxHiv0OHy+Wz7kPMG+t4LGdt31+4EmGg==} + + async@3.2.6: + resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==} + + atomic-sleep@1.0.0: + resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==} + engines: {node: '>=8.0.0'} + + autoprefixer@10.4.21: + resolution: {integrity: sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==} + engines: {node: ^10 || ^12 || >=14} + hasBin: true + peerDependencies: + postcss: ^8.1.0 + + available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} + engines: {node: '>= 0.4'} + + b4a@1.6.7: + resolution: {integrity: sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg==} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + bare-events@2.5.4: + resolution: {integrity: sha512-+gFfDkR8pj4/TrWCGUGWmJIkBwuxPS5F+a5yWjOHQt2hHvNZd5YLzadjmDUtFmMM4y429bnKLa8bYBMHcYdnQA==} + + base-x@3.0.9: + resolution: {integrity: sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==} + + base-x@5.0.1: + resolution: {integrity: sha512-M7uio8Zt++eg3jPj+rHMfCC+IuygQHHCOU+IYsVtik6FWjuYpVt/+MRKcgsAMHh8mMFAwnB+Bs+mTrFiXjMzKg==} + + base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + + better-path-resolve@1.0.0: + resolution: {integrity: sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==} + engines: {node: '>=4'} + + big.js@6.2.2: + resolution: {integrity: sha512-y/ie+Faknx7sZA5MfGA2xKlu0GDv8RWrXGsmlteyJQ2lvoKv9GBK/fpRMc2qlSoBAgNxrixICFCBefIq8WCQpQ==} + + binary-extensions@2.2.0: + resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} + engines: {node: '>=8'} + + bindings@1.5.0: + resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} + + birpc@0.2.19: + resolution: {integrity: sha512-5WeXXAvTmitV1RqJFppT5QtUiz2p1mRSYU000Jkft5ZUCLJIk4uQriYNO50HknxKwM6jd8utNc66K1qGIwwWBQ==} + + birpc@2.3.0: + resolution: {integrity: sha512-ijbtkn/F3Pvzb6jHypHRyve2QApOCZDR25D/VnkY2G/lBNcXCTsnsCxgY4k4PkVB7zfwzYbY3O9Lcqe3xufS5g==} + + bl@4.1.0: + resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} + + blakejs@1.2.1: + resolution: {integrity: sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==} + + bn.js@4.12.0: + resolution: {integrity: sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==} + + bn.js@5.2.1: + resolution: {integrity: sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==} + + boolbase@1.0.0: + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + + bowser@2.11.0: + resolution: {integrity: sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==} + + boxen@5.1.2: + resolution: {integrity: sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==} + engines: {node: '>=10'} + + brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + + brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + + braces@3.0.2: + resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} + engines: {node: '>=8'} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + brorand@1.1.0: + resolution: {integrity: sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==} + + browser-stdout@1.3.1: + resolution: {integrity: sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==} + + browserify-aes@1.2.0: + resolution: {integrity: sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==} + + browserslist@4.23.0: + resolution: {integrity: sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + browserslist@4.24.5: + resolution: {integrity: sha512-FDToo4Wo82hIdgc1CQ+NQD0hEhmpPjrZ3hiUgwgOG6IuTdlpr8jdjyG24P6cNP1yJpTLzS5OcGgSw0xmDU1/Tw==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + bs58@4.0.1: + resolution: {integrity: sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==} + + bs58@6.0.0: + resolution: {integrity: sha512-PD0wEnEYg6ijszw/u8s+iI3H17cTymlrwkKhDhPZq+Sokl3AU4htyBFTjAeNAlCCmg0f53g6ih3jATyCKftTfw==} + + bs58check@2.1.2: + resolution: {integrity: sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==} + + buffer-crc32@0.2.13: + resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} + + buffer-crc32@1.0.0: + resolution: {integrity: sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w==} + engines: {node: '>=8.0.0'} + + buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + + buffer-xor@1.0.3: + resolution: {integrity: sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==} + + buffer@5.7.1: + resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + + buffer@6.0.3: + resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + + bufferutil@4.0.8: + resolution: {integrity: sha512-4T53u4PdgsXqKaIctwF8ifXlRTTmEPJ8iEPWFdGZvcf7sbwYo6FKFEX9eNNAnzFZ7EzJAQ3CJeOtCRA4rDp7Pw==} + engines: {node: '>=6.14.2'} + + bufferutil@4.0.9: + resolution: {integrity: sha512-WDtdLmJvAuNNPzByAYpRo2rF1Mmradw6gvWsQKf63476DDXmomT9zUiGypLcG4ibIM67vhAj8jJRdbmEws2Aqw==} + engines: {node: '>=6.14.2'} + + builtin-modules@3.3.0: + resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==} + engines: {node: '>=6'} + + bun-types@1.1.29: + resolution: {integrity: sha512-En3/TzSPMPyl5UlUB1MHzHpcrZDakTm7mS203eLoX1fBoEa3PW+aSS8GAqVJ7Is/m34Z5ogL+ECniLY0uDaCPw==} + + bun@1.1.30: + resolution: {integrity: sha512-ysRL1pq10Xba0jqVLPrKU3YIv0ohfp3cTajCPtpjCyppbn3lfiAVNpGoHfyaxS17OlPmWmR67UZRPw/EueQuug==} + cpu: [arm64, x64] + os: [darwin, linux, win32] + hasBin: true + + bundle-name@4.1.0: + resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==} + engines: {node: '>=18'} + + bundle-require@5.1.0: + resolution: {integrity: sha512-3WrrOuZiyaaZPWiEt4G3+IffISVC9HYlWueJEBWED4ZH4aIAC2PnkdnuRrR94M+w6yGWn4AglWtJtBI8YqvgoA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + peerDependencies: + esbuild: '>=0.18' + + busboy@1.6.0: + resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} + engines: {node: '>=10.16.0'} + + bytes@3.1.2: + resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} + engines: {node: '>= 0.8'} + + c12@3.0.4: + resolution: {integrity: sha512-t5FaZTYbbCtvxuZq9xxIruYydrAGsJ+8UdP0pZzMiK2xl/gNiSOy0OxhLzHUEEb0m1QXYqfzfvyIFEmz/g9lqg==} + peerDependencies: + magicast: ^0.3.5 + peerDependenciesMeta: + magicast: + optional: true + + cac@6.7.14: + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} + engines: {node: '>=8'} + + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + + call-bind@1.0.8: + resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==} + engines: {node: '>= 0.4'} + + call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} + engines: {node: '>= 0.4'} + + callsite@1.0.0: + resolution: {integrity: sha512-0vdNRFXn5q+dtOqjfFtmtlI9N2eVZ7LMyEV2iKC5mEEFvSg/69Ml6b/WU2qF8W1nLRa0wiSrDT3Y5jOHZCwKPQ==} + + camelcase@5.3.1: + resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} + engines: {node: '>=6'} + + camelcase@6.3.0: + resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} + engines: {node: '>=10'} + + caniuse-api@3.0.0: + resolution: {integrity: sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==} + + caniuse-lite@1.0.30001723: + resolution: {integrity: sha512-1R/elMjtehrFejxwmexeXAtae5UO9iSyFn6G/I806CYC/BLyyBk1EPhrKBkWhy6wM6Xnm47dSJQec+tLJ39WHw==} + + ccount@2.0.1: + resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} + + chai@5.2.0: + resolution: {integrity: sha512-mCuXncKXk5iCLhfhwTc0izo0gtEmpz5CtG2y8GiOINBlMVS6v8TMRc5TaLWKS6692m9+dVVfzgeVxR5UxWHTYw==} + engines: {node: '>=12'} + + chalk@2.4.2: + resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} + engines: {node: '>=4'} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + chalk@5.3.0: + resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + + change-case@5.4.4: + resolution: {integrity: sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w==} + + char-regex@1.0.2: + resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} + engines: {node: '>=10'} + + character-entities-html4@2.1.0: + resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} + + character-entities-legacy@3.0.0: + resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} + + character-entities@2.0.2: + resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==} + + chardet@0.7.0: + resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} + + check-error@2.1.1: + resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} + engines: {node: '>= 16'} + + chokidar@3.5.3: + resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} + engines: {node: '>= 8.10.0'} + + chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} + engines: {node: '>= 8.10.0'} + + chokidar@4.0.3: + resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} + engines: {node: '>= 14.16.0'} + + chownr@2.0.0: + resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} + engines: {node: '>=10'} + + chownr@3.0.0: + resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==} + engines: {node: '>=18'} + + ci-info@2.0.0: + resolution: {integrity: sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==} + + ci-info@3.9.0: + resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} + engines: {node: '>=8'} + + cipher-base@1.0.4: + resolution: {integrity: sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==} + + citty@0.1.6: + resolution: {integrity: sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==} + + cjs-module-lexer@1.4.1: + resolution: {integrity: sha512-cuSVIHi9/9E/+821Qjdvngor+xpnlwnuwIyZOaLmHBVdXL+gP+I6QQB9VkO7RI77YIcTV+S1W9AreJ5eN63JBA==} + + clean-stack@2.2.0: + resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} + engines: {node: '>=6'} + + cli-boxes@2.2.1: + resolution: {integrity: sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==} + engines: {node: '>=6'} + + cli-highlight@2.1.11: + resolution: {integrity: sha512-9KDcoEVwyUXrjcJNvHD0NFc/hiwe/WPVYIleQh2O1N2Zro5gWJZ/K+3DGn8w8P/F6FxOgzyC5bxDyHIgCSPhGg==} + engines: {node: '>=8.0.0', npm: '>=5.0.0'} + hasBin: true + + cli-spinners@2.9.2: + resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==} + engines: {node: '>=6'} + + cli-table3@0.6.5: + resolution: {integrity: sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==} + engines: {node: 10.* || >= 12.*} + + cli-width@4.1.0: + resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==} + engines: {node: '>= 12'} + + client-only@0.0.1: + resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} + + clipboardy@4.0.0: + resolution: {integrity: sha512-5mOlNS0mhX0707P2I0aZ2V/cmHUEO/fL7VFLqszkhUsxt7RwnmrInf/eEQKlf5GzvYeHIjT+Ov1HRfNmymlG0w==} + engines: {node: '>=18'} + + cliui@6.0.0: + resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==} + + cliui@7.0.4: + resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} + + cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + + clone@1.0.4: + resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} + engines: {node: '>=0.8'} + + clsx@1.2.1: + resolution: {integrity: sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==} + engines: {node: '>=6'} + + cluster-key-slot@1.1.2: + resolution: {integrity: sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==} + engines: {node: '>=0.10.0'} + + color-convert@1.9.3: + resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.3: + resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + color-string@1.9.1: + resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} + + color-support@1.1.3: + resolution: {integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==} + hasBin: true + + color@3.2.1: + resolution: {integrity: sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==} + + color@4.2.3: + resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==} + engines: {node: '>=12.5.0'} + + colord@2.9.3: + resolution: {integrity: sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==} + + colorette@2.0.20: + resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} + + colorspace@1.1.4: + resolution: {integrity: sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==} + + comma-separated-tokens@2.0.3: + resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} + + command-exists@1.2.9: + resolution: {integrity: sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==} + + commander@10.0.1: + resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==} + engines: {node: '>=14'} + + commander@2.20.3: + resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + + commander@3.0.2: + resolution: {integrity: sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==} + + commander@4.1.1: + resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} + engines: {node: '>= 6'} + + commander@7.2.0: + resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} + engines: {node: '>= 10'} + + common-path-prefix@3.0.0: + resolution: {integrity: sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==} + + commondir@1.0.1: + resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} + + compatx@0.1.8: + resolution: {integrity: sha512-jcbsEAR81Bt5s1qOFymBufmCbXCXbk0Ql+K5ouj6gCyx2yHlu6AgmGIi9HxfKixpUDO5bCFJUHQ5uM6ecbTebw==} + + compatx@0.2.0: + resolution: {integrity: sha512-6gLRNt4ygsi5NyMVhceOCFv14CIdDFN7fQjX1U4+47qVE/+kjPoXMK65KWK+dWxmFzMTuKazoQ9sch6pM0p5oA==} + + compress-commons@4.1.2: + resolution: {integrity: sha512-D3uMHtGc/fcO1Gt1/L7i1e33VOvD4A9hfQLP+6ewd+BvG/gQ84Yh4oftEhAdjSMgBgwGL+jsppT7JYNpo6MHHg==} + engines: {node: '>= 10'} + + compress-commons@6.0.2: + resolution: {integrity: sha512-6FqVXeETqWPoGcfzrXb37E50NP0LXT8kAMu5ooZayhWWdgEY4lBEEcbQNXtkuKQsGduxiIcI4gOTsxTmuq/bSg==} + engines: {node: '>= 14'} + + computeds@0.0.1: + resolution: {integrity: sha512-7CEBgcMjVmitjYo5q8JTJVra6X5mQ20uTThdK+0kR7UEaDrAWEQcRiBtWJzga4eRpP6afNwwLsX2SET2JhVB1Q==} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + confbox@0.1.7: + resolution: {integrity: sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==} + + confbox@0.1.8: + resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} + + confbox@0.2.2: + resolution: {integrity: sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ==} + + config-chain@1.1.13: + resolution: {integrity: sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==} + + consola@3.2.3: + resolution: {integrity: sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==} + engines: {node: ^14.18.0 || >=16.10.0} + + consola@3.4.2: + resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} + engines: {node: ^14.18.0 || >=16.10.0} + + console-control-strings@1.1.0: + resolution: {integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==} + + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + + cookie-es@1.2.2: + resolution: {integrity: sha512-+W7VmiVINB+ywl1HGXJXmrqkOhpKrIiVZV6tQuV54ZyQC7MMuBt81Vc336GMLoHBq5hV/F9eXgt5Mnx0Rha5Fg==} + + cookie-es@2.0.0: + resolution: {integrity: sha512-RAj4E421UYRgqokKUmotqAwuplYw15qtdXfY+hGzgCJ/MBjCVZcSoHK/kH9kocfjRjcDME7IiDWR/1WX1TM2Pg==} + + cookie@0.4.2: + resolution: {integrity: sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==} + engines: {node: '>= 0.6'} + + cookie@0.5.0: + resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==} + engines: {node: '>= 0.6'} + + cookie@1.0.2: + resolution: {integrity: sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==} + engines: {node: '>=18'} + + copy-anything@3.0.5: + resolution: {integrity: sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==} + engines: {node: '>=12.13'} + + core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + + cp-file@10.0.0: + resolution: {integrity: sha512-vy2Vi1r2epK5WqxOLnskeKeZkdZvTKfFZQCplE3XWsP+SUJyd5XAUFC9lFgTjjXJF2GMne/UML14iEmkAaDfFg==} + engines: {node: '>=14.16'} + + crc-32@1.2.2: + resolution: {integrity: sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==} + engines: {node: '>=0.8'} + hasBin: true + + crc32-stream@4.0.3: + resolution: {integrity: sha512-NT7w2JVU7DFroFdYkeq8cywxrgjPHWkdX1wjpRQXPX5Asews3tA+Ght6lddQO5Mkumffp3X7GEqku3epj2toIw==} + engines: {node: '>= 10'} + + crc32-stream@6.0.0: + resolution: {integrity: sha512-piICUB6ei4IlTv1+653yq5+KoqfBYmj9bw6LqXoOneTMDXk5nM1qt12mFW1caG3LlJXEKW1Bp0WggEmIfQB34g==} + engines: {node: '>= 14'} + + create-hash@1.2.0: + resolution: {integrity: sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==} + + create-hmac@1.1.7: + resolution: {integrity: sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==} + + cron-parser@4.9.0: + resolution: {integrity: sha512-p0SaNjrHOnQeR8/VnfGbmg9te2kfyYSQ7Sc/j/6DtPL3JQvKxmjO9TSjNFpujqV3vEYYBvNNvXSxzyksBWAx1Q==} + engines: {node: '>=12.0.0'} + + croner@9.0.0: + resolution: {integrity: sha512-onMB0OkDjkXunhdW9htFjEhqrD54+M94i6ackoUkjHKbRnXdyEyKRelp4nJ1kAz32+s27jP1FsebpJCVl0BsvA==} + engines: {node: '>=18.0'} + + cross-fetch@3.1.5: + resolution: {integrity: sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==} + + cross-fetch@3.2.0: + resolution: {integrity: sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q==} + + cross-fetch@4.1.0: + resolution: {integrity: sha512-uKm5PU+MHTootlWEY+mZ4vvXoCn4fLQxT9dSc1sXVMSFkINTJVN8cAQROpwcKm8bJ/c7rgZVIBWzH5T78sNZZw==} + + cross-spawn@5.1.0: + resolution: {integrity: sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==} + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + crossws@0.2.4: + resolution: {integrity: sha512-DAxroI2uSOgUKLz00NX6A8U/8EE3SZHmIND+10jkVSaypvyt57J5JEOxAQOL6lQxyzi/wZbTIwssU1uy69h5Vg==} + peerDependencies: + uWebSockets.js: '*' + peerDependenciesMeta: + uWebSockets.js: + optional: true + + crossws@0.3.5: + resolution: {integrity: sha512-ojKiDvcmByhwa8YYqbQI/hg7MEU0NC03+pSdEq4ZUnZR9xXpwk7E43SMNGkn+JxJGPFtNvQ48+vV2p+P1ml5PA==} + + crypto-random-string@1.0.0: + resolution: {integrity: sha512-GsVpkFPlycH7/fRR7Dhcmnoii54gV1nz7y4CWyeFS14N+JVBBhY+r8amRHE4BwSYal7BPTDp8isvAlCxyFt3Hg==} + engines: {node: '>=4'} + + css-declaration-sorter@7.2.0: + resolution: {integrity: sha512-h70rUM+3PNFuaBDTLe8wF/cdWu+dOZmb7pJt8Z2sedYbAcQVQV/tEchueg3GWxwqS0cxtbxmaHEdkNACqcvsow==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + postcss: ^8.0.9 + + css-select@5.1.0: + resolution: {integrity: sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==} + + css-tree@2.2.1: + resolution: {integrity: sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} + + css-tree@2.3.1: + resolution: {integrity: sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} + + css-what@6.1.0: + resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==} + engines: {node: '>= 6'} + + cssesc@3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true + + cssnano-preset-default@7.0.7: + resolution: {integrity: sha512-jW6CG/7PNB6MufOrlovs1TvBTEVmhY45yz+bd0h6nw3h6d+1e+/TX+0fflZ+LzvZombbT5f+KC063w9VoHeHow==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + cssnano-utils@5.0.1: + resolution: {integrity: sha512-ZIP71eQgG9JwjVZsTPSqhc6GHgEr53uJ7tK5///VfyWj6Xp2DBmixWHqJgPno+PqATzn48pL42ww9x5SSGmhZg==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + cssnano@7.0.7: + resolution: {integrity: sha512-evKu7yiDIF7oS+EIpwFlMF730ijRyLFaM2o5cTxRGJR9OKHKkc+qP443ZEVR9kZG0syaAJJCPJyfv5pbrxlSng==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + csso@5.0.5: + resolution: {integrity: sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} + + csstype@3.1.3: + resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + + data-uri-to-buffer@4.0.1: + resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} + engines: {node: '>= 12'} + + dataloader@1.4.0: + resolution: {integrity: sha512-68s5jYdlvasItOJnCuI2Q9s4q98g0pCyL3HrcKJu8KNugUl8ahgmZYg38ysLTgQjjXX3H8CJLkAvWrclWfcalw==} + + date-fns@2.30.0: + resolution: {integrity: sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==} + engines: {node: '>=0.11'} + + dateformat@4.6.3: + resolution: {integrity: sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==} + + dayjs@1.11.13: + resolution: {integrity: sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==} + + db0@0.3.2: + resolution: {integrity: sha512-xzWNQ6jk/+NtdfLyXEipbX55dmDSeteLFt/ayF+wZUU5bzKgmrDOxmInUTbyVRp46YwnJdkDA1KhB7WIXFofJw==} + peerDependencies: + '@electric-sql/pglite': '*' + '@libsql/client': '*' + better-sqlite3: '*' + drizzle-orm: '*' + mysql2: '*' + sqlite3: '*' + peerDependenciesMeta: + '@electric-sql/pglite': + optional: true + '@libsql/client': + optional: true + better-sqlite3: + optional: true + drizzle-orm: + optional: true + mysql2: + optional: true + sqlite3: + optional: true + + de-indent@1.0.2: + resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==} + + debounce@1.2.1: + resolution: {integrity: sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==} + + debug@4.3.4: + resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@4.3.7: + resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@4.4.1: + resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + decache@4.6.2: + resolution: {integrity: sha512-2LPqkLeu8XWHU8qNCS3kcF6sCcb5zIzvWaAHYSvPfwhdd7mHuah29NssMzrTYyHN4F5oFy2ko9OBYxegtU0FEw==} + + decamelize@1.2.0: + resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} + engines: {node: '>=0.10.0'} + + decamelize@4.0.0: + resolution: {integrity: sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==} + engines: {node: '>=10'} + + decode-named-character-reference@1.0.2: + resolution: {integrity: sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==} + + decode-uri-component@0.2.2: + resolution: {integrity: sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==} + engines: {node: '>=0.10'} + + dedent@1.6.0: + resolution: {integrity: sha512-F1Z+5UCFpmQUzJa11agbyPVMbpgT/qA3/SKyJ1jyBgm7dUcUEa8v9JwDkerSQXfakBwFljIxhOJqGkjUwZ9FSA==} + peerDependencies: + babel-plugin-macros: ^3.1.0 + peerDependenciesMeta: + babel-plugin-macros: + optional: true + + deep-eql@5.0.2: + resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} + engines: {node: '>=6'} + + deepmerge@4.3.1: + resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} + engines: {node: '>=0.10.0'} + + default-browser-id@5.0.0: + resolution: {integrity: sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==} + engines: {node: '>=18'} + + default-browser@5.2.1: + resolution: {integrity: sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==} + engines: {node: '>=18'} + + defaults@1.0.4: + resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} + + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + + define-lazy-prop@2.0.0: + resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==} + engines: {node: '>=8'} + + define-lazy-prop@3.0.0: + resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==} + engines: {node: '>=12'} + + defu@6.1.4: + resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} + + delegates@1.0.0: + resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==} + + denque@2.1.0: + resolution: {integrity: sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==} + engines: {node: '>=0.10'} + + depd@2.0.0: + resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} + engines: {node: '>= 0.8'} + + dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + + derive-valtio@0.1.0: + resolution: {integrity: sha512-OCg2UsLbXK7GmmpzMXhYkdO64vhJ1ROUUGaTFyHjVwEdMEcTTRj7W1TxLbSBxdY8QLBPCcp66MTyaSy0RpO17A==} + peerDependencies: + valtio: '*' + + destr@2.0.5: + resolution: {integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==} + + detect-browser@5.3.0: + resolution: {integrity: sha512-53rsFbGdwMwlF7qvCt0ypLM5V5/Mbl0szB7GPN8y9NCcbknYOeVVXdrXEq+90IwAfrrzt6Hd+u2E2ntakICU8w==} + + detect-indent@6.1.0: + resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==} + engines: {node: '>=8'} + + detect-libc@1.0.3: + resolution: {integrity: sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==} + engines: {node: '>=0.10'} + hasBin: true + + detect-libc@2.0.4: + resolution: {integrity: sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==} + engines: {node: '>=8'} + + detective-amd@5.0.2: + resolution: {integrity: sha512-XFd/VEQ76HSpym80zxM68ieB77unNuoMwopU2TFT/ErUk5n4KvUTwW4beafAVUugrjV48l4BmmR0rh2MglBaiA==} + engines: {node: '>=14'} + hasBin: true + + detective-cjs@5.0.1: + resolution: {integrity: sha512-6nTvAZtpomyz/2pmEmGX1sXNjaqgMplhQkskq2MLrar0ZAIkHMrDhLXkRiK2mvbu9wSWr0V5/IfiTrZqAQMrmQ==} + engines: {node: '>=14'} + + detective-es6@4.0.1: + resolution: {integrity: sha512-k3Z5tB4LQ8UVHkuMrFOlvb3GgFWdJ9NqAa2YLUU/jTaWJIm+JJnEh4PsMc+6dfT223Y8ACKOaC0qcj7diIhBKw==} + engines: {node: '>=14'} + + detective-postcss@6.1.3: + resolution: {integrity: sha512-7BRVvE5pPEvk2ukUWNQ+H2XOq43xENWbH0LcdCE14mwgTBEAMoAx+Fc1rdp76SmyZ4Sp48HlV7VedUnP6GA1Tw==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + + detective-sass@5.0.3: + resolution: {integrity: sha512-YsYT2WuA8YIafp2RVF5CEfGhhyIVdPzlwQgxSjK+TUm3JoHP+Tcorbk3SfG0cNZ7D7+cYWa0ZBcvOaR0O8+LlA==} + engines: {node: '>=14'} + + detective-scss@4.0.3: + resolution: {integrity: sha512-VYI6cHcD0fLokwqqPFFtDQhhSnlFWvU614J42eY6G0s8c+MBhi9QAWycLwIOGxlmD8I/XvGSOUV1kIDhJ70ZPg==} + engines: {node: '>=14'} + + detective-stylus@4.0.0: + resolution: {integrity: sha512-TfPotjhszKLgFBzBhTOxNHDsutIxx9GTWjrL5Wh7Qx/ydxKhwUrlSFeLIn+ZaHPF+h0siVBkAQSuy6CADyTxgQ==} + engines: {node: '>=14'} + + detective-typescript@11.2.0: + resolution: {integrity: sha512-ARFxjzizOhPqs1fYC/2NMC3N4jrQ6HvVflnXBTRqNEqJuXwyKLRr9CrJwkRcV/SnZt1sNXgsF6FPm0x57Tq0rw==} + engines: {node: ^14.14.0 || >=16.0.0} + + devalue@5.1.1: + resolution: {integrity: sha512-maua5KUiapvEwiEAe+XnlZ3Rh0GD+qI1J/nb9vrJc3muPXvcF/8gXYTWF76+5DAqHyDUtOIImEuo0YKE9mshVw==} + + devlop@1.1.0: + resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + + diff@5.0.0: + resolution: {integrity: sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==} + engines: {node: '>=0.3.1'} + + diff@7.0.0: + resolution: {integrity: sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==} + engines: {node: '>=0.3.1'} + + dijkstrajs@1.0.2: + resolution: {integrity: sha512-QV6PMaHTCNmKSeP6QoXhVTw9snc9VD8MulTT0Bd99Pacp4SS1cjcrYPgBPmibqKVtMJJfqC6XvOXgPMEEPH/fg==} + + dir-glob@2.2.2: + resolution: {integrity: sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==} + engines: {node: '>=4'} + + dir-glob@3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} + + dom-accessibility-api@0.5.16: + resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==} + + dom-serializer@2.0.0: + resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} + + domelementtype@2.3.0: + resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} + + domhandler@5.0.3: + resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} + engines: {node: '>= 4'} + + domutils@3.2.2: + resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} + + dot-prop@9.0.0: + resolution: {integrity: sha512-1gxPBJpI/pcjQhKgIU91II6Wkay+dLcN3M6rf2uwP8hRur3HtQXjVrdAK3sjC0piaEuxzMwjXChcETiJl47lAQ==} + engines: {node: '>=18'} + + dotenv-expand@10.0.0: + resolution: {integrity: sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A==} + engines: {node: '>=12'} + + dotenv@16.3.1: + resolution: {integrity: sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==} + engines: {node: '>=12'} + + dotenv@16.5.0: + resolution: {integrity: sha512-m/C+AwOAr9/W1UOIZUo232ejMNnJAJtYQjUbHoNTBNTJSvqzzDh7vnrei3o3r3m9blf6ZoDkvcw0VmozNRFJxg==} + engines: {node: '>=12'} + + dotenv@8.6.0: + resolution: {integrity: sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==} + engines: {node: '>=10'} + + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + + duplexer@0.1.2: + resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} + + duplexify@4.1.2: + resolution: {integrity: sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw==} + + eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + + easy-table@1.2.0: + resolution: {integrity: sha512-OFzVOv03YpvtcWGe5AayU5G2hgybsg3iqA6drU8UaoZyB9jLGMTrz9+asnLp/E+6qPh88yEI1gvyZFZ41dmgww==} + + eciesjs@0.4.15: + resolution: {integrity: sha512-r6kEJXDKecVOCj2nLMuXK/FCPeurW33+3JRpfXVbjLja3XUYFfD9I/JBreH6sUyzcm3G/YQboBjMla6poKeSdA==} + engines: {bun: '>=1', deno: '>=2', node: '>=16'} + + editorconfig@1.0.4: + resolution: {integrity: sha512-L9Qe08KWTlqYMVvMcTIvMAdl1cDUubzRNYL+WfA4bLDMHe4nemKkpmYzkznE1FwLKu0EEmy6obgQKzMJrg4x9Q==} + engines: {node: '>=14'} + hasBin: true + + ee-first@1.1.1: + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + + electron-to-chromium@1.4.757: + resolution: {integrity: sha512-jftDaCknYSSt/+KKeXzH3LX5E2CvRLm75P3Hj+J/dv3CL0qUYcOt13d5FN1NiL5IJbbhzHrb3BomeG2tkSlZmw==} + + electron-to-chromium@1.5.155: + resolution: {integrity: sha512-ps5KcGGmwL8VaeJlvlDlu4fORQpv3+GIcF5I3f9tUKUlJ/wsysh6HU8P5L1XWRYeXfA0oJd4PyM8ds8zTFf6Ng==} + + elliptic@6.5.4: + resolution: {integrity: sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==} + + elliptic@6.6.0: + resolution: {integrity: sha512-dpwoQcLc/2WLQvJvLRHKZ+f9FgOdjnq11rurqwekGQygGPsYSK29OMMD2WalatiqQ+XGFDglTNixpPfI+lpaAA==} + + elliptic@6.6.1: + resolution: {integrity: sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + + emojilib@2.4.0: + resolution: {integrity: sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw==} + + enabled@2.0.0: + resolution: {integrity: sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==} + + encode-utf8@1.0.3: + resolution: {integrity: sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw==} + + encodeurl@2.0.0: + resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} + engines: {node: '>= 0.8'} + + encoding@0.1.13: + resolution: {integrity: sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==} + + end-of-stream@1.4.4: + resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} + + engine.io-client@6.6.3: + resolution: {integrity: sha512-T0iLjnyNWahNyv/lcjS2y4oE358tVS/SYQNxYXGAJ9/GLgH4VCvOQ/mhTjqU88mLZCQgiG8RIegFHYCdVC+j5w==} + + engine.io-parser@5.2.3: + resolution: {integrity: sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==} + engines: {node: '>=10.0.0'} + + enhanced-resolve@5.17.1: + resolution: {integrity: sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==} + engines: {node: '>=10.13.0'} + + enhanced-resolve@5.18.1: + resolution: {integrity: sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==} + engines: {node: '>=10.13.0'} + + enquirer@2.3.6: + resolution: {integrity: sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==} + engines: {node: '>=8.6'} + + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + + env-paths@2.2.1: + resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} + engines: {node: '>=6'} + + env-paths@3.0.0: + resolution: {integrity: sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + environment@1.1.0: + resolution: {integrity: sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==} + engines: {node: '>=18'} + + error-stack-parser-es@1.0.5: + resolution: {integrity: sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA==} + + errx@0.1.0: + resolution: {integrity: sha512-fZmsRiDNv07K6s2KkKFTiD2aIvECa7++PKyD5NC32tpRw46qZA3sOz+aM+/V9V0GDHxVTKLziveV4JhzBHDp9Q==} + + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-module-lexer@1.7.0: + resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} + + es-object-atoms@1.1.1: + resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} + engines: {node: '>= 0.4'} + + es-toolkit@1.33.0: + resolution: {integrity: sha512-X13Q/ZSc+vsO1q600bvNK4bxgXMkHcf//RxCmYDaRY5DAcT+eoXjY5hoAPGMdRnWQjvyLEcyauG3b6hz76LNqg==} + + esbuild@0.21.5: + resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} + engines: {node: '>=12'} + hasBin: true + + esbuild@0.25.4: + resolution: {integrity: sha512-8pgjLUcUjcgDg+2Q4NYXnPbo/vncAY4UmyaCm0jZevERqCHZIaWwdJHkf8XQtu4AxSKCdvrUbT0XUr1IdZzI8Q==} + engines: {node: '>=18'} + hasBin: true + + esbuild@0.25.5: + resolution: {integrity: sha512-P8OtKZRv/5J5hhz0cUAdu/cLuPIKXpQl1R9pZtvmHWQvrAUVd0UNIPT4IB4W3rNOqVO0rlqHmCIbSwxh/c9yUQ==} + engines: {node: '>=18'} + hasBin: true + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + + escape-string-regexp@1.0.5: + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} + engines: {node: '>=0.8.0'} + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + escape-string-regexp@5.0.0: + resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} + engines: {node: '>=12'} + + escodegen@2.1.0: + resolution: {integrity: sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==} + engines: {node: '>=6.0'} + hasBin: true + + eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + + etag@1.8.1: + resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} + engines: {node: '>= 0.6'} + + eth-block-tracker@7.1.0: + resolution: {integrity: sha512-8YdplnuE1IK4xfqpf4iU7oBxnOYAc35934o083G8ao+8WM8QQtt/mVlAY6yIAdY1eMeLqg4Z//PZjJGmWGPMRg==} + engines: {node: '>=14.0.0'} + + eth-json-rpc-filters@6.0.1: + resolution: {integrity: sha512-ITJTvqoCw6OVMLs7pI8f4gG92n/St6x80ACtHodeS+IXmO0w+t1T5OOzfSt7KLSMLRkVUoexV7tztLgDxg+iig==} + engines: {node: '>=14.0.0'} + + eth-query@2.1.2: + resolution: {integrity: sha512-srES0ZcvwkR/wd5OQBRA1bIJMww1skfGS0s8wlwK3/oNP4+wnds60krvu5R1QbpRQjMmpG5OMIWro5s7gvDPsA==} + + eth-rpc-errors@4.0.3: + resolution: {integrity: sha512-Z3ymjopaoft7JDoxZcEb3pwdGh7yiYMhOwm2doUt6ASXlMavpNlK6Cre0+IMl2VSGyEU9rkiperQhp5iRxn5Pg==} + + ethereum-cryptography@0.1.3: + resolution: {integrity: sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==} + + ethereum-cryptography@1.2.0: + resolution: {integrity: sha512-6yFQC9b5ug6/17CQpCyE3k9eKBMdhyVjzUy1WkiuY/E4vj/SXDBbCw8QEIaXqf0Mf2SnY6RmpDcwlUmBSS0EJw==} + + ethereum-cryptography@2.2.1: + resolution: {integrity: sha512-r/W8lkHSiTLxUxW8Rf3u4HGB0xQweG2RyETjywylKZSzLWoWAijRz8WCuOtJ6wah+avllXBqZuk29HCCvhEIRg==} + + ethereumjs-abi@0.6.8: + resolution: {integrity: sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA==} + deprecated: This library has been deprecated and usage is discouraged. + + ethereumjs-util@6.2.1: + resolution: {integrity: sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==} + + ethjs-util@0.1.6: + resolution: {integrity: sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==} + engines: {node: '>=6.5.0', npm: '>=3'} + + event-target-shim@5.0.1: + resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} + engines: {node: '>=6'} + + eventemitter2@6.4.9: + resolution: {integrity: sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg==} + + eventemitter3@4.0.7: + resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} + + eventemitter3@5.0.1: + resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} + + events@3.3.0: + resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} + engines: {node: '>=0.8.x'} + + evp_bytestokey@1.0.3: + resolution: {integrity: sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==} + + execa@5.1.1: + resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} + engines: {node: '>=10'} + + execa@7.2.0: + resolution: {integrity: sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA==} + engines: {node: ^14.18.0 || ^16.14.0 || >=18.0.0} + + execa@8.0.1: + resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} + engines: {node: '>=16.17'} + + execa@9.1.0: + resolution: {integrity: sha512-lSgHc4Elo2m6bUDhc3Hl/VxvUDJdQWI40RZ4KMY9bKRc+hgMOT7II/JjbNDhI8VnMtrCb7U/fhpJIkLORZozWw==} + engines: {node: '>=18'} + + expect-type@1.2.1: + resolution: {integrity: sha512-/kP8CAwxzLVEeFrMm4kMmy4CCDlpipyA7MYLVrdJIkV0fYF0UaigQHRsxHiuY/GEea+bh4KSv3TIlgr+2UL6bw==} + engines: {node: '>=12.0.0'} + + exsolve@1.0.5: + resolution: {integrity: sha512-pz5dvkYYKQ1AHVrgOzBKWeP4u4FRb3a6DNK2ucr0OoNwYIU4QWsJ+NM36LLzORT+z845MzKHHhpXiUF5nvQoJg==} + + extendable-error@0.1.7: + resolution: {integrity: sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==} + + extension-port-stream@3.0.0: + resolution: {integrity: sha512-an2S5quJMiy5bnZKEf6AkfH/7r8CzHvhchU40gxN+OM6HPhe7Z9T1FUychcf2M9PpPOO0Hf7BAEfJkw2TDIBDw==} + engines: {node: '>=12.0.0'} + + external-editor@3.1.0: + resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} + engines: {node: '>=4'} + + externality@1.0.2: + resolution: {integrity: sha512-LyExtJWKxtgVzmgtEHyQtLFpw1KFhQphF9nTG8TpAIVkiI/xQ3FJh75tRFLYl4hkn7BNIIdLJInuDAavX35pMw==} + + extract-zip@2.0.1: + resolution: {integrity: sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==} + engines: {node: '>= 10.17.0'} + hasBin: true + + fast-copy@3.0.2: + resolution: {integrity: sha512-dl0O9Vhju8IrcLndv2eU4ldt1ftXMqqfgN4H1cpmGV7P6jeB9FwpN9a2c8DPGE1Ys88rNUJVYDHq73CGAGOPfQ==} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-fifo@1.3.2: + resolution: {integrity: sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==} + + fast-glob@3.3.2: + resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} + engines: {node: '>=8.6.0'} + + fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} + engines: {node: '>=8.6.0'} + + fast-npm-meta@0.4.3: + resolution: {integrity: sha512-eUzR/uVx61fqlHBjG/eQx5mQs7SQObehMTTdq8FAkdCB4KuZSQ6DiZMIrAq4kcibB3WFLQ9c4dT26Vwkix1RKg==} + + fast-redact@3.1.2: + resolution: {integrity: sha512-+0em+Iya9fKGfEQGcd62Yv6onjBmmhV1uh86XVfOU8VwAe6kaFdQCWI9s0/Nnugx5Vd9tdbZ7e6gE2tR9dzXdw==} + engines: {node: '>=6'} + + fast-safe-stringify@2.1.1: + resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==} + + fastq@1.15.0: + resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==} + + fd-slicer@1.1.0: + resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==} + + fdir@6.1.1: + resolution: {integrity: sha512-QfKBVg453Dyn3mr0Q0O+Tkr1r79lOTAKSi9f/Ot4+qVEwxWhav2Z+SudrG9vQjM2aYRMQQZ2/Q1zdA8ACM1pDg==} + peerDependencies: + picomatch: 3.x + peerDependenciesMeta: + picomatch: + optional: true + + fdir@6.4.4: + resolution: {integrity: sha512-1NZP+GK4GfuAv3PqKvxQRDMjdSRZjnkq7KfhlNrCNNlZ0ygQFpebfrnfnq/W7fpUnAv9aGWmY1zKx7FYL3gwhg==} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + fecha@4.2.3: + resolution: {integrity: sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==} + + fetch-blob@3.2.0: + resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} + engines: {node: ^12.20 || >= 14.13} + + fflate@0.8.2: + resolution: {integrity: sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==} + + figures@6.1.0: + resolution: {integrity: sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==} + engines: {node: '>=18'} + + file-uri-to-path@1.0.0: + resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} + + fill-range@7.0.1: + resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} + engines: {node: '>=8'} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + filter-obj@1.1.0: + resolution: {integrity: sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ==} + engines: {node: '>=0.10.0'} + + filter-obj@5.1.0: + resolution: {integrity: sha512-qWeTREPoT7I0bifpPUXtxkZJ1XJzxWtfoWWkdVGqa+eCr3SHW/Ocp89o8vLvbUuQnadybJpjOKu4V+RwO6sGng==} + engines: {node: '>=14.16'} + + find-up-simple@1.0.1: + resolution: {integrity: sha512-afd4O7zpqHeRyg4PfDQsXmlDe2PfdHtJt6Akt8jOWaApLOZk5JXs6VMR29lz03pRe9mpykrRCYIYxaJYcfpncQ==} + engines: {node: '>=18'} + + find-up@2.1.0: + resolution: {integrity: sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==} + engines: {node: '>=4'} + + find-up@4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} + + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + + find-up@6.3.0: + resolution: {integrity: sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + find-up@7.0.0: + resolution: {integrity: sha512-YyZM99iHrqLKjmt4LJDj58KI+fYyufRLBSYcqycxf//KpBk9FoewoGX0450m9nB44qrZnovzC2oeP5hUibxc/g==} + engines: {node: '>=18'} + + fixturez@1.1.0: + resolution: {integrity: sha512-c4q9eZsAmCzj9gkrEO/YwIRlrHWt/TXQiX9jR9WeLFOqeeV6EyzdiiV28CpSzF6Ip+gyYrSv5UeOHqyzfcNTVA==} + + flat@5.0.2: + resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} + hasBin: true + + floating-vue@5.2.2: + resolution: {integrity: sha512-afW+h2CFafo+7Y9Lvw/xsqjaQlKLdJV7h1fCHfcYQ1C4SVMlu7OAekqWgu5d4SgvkBVU0pVpLlVsrSTBURFRkg==} + peerDependencies: + '@nuxt/kit': ^3.2.0 + vue: ^3.2.0 + peerDependenciesMeta: + '@nuxt/kit': + optional: true + + fn.name@1.1.0: + resolution: {integrity: sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==} + + focus-trap@7.6.0: + resolution: {integrity: sha512-1td0l3pMkWJLFipobUcGaf+5DTY4PLDDrcqoSaKP8ediO/CoWCCYk/fT/Y2A4e6TNB+Sh6clRJCjOPPnKoNHnQ==} + + follow-redirects@1.15.2: + resolution: {integrity: sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + + for-each@0.3.5: + resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} + engines: {node: '>= 0.4'} + + foreground-child@3.1.1: + resolution: {integrity: sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==} + engines: {node: '>=14'} + + formdata-polyfill@4.0.10: + resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} + engines: {node: '>=12.20.0'} + + fp-ts@1.19.3: + resolution: {integrity: sha512-H5KQDspykdHuztLTg+ajGN0Z2qUjcEf3Ybxc6hLt0k7/zPkn29XnKnxlBPyW2XIddWrGaJBzBl4VLYOtk39yZg==} + + fraction.js@4.3.7: + resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==} + + fresh@2.0.0: + resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} + engines: {node: '>= 0.8'} + + fs-constants@1.0.0: + resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} + + fs-extra@0.30.0: + resolution: {integrity: sha512-UvSPKyhMn6LEd/WpUaV9C9t3zATuqoqfWc3QdPhPLb58prN9tqYPlPWi8Krxi44loBoUzlobqZ3+8tGpxxSzwA==} + + fs-extra@5.0.0: + resolution: {integrity: sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ==} + + fs-extra@7.0.1: + resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} + engines: {node: '>=6 <7 || >=8'} + + fs-extra@8.1.0: + resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} + engines: {node: '>=6 <7 || >=8'} + + fs-minipass@2.1.0: + resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} + engines: {node: '>= 8'} + + fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + fuse.js@7.1.0: + resolution: {integrity: sha512-trLf4SzuuUxfusZADLINj+dE8clK1frKdmqiJNb1Es75fmI5oY6X2mxLVUciLLjxqw/xr72Dhy+lER6dGd02FQ==} + engines: {node: '>=10'} + + gauge@3.0.2: + resolution: {integrity: sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==} + engines: {node: '>=10'} + deprecated: This package is no longer supported. + + gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + + get-amd-module-type@5.0.1: + resolution: {integrity: sha512-jb65zDeHyDjFR1loOVk0HQGM5WNwoGB8aLWy3LKCieMKol0/ProHkhO2X1JxojuN10vbz1qNn09MJ7tNp7qMzw==} + engines: {node: '>=14'} + + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + + get-port-please@3.1.2: + resolution: {integrity: sha512-Gxc29eLs1fbn6LQ4jSU4vXjlwyZhF5HsGuMAa7gqBP4Rw4yxxltyDUuF5MBclFzDTXO+ACchGQoeela4DSfzdQ==} + + get-port@7.1.0: + resolution: {integrity: sha512-QB9NKEeDg3xxVwCCwJQ9+xycaz6pBB6iQ76wiWMl1927n0Kir6alPiP+yuiICLLU4jpMe08dXfpebuQppFA2zw==} + engines: {node: '>=16'} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + + get-stream@5.2.0: + resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==} + engines: {node: '>=8'} + + get-stream@6.0.1: + resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} + engines: {node: '>=10'} + + get-stream@8.0.1: + resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} + engines: {node: '>=16'} + + get-stream@9.0.1: + resolution: {integrity: sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==} + engines: {node: '>=18'} + + giget@2.0.0: + resolution: {integrity: sha512-L5bGsVkxJbJgdnwyuheIunkGatUF/zssUoxxjACCseZYAVbaqdh9Tsmmlkl8vYan09H7sbvKt4pS8GqKLBrEzA==} + hasBin: true + + git-up@8.1.1: + resolution: {integrity: sha512-FDenSF3fVqBYSaJoYy1KSc2wosx0gCvKP+c+PRBht7cAaiCeQlBtfBDX9vgnNOHmdePlSFITVcn4pFfcgNvx3g==} + + git-url-parse@16.1.0: + resolution: {integrity: sha512-cPLz4HuK86wClEW7iDdeAKcCVlWXmrLpb2L+G9goW0Z1dtpNS6BXXSOckUTlJT/LDQViE1QZKstNORzHsLnobw==} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob@10.4.5: + resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} + hasBin: true + + glob@7.2.0: + resolution: {integrity: sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==} + deprecated: Glob versions prior to v9 are no longer supported + + glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + deprecated: Glob versions prior to v9 are no longer supported + + glob@8.1.0: + resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==} + engines: {node: '>=12'} + deprecated: Glob versions prior to v9 are no longer supported + + global-directory@4.0.1: + resolution: {integrity: sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==} + engines: {node: '>=18'} + + globals@11.12.0: + resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} + engines: {node: '>=4'} + + globby@11.1.0: + resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} + engines: {node: '>=10'} + + globby@14.1.0: + resolution: {integrity: sha512-0Ia46fDOaT7k4og1PDW4YbodWWr3scS2vAr2lTbsplOt2WkKp0vQbkI9wKis/T5LV/dqPjO3bpS/z6GTJB82LA==} + engines: {node: '>=18'} + + globby@7.1.1: + resolution: {integrity: sha512-yANWAN2DUcBtuus5Cpd+SKROzXHs2iVXFZt/Ykrfz6SAXqacLX25NZpltE+39ceMexYF4TtEadjuSTw8+3wX4g==} + engines: {node: '>=4'} + + gonzales-pe@4.3.0: + resolution: {integrity: sha512-otgSPpUmdWJ43VXyiNgEYE4luzHCL2pz4wQ0OnDluC6Eg4Ko3Vexy/SrSynglw/eR+OhkzmqFCZa/OFa/RgAOQ==} + engines: {node: '>=0.6.0'} + hasBin: true + + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + graphql@16.8.1: + resolution: {integrity: sha512-59LZHPdGZVh695Ud9lRzPBVTtlX9ZCV150Er2W43ro37wVof0ctenSaskPPjN7lVTIN8mSZt8PHUNKZuNQUuxw==} + engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0} + + gzip-size@6.0.0: + resolution: {integrity: sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==} + engines: {node: '>=10'} + + gzip-size@7.0.0: + resolution: {integrity: sha512-O1Ld7Dr+nqPnmGpdhzLmMTQ4vAsD+rHwMm1NLUmoUFFymBOMKxCCrtDxqdBRYXdeEPEi3SyoR4TizJLQrnKBNA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + h3@1.15.3: + resolution: {integrity: sha512-z6GknHqyX0h9aQaTx22VZDf6QyZn+0Nh+Ym8O/u0SGSkyF5cuTJYKlc8MkzW3Nzf9LE1ivcpmYC3FUGpywhuUQ==} + + happy-dom@15.10.2: + resolution: {integrity: sha512-NbA5XrSovenJIIcfixCREX3ZnV7yHP4phhbfuxxf4CPn+LZpz/jIM9EqJ2DrPwgVDSMoAKH3pZwQvkbsSiCrUw==} + engines: {node: '>=18.0.0'} + + hardhat@2.22.3: + resolution: {integrity: sha512-k8JV2ECWNchD6ahkg2BR5wKVxY0OiKot7fuxiIpRK0frRqyOljcR2vKwgWSLw6YIeDcNNA4xybj7Og7NSxr2hA==} + hasBin: true + peerDependencies: + ts-node: '*' + typescript: '*' + peerDependenciesMeta: + ts-node: + optional: true + typescript: + optional: true + + has-flag@3.0.0: + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} + engines: {node: '>=4'} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + + has-unicode@2.0.1: + resolution: {integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==} + + hash-base@3.1.0: + resolution: {integrity: sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==} + engines: {node: '>=4'} + + hash.js@1.1.7: + resolution: {integrity: sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + hast-util-to-html@9.0.3: + resolution: {integrity: sha512-M17uBDzMJ9RPCqLMO92gNNUDuBSq10a25SDBI08iCCxmorf4Yy6sYHK57n9WAbRAAaU+DuR4W6GN9K4DFZesYg==} + + hast-util-whitespace@3.0.0: + resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} + + he@1.2.0: + resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} + hasBin: true + + headers-polyfill@4.0.2: + resolution: {integrity: sha512-EWGTfnTqAO2L/j5HZgoM/3z82L7necsJ0pO9Tp0X1wil3PDLrkypTBRgVO2ExehEEvUycejZD3FuRaXpZZc3kw==} + + help-me@5.0.0: + resolution: {integrity: sha512-7xgomUX6ADmcYzFik0HzAxh/73YlKR9bmFzf51CZwR+b6YtzU2m0u49hQCqV6SvlqIqsaxovfwdvbnsw3b/zpg==} + + highlight.js@10.7.3: + resolution: {integrity: sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==} + + hmac-drbg@1.0.1: + resolution: {integrity: sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==} + + hookable@5.5.3: + resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==} + + hosted-git-info@7.0.2: + resolution: {integrity: sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==} + engines: {node: ^16.14.0 || >=18.0.0} + + html-escaper@2.0.2: + resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + + html-void-elements@3.0.0: + resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} + + http-errors@2.0.0: + resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} + engines: {node: '>= 0.8'} + + http-proxy@1.18.1: + resolution: {integrity: sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==} + engines: {node: '>=8.0.0'} + + http-shutdown@1.2.2: + resolution: {integrity: sha512-S9wWkJ/VSY9/k4qcjG318bqJNruzE4HySUhFYknwmu6LBP97KLLfwNf+n4V1BHurvFNkSKLFnK/RsuUnRTf9Vw==} + engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} + + https-proxy-agent@5.0.1: + resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} + engines: {node: '>= 6'} + + https-proxy-agent@7.0.6: + resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} + engines: {node: '>= 14'} + + httpxy@0.1.7: + resolution: {integrity: sha512-pXNx8gnANKAndgga5ahefxc++tJvNL87CXoRwxn1cJE2ZkWEojF3tNfQIEhZX/vfpt+wzeAzpUI4qkediX1MLQ==} + + human-id@1.0.2: + resolution: {integrity: sha512-UNopramDEhHJD+VR+ehk8rOslwSfByxPIZyJRfV739NDhN5LF1fa1MqnzKm2lGTQRjNrjK19Q5fhkgIfjlVUKw==} + + human-signals@2.1.0: + resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} + engines: {node: '>=10.17.0'} + + human-signals@4.3.1: + resolution: {integrity: sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==} + engines: {node: '>=14.18.0'} + + human-signals@5.0.0: + resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} + engines: {node: '>=16.17.0'} + + human-signals@7.0.0: + resolution: {integrity: sha512-74kytxOUSvNbjrT9KisAbaTZ/eJwD/LrbM/kh5j0IhPuJzwuA19dWvniFGwBzN9rVjg+O/e+F310PjObDXS+9Q==} + engines: {node: '>=18.18.0'} + + iconv-lite@0.4.24: + resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} + engines: {node: '>=0.10.0'} + + iconv-lite@0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} + engines: {node: '>=0.10.0'} + + idb-keyval@6.2.1: + resolution: {integrity: sha512-8Sb3veuYCyrZL+VBt9LJfZjLUPWVvqn8tG28VqYNFCo43KHcKuq+b4EiXGeuaLAQWL2YmyDgMp2aSpH9JHsEQg==} + + ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + + ignore@3.3.10: + resolution: {integrity: sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==} + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + ignore@7.0.4: + resolution: {integrity: sha512-gJzzk+PQNznz8ysRrC0aOkBNVRBDtE1n53IqyqEf3PXrYwomFs5q4pGMizBMJF+ykh03insJ27hB8gSrD2Hn8A==} + engines: {node: '>= 4'} + + image-meta@0.2.1: + resolution: {integrity: sha512-K6acvFaelNxx8wc2VjbIzXKDVB0Khs0QT35U6NkGfTdCmjLNcO2945m7RFNR9/RPVFm48hq7QPzK8uGH18HCGw==} + + immutable@4.3.5: + resolution: {integrity: sha512-8eabxkth9gZatlwl5TBuJnCsoTADlL6ftEr7A4qgdaTsPyreilDSnUk57SO+jfKcNtxPa22U5KK6DSeAYhpBJw==} + + impound@0.2.2: + resolution: {integrity: sha512-9CNg+Ly8QjH4FwCUoE9nl1zeqY1NPK1s1P6Btp4L8lJxn8oZLN/0p6RZhitnyEL0BnVWrcVPfbs0Q3x+O/ucHg==} + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + indent-string@4.0.0: + resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} + engines: {node: '>=8'} + + index-to-position@1.1.0: + resolution: {integrity: sha512-XPdx9Dq4t9Qk1mTMbWONJqU7boCoumEH7fRET37HX5+khDUl3J2W6PdALxhILYlIYx2amlwYcRPp28p0tSiojg==} + engines: {node: '>=18'} + + inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + ini@1.3.8: + resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + + ini@4.1.1: + resolution: {integrity: sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + io-ts@1.10.4: + resolution: {integrity: sha512-b23PteSnYXSONJ6JQXRAlvJhuw8KOtkqa87W4wDtvMrud/DTJd5X+NpOOI+O/zZwVq6v0VLAaJ+1EDViKEuN9g==} + + ioredis@5.6.1: + resolution: {integrity: sha512-UxC0Yv1Y4WRJiGQxQkP0hfdL0/5/6YvdfOOClRgJ0qppSarkhneSa6UvkMkms0AkdGimSH3Ikqm+6mkMmX7vGA==} + engines: {node: '>=12.22.0'} + + iron-webcrypto@1.2.1: + resolution: {integrity: sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==} + + is-arguments@1.2.0: + resolution: {integrity: sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==} + engines: {node: '>= 0.4'} + + is-arrayish@0.3.2: + resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} + + is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + + is-builtin-module@3.2.1: + resolution: {integrity: sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==} + engines: {node: '>=6'} + + is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + + is-core-module@2.16.1: + resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} + engines: {node: '>= 0.4'} + + is-docker@2.2.1: + resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} + engines: {node: '>=8'} + hasBin: true + + is-docker@3.0.0: + resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + hasBin: true + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-generator-function@1.1.0: + resolution: {integrity: sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==} + engines: {node: '>= 0.4'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-hex-prefixed@1.0.0: + resolution: {integrity: sha512-WvtOiug1VFrE9v1Cydwm+FnXd3+w9GaeVUss5W4v/SLy3UW00vP+6iNF2SdnfiBoLy4bTqVdkftNGTUeOFVsbA==} + engines: {node: '>=6.5.0', npm: '>=3'} + + is-inside-container@1.0.0: + resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} + engines: {node: '>=14.16'} + hasBin: true + + is-installed-globally@1.0.0: + resolution: {integrity: sha512-K55T22lfpQ63N4KEN57jZUAaAYqYHEe8veb/TycJRk9DdSCLLcovXz/mL6mOnhQaZsQGwPhuFopdQIlqGSEjiQ==} + engines: {node: '>=18'} + + is-module@1.0.0: + resolution: {integrity: sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==} + + is-node-process@1.2.0: + resolution: {integrity: sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw==} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-path-inside@4.0.0: + resolution: {integrity: sha512-lJJV/5dYS+RcL8uQdBDW9c9uWFLLBNRyFhnAKXw5tVqLlKZ4RMGZKv+YQ/IA3OhD+RpbJa1LLFM1FQPGyIXvOA==} + engines: {node: '>=12'} + + is-plain-obj@2.1.0: + resolution: {integrity: sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==} + engines: {node: '>=8'} + + is-plain-obj@4.1.0: + resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} + engines: {node: '>=12'} + + is-plain-object@5.0.0: + resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==} + engines: {node: '>=0.10.0'} + + is-reference@1.2.1: + resolution: {integrity: sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==} + + is-regex@1.2.1: + resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} + engines: {node: '>= 0.4'} + + is-ssh@1.4.1: + resolution: {integrity: sha512-JNeu1wQsHjyHgn9NcWTaXq6zWSR6hqE0++zhfZlkFBbScNkyvxCdeV8sRkSBaeLKxmbpR21brail63ACNxJ0Tg==} + + is-stream@2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + + is-stream@3.0.0: + resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + is-stream@4.0.1: + resolution: {integrity: sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==} + engines: {node: '>=18'} + + is-subdir@1.2.0: + resolution: {integrity: sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==} + engines: {node: '>=4'} + + is-typed-array@1.1.15: + resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} + engines: {node: '>= 0.4'} + + is-unicode-supported@0.1.0: + resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} + engines: {node: '>=10'} + + is-unicode-supported@2.0.0: + resolution: {integrity: sha512-FRdAyx5lusK1iHG0TWpVtk9+1i+GjrzRffhDg4ovQ7mcidMQ6mj+MhKPmvh7Xwyv5gIS06ns49CA7Sqg7lC22Q==} + engines: {node: '>=18'} + + is-url-superb@4.0.0: + resolution: {integrity: sha512-GI+WjezhPPcbM+tqE9LnmsY5qqjwHzTvjJ36wxYX5ujNXefSUJ/T17r5bqDV8yLhcgB59KTPNOc9O9cmHTPWsA==} + engines: {node: '>=10'} + + is-url@1.2.4: + resolution: {integrity: sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==} + + is-what@4.1.16: + resolution: {integrity: sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==} + engines: {node: '>=12.13'} + + is-windows@1.0.2: + resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} + engines: {node: '>=0.10.0'} + + is-wsl@2.2.0: + resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} + engines: {node: '>=8'} + + is-wsl@3.1.0: + resolution: {integrity: sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==} + engines: {node: '>=16'} + + is64bit@2.0.0: + resolution: {integrity: sha512-jv+8jaWCl0g2lSBkNSVXdzfBA0npK1HGC2KtWM9FumFRoGS94g3NbCCLVnCYHLjp4GrW2KZeeSTMo5ddtznmGw==} + engines: {node: '>=18'} + + isarray@1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + isexe@3.1.1: + resolution: {integrity: sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==} + engines: {node: '>=16'} + + isows@1.0.4: + resolution: {integrity: sha512-hEzjY+x9u9hPmBom9IIAqdJCwNLax+xrPb51vEPpERoFlIxgmZcHzsT5jKG06nvInKOBGvReAVz80Umed5CczQ==} + peerDependencies: + ws: '*' + + isows@1.0.6: + resolution: {integrity: sha512-lPHCayd40oW98/I0uvgaHKWCSvkzY27LjWLbtzOm64yQ+G3Q5npjjbdppU65iZXkK1Zt+kH9pfegli0AYfwYYw==} + peerDependencies: + ws: '*' + + istanbul-lib-coverage@3.2.2: + resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} + engines: {node: '>=8'} + + istanbul-lib-report@3.0.1: + resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} + engines: {node: '>=10'} + + istanbul-lib-source-maps@5.0.6: + resolution: {integrity: sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==} + engines: {node: '>=10'} + + istanbul-reports@3.1.7: + resolution: {integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==} + engines: {node: '>=8'} + + jackspeak@3.4.3: + resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + + jiti@1.21.0: + resolution: {integrity: sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==} + hasBin: true + + jiti@1.21.6: + resolution: {integrity: sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==} + hasBin: true + + jiti@1.21.7: + resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==} + hasBin: true + + jiti@2.4.2: + resolution: {integrity: sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==} + hasBin: true + + joycon@3.1.1: + resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} + engines: {node: '>=10'} + + js-beautify@1.15.1: + resolution: {integrity: sha512-ESjNzSlt/sWE8sciZH8kBF8BPlwXPwhR6pWKAw8bw4Bwj+iZcnKW6ONWUutJ7eObuBZQpiIb8S7OYspWrKt7rA==} + engines: {node: '>=14'} + hasBin: true + + js-cookie@3.0.5: + resolution: {integrity: sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==} + engines: {node: '>=14'} + + js-sha3@0.8.0: + resolution: {integrity: sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==} + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-tokens@9.0.1: + resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==} + + js-yaml@3.14.1: + resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} + hasBin: true + + js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + + jsesc@2.5.2: + resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} + engines: {node: '>=4'} + hasBin: true + + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} + hasBin: true + + json-rpc-engine@6.1.0: + resolution: {integrity: sha512-NEdLrtrq1jUZyfjkr9OCz9EzCNhnRyWtt1PAnvnhwy6e8XETS0Dtc+ZNCO2gvuAoKsIn2+vCSowXTYE4CkgnAQ==} + engines: {node: '>=10.0.0'} + + json-rpc-random-id@1.0.1: + resolution: {integrity: sha512-RJ9YYNCkhVDBuP4zN5BBtYAzEl03yq/jIIsyif0JY9qyJuQQZNeDK7anAPKKlyEtLSj2s8h6hNh2F8zO5q7ScA==} + + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + + jsonfile@2.4.0: + resolution: {integrity: sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw==} + + jsonfile@4.0.0: + resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} + + junk@4.0.1: + resolution: {integrity: sha512-Qush0uP+G8ZScpGMZvHUiRfI0YBWuB3gVBYlI0v0vvOJt5FLicco+IkP0a50LqTTQhmts/m6tP5SWE+USyIvcQ==} + engines: {node: '>=12.20'} + + jwt-decode@4.0.0: + resolution: {integrity: sha512-+KJGIyHgkGuIq3IEBNftfhW/LfWhXUIY6OmyVWjliu5KH1y0fw7VQ8YndE2O4qZdMSd9SqbnC8GOcZEy0Om7sA==} + engines: {node: '>=18'} + + keccak@3.0.3: + resolution: {integrity: sha512-JZrLIAJWuZxKbCilMpNz5Vj7Vtb4scDG3dMXLOsbzBmQGyjwE61BbW7bJkfKKCShXiQZt3T6sBgALRtmd+nZaQ==} + engines: {node: '>=10.0.0'} + + keyvaluestorage-interface@1.0.0: + resolution: {integrity: sha512-8t6Q3TclQ4uZynJY9IGr2+SsIGwK9JHcO6ootkHCGA0CrQCRy+VkouYNO2xicET6b9al7QKzpebNow+gkpCL8g==} + + klaw@1.3.1: + resolution: {integrity: sha512-TED5xi9gGQjGpNnvRWknrwAB1eL5GciPfVFOt3Vk1OJCVDQbzuSfrF3hkUQKlsgKrG1F+0t5W0m+Fje1jIt8rw==} + + kleur@3.0.3: + resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} + engines: {node: '>=6'} + + kleur@4.1.5: + resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} + engines: {node: '>=6'} + + klona@2.0.6: + resolution: {integrity: sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==} + engines: {node: '>= 8'} + + knip@5.30.6: + resolution: {integrity: sha512-YkcnRVl0N99xZ7eaXE7KlH/4cPTCn6BGuk9KxINEdCMFN3yita2vGBizApy97ZOHgghy8tb589gQ3xvLMFIO4w==} + engines: {node: '>=18.6.0'} + hasBin: true + peerDependencies: + '@types/node': '>=18' + typescript: '>=5.0.4' + + knitwork@1.2.0: + resolution: {integrity: sha512-xYSH7AvuQ6nXkq42x0v5S8/Iry+cfulBz/DJQzhIyESdLD7425jXsPy4vn5cCXU+HhRN2kVw51Vd1K6/By4BQg==} + + kolorist@1.8.0: + resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==} + + kuler@2.0.0: + resolution: {integrity: sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==} + + lambda-local@2.2.0: + resolution: {integrity: sha512-bPcgpIXbHnVGfI/omZIlgucDqlf4LrsunwoKue5JdZeGybt8L6KyJz2Zu19ffuZwIwLj2NAI2ZyaqNT6/cetcg==} + engines: {node: '>=8'} + hasBin: true + + launch-editor@2.10.0: + resolution: {integrity: sha512-D7dBRJo/qcGX9xlvt/6wUYzQxjh5G1RvZPgPv8vi4KRU99DVQL/oW7tnVOCCTm2HGeo3C5HvGE5Yrh6UBoZ0vA==} + + lazystream@1.0.1: + resolution: {integrity: sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==} + engines: {node: '>= 0.6.3'} + + lilconfig@3.1.3: + resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} + engines: {node: '>=14'} + + listhen@1.7.2: + resolution: {integrity: sha512-7/HamOm5YD9Wb7CFgAZkKgVPA96WwhcTQoqtm2VTZGVbVVn3IWKRBTgrU7cchA3Q8k9iCsG8Osoi9GX4JsGM9g==} + hasBin: true + + listhen@1.9.0: + resolution: {integrity: sha512-I8oW2+QL5KJo8zXNWX046M134WchxsXC7SawLPvRQpogCbkyQIaFxPE89A2HiwR7vAK2Dm2ERBAmyjTYGYEpBg==} + hasBin: true + + lit-element@4.2.0: + resolution: {integrity: sha512-MGrXJVAI5x+Bfth/pU9Kst1iWID6GHDLEzFEnyULB/sFiRLgkd8NPK/PeeXxktA3T6EIIaq8U3KcbTU5XFcP2Q==} + + lit-html@3.3.0: + resolution: {integrity: sha512-RHoswrFAxY2d8Cf2mm4OZ1DgzCoBKUKSPvA1fhtSELxUERq2aQQ2h05pO9j81gS1o7RIRJ+CePLogfyahwmynw==} + + lit@3.1.0: + resolution: {integrity: sha512-rzo/hmUqX8zmOdamDAeydfjsGXbbdtAFqMhmocnh2j9aDYqbu0fjXygjCa0T99Od9VQ/2itwaGrjZz/ZELVl7w==} + + load-tsconfig@0.2.5: + resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + local-pkg@0.5.0: + resolution: {integrity: sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==} + engines: {node: '>=14'} + + local-pkg@0.5.1: + resolution: {integrity: sha512-9rrA30MRRP3gBD3HTGnC6cDFpaE1kVDWxWgqWJUN0RvDNAo+Nz/9GxB+nHOH0ifbVFy0hSA1V6vFDvnx54lTEQ==} + engines: {node: '>=14'} + + local-pkg@1.1.1: + resolution: {integrity: sha512-WunYko2W1NcdfAFpuLUoucsgULmgDBRkdxHxWQ7mK0cQqwPiy8E1enjuRBrhLtZkB5iScJ1XIPdhVEFK8aOLSg==} + engines: {node: '>=14'} + + locate-path@2.0.0: + resolution: {integrity: sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==} + engines: {node: '>=4'} + + locate-path@5.0.0: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + locate-path@7.2.0: + resolution: {integrity: sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + lodash-es@4.17.21: + resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==} + + lodash.debounce@4.0.8: + resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} + + lodash.defaults@4.2.0: + resolution: {integrity: sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==} + + lodash.difference@4.5.0: + resolution: {integrity: sha512-dS2j+W26TQ7taQBGN8Lbbq04ssV3emRw4NY58WErlTO29pIqS0HmoT5aJ9+TUQ1N3G+JOZSji4eugsWwGp9yPA==} + + lodash.flatten@4.4.0: + resolution: {integrity: sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==} + + lodash.isarguments@3.1.0: + resolution: {integrity: sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==} + + lodash.isplainobject@4.0.6: + resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==} + + lodash.memoize@4.1.2: + resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==} + + lodash.startcase@4.4.0: + resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==} + + lodash.union@4.6.0: + resolution: {integrity: sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw==} + + lodash.uniq@4.5.0: + resolution: {integrity: sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==} + + lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + + log-symbols@4.1.0: + resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} + engines: {node: '>=10'} + + logform@2.7.0: + resolution: {integrity: sha512-TFYA4jnP7PVbmlBIfhlSe+WKxs9dklXMTEGcBCIvLhE/Tn3H6Gk1norupVW7m5Cnd4bLcr08AytbyV/xj7f/kQ==} + engines: {node: '>= 12.0.0'} + + lokijs@1.5.12: + resolution: {integrity: sha512-Q5ALD6JiS6xAUWCwX3taQmgwxyveCtIIuL08+ml0nHwT3k0S/GIFJN+Hd38b1qYIMaE5X++iqsqWVksz7SYW+Q==} + + longest-streak@3.1.0: + resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} + + loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + + loupe@3.1.3: + resolution: {integrity: sha512-kkIp7XSkP78ZxJEsSxW3712C6teJVoeHHwgo9zJ380de7IYyJ2ISlxojcH2pC5OFLewESmnRi/+XCDIEEVyoug==} + + lru-cache@10.2.2: + resolution: {integrity: sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==} + engines: {node: 14 || >=16.14} + + lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + + lru-cache@4.1.5: + resolution: {integrity: sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==} + + lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + + lru-cache@6.0.0: + resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} + engines: {node: '>=10'} + + lru_map@0.3.3: + resolution: {integrity: sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ==} + + luxon@3.6.1: + resolution: {integrity: sha512-tJLxrKJhO2ukZ5z0gyjY1zPh3Rh88Ej9P7jNrZiHMUXHae1yvI2imgOZtL1TO8TW6biMMKfTtAOoEJANgtWBMQ==} + engines: {node: '>=12'} + + lz-string@1.5.0: + resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} + hasBin: true + + magic-string-ast@0.7.1: + resolution: {integrity: sha512-ub9iytsEbT7Yw/Pd29mSo/cNQpaEu67zR1VVcXDiYjSFwzeBxNdTd0FMnSslLQXiRj8uGPzwsaoefrMD5XAmdw==} + engines: {node: '>=16.14.0'} + + magic-string@0.30.10: + resolution: {integrity: sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==} + + magic-string@0.30.11: + resolution: {integrity: sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==} + + magic-string@0.30.12: + resolution: {integrity: sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw==} + + magic-string@0.30.17: + resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} + + magicast@0.3.4: + resolution: {integrity: sha512-TyDF/Pn36bBji9rWKHlZe+PZb6Mx5V8IHCSxk7X4aljM4e/vyDvZZYwHewdVaqiA0nb3ghfHU/6AUpDxWoER2Q==} + + magicast@0.3.5: + resolution: {integrity: sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==} + + make-dir@3.1.0: + resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} + engines: {node: '>=8'} + + make-dir@4.0.0: + resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} + engines: {node: '>=10'} + + mark.js@8.11.1: + resolution: {integrity: sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ==} + + markdown-table@3.0.3: + resolution: {integrity: sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==} + + marked-terminal@7.1.0: + resolution: {integrity: sha512-+pvwa14KZL74MVXjYdPR3nSInhGhNvPce/3mqLVZT2oUvt654sL1XImFuLZ1pkA866IYZ3ikDTOFUIC7XzpZZg==} + engines: {node: '>=16.0.0'} + peerDependencies: + marked: '>=1 <14' + + marked@9.1.6: + resolution: {integrity: sha512-jcByLnIFkd5gSXZmjNvS1TlmRhCXZjIzHYlaGkPlLIekG55JDR2Z4va9tZwCiP+/RDERiNhMOFu01xd6O5ct1Q==} + engines: {node: '>= 16'} + hasBin: true + + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + md5.js@1.3.5: + resolution: {integrity: sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==} + + mdast-util-find-and-replace@3.0.1: + resolution: {integrity: sha512-SG21kZHGC3XRTSUhtofZkBzZTJNM5ecCi0SK2IMKmSXR8vO3peL+kb1O0z7Zl83jKtutG4k5Wv/W7V3/YHvzPA==} + + mdast-util-from-markdown@2.0.2: + resolution: {integrity: sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==} + + mdast-util-gfm-autolink-literal@2.0.0: + resolution: {integrity: sha512-FyzMsduZZHSc3i0Px3PQcBT4WJY/X/RCtEJKuybiC6sjPqLv7h1yqAkmILZtuxMSsUyaLUWNp71+vQH2zqp5cg==} + + mdast-util-gfm-footnote@2.0.0: + resolution: {integrity: sha512-5jOT2boTSVkMnQ7LTrd6n/18kqwjmuYqo7JUPe+tRCY6O7dAuTFMtTPauYYrMPpox9hlN0uOx/FL8XvEfG9/mQ==} + + mdast-util-gfm-strikethrough@2.0.0: + resolution: {integrity: sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==} + + mdast-util-gfm-table@2.0.0: + resolution: {integrity: sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==} + + mdast-util-gfm-task-list-item@2.0.0: + resolution: {integrity: sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==} + + mdast-util-gfm@3.0.0: + resolution: {integrity: sha512-dgQEX5Amaq+DuUqf26jJqSK9qgixgd6rYDHAv4aTBuA92cTknZlKpPfa86Z/s8Dj8xsAQpFfBmPUHWJBWqS4Bw==} + + mdast-util-phrasing@4.1.0: + resolution: {integrity: sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==} + + mdast-util-to-hast@13.1.0: + resolution: {integrity: sha512-/e2l/6+OdGp/FB+ctrJ9Avz71AN/GRH3oi/3KAx/kMnoUsD6q0woXlDT8lLEeViVKE7oZxE7RXzvO3T8kF2/sA==} + + mdast-util-to-hast@13.2.0: + resolution: {integrity: sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==} + + mdast-util-to-markdown@2.1.0: + resolution: {integrity: sha512-SR2VnIEdVNCJbP6y7kVTJgPLifdr8WEU440fQec7qHoHOUz/oJ2jmNRqdDQ3rbiStOXb2mCDGTuwsK5OPUgYlQ==} + + mdast-util-to-string@4.0.0: + resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==} + + mdn-data@2.0.28: + resolution: {integrity: sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==} + + mdn-data@2.0.30: + resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==} + + memorystream@0.3.1: + resolution: {integrity: sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==} + engines: {node: '>= 0.10.0'} + + merge-options@3.0.4: + resolution: {integrity: sha512-2Sug1+knBjkaMsMgf1ctR1Ujx+Ayku4EdJN4Z+C2+JzoeF7A3OZ9KM2GY0CpQS51NR61LTurMJrRKPhSs3ZRTQ==} + engines: {node: '>=10'} + + merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + micro-api-client@3.3.0: + resolution: {integrity: sha512-y0y6CUB9RLVsy3kfgayU28746QrNMpSm9O/AYGNsBgOkJr/X/Jk0VLGoO8Ude7Bpa8adywzF+MzXNZRFRsNPhg==} + + micro-ftch@0.3.1: + resolution: {integrity: sha512-/0LLxhzP0tfiR5hcQebtudP56gUurs2CLkGarnCiB/OqEyUFQ6U3paQi/tgLv0hBJYt2rnr9MNpxz4fiiugstg==} + + micromark-core-commonmark@2.0.1: + resolution: {integrity: sha512-CUQyKr1e///ZODyD1U3xit6zXwy1a8q2a1S1HKtIlmgvurrEpaw/Y9y6KSIbF8P59cn/NjzHyO+Q2fAyYLQrAA==} + + micromark-factory-destination@2.0.0: + resolution: {integrity: sha512-j9DGrQLm/Uhl2tCzcbLhy5kXsgkHUrjJHg4fFAeoMRwJmJerT9aw4FEhIbZStWN8A3qMwOp1uzHr4UL8AInxtA==} + + micromark-factory-label@2.0.0: + resolution: {integrity: sha512-RR3i96ohZGde//4WSe/dJsxOX6vxIg9TimLAS3i4EhBAFx8Sm5SmqVfR8E87DPSR31nEAjZfbt91OMZWcNgdZw==} + + micromark-factory-space@2.0.0: + resolution: {integrity: sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==} + + micromark-factory-title@2.0.0: + resolution: {integrity: sha512-jY8CSxmpWLOxS+t8W+FG3Xigc0RDQA9bKMY/EwILvsesiRniiVMejYTE4wumNc2f4UbAa4WsHqe3J1QS1sli+A==} + + micromark-factory-whitespace@2.0.0: + resolution: {integrity: sha512-28kbwaBjc5yAI1XadbdPYHX/eDnqaUFVikLwrO7FDnKG7lpgxnvk/XGRhX/PN0mOZ+dBSZ+LgunHS+6tYQAzhA==} + + micromark-util-character@2.1.0: + resolution: {integrity: sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==} + + micromark-util-chunked@2.0.0: + resolution: {integrity: sha512-anK8SWmNphkXdaKgz5hJvGa7l00qmcaUQoMYsBwDlSKFKjc6gjGXPDw3FNL3Nbwq5L8gE+RCbGqTw49FK5Qyvg==} + + micromark-util-classify-character@2.0.0: + resolution: {integrity: sha512-S0ze2R9GH+fu41FA7pbSqNWObo/kzwf8rN/+IGlW/4tC6oACOs8B++bh+i9bVyNnwCcuksbFwsBme5OCKXCwIw==} + + micromark-util-combine-extensions@2.0.0: + resolution: {integrity: sha512-vZZio48k7ON0fVS3CUgFatWHoKbbLTK/rT7pzpJ4Bjp5JjkZeasRfrS9wsBdDJK2cJLHMckXZdzPSSr1B8a4oQ==} + + micromark-util-decode-numeric-character-reference@2.0.1: + resolution: {integrity: sha512-bmkNc7z8Wn6kgjZmVHOX3SowGmVdhYS7yBpMnuMnPzDq/6xwVA604DuOXMZTO1lvq01g+Adfa0pE2UKGlxL1XQ==} + + micromark-util-decode-string@2.0.0: + resolution: {integrity: sha512-r4Sc6leeUTn3P6gk20aFMj2ntPwn6qpDZqWvYmAG6NgvFTIlj4WtrAudLi65qYoaGdXYViXYw2pkmn7QnIFasA==} + + micromark-util-encode@2.0.0: + resolution: {integrity: sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==} + + micromark-util-html-tag-name@2.0.0: + resolution: {integrity: sha512-xNn4Pqkj2puRhKdKTm8t1YHC/BAjx6CEwRFXntTaRf/x16aqka6ouVoutm+QdkISTlT7e2zU7U4ZdlDLJd2Mcw==} + + micromark-util-normalize-identifier@2.0.0: + resolution: {integrity: sha512-2xhYT0sfo85FMrUPtHcPo2rrp1lwbDEEzpx7jiH2xXJLqBuy4H0GgXk5ToU8IEwoROtXuL8ND0ttVa4rNqYK3w==} + + micromark-util-resolve-all@2.0.0: + resolution: {integrity: sha512-6KU6qO7DZ7GJkaCgwBNtplXCvGkJToU86ybBAUdavvgsCiG8lSSvYxr9MhwmQ+udpzywHsl4RpGJsYWG1pDOcA==} + + micromark-util-sanitize-uri@2.0.0: + resolution: {integrity: sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==} + + micromark-util-subtokenize@2.0.1: + resolution: {integrity: sha512-jZNtiFl/1aY73yS3UGQkutD0UbhTt68qnRpw2Pifmz5wV9h8gOVsN70v+Lq/f1rKaU/W8pxRe8y8Q9FX1AOe1Q==} + + micromark-util-symbol@2.0.0: + resolution: {integrity: sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==} + + micromark-util-types@2.0.0: + resolution: {integrity: sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==} + + micromark@4.0.0: + resolution: {integrity: sha512-o/sd0nMof8kYff+TqcDx3VSrgBTcZpSvYcAHIfHhv5VAuNmisCxjhx6YmxS8PFEpb9z5WKWKPdzf0jM23ro3RQ==} + + micromatch@4.0.5: + resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} + engines: {node: '>=8.6'} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + + mime-db@1.54.0: + resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} + engines: {node: '>= 0.6'} + + mime-types@3.0.1: + resolution: {integrity: sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==} + engines: {node: '>= 0.6'} + + mime@3.0.0: + resolution: {integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==} + engines: {node: '>=10.0.0'} + hasBin: true + + mime@4.0.7: + resolution: {integrity: sha512-2OfDPL+e03E0LrXaGYOtTFIYhiuzep94NSsuhrNULq+stylcJedcHdzHtz0atMUuGwJfFYs0YL5xeC/Ca2x0eQ==} + engines: {node: '>=16'} + hasBin: true + + mimic-fn@2.1.0: + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + engines: {node: '>=6'} + + mimic-fn@4.0.0: + resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} + engines: {node: '>=12'} + + minimalistic-assert@1.0.1: + resolution: {integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==} + + minimalistic-crypto-utils@1.0.1: + resolution: {integrity: sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==} + + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + + minimatch@5.0.1: + resolution: {integrity: sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==} + engines: {node: '>=10'} + + minimatch@5.1.6: + resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} + engines: {node: '>=10'} + + minimatch@9.0.1: + resolution: {integrity: sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==} + engines: {node: '>=16 || 14 >=14.17'} + + minimatch@9.0.4: + resolution: {integrity: sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==} + engines: {node: '>=16 || 14 >=14.17'} + + minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + engines: {node: '>=16 || 14 >=14.17'} + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + minipass@3.3.6: + resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==} + engines: {node: '>=8'} + + minipass@5.0.0: + resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==} + engines: {node: '>=8'} + + minipass@7.1.2: + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + engines: {node: '>=16 || 14 >=14.17'} + + minisearch@7.1.0: + resolution: {integrity: sha512-tv7c/uefWdEhcu6hvrfTihflgeEi2tN6VV7HJnCjK6VxM75QQJh4t9FwJCsA2EsRS8LCnu3W87CuGPWMocOLCA==} + + minizlib@2.1.2: + resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} + engines: {node: '>= 8'} + + minizlib@3.0.1: + resolution: {integrity: sha512-umcy022ILvb5/3Djuu8LWeqUa8D68JaBzlttKeMWen48SjabqS3iY5w/vzeMzMUNhLDifyhbOwKDSznB1vvrwg==} + engines: {node: '>= 18'} + + minizlib@3.0.2: + resolution: {integrity: sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA==} + engines: {node: '>= 18'} + + mipd@0.0.7: + resolution: {integrity: sha512-aAPZPNDQ3uMTdKbuO2YmAw2TxLHO0moa4YKAyETM/DTj5FloZo+a+8tU+iv4GmW+sOxKLSRwcSFuczk+Cpt6fg==} + peerDependencies: + typescript: '>=5.0.4' + peerDependenciesMeta: + typescript: + optional: true + + mitt@3.0.1: + resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==} + + mkdirp@1.0.4: + resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} + engines: {node: '>=10'} + hasBin: true + + mkdirp@3.0.1: + resolution: {integrity: sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==} + engines: {node: '>=10'} + hasBin: true + + mlly@1.7.0: + resolution: {integrity: sha512-U9SDaXGEREBYQgfejV97coK0UL1r+qnF2SyO9A3qcI8MzKnsIFKHNVEkrDyNncQTKQQumsasmeq84eNMdBfsNQ==} + + mlly@1.7.4: + resolution: {integrity: sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==} + + mnemonist@0.38.5: + resolution: {integrity: sha512-bZTFT5rrPKtPJxj8KSV0WkPyNxl72vQepqqVUAW2ARUpUSF2qXMB6jZj7hW5/k7C1rtpzqbD/IIbJwLXUjCHeg==} + + mocha@10.2.0: + resolution: {integrity: sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==} + engines: {node: '>= 14.0.0'} + hasBin: true + + mocked-exports@0.1.1: + resolution: {integrity: sha512-aF7yRQr/Q0O2/4pIXm6PZ5G+jAd7QS4Yu8m+WEeEHGnbo+7mE36CbLSDQiXYV8bVL3NfmdeqPJct0tUlnjVSnA==} + + module-definition@5.0.1: + resolution: {integrity: sha512-kvw3B4G19IXk+BOXnYq/D/VeO9qfHaapMeuS7w7sNUqmGaA6hywdFHMi+VWeR9wUScXM7XjoryTffCZ5B0/8IA==} + engines: {node: '>=14'} + hasBin: true + + mri@1.2.0: + resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} + engines: {node: '>=4'} + + mrmime@2.0.1: + resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==} + engines: {node: '>=10'} + + ms@2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + msw@2.4.9: + resolution: {integrity: sha512-1m8xccT6ipN4PTqLinPwmzhxQREuxaEJYdx4nIbggxP8aM7r1e71vE7RtOUSQoAm1LydjGfZKy7370XD/tsuYg==} + engines: {node: '>=18'} + hasBin: true + peerDependencies: + typescript: '>= 4.8.x' + peerDependenciesMeta: + typescript: + optional: true + + muggle-string@0.4.1: + resolution: {integrity: sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==} + + multiformats@9.9.0: + resolution: {integrity: sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg==} + + mute-stream@1.0.0: + resolution: {integrity: sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + mz@2.7.0: + resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + nanoid@3.3.3: + resolution: {integrity: sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + nanoid@3.3.7: + resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + nanoid@5.1.5: + resolution: {integrity: sha512-Ir/+ZpE9fDsNH0hQ3C68uyThDXzYcim2EqcZ8zn8Chtt1iylPT9xXJB0kPCnqzgcEGikO9RxSrh63MsmVCU7Fw==} + engines: {node: ^18 || >=20} + hasBin: true + + nanospinner@1.2.2: + resolution: {integrity: sha512-Zt/AmG6qRU3e+WnzGGLuMCEAO/dAu45stNbHY223tUxldaDAeE+FxSPsd9Q+j+paejmm0ZbrNVs5Sraqy3dRxA==} + + nanotar@0.2.0: + resolution: {integrity: sha512-9ca1h0Xjvo9bEkE4UOxgAzLV0jHKe6LMaxo37ND2DAhhAtd0j8pR1Wxz+/goMrZO8AEZTWCmyaOsFI/W5AdpCQ==} + + nested-error-stacks@2.1.1: + resolution: {integrity: sha512-9iN1ka/9zmX1ZvLV9ewJYEk9h7RyRRtqdK0woXcqohu8EWIerfPUjYJPg0ULy0UqP7cslmdGc8xKDJcojlKiaw==} + + netlify@13.3.5: + resolution: {integrity: sha512-Nc3loyVASW59W+8fLDZT1lncpG7llffyZ2o0UQLx/Fr20i7P8oP+lE7+TEcFvXj9IUWU6LjB9P3BH+iFGyp+mg==} + engines: {node: ^14.16.0 || >=16.0.0} + + next@15.3.3: + resolution: {integrity: sha512-JqNj29hHNmCLtNvd090SyRbXJiivQ+58XjCcrC50Crb5g5u2zi7Y2YivbsEfzk6AtVI80akdOQbaMZwWB1Hthw==} + engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0} + hasBin: true + peerDependencies: + '@opentelemetry/api': ^1.1.0 + '@playwright/test': ^1.41.2 + babel-plugin-react-compiler: '*' + react: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 + react-dom: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 + sass: ^1.3.0 + peerDependenciesMeta: + '@opentelemetry/api': + optional: true + '@playwright/test': + optional: true + babel-plugin-react-compiler: + optional: true + sass: + optional: true + + nitropack@2.11.12: + resolution: {integrity: sha512-e2AdQrEY1IVoNTdyjfEQV93xkqz4SQxAMR0xWF8mZUUHxMLm6S4nPzpscjksmT4OdUxl0N8/DCaGjKQ9ghdodA==} + engines: {node: ^16.11.0 || >=17.0.0} + hasBin: true + peerDependencies: + xml2js: ^0.6.2 + peerDependenciesMeta: + xml2js: + optional: true + + node-addon-api@2.0.2: + resolution: {integrity: sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==} + + node-addon-api@7.0.0: + resolution: {integrity: sha512-vgbBJTS4m5/KkE16t5Ly0WW9hz46swAstv0hYYwMtbG7AznRhNyfLRe8HZAiWIpcHzoO7HxhLuBQj9rJ/Ho0ZA==} + + node-addon-api@7.1.1: + resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==} + + node-domexception@1.0.0: + resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} + engines: {node: '>=10.5.0'} + deprecated: Use your platform's native DOMException instead + + node-emoji@2.1.3: + resolution: {integrity: sha512-E2WEOVsgs7O16zsURJ/eH8BqhF029wGpEOnv7Urwdo2wmQanOACwJQh0devF9D9RhoZru0+9JXIS0dBXIAz+lA==} + engines: {node: '>=18'} + + node-fetch-native@1.6.4: + resolution: {integrity: sha512-IhOigYzAKHd244OC0JIMIUrjzctirCmPkaIfhDeGcEETWof5zKYUW7e7MYvChGWh/4CJeXEgsRyGzuF334rOOQ==} + + node-fetch-native@1.6.6: + resolution: {integrity: sha512-8Mc2HhqPdlIfedsuZoc3yioPuzp6b+L5jRCRY1QzuWZh2EGJVQrGppC6V6cF0bLdbW0+O2YpqCA25aF/1lvipQ==} + + node-fetch@2.6.7: + resolution: {integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + + node-fetch@2.6.9: + resolution: {integrity: sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + + node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + + node-fetch@3.3.2: + resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + node-forge@1.3.1: + resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==} + engines: {node: '>= 6.13.0'} + + node-gyp-build@4.6.0: + resolution: {integrity: sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==} + hasBin: true + + node-gyp-build@4.8.4: + resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} + hasBin: true + + node-mock-http@1.0.0: + resolution: {integrity: sha512-0uGYQ1WQL1M5kKvGRXWQ3uZCHtLTO8hln3oBjIusM75WoesZ909uQJs/Hb946i2SS+Gsrhkaa6iAO17jRIv6DQ==} + + node-releases@2.0.14: + resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==} + + node-releases@2.0.19: + resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==} + + node-source-walk@6.0.2: + resolution: {integrity: sha512-jn9vOIK/nfqoFCcpK89/VCVaLg1IHE6UVfDOzvqmANaJ/rWCTEdH8RZ1V278nv2jr36BJdyQXIAavBLXpzdlag==} + engines: {node: '>=14'} + + nopt@5.0.0: + resolution: {integrity: sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==} + engines: {node: '>=6'} + hasBin: true + + nopt@7.2.1: + resolution: {integrity: sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + hasBin: true + + nopt@8.1.0: + resolution: {integrity: sha512-ieGu42u/Qsa4TFktmaKEwM6MQH0pOWnaB3htzh0JRtx84+Mebc0cbZYN5bC+6WTZ4+77xrL9Pn5m7CV6VIkV7A==} + engines: {node: ^18.17.0 || >=20.5.0} + hasBin: true + + normalize-package-data@6.0.2: + resolution: {integrity: sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g==} + engines: {node: ^16.14.0 || >=18.0.0} + + normalize-path@2.1.1: + resolution: {integrity: sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==} + engines: {node: '>=0.10.0'} + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + normalize-range@0.1.2: + resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==} + engines: {node: '>=0.10.0'} + + npm-run-path@4.0.1: + resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} + engines: {node: '>=8'} + + npm-run-path@5.3.0: + resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + npm-run-path@6.0.0: + resolution: {integrity: sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==} + engines: {node: '>=18'} + + npmlog@5.0.1: + resolution: {integrity: sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==} + deprecated: This package is no longer supported. + + nth-check@2.1.1: + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + + nuxt@3.16.0: + resolution: {integrity: sha512-4j2tuHo+kcComQ1WrCD+i1w3UFOHrcnNH30cwiEY/WZZlBZOlC6DtUm6aBjhfpBFaMYsF4PbyKsNW+7FHwckHA==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0.0} + hasBin: true + peerDependencies: + '@parcel/watcher': ^2.1.0 + '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 + peerDependenciesMeta: + '@parcel/watcher': + optional: true + '@types/node': + optional: true + + nypm@0.6.0: + resolution: {integrity: sha512-mn8wBFV9G9+UFHIrq+pZ2r2zL4aPau/by3kJb3cM7+5tQHMt6HGQB8FDIeKFYp8o0D2pnH6nVsO88N4AmUxIWg==} + engines: {node: ^14.16.0 || >=16.10.0} + hasBin: true + + obj-multiplex@1.0.0: + resolution: {integrity: sha512-0GNJAOsHoBHeNTvl5Vt6IWnpUEcc3uSRxzBri7EDyIcMgYvnY2JL2qdeV5zTMjWQX5OHcD5amcW2HFfDh0gjIA==} + + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + object-inspect@1.13.4: + resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} + engines: {node: '>= 0.4'} + + obliterator@2.0.4: + resolution: {integrity: sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ==} + + ofetch@1.4.1: + resolution: {integrity: sha512-QZj2DfGplQAr2oj9KzceK9Hwz6Whxazmn85yYeVuS3u9XTMOGMRx0kO95MQ+vLsj/S/NwBDMMLU5hpxvI6Tklw==} + + ohash@2.0.11: + resolution: {integrity: sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==} + + on-change@5.0.1: + resolution: {integrity: sha512-n7THCP7RkyReRSLkJb8kUWoNsxUIBxTkIp3JKno+sEz6o/9AJ3w3P9fzQkITEkMwyTKJjZciF3v/pVoouxZZMg==} + engines: {node: '>=18'} + + on-exit-leak-free@0.2.0: + resolution: {integrity: sha512-dqaz3u44QbRXQooZLTUKU41ZrzYrcvLISVgbrzbyCMxpmSLJvZ3ZamIJIZ29P6OhZIkNIQKosdeM6t1LYbA9hg==} + + on-exit-leak-free@2.1.2: + resolution: {integrity: sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==} + engines: {node: '>=14.0.0'} + + on-finished@2.4.1: + resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} + engines: {node: '>= 0.8'} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + one-time@1.0.0: + resolution: {integrity: sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==} + + onetime@5.1.2: + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} + engines: {node: '>=6'} + + onetime@6.0.0: + resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} + engines: {node: '>=12'} + + oniguruma-to-js@0.4.3: + resolution: {integrity: sha512-X0jWUcAlxORhOqqBREgPMgnshB7ZGYszBNspP+tS9hPD3l13CdaXcHbgImoHUHlrvGx/7AvFEkTRhAGYh+jzjQ==} + + open@10.1.2: + resolution: {integrity: sha512-cxN6aIDPz6rm8hbebcP7vrQNhvRcveZoJU72Y7vskh4oIm+BZwBECnx5nTmrlres1Qapvx27Qo1Auukpf8PKXw==} + engines: {node: '>=18'} + + open@8.4.2: + resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==} + engines: {node: '>=12'} + + opener@1.5.2: + resolution: {integrity: sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==} + hasBin: true + + os-tmpdir@1.0.2: + resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} + engines: {node: '>=0.10.0'} + + outdent@0.5.0: + resolution: {integrity: sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==} + + outvariant@1.4.2: + resolution: {integrity: sha512-Ou3dJ6bA/UJ5GVHxah4LnqDwZRwAmWxrG3wtrHrbGnP4RnLCtA64A4F+ae7Y8ww660JaddSoArUR5HjipWSHAQ==} + + outvariant@1.4.3: + resolution: {integrity: sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA==} + + ox@0.6.7: + resolution: {integrity: sha512-17Gk/eFsFRAZ80p5eKqv89a57uXjd3NgIf1CaXojATPBuujVc/fQSVhBeAU9JCRB+k7J50WQAyWTxK19T9GgbA==} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + ox@0.6.9: + resolution: {integrity: sha512-wi5ShvzE4eOcTwQVsIPdFr+8ycyX+5le/96iAJutaZAvCes1J0+RvpEPg5QDPDiaR0XQQAvZVl7AwqQcINuUug==} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + oxc-parser@0.56.5: + resolution: {integrity: sha512-MNT32sqiTFeSbQZP2WZIRQ/mlIpNNq4sua+/4hBG4qT5aef2iQe+1/BjezZURPlvucZeSfN1Y6b60l7OgBdyUA==} + engines: {node: '>=14.0.0'} + + p-event@5.0.1: + resolution: {integrity: sha512-dd589iCQ7m1L0bmC5NLlVYfy3TbBEsMUfWx9PyAgPeIcFZ/E2yaTZ4Rz4MiBmmJShviiftHVXOqfnfzJ6kyMrQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + p-filter@2.1.0: + resolution: {integrity: sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==} + engines: {node: '>=8'} + + p-limit@1.3.0: + resolution: {integrity: sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==} + engines: {node: '>=4'} + + p-limit@2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-limit@4.0.0: + resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + p-locate@2.0.0: + resolution: {integrity: sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==} + engines: {node: '>=4'} + + p-locate@4.1.0: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + + p-locate@6.0.0: + resolution: {integrity: sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + p-map@2.1.0: + resolution: {integrity: sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==} + engines: {node: '>=6'} + + p-map@4.0.0: + resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==} + engines: {node: '>=10'} + + p-map@7.0.3: + resolution: {integrity: sha512-VkndIv2fIB99swvQoA65bm+fsmt6UNdGeIB0oxBs+WhAhdh08QA04JXpI7rbB9r08/nkbysKoya9rtDERYOYMA==} + engines: {node: '>=18'} + + p-timeout@5.1.0: + resolution: {integrity: sha512-auFDyzzzGZZZdHz3BtET9VEz0SE/uMEAx7uWfGPucfzEwwe/xH0iVeZibQmANYE/hp9T2+UUZT5m+BKyrDp3Ew==} + engines: {node: '>=12'} + + p-timeout@6.1.4: + resolution: {integrity: sha512-MyIV3ZA/PmyBN/ud8vV9XzwTrNtR4jFrObymZYnZqMmW0zA8Z17vnT0rBgFE/TlohB+YCHqXMgZzb3Csp49vqg==} + engines: {node: '>=14.16'} + + p-try@1.0.0: + resolution: {integrity: sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==} + engines: {node: '>=4'} + + p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + + p-wait-for@5.0.2: + resolution: {integrity: sha512-lwx6u1CotQYPVju77R+D0vFomni/AqRfqLmqQ8hekklqZ6gAY9rONh7lBQ0uxWMkC2AuX9b2DVAl8To0NyP1JA==} + engines: {node: '>=12'} + + package-json-from-dist@1.0.1: + resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + + package-manager-detector@0.2.0: + resolution: {integrity: sha512-E385OSk9qDcXhcM9LNSe4sdhx8a9mAPrZ4sMLW+tmxl5ZuGtPUcdFu+MPP2jbgiWAZ6Pfe5soGFMd+0Db5Vrog==} + + package-manager-detector@1.3.0: + resolution: {integrity: sha512-ZsEbbZORsyHuO00lY1kV3/t72yp6Ysay6Pd17ZAlNGuGwmWDLCJxFpRs0IzfXfj1o4icJOkUEioexFHzyPurSQ==} + + parse-gitignore@2.0.0: + resolution: {integrity: sha512-RmVuCHWsfu0QPNW+mraxh/xjQVw/lhUCUru8Zni3Ctq3AoMhpDTq0OVdKS6iesd6Kqb7viCV3isAL43dciOSog==} + engines: {node: '>=14'} + + parse-json@8.3.0: + resolution: {integrity: sha512-ybiGyvspI+fAoRQbIPRddCcSTV9/LsJbf0e/S85VLowVGzRmokfneg2kwVW/KU5rOXrPSbF1qAKPMgNTqqROQQ==} + engines: {node: '>=18'} + + parse-ms@4.0.0: + resolution: {integrity: sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==} + engines: {node: '>=18'} + + parse-path@7.1.0: + resolution: {integrity: sha512-EuCycjZtfPcjWk7KTksnJ5xPMvWGA/6i4zrLYhRG0hGvC3GPU/jGUj3Cy+ZR0v30duV3e23R95T1lE2+lsndSw==} + + parse-url@9.2.0: + resolution: {integrity: sha512-bCgsFI+GeGWPAvAiUv63ZorMeif3/U0zaXABGJbOWt5OH2KCaPHF6S+0ok4aqM9RuIPGyZdx9tR9l13PsW4AYQ==} + engines: {node: '>=14.13.0'} + + parse5-htmlparser2-tree-adapter@6.0.1: + resolution: {integrity: sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==} + + parse5@5.1.1: + resolution: {integrity: sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==} + + parse5@6.0.1: + resolution: {integrity: sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==} + + parseurl@1.3.3: + resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} + engines: {node: '>= 0.8'} + + path-browserify@1.0.1: + resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} + + path-exists@3.0.0: + resolution: {integrity: sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==} + engines: {node: '>=4'} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-exists@5.0.0: + resolution: {integrity: sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-key@4.0.0: + resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} + engines: {node: '>=12'} + + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + + path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} + + path-to-regexp@6.3.0: + resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==} + + path-type@3.0.0: + resolution: {integrity: sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==} + engines: {node: '>=4'} + + path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + + path-type@6.0.0: + resolution: {integrity: sha512-Vj7sf++t5pBD637NSfkxpHSMfWaeig5+DKWLhcqIYx6mWQz5hdJTGDVMQiJcw1ZYkhs7AazKDGpRVji1LJCZUQ==} + engines: {node: '>=18'} + + pathe@1.1.2: + resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} + + pathe@2.0.3: + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + + pathval@2.0.0: + resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==} + engines: {node: '>= 14.16'} + + pbkdf2@3.1.2: + resolution: {integrity: sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==} + engines: {node: '>=0.12'} + + pend@1.2.0: + resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==} + + perfect-debounce@1.0.0: + resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==} + + picocolors@1.0.0: + resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} + + picocolors@1.1.0: + resolution: {integrity: sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + picomatch@4.0.2: + resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} + engines: {node: '>=12'} + + pify@3.0.0: + resolution: {integrity: sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==} + engines: {node: '>=4'} + + pify@4.0.1: + resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} + engines: {node: '>=6'} + + pify@5.0.0: + resolution: {integrity: sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA==} + engines: {node: '>=10'} + + pino-abstract-transport@0.5.0: + resolution: {integrity: sha512-+KAgmVeqXYbTtU2FScx1XS3kNyfZ5TrXY07V96QnUSFqo2gAqlvmaxH67Lj7SWazqsMabf+58ctdTcBgnOLUOQ==} + + pino-abstract-transport@2.0.0: + resolution: {integrity: sha512-F63x5tizV6WCh4R6RHyi2Ml+M70DNRXt/+HANowMflpgGFMAym/VKm6G7ZOQRjqN7XbGxK1Lg9t6ZrtzOaivMw==} + + pino-pretty@13.0.0: + resolution: {integrity: sha512-cQBBIVG3YajgoUjo1FdKVRX6t9XPxwB9lcNJVD5GCnNM4Y6T12YYx8c6zEejxQsU0wrg9TwmDulcE9LR7qcJqA==} + hasBin: true + + pino-std-serializers@4.0.0: + resolution: {integrity: sha512-cK0pekc1Kjy5w9V2/n+8MkZwusa6EyyxfeQCB799CQRhRt/CqYKiWs5adeu8Shve2ZNffvfC/7J64A2PJo1W/Q==} + + pino@7.11.0: + resolution: {integrity: sha512-dMACeu63HtRLmCG8VKdy4cShCPKaYDR4youZqoSWLxl5Gu99HUw8bw75thbPv9Nip+H+QYX8o3ZJbTdVZZ2TVg==} + hasBin: true + + pkg-types@1.1.0: + resolution: {integrity: sha512-/RpmvKdxKf8uILTtoOhAgf30wYbP2Qw+L9p3Rvshx1JZVX+XQNZQFjlbmGHEGIm4CkVPlSn+NXmIM8+9oWQaSA==} + + pkg-types@1.1.1: + resolution: {integrity: sha512-ko14TjmDuQJ14zsotODv7dBlwxKhUKQEhuhmbqo1uCi9BB0Z2alo/wAXg6q1dTR5TyuqYyWhjtfe/Tsh+X28jQ==} + + pkg-types@1.3.1: + resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} + + pkg-types@2.1.0: + resolution: {integrity: sha512-wmJwA+8ihJixSoHKxZJRBQG1oY8Yr9pGLzRmSsNms0iNWyHHAlZCa7mmKiFR10YPZuz/2k169JiS/inOjBCZ2A==} + + pngjs@5.0.0: + resolution: {integrity: sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==} + engines: {node: '>=10.13.0'} + + pony-cause@2.1.11: + resolution: {integrity: sha512-M7LhCsdNbNgiLYiP4WjsfLUuFmCfnjdF6jKe2R9NKl4WFN+HZPGHJZ9lnLP7f9ZnKe3U9nuWD0szirmj+migUg==} + engines: {node: '>=12.0.0'} + + possible-typed-array-names@1.1.0: + resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} + engines: {node: '>= 0.4'} + + postcss-calc@10.1.1: + resolution: {integrity: sha512-NYEsLHh8DgG/PRH2+G9BTuUdtf9ViS+vdoQ0YA5OQdGsfN4ztiwtDWNtBl9EKeqNMFnIu8IKZ0cLxEQ5r5KVMw==} + engines: {node: ^18.12 || ^20.9 || >=22.0} + peerDependencies: + postcss: ^8.4.38 + + postcss-colormin@7.0.3: + resolution: {integrity: sha512-xZxQcSyIVZbSsl1vjoqZAcMYYdnJsIyG8OvqShuuqf12S88qQboxxEy0ohNCOLwVPXTU+hFHvJPACRL2B5ohTA==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-convert-values@7.0.5: + resolution: {integrity: sha512-0VFhH8nElpIs3uXKnVtotDJJNX0OGYSZmdt4XfSfvOMrFw1jKfpwpZxfC4iN73CTM/MWakDEmsHQXkISYj4BXw==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-discard-comments@7.0.4: + resolution: {integrity: sha512-6tCUoql/ipWwKtVP/xYiFf1U9QgJ0PUvxN7pTcsQ8Ns3Fnwq1pU5D5s1MhT/XySeLq6GXNvn37U46Ded0TckWg==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-discard-duplicates@7.0.2: + resolution: {integrity: sha512-eTonaQvPZ/3i1ASDHOKkYwAybiM45zFIc7KXils4mQmHLqIswXD9XNOKEVxtTFnsmwYzF66u4LMgSr0abDlh5w==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-discard-empty@7.0.1: + resolution: {integrity: sha512-cFrJKZvcg/uxB6Ijr4l6qmn3pXQBna9zyrPC+sK0zjbkDUZew+6xDltSF7OeB7rAtzaaMVYSdbod+sZOCWnMOg==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-discard-overridden@7.0.1: + resolution: {integrity: sha512-7c3MMjjSZ/qYrx3uc1940GSOzN1Iqjtlqe8uoSg+qdVPYyRb0TILSqqmtlSFuE4mTDECwsm397Ya7iXGzfF7lg==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-merge-longhand@7.0.5: + resolution: {integrity: sha512-Kpu5v4Ys6QI59FxmxtNB/iHUVDn9Y9sYw66D6+SZoIk4QTz1prC4aYkhIESu+ieG1iylod1f8MILMs1Em3mmIw==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-merge-rules@7.0.5: + resolution: {integrity: sha512-ZonhuSwEaWA3+xYbOdJoEReKIBs5eDiBVLAGpYZpNFPzXZcEE5VKR7/qBEQvTZpiwjqhhqEQ+ax5O3VShBj9Wg==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-minify-font-values@7.0.1: + resolution: {integrity: sha512-2m1uiuJeTplll+tq4ENOQSzB8LRnSUChBv7oSyFLsJRtUgAAJGP6LLz0/8lkinTgxrmJSPOEhgY1bMXOQ4ZXhQ==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-minify-gradients@7.0.1: + resolution: {integrity: sha512-X9JjaysZJwlqNkJbUDgOclyG3jZEpAMOfof6PUZjPnPrePnPG62pS17CjdM32uT1Uq1jFvNSff9l7kNbmMSL2A==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-minify-params@7.0.3: + resolution: {integrity: sha512-vUKV2+f5mtjewYieanLX0xemxIp1t0W0H/D11u+kQV/MWdygOO7xPMkbK+r9P6Lhms8MgzKARF/g5OPXhb8tgg==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-minify-selectors@7.0.5: + resolution: {integrity: sha512-x2/IvofHcdIrAm9Q+p06ZD1h6FPcQ32WtCRVodJLDR+WMn8EVHI1kvLxZuGKz/9EY5nAmI6lIQIrpo4tBy5+ug==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-normalize-charset@7.0.1: + resolution: {integrity: sha512-sn413ofhSQHlZFae//m9FTOfkmiZ+YQXsbosqOWRiVQncU2BA3daX3n0VF3cG6rGLSFVc5Di/yns0dFfh8NFgQ==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-normalize-display-values@7.0.1: + resolution: {integrity: sha512-E5nnB26XjSYz/mGITm6JgiDpAbVuAkzXwLzRZtts19jHDUBFxZ0BkXAehy0uimrOjYJbocby4FVswA/5noOxrQ==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-normalize-positions@7.0.1: + resolution: {integrity: sha512-pB/SzrIP2l50ZIYu+yQZyMNmnAcwyYb9R1fVWPRxm4zcUFCY2ign7rcntGFuMXDdd9L2pPNUgoODDk91PzRZuQ==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-normalize-repeat-style@7.0.1: + resolution: {integrity: sha512-NsSQJ8zj8TIDiF0ig44Byo3Jk9e4gNt9x2VIlJudnQQ5DhWAHJPF4Tr1ITwyHio2BUi/I6Iv0HRO7beHYOloYQ==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-normalize-string@7.0.1: + resolution: {integrity: sha512-QByrI7hAhsoze992kpbMlJSbZ8FuCEc1OT9EFbZ6HldXNpsdpZr+YXC5di3UEv0+jeZlHbZcoCADgb7a+lPmmQ==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-normalize-timing-functions@7.0.1: + resolution: {integrity: sha512-bHifyuuSNdKKsnNJ0s8fmfLMlvsQwYVxIoUBnowIVl2ZAdrkYQNGVB4RxjfpvkMjipqvbz0u7feBZybkl/6NJg==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-normalize-unicode@7.0.3: + resolution: {integrity: sha512-EcoA29LvG3F+EpOh03iqu+tJY3uYYKzArqKJHxDhUYLa2u58aqGq16K6/AOsXD9yqLN8O6y9mmePKN5cx6krOw==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-normalize-url@7.0.1: + resolution: {integrity: sha512-sUcD2cWtyK1AOL/82Fwy1aIVm/wwj5SdZkgZ3QiUzSzQQofrbq15jWJ3BA7Z+yVRwamCjJgZJN0I9IS7c6tgeQ==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-normalize-whitespace@7.0.1: + resolution: {integrity: sha512-vsbgFHMFQrJBJKrUFJNZ2pgBeBkC2IvvoHjz1to0/0Xk7sII24T0qFOiJzG6Fu3zJoq/0yI4rKWi7WhApW+EFA==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-ordered-values@7.0.2: + resolution: {integrity: sha512-AMJjt1ECBffF7CEON/Y0rekRLS6KsePU6PRP08UqYW4UGFRnTXNrByUzYK1h8AC7UWTZdQ9O3Oq9kFIhm0SFEw==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-reduce-initial@7.0.3: + resolution: {integrity: sha512-RFvkZaqiWtGMlVjlUHpaxGqEL27lgt+Q2Ixjf83CRAzqdo+TsDyGPtJUbPx2MuYIJ+sCQc2TrOvRnhcXQfgIVA==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-reduce-transforms@7.0.1: + resolution: {integrity: sha512-MhyEbfrm+Mlp/36hvZ9mT9DaO7dbncU0CvWI8V93LRkY6IYlu38OPg3FObnuKTUxJ4qA8HpurdQOo5CyqqO76g==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-selector-parser@7.1.0: + resolution: {integrity: sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==} + engines: {node: '>=4'} + + postcss-svgo@7.0.2: + resolution: {integrity: sha512-5Dzy66JlnRM6pkdOTF8+cGsB1fnERTE8Nc+Eed++fOWo1hdsBptCsbG8UuJkgtZt75bRtMJIrPeZmtfANixdFA==} + engines: {node: ^18.12.0 || ^20.9.0 || >= 18} + peerDependencies: + postcss: ^8.4.32 + + postcss-unique-selectors@7.0.4: + resolution: {integrity: sha512-pmlZjsmEAG7cHd7uK3ZiNSW6otSZ13RHuZ/4cDN/bVglS5EpF2r2oxY99SuOHa8m7AWoBCelTS3JPpzsIs8skQ==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-value-parser@4.2.0: + resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} + + postcss-values-parser@6.0.2: + resolution: {integrity: sha512-YLJpK0N1brcNJrs9WatuJFtHaV9q5aAOj+S4DI5S7jgHlRfm0PIbDCAFRYMQD5SHq7Fy6xsDhyutgS0QOAs0qw==} + engines: {node: '>=10'} + peerDependencies: + postcss: ^8.2.9 + + postcss@8.4.31: + resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==} + engines: {node: ^10 || ^12 || >=14} + + postcss@8.4.47: + resolution: {integrity: sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==} + engines: {node: ^10 || ^12 || >=14} + + postcss@8.5.3: + resolution: {integrity: sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==} + engines: {node: ^10 || ^12 || >=14} + + postcss@8.5.5: + resolution: {integrity: sha512-d/jtm+rdNT8tpXuHY5MMtcbJFBkhXE6593XVR9UoGCH8jSFGci7jGvMGH5RYd5PBJW+00NZQt6gf7CbagJCrhg==} + engines: {node: ^10 || ^12 || >=14} + + preact@10.17.1: + resolution: {integrity: sha512-X9BODrvQ4Ekwv9GURm9AKAGaomqXmip7NQTZgY7gcNmr7XE83adOMJvd3N42id1tMFU7ojiynRsYnY6/BRFxLA==} + + preact@10.24.3: + resolution: {integrity: sha512-Z2dPnBnMUfyQfSQ+GBdsGa16hz35YmLmtTLhM169uW944hYL6xzTYkJjC07j+Wosz733pMWx0fgON3JNw1jJQA==} + + precinct@11.0.5: + resolution: {integrity: sha512-oHSWLC8cL/0znFhvln26D14KfCQFFn4KOLSw6hmLhd+LQ2SKt9Ljm89but76Pc7flM9Ty1TnXyrA2u16MfRV3w==} + engines: {node: ^14.14.0 || >=16.0.0} + hasBin: true + + prettier@2.8.8: + resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} + engines: {node: '>=10.13.0'} + hasBin: true + + prettier@3.0.3: + resolution: {integrity: sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg==} + engines: {node: '>=14'} + hasBin: true + + pretty-bytes@6.1.1: + resolution: {integrity: sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ==} + engines: {node: ^14.13.1 || >=16.0.0} + + pretty-format@27.5.1: + resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + pretty-ms@9.0.0: + resolution: {integrity: sha512-E9e9HJ9R9NasGOgPaPE8VMeiPKAyWR5jcFpNnwIejslIhWqdqOrb2wShBsncMPUb+BcCd2OPYfh7p2W6oemTng==} + engines: {node: '>=18'} + + process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + + process-warning@1.0.0: + resolution: {integrity: sha512-du4wfLyj4yCZq1VupnVSZmRsPJsNuxoDQFdCFHLaYiEbFBD7QE0a+I4D7hOxrVnh78QE/YipFAj9lXHiXocV+Q==} + + process@0.11.10: + resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} + engines: {node: '>= 0.6.0'} + + prompts@2.4.2: + resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} + engines: {node: '>= 6'} + + prool@0.0.23: + resolution: {integrity: sha512-r1d0DIiVsp7aXqGiNGKmgrqJZa8GjMGEjsgjQO22DEClYYvK+HMPZTQ9diBqleGuwfiRk3lnsWRMbFTRmFbk9g==} + engines: {node: '>=22'} + peerDependencies: + '@pimlico/alto': '*' + peerDependenciesMeta: + '@pimlico/alto': + optional: true + + property-information@6.5.0: + resolution: {integrity: sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==} + + proto-list@1.2.4: + resolution: {integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==} + + protocols@2.0.2: + resolution: {integrity: sha512-hHVTzba3wboROl0/aWRRG9dMytgH6ow//STBZh43l/wQgmMhYhOFi0EHWAPtoCz9IAUymsyP0TSBHkhgMEGNnQ==} + + proxy-compare@2.6.0: + resolution: {integrity: sha512-8xuCeM3l8yqdmbPoYeLbrAXCBWu19XEYc5/F28f5qOaoAIMyfmBUkl5axiK+x9olUvRlcekvnm98AP9RDngOIw==} + + pseudomap@1.0.2: + resolution: {integrity: sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==} + + psl@1.9.0: + resolution: {integrity: sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==} + + publint@0.3.12: + resolution: {integrity: sha512-1w3MMtL9iotBjm1mmXtG3Nk06wnq9UhGNRpQ2j6n1Zq7YAD6gnxMMZMIxlRPAydVjVbjSm+n0lhwqsD1m4LD5w==} + engines: {node: '>=18'} + hasBin: true + + pump@3.0.2: + resolution: {integrity: sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + qrcode@1.5.3: + resolution: {integrity: sha512-puyri6ApkEHYiVl4CFzo1tDkAZ+ATcnbJrJ6RiBM1Fhctdn/ix9MTE3hRph33omisEbC/2fcfemsseiKgBPKZg==} + engines: {node: '>=10.13.0'} + hasBin: true + + qs@6.14.0: + resolution: {integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==} + engines: {node: '>=0.6'} + + quansync@0.2.10: + resolution: {integrity: sha512-t41VRkMYbkHyCYmOvx/6URnN80H7k4X0lLdBMGsz+maAwrJQYB1djpV6vHrQIBE0WBSGqhtEHrK9U3DWWH8v7A==} + + query-string@7.1.3: + resolution: {integrity: sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg==} + engines: {node: '>=6'} + + querystringify@2.2.0: + resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + quick-format-unescaped@4.0.4: + resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==} + + quote-unquote@1.0.0: + resolution: {integrity: sha512-twwRO/ilhlG/FIgYeKGFqyHhoEhqgnKVkcmqMKi2r524gz3ZbDTcyFt38E9xjJI2vT+KbRNHVbnJ/e0I25Azwg==} + + radix3@1.1.2: + resolution: {integrity: sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==} + + randombytes@2.1.0: + resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} + + range-parser@1.2.1: + resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} + engines: {node: '>= 0.6'} + + raw-body@2.5.1: + resolution: {integrity: sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==} + engines: {node: '>= 0.8'} + + rc9@2.1.2: + resolution: {integrity: sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg==} + + react-dom@18.3.1: + resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==} + peerDependencies: + react: ^18.3.1 + + react-is@17.0.2: + resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} + + react-refresh@0.14.0: + resolution: {integrity: sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==} + engines: {node: '>=0.10.0'} + + react@18.3.1: + resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} + engines: {node: '>=0.10.0'} + + read-package-up@11.0.0: + resolution: {integrity: sha512-MbgfoNPANMdb4oRBNg5eqLbB2t2r+o5Ua1pNt8BqGp4I0FJZhuVSOj3PaBPni4azWuSzEdNn2evevzVmEk1ohQ==} + engines: {node: '>=18'} + + read-pkg@9.0.1: + resolution: {integrity: sha512-9viLL4/n1BJUCT1NXVTdS1jtm80yDEgR5T4yCelII49Mbj0v1rZdKqj7zCiYdbB0CuCgdrvHcNogAKTFPBocFA==} + engines: {node: '>=18'} + + read-yaml-file@1.1.0: + resolution: {integrity: sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==} + engines: {node: '>=6'} + + readable-stream@2.3.8: + resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + + readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + + readable-stream@4.7.0: + resolution: {integrity: sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + readdir-glob@1.1.3: + resolution: {integrity: sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==} + + readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + + readdirp@4.1.2: + resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} + engines: {node: '>= 14.18.0'} + + real-require@0.1.0: + resolution: {integrity: sha512-r/H9MzAWtrv8aSVjPCMFpDMl5q66GqtmmRkRjpHTsp4zBAa+snZyiQNlMONiUmEJcsnaw0wCauJ2GWODr/aFkg==} + engines: {node: '>= 12.13.0'} + + redis-errors@1.2.0: + resolution: {integrity: sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==} + engines: {node: '>=4'} + + redis-parser@3.0.0: + resolution: {integrity: sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==} + engines: {node: '>=4'} + + regenerator-runtime@0.14.0: + resolution: {integrity: sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==} + + regex@4.4.0: + resolution: {integrity: sha512-uCUSuobNVeqUupowbdZub6ggI5/JZkYyJdDogddJr60L764oxC2pMZov1fQ3wM9bdyzUILDG+Sqx6NAKAz9rKQ==} + + remove-accents@0.5.0: + resolution: {integrity: sha512-8g3/Otx1eJaVD12e31UbJj1YzdtVvzH85HV7t+9MJYk/u3XmkOUJ5Ys9wQrf9PCPK8+xn4ymzqYCiZl6QWKn+A==} + + remove-trailing-separator@1.1.0: + resolution: {integrity: sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==} + + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + + require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + + require-main-filename@2.0.0: + resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} + + require-package-name@2.0.1: + resolution: {integrity: sha512-uuoJ1hU/k6M0779t3VMVIYpb2VMJk05cehCaABFhXaibcbvfgR8wKiozLjVFSzJPmQMRqIcO0HMyTFqfV09V6Q==} + + requires-port@1.0.0: + resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} + + resolve-from@5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + + resolve@1.17.0: + resolution: {integrity: sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==} + + resolve@1.22.10: + resolution: {integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==} + engines: {node: '>= 0.4'} + hasBin: true + + resolve@2.0.0-next.5: + resolution: {integrity: sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==} + hasBin: true + + reusify@1.0.4: + resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + rfdc@1.4.1: + resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} + + rimraf@2.7.1: + resolution: {integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==} + deprecated: Rimraf versions prior to v4 are no longer supported + hasBin: true + + rimraf@3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + deprecated: Rimraf versions prior to v4 are no longer supported + hasBin: true + + rimraf@5.0.10: + resolution: {integrity: sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==} + hasBin: true + + ripemd160@2.0.2: + resolution: {integrity: sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==} + + rlp@2.2.7: + resolution: {integrity: sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ==} + hasBin: true + + rollup-plugin-visualizer@5.14.0: + resolution: {integrity: sha512-VlDXneTDaKsHIw8yzJAFWtrzguoJ/LnQ+lMpoVfYJ3jJF4Ihe5oYLAqLklIK/35lgUY+1yEzCkHyZ1j4A5w5fA==} + engines: {node: '>=18'} + hasBin: true + peerDependencies: + rolldown: 1.x + rollup: 2.x || 3.x || 4.x + peerDependenciesMeta: + rolldown: + optional: true + rollup: + optional: true + + rollup@4.41.0: + resolution: {integrity: sha512-HqMFpUbWlf/tvcxBFNKnJyzc7Lk+XO3FGc3pbNBLqEbOz0gPLRgcrlS3UF4MfUrVlstOaP/q0kM6GVvi+LrLRg==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + run-applescript@7.0.0: + resolution: {integrity: sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==} + engines: {node: '>=18'} + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + sade@1.8.1: + resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==} + engines: {node: '>=6'} + + safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + safe-regex-test@1.1.0: + resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==} + engines: {node: '>= 0.4'} + + safe-stable-stringify@2.4.3: + resolution: {integrity: sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==} + engines: {node: '>=10'} + + safe-stable-stringify@2.5.0: + resolution: {integrity: sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==} + engines: {node: '>=10'} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + scheduler@0.23.2: + resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==} + + scrypt-js@3.0.1: + resolution: {integrity: sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==} + + scule@1.3.0: + resolution: {integrity: sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==} + + secp256k1@4.0.3: + resolution: {integrity: sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA==} + engines: {node: '>=10.0.0'} + + secure-json-parse@2.7.0: + resolution: {integrity: sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==} + + semver@5.7.1: + resolution: {integrity: sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==} + hasBin: true + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + semver@7.5.4: + resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==} + engines: {node: '>=10'} + hasBin: true + + semver@7.6.2: + resolution: {integrity: sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==} + engines: {node: '>=10'} + hasBin: true + + semver@7.7.2: + resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==} + engines: {node: '>=10'} + hasBin: true + + send@1.2.0: + resolution: {integrity: sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==} + engines: {node: '>= 18'} + + serialize-javascript@6.0.0: + resolution: {integrity: sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==} + + serialize-javascript@6.0.2: + resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} + + serve-placeholder@2.0.2: + resolution: {integrity: sha512-/TMG8SboeiQbZJWRlfTCqMs2DD3SZgWp0kDQePz9yUuCnDfDh/92gf7/PxGhzXTKBIPASIHxFcZndoNbp6QOLQ==} + + serve-static@2.2.0: + resolution: {integrity: sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==} + engines: {node: '>= 18'} + + set-blocking@2.0.0: + resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} + + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + + setimmediate@1.0.5: + resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==} + + setprototypeof@1.2.0: + resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + + sha.js@2.4.11: + resolution: {integrity: sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==} + hasBin: true + + sharp@0.34.2: + resolution: {integrity: sha512-lszvBmB9QURERtyKT2bNmsgxXK0ShJrL/fvqlonCo7e6xBF8nT8xU6pW+PMIbLsz0RxQk3rgH9kd8UmvOzlMJg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + + shebang-command@1.2.0: + resolution: {integrity: sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==} + engines: {node: '>=0.10.0'} + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@1.0.0: + resolution: {integrity: sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==} + engines: {node: '>=0.10.0'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + shell-quote@1.8.2: + resolution: {integrity: sha512-AzqKpGKjrj7EM6rKVQEPpB288oCfnrEIuyoT9cyF4nmGa7V8Zk6f7RRqYisX8X9m+Q7bd632aZW4ky7EhbQztA==} + engines: {node: '>= 0.4'} + + sherif-darwin-arm64@1.0.0: + resolution: {integrity: sha512-BRzDsWGjdZ6JqaDQ0HdcpapfHcnZyN24wUWpnFkljZOH78N+vB4qr+wwhmM7oyePJiO4pZWEoIBvzVT4cn1+3g==} + cpu: [arm64] + os: [darwin] + + sherif-darwin-x64@1.0.0: + resolution: {integrity: sha512-forkTw6v2N2sjvDdHGL+MqSPdLc0e7Z0v9BsmSdIKv5kdCPncVn6tRv/4xfAE7q+Xqa2a2bH9EEXppGb4gR3Tw==} + cpu: [x64] + os: [darwin] + + sherif-linux-arm64@1.0.0: + resolution: {integrity: sha512-psjD3YupFQtphWbwptM8EnU2jRkS6cnhxdxqJhMG9/yJpGsk99JD4tEmrDq0j/+T9UXZ5g7kXvQZXzocl3J62A==} + cpu: [arm64] + os: [linux] + + sherif-linux-x64@1.0.0: + resolution: {integrity: sha512-4VM2Z0xfKOEEkZ2bZppq4PAxP4RYC2eWyUq23Jl/nQFeoPMQpA9IkF51UGzxZT4WZ2kZDFftgyJeB09yPvd1CA==} + cpu: [x64] + os: [linux] + + sherif-windows-arm64@1.0.0: + resolution: {integrity: sha512-tSEzytTz3guhKLtdMCKWWru6UtmuCXD+0RsUWcqOMpzPBZZwvSr7OrTc83z8Oabmo8k6SJ5fvQeg33JSthgTqw==} + cpu: [arm64] + os: [win32] + + sherif-windows-x64@1.0.0: + resolution: {integrity: sha512-R/KXUHBWVPU9hSlWS+Gea/ogP1h/3q/Dm/quqGrVq+MN/F+fiRsJlU52EAjAJ6G5r/4RsvQddD1ova8MKsffdw==} + cpu: [x64] + os: [win32] + + sherif@1.0.0: + resolution: {integrity: sha512-x5gZqXmBT0G6Xnr2N63FwbMjaOikk/mPszl2bl3pnDMMyRi89w1ynAfcdIJpOyqZXW445418zkMIXAkQEfEtHw==} + hasBin: true + + shiki@1.22.2: + resolution: {integrity: sha512-3IZau0NdGKXhH2bBlUk4w1IHNxPh6A5B2sUpyY+8utLu2j/h1QpFkAaUA1bAMxOWWGtTWcAh531vnS4NJKS/lA==} + + side-channel-list@1.0.0: + resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} + engines: {node: '>= 0.4'} + + side-channel-map@1.0.1: + resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} + engines: {node: '>= 0.4'} + + side-channel-weakmap@1.0.2: + resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} + engines: {node: '>= 0.4'} + + side-channel@1.1.0: + resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} + engines: {node: '>= 0.4'} + + siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + + signal-exit@3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + simple-git-hooks@2.11.1: + resolution: {integrity: sha512-tgqwPUMDcNDhuf1Xf6KTUsyeqGdgKMhzaH4PAZZuzguOgTl5uuyeYe/8mWgAr6IBxB5V06uqEf6Dy37gIWDtDg==} + hasBin: true + + simple-git@3.27.0: + resolution: {integrity: sha512-ivHoFS9Yi9GY49ogc6/YAi3Fl9ROnF4VyubNylgCkA+RVqLaKWnDSzXOVzya8csELIaWaYNutsEuAhZrtOjozA==} + + simple-swizzle@0.2.2: + resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} + + sirv@2.0.4: + resolution: {integrity: sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==} + engines: {node: '>= 10'} + + sirv@3.0.1: + resolution: {integrity: sha512-FoqMu0NCGBLCcAkS1qA+XJIQTR6/JHfQXl+uGteNCQ76T91DMUjPa9xfmeqMY3z80nLSg9yQmNjK0Px6RWsH/A==} + engines: {node: '>=18'} + + sisteransi@1.0.5: + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + + skin-tone@2.0.0: + resolution: {integrity: sha512-kUMbT1oBJCpgrnKoSr0o6wPtvRWT9W9UKvGLwfJYO2WuahZRHOpEyL1ckyMGgMWh0UdpmaoFqKKD29WTomNEGA==} + engines: {node: '>=8'} + + slash@1.0.0: + resolution: {integrity: sha512-3TYDR7xWt4dIqV2JauJr+EJeW356RXijHeUlO+8djJ+uBXPn8/2dpzBc8yQhh583sVvc9CvFAeQVgijsH+PNNg==} + engines: {node: '>=0.10.0'} + + slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + + slash@5.1.0: + resolution: {integrity: sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==} + engines: {node: '>=14.16'} + + smob@1.5.0: + resolution: {integrity: sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig==} + + smol-toml@1.3.0: + resolution: {integrity: sha512-tWpi2TsODPScmi48b/OQZGi2lgUmBCHy6SZrhi/FdnnHiU1GwebbCfuQuxsC3nHaLwtYeJGPrDZDIeodDOc4pA==} + engines: {node: '>= 18'} + + socket.io-client@4.8.1: + resolution: {integrity: sha512-hJVXfu3E28NmzGk8o1sHhN3om52tRvwYeidbj7xKy2eIIse5IoKX3USlS6Tqt3BHAtflLIkCQBkzVrEEfWUyYQ==} + engines: {node: '>=10.0.0'} + + socket.io-parser@4.2.4: + resolution: {integrity: sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==} + engines: {node: '>=10.0.0'} + + solc@0.7.3: + resolution: {integrity: sha512-GAsWNAjGzIDg7VxzP6mPjdurby3IkGCjQcM8GFYZT6RyaoUZKmMU6Y7YwG+tFGhv7dwZ8rmR4iwFDrrD99JwqA==} + engines: {node: '>=8.0.0'} + hasBin: true + + sonic-boom@2.8.0: + resolution: {integrity: sha512-kuonw1YOYYNOve5iHdSahXPOK49GqwA+LZhI6Wz/l0rP57iKyXXIHaRagOBHAPmGwJC6od2Z9zgvZ5loSgMlVg==} + + sonic-boom@4.2.0: + resolution: {integrity: sha512-INb7TM37/mAcsGmc9hyyI6+QR3rR1zVRu36B0NeGXKnOOLiZOfER5SA+N7X7k3yUYRzLWafduTDvJAfDswwEww==} + + source-map-js@1.2.0: + resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} + engines: {node: '>=0.10.0'} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + source-map-support@0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + + source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + + source-map@0.7.4: + resolution: {integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==} + engines: {node: '>= 8'} + + space-separated-tokens@2.0.2: + resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} + + spawndamnit@2.0.0: + resolution: {integrity: sha512-j4JKEcncSjFlqIwU5L/rp2N5SIPsdxaRsIv678+TZxZ0SRDJTm8JrxJMjE/XuiEZNEir3S8l0Fa3Ke339WI4qA==} + + spdx-correct@3.2.0: + resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==} + + spdx-exceptions@2.5.0: + resolution: {integrity: sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==} + + spdx-expression-parse@3.0.1: + resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} + + spdx-license-ids@3.0.21: + resolution: {integrity: sha512-Bvg/8F5XephndSK3JffaRqdT+gyhfqIPwDHpX80tJrF8QQRYMo8sNMeaZ2Dp5+jhwKnUmIOyFFQfHRkjJm5nXg==} + + speakingurl@14.0.1: + resolution: {integrity: sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==} + engines: {node: '>=0.10.0'} + + split-on-first@1.1.0: + resolution: {integrity: sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==} + engines: {node: '>=6'} + + split2@4.2.0: + resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} + engines: {node: '>= 10.x'} + + sprintf-js@1.0.3: + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + + stack-trace@0.0.10: + resolution: {integrity: sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==} + + stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + + stacktrace-parser@0.1.10: + resolution: {integrity: sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg==} + engines: {node: '>=6'} + + standard-as-callback@2.1.0: + resolution: {integrity: sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==} + + statuses@2.0.1: + resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} + engines: {node: '>= 0.8'} + + std-env@3.7.0: + resolution: {integrity: sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==} + + std-env@3.9.0: + resolution: {integrity: sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==} + + stream-shift@1.0.1: + resolution: {integrity: sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==} + + streamsearch@1.1.0: + resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} + engines: {node: '>=10.0.0'} + + streamx@2.22.0: + resolution: {integrity: sha512-sLh1evHOzBy/iWRiR6d1zRcLao4gGZr3C1kzNz4fopCOKJb6xD9ub8Mpi9Mr1R6id5o43S+d93fI48UC5uM9aw==} + + strict-event-emitter@0.5.1: + resolution: {integrity: sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==} + + strict-uri-encode@2.0.0: + resolution: {integrity: sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ==} + engines: {node: '>=4'} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + + string_decoder@1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + + string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + + stringify-entities@4.0.4: + resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-ansi@7.1.0: + resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + engines: {node: '>=12'} + + strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + + strip-final-newline@2.0.0: + resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} + engines: {node: '>=6'} + + strip-final-newline@3.0.0: + resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} + engines: {node: '>=12'} + + strip-final-newline@4.0.0: + resolution: {integrity: sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==} + engines: {node: '>=18'} + + strip-hex-prefix@1.0.0: + resolution: {integrity: sha512-q8d4ue7JGEiVcypji1bALTos+0pWtyGlivAWyPuTkHzuTCJqrK9sWxYQZUq6Nq3cuyv3bm734IhHvHtGGURU6A==} + engines: {node: '>=6.5.0', npm: '>=3'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + strip-json-comments@5.0.1: + resolution: {integrity: sha512-0fk9zBqO67Nq5M/m45qHCJxylV/DhBlIOVExqgOMiCCrzrhU6tCibRXNqE3jwJLftzE9SNuZtYbpzcO+i9FiKw==} + engines: {node: '>=14.16'} + + strip-literal@1.3.0: + resolution: {integrity: sha512-PugKzOsyXpArk0yWmUwqOZecSO0GH0bPoctLcqNDH9J04pVW3lflYE0ujElBGTloevcxF5MofAOZ7C5l2b+wLg==} + + strip-literal@3.0.0: + resolution: {integrity: sha512-TcccoMhJOM3OebGhSBEmp3UZ2SfDMZUEBdRA/9ynfLi8yYajyWX3JiXArcJt4Umh4vISpspkQIY8ZZoCqjbviA==} + + structured-clone-es@1.0.0: + resolution: {integrity: sha512-FL8EeKFFyNQv5cMnXI31CIMCsFarSVI2bF0U0ImeNE3g/F1IvJQyqzOXxPBRXiwQfyBTlbNe88jh1jFW0O/jiQ==} + + styled-jsx@5.1.6: + resolution: {integrity: sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==} + engines: {node: '>= 12.0.0'} + peerDependencies: + '@babel/core': '*' + babel-plugin-macros: '*' + react: '>= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0' + peerDependenciesMeta: + '@babel/core': + optional: true + babel-plugin-macros: + optional: true + + stylehacks@7.0.5: + resolution: {integrity: sha512-5kNb7V37BNf0Q3w+1pxfa+oiNPS++/b4Jil9e/kPDgrk1zjEd6uR7SZeJiYaLYH6RRSC1XX2/37OTeU/4FvuIA==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + summary@2.1.0: + resolution: {integrity: sha512-nMIjMrd5Z2nuB2RZCKJfFMjgS3fygbeyGk9PxPPaJR1RIcyN9yn4A63Isovzm3ZtQuEkLBVgMdPup8UeLH7aQw==} + + superjson@2.2.1: + resolution: {integrity: sha512-8iGv75BYOa0xRJHK5vRLEjE2H/i4lulTjzpUXic3Eg8akftYjkmQDa8JARQ42rlczXyFR3IeRoeFCc7RxHsYZA==} + engines: {node: '>=16'} + + superjson@2.2.2: + resolution: {integrity: sha512-5JRxVqC8I8NuOUjzBbvVJAKNM8qoVuH0O77h4WInc/qC2q5IreqKxYwgkga3PfA22OayK2ikceb/B26dztPl+Q==} + engines: {node: '>=16'} + + superstruct@1.0.3: + resolution: {integrity: sha512-8iTn3oSS8nRGn+C2pgXSKPI3jmpm6FExNazNpjvqS6ZUJQCej3PUXEKM8NjHBOs54ExM+LPW/FBRhymrdcCiSg==} + engines: {node: '>=14.0.0'} + + supports-color@10.0.0: + resolution: {integrity: sha512-HRVVSbCCMbj7/kdWF9Q+bbckjBHLtHMEoJWlkmYzzdwhYMkjkOwubLM6t7NbWKjgKamGDrWL1++KrjUO1t9oAQ==} + engines: {node: '>=18'} + + supports-color@5.5.0: + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + engines: {node: '>=4'} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + supports-color@8.1.1: + resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} + engines: {node: '>=10'} + + supports-color@9.4.0: + resolution: {integrity: sha512-VL+lNrEoIXww1coLPOmiEmK/0sGigko5COxI09KzHc2VJXJsQ37UaQ+8quuxjDeA7+KnLGTWRyOXSLLR2Wb4jw==} + engines: {node: '>=12'} + + supports-hyperlinks@3.0.0: + resolution: {integrity: sha512-QBDPHyPQDRTy9ku4URNGY5Lah8PAaXs6tAAwp55sL5WCsSW7GIfdf6W5ixfziW+t7wh3GVvHyHHyQ1ESsoRvaA==} + engines: {node: '>=14.18'} + + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + svgo@3.3.2: + resolution: {integrity: sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw==} + engines: {node: '>=14.0.0'} + hasBin: true + + system-architecture@0.1.0: + resolution: {integrity: sha512-ulAk51I9UVUyJgxlv9M6lFot2WP3e7t8Kz9+IS6D4rVba1tR9kON+Ey69f+1R4Q8cd45Lod6a4IcJIxnzGc/zA==} + engines: {node: '>=18'} + + tabbable@6.2.0: + resolution: {integrity: sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==} + + tapable@2.2.1: + resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} + engines: {node: '>=6'} + + tapable@2.2.2: + resolution: {integrity: sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==} + engines: {node: '>=6'} + + tar-stream@2.2.0: + resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} + engines: {node: '>=6'} + + tar-stream@3.1.7: + resolution: {integrity: sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==} + + tar@6.2.1: + resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==} + engines: {node: '>=10'} + + tar@7.2.0: + resolution: {integrity: sha512-hctwP0Nb4AB60bj8WQgRYaMOuJYRAPMGiQUAotms5igN8ppfQM+IvjQ5HcKu1MaZh2Wy2KWVTe563Yj8dfc14w==} + engines: {node: '>=18'} + + tar@7.4.3: + resolution: {integrity: sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==} + engines: {node: '>=18'} + + temp-dir@1.0.0: + resolution: {integrity: sha512-xZFXEGbG7SNC3itwBzI3RYjq/cEhBkx2hJuKGIUOcEULmkQExXiHat2z/qkISYsuR+IKumhEfKKbV5qXmhICFQ==} + engines: {node: '>=4'} + + tempy@0.2.1: + resolution: {integrity: sha512-LB83o9bfZGrntdqPuRdanIVCPReam9SOZKW0fOy5I9X3A854GGWi0tjCqoXEk84XIEYBc/x9Hq3EFop/H5wJaw==} + engines: {node: '>=4'} + + term-size@2.2.1: + resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==} + engines: {node: '>=8'} + + terser@5.39.2: + resolution: {integrity: sha512-yEPUmWve+VA78bI71BW70Dh0TuV4HHd+I5SHOAfS1+QBOmvmCiiffgjR8ryyEd3KIfvPGFqoADt8LdQ6XpXIvg==} + engines: {node: '>=10'} + hasBin: true + + test-exclude@7.0.1: + resolution: {integrity: sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg==} + engines: {node: '>=18'} + + text-decoder@1.2.3: + resolution: {integrity: sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==} + + text-hex@1.0.0: + resolution: {integrity: sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==} + + thenify-all@1.6.0: + resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} + engines: {node: '>=0.8'} + + thenify@3.3.1: + resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + + thread-stream@0.15.2: + resolution: {integrity: sha512-UkEhKIg2pD+fjkHQKyJO3yoIvAP3N6RlNFt2dUhcS1FGvCD1cQa1M/PGknCLFIyZdtJOWQjejp7bdNqmN7zwdA==} + + tiny-invariant@1.3.3: + resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} + + tinybench@2.9.0: + resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} + + tinyexec@0.3.2: + resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} + + tinyexec@1.0.1: + resolution: {integrity: sha512-5uC6DDlmeqiOwCPmK9jMSdOuZTh8bU39Ys6yidB+UTt5hfZUPGAypSgFRiEp+jbi9qH40BLDvy85jIU88wKSqw==} + + tinyglobby@0.2.12: + resolution: {integrity: sha512-qkf4trmKSIiMTs/E63cxH+ojC2unam7rJ0WrauAzpT3ECNTxGRMlaXxVbfxMUC/w0LaYk6jQ4y/nGR9uBO3tww==} + engines: {node: '>=12.0.0'} + + tinyglobby@0.2.13: + resolution: {integrity: sha512-mEwzpUgrLySlveBwEVDMKk5B57bhLPYovRfPAXD5gA/98Opn0rCDj3GtLwFvCvH5RK9uPCExUROW5NjDwvqkxw==} + engines: {node: '>=12.0.0'} + + tinypool@1.0.2: + resolution: {integrity: sha512-al6n+QEANGFOMf/dmUMsuS5/r9B06uwlyNjZZql/zv8J7ybHCgoihBNORZCY2mzUuAnomQa2JdhyHKzZxPCrFA==} + engines: {node: ^18.0.0 || >=20.0.0} + + tinyrainbow@1.2.0: + resolution: {integrity: sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==} + engines: {node: '>=14.0.0'} + + tinyspy@3.0.2: + resolution: {integrity: sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==} + engines: {node: '>=14.0.0'} + + tmp-promise@3.0.3: + resolution: {integrity: sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ==} + + tmp@0.0.33: + resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} + engines: {node: '>=0.6.0'} + + tmp@0.2.3: + resolution: {integrity: sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==} + engines: {node: '>=14.14'} + + to-fast-properties@2.0.0: + resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} + engines: {node: '>=4'} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + toidentifier@1.0.1: + resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} + engines: {node: '>=0.6'} + + toml@3.0.0: + resolution: {integrity: sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==} + + totalist@3.0.1: + resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} + engines: {node: '>=6'} + + tough-cookie@4.1.4: + resolution: {integrity: sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==} + engines: {node: '>=6'} + + tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + + trim-lines@3.0.1: + resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} + + triple-beam@1.4.1: + resolution: {integrity: sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==} + engines: {node: '>= 14.0.0'} + + tslib@1.14.1: + resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + tsort@0.0.1: + resolution: {integrity: sha512-Tyrf5mxF8Ofs1tNoxA13lFeZ2Zrbd6cKbuH3V+MQ5sb6DtBj5FjrXVsRWT8YvNAQTqNoz66dz1WsbigI22aEnw==} + + tsutils@3.21.0: + resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} + engines: {node: '>= 6'} + peerDependencies: + typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta' + + tweetnacl-util@0.15.1: + resolution: {integrity: sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==} + + tweetnacl@1.0.3: + resolution: {integrity: sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==} + + twoslash-protocol@0.2.12: + resolution: {integrity: sha512-5qZLXVYfZ9ABdjqbvPc4RWMr7PrpPaaDSeaYY55vl/w1j6H6kzsWK/urAEIXlzYlyrFmyz1UbwIt+AA0ck+wbg==} + + twoslash-vue@0.2.12: + resolution: {integrity: sha512-kxH60DLn2QBcN2wjqxgMDkyRgmPXsytv7fJIlsyFMDPSkm1/lMrI/UMrNAshNaRHcI+hv8x3h/WBgcvlb2RNAQ==} + peerDependencies: + typescript: '*' + + twoslash@0.2.12: + resolution: {integrity: sha512-tEHPASMqi7kqwfJbkk7hc/4EhlrKCSLcur+TcvYki3vhIfaRMXnXjaYFgXpoZRbT6GdprD4tGuVBEmTpUgLBsw==} + peerDependencies: + typescript: '*' + + type-fest@0.20.2: + resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} + engines: {node: '>=10'} + + type-fest@0.21.3: + resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} + engines: {node: '>=10'} + + type-fest@0.7.1: + resolution: {integrity: sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==} + engines: {node: '>=8'} + + type-fest@4.18.2: + resolution: {integrity: sha512-+suCYpfJLAe4OXS6+PPXjW3urOS4IoP9waSiLuXfLgqZODKw/aWwASvzqE886wA0kQgGy0mIWyhd87VpqIy6Xg==} + engines: {node: '>=16'} + + type-fest@4.41.0: + resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} + engines: {node: '>=16'} + + typescript@5.6.1-rc: + resolution: {integrity: sha512-E3b2+1zEFu84jB0YQi9BORDjz9+jGbwwy1Zi3G0LUNw7a7cePUrHMRNy8aPh53nXpkFGVHSxIZo5vKTfYaFiBQ==} + engines: {node: '>=14.17'} + hasBin: true + + typescript@5.8.3: + resolution: {integrity: sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==} + engines: {node: '>=14.17'} + hasBin: true + + ufo@1.5.3: + resolution: {integrity: sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==} + + ufo@1.6.1: + resolution: {integrity: sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==} + + uint8arrays@3.1.0: + resolution: {integrity: sha512-ei5rfKtoRO8OyOIor2Rz5fhzjThwIHJZ3uyDPnDHTXbP0aMQ1RN/6AI5B5d9dBxJOU+BvOAk7ZQ1xphsX8Lrog==} + + uint8arrays@3.1.1: + resolution: {integrity: sha512-+QJa8QRnbdXVpHYjLoTpJIdCTiw9Ir62nocClWuXIq2JIh4Uta0cQsTSpFL678p2CN8B+XSApwcU+pQEqVpKWg==} + + ultrahtml@1.6.0: + resolution: {integrity: sha512-R9fBn90VTJrqqLDwyMph+HGne8eqY1iPfYhPzZrvKpIfwkWZbcYlfpsb8B9dTvBfpy1/hqAD7Wi8EKfP9e8zdw==} + + unconfig@0.3.13: + resolution: {integrity: sha512-N9Ph5NC4+sqtcOjPfHrRcHekBCadCXWTBzp2VYYbySOHW0PfD9XLCeXshTXjkPYwLrBr9AtSeU0CZmkYECJhng==} + + uncrypto@0.1.3: + resolution: {integrity: sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==} + + unctx@2.4.1: + resolution: {integrity: sha512-AbaYw0Nm4mK4qjhns67C+kgxR2YWiwlDBPzxrN8h8C6VtAdCgditAY5Dezu3IJy4XVqAnbrXt9oQJvsn3fyozg==} + + undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + + undici-types@6.21.0: + resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + + undici-types@7.8.0: + resolution: {integrity: sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==} + + undici@5.28.3: + resolution: {integrity: sha512-3ItfzbrhDlINjaP0duwnNsKpDQk3acHI3gVJ1z4fmwMK31k5G9OVIAMLSIaP6w4FaGkaAkN6zaQO9LUvZ1t7VA==} + engines: {node: '>=14.0'} + + unenv@2.0.0-rc.17: + resolution: {integrity: sha512-B06u0wXkEd+o5gOCMl/ZHl5cfpYbDZKAT+HWTL+Hws6jWu7dCiqBBXXXzMFcFVJb8D4ytAnYmxJA83uwOQRSsg==} + + unhead@2.0.9: + resolution: {integrity: sha512-ZLTNJ51PZPO4/3keW7FHiTMb6K+JmhhVApJA52qWNw7NMYPD8fM2eA+hUEaCA2L5bZtbRg43TT7n/lJ+/9o6pw==} + + unicode-emoji-modifier-base@1.0.0: + resolution: {integrity: sha512-yLSH4py7oFH3oG/9K+XWrz1pSi3dfUrWEnInbxMfArOfc1+33BlGPQtLsOYwvdMy11AwUBetYuaRxSPqgkq+8g==} + engines: {node: '>=4'} + + unicorn-magic@0.1.0: + resolution: {integrity: sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==} + engines: {node: '>=18'} + + unicorn-magic@0.3.0: + resolution: {integrity: sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==} + engines: {node: '>=18'} + + unimport@3.7.1: + resolution: {integrity: sha512-V9HpXYfsZye5bPPYUgs0Otn3ODS1mDUciaBlXljI4C2fTwfFpvFZRywmlOu943puN9sncxROMZhsZCjNXEpzEQ==} + + unimport@4.2.0: + resolution: {integrity: sha512-mYVtA0nmzrysnYnyb3ALMbByJ+Maosee2+WyE0puXl+Xm2bUwPorPaaeZt0ETfuroPOtG8jj1g/qeFZ6buFnag==} + engines: {node: '>=18.12.0'} + + unimport@5.0.1: + resolution: {integrity: sha512-1YWzPj6wYhtwHE+9LxRlyqP4DiRrhGfJxdtH475im8ktyZXO3jHj/3PZ97zDdvkYoovFdi0K4SKl3a7l92v3sQ==} + engines: {node: '>=18.12.0'} + + unique-string@1.0.0: + resolution: {integrity: sha512-ODgiYu03y5g76A1I9Gt0/chLCzQjvzDy7DsZGsLOE/1MrF6wriEskSncj1+/C58Xk/kPZDppSctDybCwOSaGAg==} + engines: {node: '>=4'} + + unist-util-is@6.0.0: + resolution: {integrity: sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==} + + unist-util-position@5.0.0: + resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==} + + unist-util-stringify-position@4.0.0: + resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} + + unist-util-visit-parents@6.0.1: + resolution: {integrity: sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==} + + unist-util-visit@5.0.0: + resolution: {integrity: sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==} + + universalify@0.1.2: + resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} + engines: {node: '>= 4.0.0'} + + universalify@0.2.0: + resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==} + engines: {node: '>= 4.0.0'} + + unixify@1.0.0: + resolution: {integrity: sha512-6bc58dPYhCMHHuwxldQxO3RRNZ4eCogZ/st++0+fcC1nr0jiGUtAdBJ2qzmLQWSxbtz42pWt4QQMiZ9HvZf5cg==} + engines: {node: '>=0.10.0'} + + unocss@0.59.4: + resolution: {integrity: sha512-QmCVjRObvVu/gsGrJGVt0NnrdhFFn314BUZn2WQyXV9rIvHLRmG5bIu0j5vibJkj7ZhFchTrnTM1pTFXP1xt5g==} + engines: {node: '>=14'} + peerDependencies: + '@unocss/webpack': 0.59.4 + vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0 || ^5.0.0-0 + peerDependenciesMeta: + '@unocss/webpack': + optional: true + vite: + optional: true + + unpipe@1.0.0: + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} + engines: {node: '>= 0.8'} + + unplugin-utils@0.2.4: + resolution: {integrity: sha512-8U/MtpkPkkk3Atewj1+RcKIjb5WBimZ/WSLhhR3w6SsIj8XJuKTacSP8g+2JhfSGw0Cb125Y+2zA/IzJZDVbhA==} + engines: {node: '>=18.12.0'} + + unplugin-vue-router@0.12.0: + resolution: {integrity: sha512-xjgheKU0MegvXQcy62GVea0LjyOdMxN0/QH+ijN29W62ZlMhG7o7K+0AYqfpprvPwpWtuRjiyC5jnV2SxWye2w==} + peerDependencies: + vue-router: ^4.4.0 + peerDependenciesMeta: + vue-router: + optional: true + + unplugin@1.10.1: + resolution: {integrity: sha512-d6Mhq8RJeGA8UfKCu54Um4lFA0eSaRa3XxdAJg8tIdxbu1ubW0hBCZUL7yI2uGyYCRndvbK8FLHzqy2XKfeMsg==} + engines: {node: '>=14.0.0'} + + unplugin@1.16.1: + resolution: {integrity: sha512-4/u/j4FrCKdi17jaxuJA0jClGxB1AvU2hw/IuayPc4ay1XGaJs/rbb4v5WKwAjNifjmXK9PIFyuPiaK8azyR9w==} + engines: {node: '>=14.0.0'} + + unplugin@2.3.4: + resolution: {integrity: sha512-m4PjxTurwpWfpMomp8AptjD5yj8qEZN5uQjjGM3TAs9MWWD2tXSSNNj6jGR2FoVGod4293ytyV6SwBbertfyJg==} + engines: {node: '>=18.12.0'} + + unstorage@1.10.2: + resolution: {integrity: sha512-cULBcwDqrS8UhlIysUJs2Dk0Mmt8h7B0E6mtR+relW9nZvsf/u4SkAYyNliPiPW7XtFNb5u3IUMkxGxFTTRTgQ==} + peerDependencies: + '@azure/app-configuration': ^1.5.0 + '@azure/cosmos': ^4.0.0 + '@azure/data-tables': ^13.2.2 + '@azure/identity': ^4.0.1 + '@azure/keyvault-secrets': ^4.8.0 + '@azure/storage-blob': ^12.17.0 + '@capacitor/preferences': ^5.0.7 + '@netlify/blobs': ^6.5.0 || ^7.0.0 + '@planetscale/database': ^1.16.0 + '@upstash/redis': ^1.28.4 + '@vercel/kv': ^1.0.1 + idb-keyval: ^6.2.1 + ioredis: ^5.3.2 + peerDependenciesMeta: + '@azure/app-configuration': + optional: true + '@azure/cosmos': + optional: true + '@azure/data-tables': + optional: true + '@azure/identity': + optional: true + '@azure/keyvault-secrets': + optional: true + '@azure/storage-blob': + optional: true + '@capacitor/preferences': + optional: true + '@netlify/blobs': + optional: true + '@planetscale/database': + optional: true + '@upstash/redis': + optional: true + '@vercel/kv': + optional: true + idb-keyval: + optional: true + ioredis: + optional: true + + unstorage@1.16.0: + resolution: {integrity: sha512-WQ37/H5A7LcRPWfYOrDa1Ys02xAbpPJq6q5GkO88FBXVSQzHd7+BjEwfRqyaSWCv9MbsJy058GWjjPjcJ16GGA==} + peerDependencies: + '@azure/app-configuration': ^1.8.0 + '@azure/cosmos': ^4.2.0 + '@azure/data-tables': ^13.3.0 + '@azure/identity': ^4.6.0 + '@azure/keyvault-secrets': ^4.9.0 + '@azure/storage-blob': ^12.26.0 + '@capacitor/preferences': ^6.0.3 || ^7.0.0 + '@deno/kv': '>=0.9.0' + '@netlify/blobs': ^6.5.0 || ^7.0.0 || ^8.1.0 + '@planetscale/database': ^1.19.0 + '@upstash/redis': ^1.34.3 + '@vercel/blob': '>=0.27.1' + '@vercel/kv': ^1.0.1 + aws4fetch: ^1.0.20 + db0: '>=0.2.1' + idb-keyval: ^6.2.1 + ioredis: ^5.4.2 + uploadthing: ^7.4.4 + peerDependenciesMeta: + '@azure/app-configuration': + optional: true + '@azure/cosmos': + optional: true + '@azure/data-tables': + optional: true + '@azure/identity': + optional: true + '@azure/keyvault-secrets': + optional: true + '@azure/storage-blob': + optional: true + '@capacitor/preferences': + optional: true + '@deno/kv': + optional: true + '@netlify/blobs': + optional: true + '@planetscale/database': + optional: true + '@upstash/redis': + optional: true + '@vercel/blob': + optional: true + '@vercel/kv': + optional: true + aws4fetch: + optional: true + db0: + optional: true + idb-keyval: + optional: true + ioredis: + optional: true + uploadthing: + optional: true + + untun@0.1.3: + resolution: {integrity: sha512-4luGP9LMYszMRZwsvyUd9MrxgEGZdZuZgpVQHEEX0lCYFESasVRvZd0EYpCkOIbJKHMuv0LskpXc/8Un+MJzEQ==} + hasBin: true + + untyped@1.4.2: + resolution: {integrity: sha512-nC5q0DnPEPVURPhfPQLahhSTnemVtPzdx7ofiRxXpOB2SYnb3MfdU3DVGyJdS8Lx+tBWeAePO8BfU/3EgksM7Q==} + hasBin: true + + untyped@2.0.0: + resolution: {integrity: sha512-nwNCjxJTjNuLCgFr42fEak5OcLuB3ecca+9ksPFNvtfYSLpjf+iJqSIaSnIile6ZPbKYxI5k2AfXqeopGudK/g==} + hasBin: true + + unwasm@0.3.9: + resolution: {integrity: sha512-LDxTx/2DkFURUd+BU1vUsF/moj0JsoTvl+2tcg2AUOiEzVturhGGx17/IMgGvKUYdZwr33EJHtChCJuhu9Ouvg==} + + update-browserslist-db@1.0.15: + resolution: {integrity: sha512-K9HWH62x3/EalU1U6sjSZiylm9C8tgq2mSvshZpqc7QE69RaA2qjhkW2HlNA0tFpEbtyFz7HTqbSdN4MSwUodA==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + update-browserslist-db@1.1.3: + resolution: {integrity: sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + uqr@0.1.2: + resolution: {integrity: sha512-MJu7ypHq6QasgF5YRTjqscSzQp/W11zoUk6kvmlH+fmWEs63Y0Eib13hYFwAzagRJcVY8WVnlV+eBDUGMJ5IbA==} + + url-parse@1.5.10: + resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==} + + urlpattern-polyfill@10.1.0: + resolution: {integrity: sha512-IGjKp/o0NL3Bso1PymYURCJxMPNAf/ILOpendP9f5B6e1rTJgdgiOvgfoT8VxCAdY+Wisb9uhGaJJf3yZ2V9nw==} + + urlpattern-polyfill@8.0.2: + resolution: {integrity: sha512-Qp95D4TPJl1kC9SKigDcqgyM2VDVO4RiJc2d4qe5GrYm+zbIQCWWKAFaJNQ4BhdFeDGwBmAxqJBwWSJDb9T3BQ==} + + use-sync-external-store@1.2.0: + resolution: {integrity: sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + + use-sync-external-store@1.4.0: + resolution: {integrity: sha512-9WXSPC5fMv61vaupRkCKCxsPxBocVnwakBEkMIHHpkTTg6icbJtg6jzgtLDm4bl3cSHAca52rYWih0k4K3PfHw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + utf-8-validate@5.0.10: + resolution: {integrity: sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==} + engines: {node: '>=6.14.2'} + + utf-8-validate@6.0.5: + resolution: {integrity: sha512-EYZR+OpIXp9Y1eG1iueg8KRsY8TuT8VNgnanZ0uA3STqhHQTLwbl+WX76/9X5OY12yQubymBpaBSmMPkSTQcKA==} + engines: {node: '>=6.14.2'} + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + util@0.12.5: + resolution: {integrity: sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==} + + uuid@11.1.0: + resolution: {integrity: sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==} + hasBin: true + + uuid@8.3.2: + resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} + hasBin: true + + uuid@9.0.1: + resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} + hasBin: true + + validate-npm-package-license@3.0.4: + resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} + + validate-npm-package-name@5.0.1: + resolution: {integrity: sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + valtio@1.13.2: + resolution: {integrity: sha512-Qik0o+DSy741TmkqmRfjq+0xpZBXi/Y6+fXZLn0xNF1z/waFMbE3rkivv5Zcf9RrMUp6zswf2J7sbh2KBlba5A==} + engines: {node: '>=12.20.0'} + peerDependencies: + '@types/react': '>=16.8' + react: '>=16.8' + peerDependenciesMeta: + '@types/react': + optional: true + react: + optional: true + + vfile-message@4.0.2: + resolution: {integrity: sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==} + + vfile@6.0.1: + resolution: {integrity: sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==} + + viem@2.10.8: + resolution: {integrity: sha512-ttCXlDmjjcZ8M/eJezXFzDtHj+RFOjEQ3elmXnCC7suXo/y8CuIM1LrIoyUFk7LKIE5E+bzmWUErS4u/MQBtpQ==} + peerDependencies: + typescript: '>=5.0.4' + peerDependenciesMeta: + typescript: + optional: true + + viem@2.17.0: + resolution: {integrity: sha512-+gaVlsfDsHL1oYdjpatdRxW1WK/slLYVvpOws3fEdLfQFUToezKI6YLC9l1g2uKm4Hg3OdGX1KQy/G7/58tTKQ==} + peerDependencies: + typescript: '>=5.0.4' + peerDependenciesMeta: + typescript: + optional: true + + viem@2.23.2: + resolution: {integrity: sha512-NVmW/E0c5crMOtbEAqMF0e3NmvQykFXhLOc/CkLIXOlzHSA6KXVz3CYVmaKqBF8/xtjsjHAGjdJN3Ru1kFJLaA==} + peerDependencies: + typescript: '>=5.0.4' + peerDependenciesMeta: + typescript: + optional: true + + viem@2.29.2: + resolution: {integrity: sha512-cukRxab90jvQ+TDD84sU3qB3UmejYqgCw4cX8SfWzvh7JPfZXI3kAMUaT5OSR2As1Mgvx1EJawccwPjGqkSSwA==} + peerDependencies: + typescript: '>=5.0.4' + peerDependenciesMeta: + typescript: + optional: true + + vite-dev-rpc@1.0.7: + resolution: {integrity: sha512-FxSTEofDbUi2XXujCA+hdzCDkXFG1PXktMjSk1efq9Qb5lOYaaM9zNSvKvPPF7645Bak79kSp1PTooMW2wktcA==} + peerDependencies: + vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0-0 || ^5.0.0-0 || ^6.0.1 + + vite-hot-client@2.0.4: + resolution: {integrity: sha512-W9LOGAyGMrbGArYJN4LBCdOC5+Zwh7dHvOHC0KmGKkJhsOzaKbpo/jEjpPKVHIW0/jBWj8RZG0NUxfgA8BxgAg==} + peerDependencies: + vite: ^2.6.0 || ^3.0.0 || ^4.0.0 || ^5.0.0-0 || ^6.0.0-0 + + vite-node@2.1.9: + resolution: {integrity: sha512-AM9aQ/IPrW/6ENLQg3AGY4K1N2TGZdR5e4gu/MmmR2xR3Ll1+dib+nook92g4TV3PXVyeyxdWwtaCAiUL0hMxA==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + + vite-node@3.1.4: + resolution: {integrity: sha512-6enNwYnpyDo4hEgytbmc6mYWHXDHYEn0D1/rw4Q+tnHUGtKTJsn8T1YkX6Q18wI5LCrS8CTYlBaiCqxOy2kvUA==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + hasBin: true + + vite-plugin-checker@0.9.3: + resolution: {integrity: sha512-Tf7QBjeBtG7q11zG0lvoF38/2AVUzzhMNu+Wk+mcsJ00Rk/FpJ4rmUviVJpzWkagbU13cGXvKpt7CMiqtxVTbQ==} + engines: {node: '>=14.16'} + peerDependencies: + '@biomejs/biome': '>=1.7' + eslint: '>=7' + meow: ^13.2.0 + optionator: ^0.9.4 + stylelint: '>=16' + typescript: '*' + vite: '>=2.0.0' + vls: '*' + vti: '*' + vue-tsc: ~2.2.10 + peerDependenciesMeta: + '@biomejs/biome': + optional: true + eslint: + optional: true + meow: + optional: true + optionator: + optional: true + stylelint: + optional: true + typescript: + optional: true + vls: + optional: true + vti: + optional: true + vue-tsc: + optional: true + + vite-plugin-inspect@11.1.0: + resolution: {integrity: sha512-r3Nx8xGQ08bSoNu7gJGfP5H/wNOROHtv0z3tWspplyHZJlABwNoPOdFEmcVh+lVMDyk/Be4yt8oS596ZHoYhOg==} + engines: {node: '>=14'} + peerDependencies: + '@nuxt/kit': '*' + vite: ^6.0.0 + peerDependenciesMeta: + '@nuxt/kit': + optional: true + + vite-plugin-vue-tracer@0.1.3: + resolution: {integrity: sha512-+fN6oo0//dwZP9Ax9gRKeUroCqpQ43P57qlWgL0ljCIxAs+Rpqn/L4anIPZPgjDPga5dZH+ZJsshbF0PNJbm3Q==} + peerDependencies: + vite: ^6.0.0 + vue: ^3.5.0 + + vite@5.4.19: + resolution: {integrity: sha512-qO3aKv3HoQC8QKiNSTuUM1l9o/XX3+c+VTgLHbJWHZGeTPVAg2XwazI9UWzoxjIJCGCV2zU60uqMzjeLZuULqA==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || >=20.0.0 + less: '*' + lightningcss: ^1.21.0 + sass: '*' + sass-embedded: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + + vite@6.3.5: + resolution: {integrity: sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 + jiti: '>=1.21.0' + less: '*' + lightningcss: ^1.21.0 + sass: '*' + sass-embedded: '*' + stylus: '*' + sugarss: '*' + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + jiti: + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + + vitepress@1.5.0: + resolution: {integrity: sha512-q4Q/G2zjvynvizdB3/bupdYkCJe2umSAMv9Ju4d92E6/NXJ59z70xB0q5p/4lpRyAwflDsbwy1mLV9Q5+nlB+g==} + hasBin: true + peerDependencies: + markdown-it-mathjax3: ^4 + postcss: ^8 + peerDependenciesMeta: + markdown-it-mathjax3: + optional: true + postcss: + optional: true + + vitest@2.1.9: + resolution: {integrity: sha512-MSmPM9REYqDGBI8439mA4mWhV5sKmDlBKWIYbA3lRb2PTHACE0mgKwA8yQ2xq9vxDTuk4iPrECBAEW2aoFXY0Q==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@types/node': ^18.0.0 || >=20.0.0 + '@vitest/browser': 2.1.9 + '@vitest/ui': 2.1.9 + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@types/node': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + + vscode-uri@3.1.0: + resolution: {integrity: sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==} + + vue-bundle-renderer@2.1.1: + resolution: {integrity: sha512-+qALLI5cQncuetYOXp4yScwYvqh8c6SMXee3B+M7oTZxOgtESP0l4j/fXdEJoZ+EdMxkGWIj+aSEyjXkOdmd7g==} + + vue-component-type-helpers@2.0.16: + resolution: {integrity: sha512-qisL/iAfdO++7w+SsfYQJVPj6QKvxp4i1MMxvsNO41z/8zu3KuAw9LkhKUfP/kcOWGDxESp+pQObWppXusejCA==} + + vue-demi@0.14.10: + resolution: {integrity: sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==} + engines: {node: '>=12'} + hasBin: true + peerDependencies: + '@vue/composition-api': ^1.0.0-rc.1 + vue: ^3.0.0-0 || ^2.6.0 + peerDependenciesMeta: + '@vue/composition-api': + optional: true + + vue-devtools-stub@0.1.0: + resolution: {integrity: sha512-RutnB7X8c5hjq39NceArgXg28WZtZpGc3+J16ljMiYnFhKvd8hITxSWQSQ5bvldxMDU6gG5mkxl1MTQLXckVSQ==} + + vue-resize@2.0.0-alpha.1: + resolution: {integrity: sha512-7+iqOueLU7uc9NrMfrzbG8hwMqchfVfSzpVlCMeJQe4pyibqyoifDNbKTZvwxZKDvGkB+PdFeKvnGZMoEb8esg==} + peerDependencies: + vue: ^3.0.0 + + vue-router@4.3.2: + resolution: {integrity: sha512-hKQJ1vDAZ5LVkKEnHhmm1f9pMiWIBNGF5AwU67PdH7TyXCj/a4hTccuUuYCAMgJK6rO/NVYtQIEN3yL8CECa7Q==} + peerDependencies: + vue: ^3.2.0 + + vue-router@4.5.1: + resolution: {integrity: sha512-ogAF3P97NPm8fJsE4by9dwSYtDwXIY1nFY9T6DyQnGHd1E2Da94w9JIolpe42LJGIl0DwOHBi8TcRPlPGwbTtw==} + peerDependencies: + vue: ^3.2.0 + + vue-template-compiler@2.7.16: + resolution: {integrity: sha512-AYbUWAJHLGGQM7+cNTELw+KsOG9nl2CnSv467WobS5Cv9uk3wFcnr1Etsz2sEIHEZvw1U+o9mRlEO6QbZvUPGQ==} + + vue-tsc@2.0.16: + resolution: {integrity: sha512-/gHAWJa216PeEhfxtAToIbxdWgw01wuQzo48ZUqMYVEyNqDp+OYV9xMO5HaPS2P3Ls0+EsjguMZLY4cGobX4Ew==} + hasBin: true + peerDependencies: + typescript: '*' + + vue@3.4.27: + resolution: {integrity: sha512-8s/56uK6r01r1icG/aEOHqyMVxd1bkYcSe9j8HcKtr/xTOFWvnzIVTehNW+5Yt89f+DLBe4A569pnZLS5HzAMA==} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + vue@3.5.12: + resolution: {integrity: sha512-CLVZtXtn2ItBIi/zHZ0Sg1Xkb7+PU32bJJ8Bmy7ts3jxXTcbfsEfBivFYYWz1Hur+lalqGAh65Coin0r+HRUfg==} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + vue@3.5.14: + resolution: {integrity: sha512-LbOm50/vZFG6Mhy6KscQYXZMQ0LMCC/y40HDJPPvGFQ+i/lUH+PJHR6C3assgOQiXdl6tAfsXHbXYVBZZu65ew==} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + wcwidth@1.0.1: + resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} + + web-streams-polyfill@3.3.3: + resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==} + engines: {node: '>= 8'} + + webextension-polyfill@0.10.0: + resolution: {integrity: sha512-c5s35LgVa5tFaHhrZDnr3FpQpjj1BB+RXhLTYUxGqBVN460HkbM8TBtEqdXWbpTKfzwCcjAZVF7zXCYSKtcp9g==} + + webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + + webidl-conversions@7.0.0: + resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==} + engines: {node: '>=12'} + + webpack-bundle-analyzer@4.10.1: + resolution: {integrity: sha512-s3P7pgexgT/HTUSYgxJyn28A+99mmLq4HsJepMPzu0R8ImJc52QNqaFYW1Z2z2uIb1/J3eYgaAWVpaC+v/1aAQ==} + engines: {node: '>= 10.13.0'} + hasBin: true + + webpack-sources@3.2.3: + resolution: {integrity: sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==} + engines: {node: '>=10.13.0'} + + webpack-virtual-modules@0.6.1: + resolution: {integrity: sha512-poXpCylU7ExuvZK8z+On3kX+S8o/2dQ/SVYueKA0D4WEMXROXgY8Ez50/bQEUmvoSMMrWcrJqCHuhAbsiwg7Dg==} + + webpack-virtual-modules@0.6.2: + resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==} + + whatwg-mimetype@3.0.0: + resolution: {integrity: sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==} + engines: {node: '>=12'} + + whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + + which-module@2.0.0: + resolution: {integrity: sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==} + + which-typed-array@1.1.19: + resolution: {integrity: sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==} + engines: {node: '>= 0.4'} + + which@1.3.1: + resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} + hasBin: true + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + which@5.0.0: + resolution: {integrity: sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==} + engines: {node: ^18.17.0 || >=20.5.0} + hasBin: true + + why-is-node-running@2.3.0: + resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} + engines: {node: '>=8'} + hasBin: true + + wide-align@1.1.5: + resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==} + + widest-line@3.1.0: + resolution: {integrity: sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==} + engines: {node: '>=8'} + + winston-transport@4.9.0: + resolution: {integrity: sha512-8drMJ4rkgaPo1Me4zD/3WLfI/zPdA9o2IipKODunnGDcuqbHwjsbB79ylv04LCGGzU0xQ6vTznOMpQGaLhhm6A==} + engines: {node: '>= 12.0.0'} + + winston@3.17.0: + resolution: {integrity: sha512-DLiFIXYC5fMPxaRg832S6F5mJYvePtmO5G9v9IgUFPhXm9/GkXarH/TUrBAVzhTCzAj9anE/+GjrgXp/54nOgw==} + engines: {node: '>= 12.0.0'} + + workerpool@6.2.1: + resolution: {integrity: sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==} + + wrap-ansi@6.2.0: + resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} + engines: {node: '>=8'} + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + write-file-atomic@6.0.0: + resolution: {integrity: sha512-GmqrO8WJ1NuzJ2DrziEI2o57jKAVIQNf8a18W3nCYU3H7PNWqCCVTeH6/NQE93CIllIgQS98rrmVkYgTX9fFJQ==} + engines: {node: ^18.17.0 || >=20.5.0} + + ws@7.5.10: + resolution: {integrity: sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==} + engines: {node: '>=8.3.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + ws@7.5.9: + resolution: {integrity: sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==} + engines: {node: '>=8.3.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + ws@8.13.0: + resolution: {integrity: sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + ws@8.17.1: + resolution: {integrity: sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + ws@8.18.0: + resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + ws@8.18.1: + resolution: {integrity: sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + ws@8.18.2: + resolution: {integrity: sha512-DMricUmwGZUVr++AEAe2uiVM7UoO9MAVZMDu05UQOaUII0lp+zOzLLU4Xqh/JvTqklB1T4uELaaPBKyjE1r4fQ==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + xmlhttprequest-ssl@2.1.2: + resolution: {integrity: sha512-TEU+nJVUUnA4CYJFLvK5X9AOeH4KvDvhIfm0vV1GaQRtchnG0hgK5p8hw/xjv8cunWYCsiPCSDzObPyhEwq3KQ==} + engines: {node: '>=0.4.0'} + + xtend@4.0.2: + resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} + engines: {node: '>=0.4'} + + y18n@4.0.3: + resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==} + + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + + yallist@2.1.2: + resolution: {integrity: sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==} + + yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + + yallist@4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + + yallist@5.0.0: + resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==} + engines: {node: '>=18'} + + yaml@2.8.0: + resolution: {integrity: sha512-4lLa/EcQCB0cJkyts+FpIRx5G/llPxfP6VQU5KByHEhLxY3IJCH0f0Hy1MHI8sClTvsIb8qwRJ6R/ZdlDJ/leQ==} + engines: {node: '>= 14.6'} + hasBin: true + + yargs-parser@18.1.3: + resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==} + engines: {node: '>=6'} + + yargs-parser@20.2.4: + resolution: {integrity: sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==} + engines: {node: '>=10'} + + yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + + yargs-unparser@2.0.0: + resolution: {integrity: sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==} + engines: {node: '>=10'} + + yargs@15.4.1: + resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==} + engines: {node: '>=8'} + + yargs@16.2.0: + resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} + engines: {node: '>=10'} + + yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + + yauzl@2.10.0: + resolution: {integrity: sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==} + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + + yocto-queue@1.2.1: + resolution: {integrity: sha512-AyeEbWOu/TAXdxlV9wmGcR0+yh2j3vYPGOECcIj2S7MkrLyC7ne+oye2BKTItt0ii2PHk4cDy+95+LshzbXnGg==} + engines: {node: '>=12.20'} + + yoctocolors@2.0.2: + resolution: {integrity: sha512-Ct97huExsu7cWeEjmrXlofevF8CvzUglJ4iGUet5B8xn1oumtAZBpHU4GzYuoE6PVqcZ5hghtBrSlhwHuR1Jmw==} + engines: {node: '>=18'} + + youch-core@0.3.2: + resolution: {integrity: sha512-fusrlIMLeRvTFYLUjJ9KzlGC3N+6MOPJ68HNj/yJv2nz7zq8t4HEviLms2gkdRPUS7F5rZ5n+pYx9r88m6IE1g==} + engines: {node: '>=18'} + + youch@4.1.0-beta.7: + resolution: {integrity: sha512-HUn0M24AUTMvjdkoMtH8fJz2FEd+k1xvtR9EoTrDUoVUi6o7xl5X+pST/vjk4T3GEQo2mJ9FlAvhWBm8dIdD4g==} + engines: {node: '>=18'} + + zip-stream@4.1.1: + resolution: {integrity: sha512-9qv4rlDiopXg4E69k+vMHjNN63YFMe9sZMrdlvKnCjlCRWeCBswPPMPUfx+ipsAWq1LXHe70RcbaHdJJpS6hyQ==} + engines: {node: '>= 10'} + + zip-stream@6.0.1: + resolution: {integrity: sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA==} + engines: {node: '>= 14'} + + zod-validation-error@3.2.0: + resolution: {integrity: sha512-cYlPR6zuyrgmu2wRTdumEAJGuwI7eHVHGT+VyneAQxmRAKtGRL1/7pjz4wfLhz4J05f5qoSZc3rGacswgyTjjw==} + engines: {node: '>=18.0.0'} + peerDependencies: + zod: ^3.18.0 + + zod@3.22.4: + resolution: {integrity: sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==} + + zod@3.25.20: + resolution: {integrity: sha512-z03fqpTMDF1G02VLKUMt6vyACE7rNWkh3gpXVHgPTw28NPtDFRGvcpTtPwn2kMKtQ0idtYJUTxchytmnqYswcw==} + + zustand@5.0.0: + resolution: {integrity: sha512-LE+VcmbartOPM+auOjCCLQOsQ05zUTp8RkgwRzefUk+2jISdMMFnxvyTjA4YNWr5ZGXYbVsEMZosttuxUBkojQ==} + engines: {node: '>=12.20.0'} + peerDependencies: + '@types/react': '>=18.0.0' + immer: '>=9.0.6' + react: '>=18.0.0' + use-sync-external-store: '>=1.2.0' + peerDependenciesMeta: + '@types/react': + optional: true + immer: + optional: true + react: + optional: true + use-sync-external-store: + optional: true + + zwitch@2.0.4: + resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} + +snapshots: + + '@adraffy/ens-normalize@1.10.0': {} + + '@adraffy/ens-normalize@1.11.0': {} + + '@algolia/autocomplete-core@1.9.3(@algolia/client-search@5.12.0)(algoliasearch@5.12.0)': + dependencies: + '@algolia/autocomplete-plugin-algolia-insights': 1.9.3(@algolia/client-search@5.12.0)(algoliasearch@5.12.0) + '@algolia/autocomplete-shared': 1.9.3(@algolia/client-search@5.12.0)(algoliasearch@5.12.0) + transitivePeerDependencies: + - '@algolia/client-search' + - algoliasearch + - search-insights + + '@algolia/autocomplete-plugin-algolia-insights@1.9.3(@algolia/client-search@5.12.0)(algoliasearch@5.12.0)': + dependencies: + '@algolia/autocomplete-shared': 1.9.3(@algolia/client-search@5.12.0)(algoliasearch@5.12.0) + transitivePeerDependencies: + - '@algolia/client-search' + - algoliasearch + + '@algolia/autocomplete-preset-algolia@1.17.6(@algolia/client-search@5.12.0)(algoliasearch@5.12.0)': + dependencies: + '@algolia/autocomplete-shared': 1.17.6(@algolia/client-search@5.12.0)(algoliasearch@5.12.0) + '@algolia/client-search': 5.12.0 + algoliasearch: 5.12.0 + + '@algolia/autocomplete-shared@1.17.6(@algolia/client-search@5.12.0)(algoliasearch@5.12.0)': + dependencies: + '@algolia/client-search': 5.12.0 + algoliasearch: 5.12.0 + + '@algolia/autocomplete-shared@1.9.3(@algolia/client-search@5.12.0)(algoliasearch@5.12.0)': + dependencies: + '@algolia/client-search': 5.12.0 + algoliasearch: 5.12.0 + + '@algolia/client-abtesting@5.12.0': + dependencies: + '@algolia/client-common': 5.12.0 + '@algolia/requester-browser-xhr': 5.12.0 + '@algolia/requester-fetch': 5.12.0 + '@algolia/requester-node-http': 5.12.0 + + '@algolia/client-analytics@5.12.0': + dependencies: + '@algolia/client-common': 5.12.0 + '@algolia/requester-browser-xhr': 5.12.0 + '@algolia/requester-fetch': 5.12.0 + '@algolia/requester-node-http': 5.12.0 + + '@algolia/client-common@5.12.0': {} + + '@algolia/client-insights@5.12.0': + dependencies: + '@algolia/client-common': 5.12.0 + '@algolia/requester-browser-xhr': 5.12.0 + '@algolia/requester-fetch': 5.12.0 + '@algolia/requester-node-http': 5.12.0 + + '@algolia/client-personalization@5.12.0': + dependencies: + '@algolia/client-common': 5.12.0 + '@algolia/requester-browser-xhr': 5.12.0 + '@algolia/requester-fetch': 5.12.0 + '@algolia/requester-node-http': 5.12.0 + + '@algolia/client-query-suggestions@5.12.0': + dependencies: + '@algolia/client-common': 5.12.0 + '@algolia/requester-browser-xhr': 5.12.0 + '@algolia/requester-fetch': 5.12.0 + '@algolia/requester-node-http': 5.12.0 + + '@algolia/client-search@5.12.0': + dependencies: + '@algolia/client-common': 5.12.0 + '@algolia/requester-browser-xhr': 5.12.0 + '@algolia/requester-fetch': 5.12.0 + '@algolia/requester-node-http': 5.12.0 + + '@algolia/ingestion@1.12.0': + dependencies: + '@algolia/client-common': 5.12.0 + '@algolia/requester-browser-xhr': 5.12.0 + '@algolia/requester-fetch': 5.12.0 + '@algolia/requester-node-http': 5.12.0 + + '@algolia/monitoring@1.12.0': + dependencies: + '@algolia/client-common': 5.12.0 + '@algolia/requester-browser-xhr': 5.12.0 + '@algolia/requester-fetch': 5.12.0 + '@algolia/requester-node-http': 5.12.0 + + '@algolia/recommend@5.12.0': + dependencies: + '@algolia/client-common': 5.12.0 + '@algolia/requester-browser-xhr': 5.12.0 + '@algolia/requester-fetch': 5.12.0 + '@algolia/requester-node-http': 5.12.0 + + '@algolia/requester-browser-xhr@5.12.0': + dependencies: + '@algolia/client-common': 5.12.0 + + '@algolia/requester-fetch@5.12.0': + dependencies: + '@algolia/client-common': 5.12.0 + + '@algolia/requester-node-http@5.12.0': + dependencies: + '@algolia/client-common': 5.12.0 + + '@ampproject/remapping@2.2.1': + dependencies: + '@jridgewell/gen-mapping': 0.3.3 + '@jridgewell/trace-mapping': 0.3.17 + + '@ampproject/remapping@2.3.0': + dependencies: + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 + + '@andrewbranch/untar.js@1.0.3': {} + + '@antfu/install-pkg@0.1.1': + dependencies: + execa: 5.1.1 + find-up: 5.0.0 + + '@antfu/utils@0.7.7': {} + + '@arethetypeswrong/cli@0.16.4': + dependencies: + '@arethetypeswrong/core': 0.16.4 + chalk: 4.1.2 + cli-table3: 0.6.5 + commander: 10.0.1 + marked: 9.1.6 + marked-terminal: 7.1.0(marked@9.1.6) + semver: 7.6.2 + + '@arethetypeswrong/core@0.16.4': + dependencies: + '@andrewbranch/untar.js': 1.0.3 + cjs-module-lexer: 1.4.1 + fflate: 0.8.2 + lru-cache: 10.4.3 + semver: 7.7.2 + typescript: 5.6.1-rc + validate-npm-package-name: 5.0.1 + + '@babel/code-frame@7.24.2': + dependencies: + '@babel/highlight': 7.24.5 + picocolors: 1.1.1 + + '@babel/code-frame@7.27.1': + dependencies: + '@babel/helper-validator-identifier': 7.27.1 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/compat-data@7.24.4': {} + + '@babel/compat-data@7.27.2': {} + + '@babel/core@7.24.5': + dependencies: + '@ampproject/remapping': 2.2.1 + '@babel/code-frame': 7.24.2 + '@babel/generator': 7.24.5 + '@babel/helper-compilation-targets': 7.23.6 + '@babel/helper-module-transforms': 7.24.5(@babel/core@7.24.5) + '@babel/helpers': 7.24.5 + '@babel/parser': 7.24.5 + '@babel/template': 7.24.0 + '@babel/traverse': 7.24.5 + '@babel/types': 7.24.5 + convert-source-map: 2.0.0 + debug: 4.4.1 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/core@7.27.1': + dependencies: + '@ampproject/remapping': 2.3.0 + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.27.1 + '@babel/helper-compilation-targets': 7.27.2 + '@babel/helper-module-transforms': 7.27.1(@babel/core@7.27.1) + '@babel/helpers': 7.27.1 + '@babel/parser': 7.27.2 + '@babel/template': 7.27.2 + '@babel/traverse': 7.27.1 + '@babel/types': 7.27.1 + convert-source-map: 2.0.0 + debug: 4.4.1 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/generator@7.24.5': + dependencies: + '@babel/types': 7.27.1 + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 + jsesc: 2.5.2 + + '@babel/generator@7.27.1': + dependencies: + '@babel/parser': 7.27.2 + '@babel/types': 7.27.1 + '@jridgewell/gen-mapping': 0.3.8 + '@jridgewell/trace-mapping': 0.3.25 + jsesc: 3.1.0 + + '@babel/helper-annotate-as-pure@7.22.5': + dependencies: + '@babel/types': 7.27.1 + + '@babel/helper-annotate-as-pure@7.27.1': + dependencies: + '@babel/types': 7.27.1 + + '@babel/helper-compilation-targets@7.23.6': + dependencies: + '@babel/compat-data': 7.24.4 + '@babel/helper-validator-option': 7.23.5 + browserslist: 4.23.0 + lru-cache: 5.1.1 + semver: 6.3.1 + + '@babel/helper-compilation-targets@7.27.2': + dependencies: + '@babel/compat-data': 7.27.2 + '@babel/helper-validator-option': 7.27.1 + browserslist: 4.24.5 + lru-cache: 5.1.1 + semver: 6.3.1 + + '@babel/helper-create-class-features-plugin@7.24.5(@babel/core@7.24.5)': + dependencies: + '@babel/core': 7.24.5 + '@babel/helper-annotate-as-pure': 7.27.1 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-function-name': 7.23.0 + '@babel/helper-member-expression-to-functions': 7.24.5 + '@babel/helper-optimise-call-expression': 7.22.5 + '@babel/helper-replace-supers': 7.24.1(@babel/core@7.24.5) + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/helper-split-export-declaration': 7.24.5 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/helper-create-class-features-plugin@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-annotate-as-pure': 7.27.1 + '@babel/helper-member-expression-to-functions': 7.27.1 + '@babel/helper-optimise-call-expression': 7.27.1 + '@babel/helper-replace-supers': 7.27.1(@babel/core@7.27.1) + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/traverse': 7.27.1 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/helper-environment-visitor@7.22.20': {} + + '@babel/helper-function-name@7.23.0': + dependencies: + '@babel/template': 7.24.0 + '@babel/types': 7.27.1 + + '@babel/helper-hoist-variables@7.22.5': + dependencies: + '@babel/types': 7.27.1 + + '@babel/helper-member-expression-to-functions@7.24.5': + dependencies: + '@babel/types': 7.27.1 + + '@babel/helper-member-expression-to-functions@7.27.1': + dependencies: + '@babel/traverse': 7.27.1 + '@babel/types': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-imports@7.24.3': + dependencies: + '@babel/types': 7.27.1 + + '@babel/helper-module-imports@7.27.1': + dependencies: + '@babel/traverse': 7.27.1 + '@babel/types': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-transforms@7.24.5(@babel/core@7.24.5)': + dependencies: + '@babel/core': 7.24.5 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-module-imports': 7.24.3 + '@babel/helper-simple-access': 7.24.5 + '@babel/helper-split-export-declaration': 7.24.5 + '@babel/helper-validator-identifier': 7.24.5 + + '@babel/helper-module-transforms@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-module-imports': 7.27.1 + '@babel/helper-validator-identifier': 7.27.1 + '@babel/traverse': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/helper-optimise-call-expression@7.22.5': + dependencies: + '@babel/types': 7.27.1 + + '@babel/helper-optimise-call-expression@7.27.1': + dependencies: + '@babel/types': 7.27.1 + + '@babel/helper-plugin-utils@7.24.5': {} + + '@babel/helper-plugin-utils@7.27.1': {} + + '@babel/helper-replace-supers@7.24.1(@babel/core@7.24.5)': + dependencies: + '@babel/core': 7.24.5 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-member-expression-to-functions': 7.27.1 + '@babel/helper-optimise-call-expression': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/helper-replace-supers@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-member-expression-to-functions': 7.27.1 + '@babel/helper-optimise-call-expression': 7.27.1 + '@babel/traverse': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/helper-simple-access@7.24.5': + dependencies: + '@babel/types': 7.27.1 + + '@babel/helper-skip-transparent-expression-wrappers@7.27.1': + dependencies: + '@babel/traverse': 7.27.1 + '@babel/types': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/helper-split-export-declaration@7.24.5': + dependencies: + '@babel/types': 7.27.1 + + '@babel/helper-string-parser@7.24.1': {} + + '@babel/helper-string-parser@7.25.9': {} + + '@babel/helper-string-parser@7.27.1': {} + + '@babel/helper-validator-identifier@7.24.5': {} + + '@babel/helper-validator-identifier@7.25.9': {} + + '@babel/helper-validator-identifier@7.27.1': {} + + '@babel/helper-validator-option@7.23.5': {} + + '@babel/helper-validator-option@7.27.1': {} + + '@babel/helpers@7.24.5': + dependencies: + '@babel/template': 7.24.0 + '@babel/traverse': 7.24.5 + '@babel/types': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/helpers@7.27.1': + dependencies: + '@babel/template': 7.27.2 + '@babel/types': 7.27.1 + + '@babel/highlight@7.24.5': + dependencies: + '@babel/helper-validator-identifier': 7.25.9 + chalk: 2.4.2 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/parser@7.24.5': + dependencies: + '@babel/types': 7.27.1 + + '@babel/parser@7.26.2': + dependencies: + '@babel/types': 7.26.0 + + '@babel/parser@7.27.2': + dependencies: + '@babel/types': 7.27.1 + + '@babel/plugin-syntax-jsx@7.24.1(@babel/core@7.24.5)': + dependencies: + '@babel/core': 7.24.5 + '@babel/helper-plugin-utils': 7.24.5 + + '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-typescript@7.24.1(@babel/core@7.24.5)': + dependencies: + '@babel/core': 7.24.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-modules-commonjs@7.24.1(@babel/core@7.24.5)': + dependencies: + '@babel/core': 7.24.5 + '@babel/helper-module-transforms': 7.24.5(@babel/core@7.24.5) + '@babel/helper-plugin-utils': 7.24.5 + '@babel/helper-simple-access': 7.24.5 + + '@babel/plugin-transform-react-jsx-self@7.24.5(@babel/core@7.24.5)': + dependencies: + '@babel/core': 7.24.5 + '@babel/helper-plugin-utils': 7.24.5 + + '@babel/plugin-transform-react-jsx-source@7.24.1(@babel/core@7.24.5)': + dependencies: + '@babel/core': 7.24.5 + '@babel/helper-plugin-utils': 7.24.5 + + '@babel/plugin-transform-typescript@7.24.5(@babel/core@7.24.5)': + dependencies: + '@babel/core': 7.24.5 + '@babel/helper-annotate-as-pure': 7.22.5 + '@babel/helper-create-class-features-plugin': 7.24.5(@babel/core@7.24.5) + '@babel/helper-plugin-utils': 7.24.5 + '@babel/plugin-syntax-typescript': 7.24.1(@babel/core@7.24.5) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-typescript@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-annotate-as-pure': 7.27.1 + '@babel/helper-create-class-features-plugin': 7.27.1(@babel/core@7.27.1) + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.27.1) + transitivePeerDependencies: + - supports-color + + '@babel/preset-typescript@7.24.1(@babel/core@7.24.5)': + dependencies: + '@babel/core': 7.24.5 + '@babel/helper-plugin-utils': 7.24.5 + '@babel/helper-validator-option': 7.23.5 + '@babel/plugin-syntax-jsx': 7.24.1(@babel/core@7.24.5) + '@babel/plugin-transform-modules-commonjs': 7.24.1(@babel/core@7.24.5) + '@babel/plugin-transform-typescript': 7.24.5(@babel/core@7.24.5) + transitivePeerDependencies: + - supports-color + + '@babel/runtime@7.26.0': + dependencies: + regenerator-runtime: 0.14.0 + + '@babel/runtime@7.27.6': {} + + '@babel/standalone@7.24.5': {} + + '@babel/template@7.24.0': + dependencies: + '@babel/code-frame': 7.24.2 + '@babel/parser': 7.26.2 + '@babel/types': 7.27.1 + + '@babel/template@7.27.2': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/parser': 7.27.2 + '@babel/types': 7.27.1 + + '@babel/traverse@7.24.5': + dependencies: + '@babel/code-frame': 7.24.2 + '@babel/generator': 7.24.5 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-function-name': 7.23.0 + '@babel/helper-hoist-variables': 7.22.5 + '@babel/helper-split-export-declaration': 7.24.5 + '@babel/parser': 7.26.2 + '@babel/types': 7.27.1 + debug: 4.4.1 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + + '@babel/traverse@7.27.1': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.27.1 + '@babel/parser': 7.27.2 + '@babel/template': 7.27.2 + '@babel/types': 7.27.1 + debug: 4.4.1 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + + '@babel/types@7.24.5': + dependencies: + '@babel/helper-string-parser': 7.24.1 + '@babel/helper-validator-identifier': 7.24.5 + to-fast-properties: 2.0.0 + + '@babel/types@7.26.0': + dependencies: + '@babel/helper-string-parser': 7.25.9 + '@babel/helper-validator-identifier': 7.25.9 + + '@babel/types@7.27.1': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.27.1 + + '@bcoe/v8-coverage@0.2.3': {} + + '@biomejs/biome@1.9.4': + optionalDependencies: + '@biomejs/cli-darwin-arm64': 1.9.4 + '@biomejs/cli-darwin-x64': 1.9.4 + '@biomejs/cli-linux-arm64': 1.9.4 + '@biomejs/cli-linux-arm64-musl': 1.9.4 + '@biomejs/cli-linux-x64': 1.9.4 + '@biomejs/cli-linux-x64-musl': 1.9.4 + '@biomejs/cli-win32-arm64': 1.9.4 + '@biomejs/cli-win32-x64': 1.9.4 + + '@biomejs/cli-darwin-arm64@1.9.4': + optional: true + + '@biomejs/cli-darwin-x64@1.9.4': + optional: true + + '@biomejs/cli-linux-arm64-musl@1.9.4': + optional: true + + '@biomejs/cli-linux-arm64@1.9.4': + optional: true + + '@biomejs/cli-linux-x64-musl@1.9.4': + optional: true + + '@biomejs/cli-linux-x64@1.9.4': + optional: true + + '@biomejs/cli-win32-arm64@1.9.4': + optional: true + + '@biomejs/cli-win32-x64@1.9.4': + optional: true + + '@bundled-es-modules/cookie@2.0.0': + dependencies: + cookie: 0.5.0 + + '@bundled-es-modules/statuses@1.0.1': + dependencies: + statuses: 2.0.1 + + '@bundled-es-modules/tough-cookie@0.1.6': + dependencies: + '@types/tough-cookie': 4.0.5 + tough-cookie: 4.1.4 + + '@changesets/apply-release-plan@7.0.5': + dependencies: + '@changesets/config': 3.0.3 + '@changesets/get-version-range-type': 0.4.0 + '@changesets/git': 3.0.1 + '@changesets/should-skip-package': 0.1.1 + '@changesets/types': 6.0.0 + '@manypkg/get-packages': 1.1.3 + detect-indent: 6.1.0 + fs-extra: 7.0.1 + lodash.startcase: 4.4.0 + outdent: 0.5.0 + prettier: 2.8.8 + resolve-from: 5.0.0 + semver: 7.7.2 + + '@changesets/assemble-release-plan@6.0.4': + dependencies: + '@changesets/errors': 0.2.0 + '@changesets/get-dependents-graph': 2.1.2 + '@changesets/should-skip-package': 0.1.1 + '@changesets/types': 6.0.0 + '@manypkg/get-packages': 1.1.3 + semver: 7.7.2 + + '@changesets/changelog-git@0.2.0': + dependencies: + '@changesets/types': 6.0.0 + + '@changesets/changelog-github@0.4.6(encoding@0.1.13)': + dependencies: + '@changesets/get-github-info': 0.5.2(encoding@0.1.13) + '@changesets/types': 5.2.1 + dotenv: 8.6.0 + transitivePeerDependencies: + - encoding + + '@changesets/cli@2.27.8': + dependencies: + '@changesets/apply-release-plan': 7.0.5 + '@changesets/assemble-release-plan': 6.0.4 + '@changesets/changelog-git': 0.2.0 + '@changesets/config': 3.0.3 + '@changesets/errors': 0.2.0 + '@changesets/get-dependents-graph': 2.1.2 + '@changesets/get-release-plan': 4.0.4 + '@changesets/git': 3.0.1 + '@changesets/logger': 0.1.1 + '@changesets/pre': 2.0.1 + '@changesets/read': 0.6.1 + '@changesets/should-skip-package': 0.1.1 + '@changesets/types': 6.0.0 + '@changesets/write': 0.3.2 + '@manypkg/get-packages': 1.1.3 + '@types/semver': 7.5.3 + ansi-colors: 4.1.3 + ci-info: 3.9.0 + enquirer: 2.3.6 + external-editor: 3.1.0 + fs-extra: 7.0.1 + mri: 1.2.0 + outdent: 0.5.0 + p-limit: 2.3.0 + package-manager-detector: 0.2.0 + picocolors: 1.1.0 + resolve-from: 5.0.0 + semver: 7.6.2 + spawndamnit: 2.0.0 + term-size: 2.2.1 + + '@changesets/config@3.0.3': + dependencies: + '@changesets/errors': 0.2.0 + '@changesets/get-dependents-graph': 2.1.2 + '@changesets/logger': 0.1.1 + '@changesets/types': 6.0.0 + '@manypkg/get-packages': 1.1.3 + fs-extra: 7.0.1 + micromatch: 4.0.5 + + '@changesets/errors@0.2.0': + dependencies: + extendable-error: 0.1.7 + + '@changesets/get-dependents-graph@2.1.2': + dependencies: + '@changesets/types': 6.0.0 + '@manypkg/get-packages': 1.1.3 + picocolors: 1.1.0 + semver: 7.7.2 + + '@changesets/get-github-info@0.5.2(encoding@0.1.13)': + dependencies: + dataloader: 1.4.0 + node-fetch: 2.6.9(encoding@0.1.13) + transitivePeerDependencies: + - encoding + + '@changesets/get-release-plan@4.0.4': + dependencies: + '@changesets/assemble-release-plan': 6.0.4 + '@changesets/config': 3.0.3 + '@changesets/pre': 2.0.1 + '@changesets/read': 0.6.1 + '@changesets/types': 6.0.0 + '@manypkg/get-packages': 1.1.3 + + '@changesets/get-version-range-type@0.4.0': {} + + '@changesets/git@3.0.1': + dependencies: + '@changesets/errors': 0.2.0 + '@manypkg/get-packages': 1.1.3 + is-subdir: 1.2.0 + micromatch: 4.0.5 + spawndamnit: 2.0.0 + + '@changesets/logger@0.1.1': + dependencies: + picocolors: 1.1.0 + + '@changesets/parse@0.4.0': + dependencies: + '@changesets/types': 6.0.0 + js-yaml: 3.14.1 + + '@changesets/pre@2.0.1': + dependencies: + '@changesets/errors': 0.2.0 + '@changesets/types': 6.0.0 + '@manypkg/get-packages': 1.1.3 + fs-extra: 7.0.1 + + '@changesets/read@0.6.1': + dependencies: + '@changesets/git': 3.0.1 + '@changesets/logger': 0.1.1 + '@changesets/parse': 0.4.0 + '@changesets/types': 6.0.0 + fs-extra: 7.0.1 + p-filter: 2.1.0 + picocolors: 1.1.0 + + '@changesets/should-skip-package@0.1.1': + dependencies: + '@changesets/types': 6.0.0 + '@manypkg/get-packages': 1.1.3 + + '@changesets/types@4.1.0': {} + + '@changesets/types@5.2.1': {} + + '@changesets/types@6.0.0': {} + + '@changesets/write@0.3.2': + dependencies: + '@changesets/types': 6.0.0 + fs-extra: 7.0.1 + human-id: 1.0.2 + prettier: 2.8.8 + + '@cloudflare/kv-asset-handler@0.4.0': + dependencies: + mime: 3.0.0 + + '@coinbase/wallet-sdk@3.9.3': + dependencies: + bn.js: 5.2.1 + buffer: 6.0.3 + clsx: 1.2.1 + eth-block-tracker: 7.1.0 + eth-json-rpc-filters: 6.0.1 + eventemitter3: 5.0.1 + keccak: 3.0.3 + preact: 10.17.1 + sha.js: 2.4.11 + transitivePeerDependencies: + - supports-color + + '@coinbase/wallet-sdk@4.3.0': + dependencies: + '@noble/hashes': 1.5.0 + clsx: 1.2.1 + eventemitter3: 5.0.1 + preact: 10.24.3 + + '@colors/colors@1.5.0': + optional: true + + '@colors/colors@1.6.0': {} + + '@dabh/diagnostics@2.0.3': + dependencies: + colorspace: 1.1.4 + enabled: 2.0.0 + kuler: 2.0.0 + + '@dependents/detective-less@4.1.0': + dependencies: + gonzales-pe: 4.3.0 + node-source-walk: 6.0.2 + + '@discoveryjs/json-ext@0.5.7': {} + + '@docsearch/css@3.6.3': {} + + '@docsearch/js@3.6.3(@algolia/client-search@5.12.0)(@types/react@18.3.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@docsearch/react': 3.6.3(@algolia/client-search@5.12.0)(@types/react@18.3.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + preact: 10.24.3 + transitivePeerDependencies: + - '@algolia/client-search' + - '@types/react' + - react + - react-dom + - search-insights + + '@docsearch/react@3.6.3(@algolia/client-search@5.12.0)(@types/react@18.3.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@algolia/autocomplete-core': 1.9.3(@algolia/client-search@5.12.0)(algoliasearch@5.12.0) + '@algolia/autocomplete-preset-algolia': 1.17.6(@algolia/client-search@5.12.0)(algoliasearch@5.12.0) + '@docsearch/css': 3.6.3 + algoliasearch: 5.12.0 + optionalDependencies: + '@types/react': 18.3.1 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + transitivePeerDependencies: + - '@algolia/client-search' + + '@ecies/ciphers@0.2.3(@noble/ciphers@1.3.0)': + dependencies: + '@noble/ciphers': 1.3.0 + + '@emnapi/core@1.4.3': + dependencies: + '@emnapi/wasi-threads': 1.0.2 + tslib: 2.8.1 + optional: true + + '@emnapi/runtime@1.4.3': + dependencies: + tslib: 2.8.1 + optional: true + + '@emnapi/wasi-threads@1.0.2': + dependencies: + tslib: 2.8.1 + optional: true + + '@esbuild/aix-ppc64@0.21.5': + optional: true + + '@esbuild/aix-ppc64@0.25.4': + optional: true + + '@esbuild/aix-ppc64@0.25.5': + optional: true + + '@esbuild/android-arm64@0.21.5': + optional: true + + '@esbuild/android-arm64@0.25.4': + optional: true + + '@esbuild/android-arm64@0.25.5': + optional: true + + '@esbuild/android-arm@0.21.5': + optional: true + + '@esbuild/android-arm@0.25.4': + optional: true + + '@esbuild/android-arm@0.25.5': + optional: true + + '@esbuild/android-x64@0.21.5': + optional: true + + '@esbuild/android-x64@0.25.4': + optional: true + + '@esbuild/android-x64@0.25.5': + optional: true + + '@esbuild/darwin-arm64@0.21.5': + optional: true + + '@esbuild/darwin-arm64@0.25.4': + optional: true + + '@esbuild/darwin-arm64@0.25.5': + optional: true + + '@esbuild/darwin-x64@0.21.5': + optional: true + + '@esbuild/darwin-x64@0.25.4': + optional: true + + '@esbuild/darwin-x64@0.25.5': + optional: true + + '@esbuild/freebsd-arm64@0.21.5': + optional: true + + '@esbuild/freebsd-arm64@0.25.4': + optional: true + + '@esbuild/freebsd-arm64@0.25.5': + optional: true + + '@esbuild/freebsd-x64@0.21.5': + optional: true + + '@esbuild/freebsd-x64@0.25.4': + optional: true + + '@esbuild/freebsd-x64@0.25.5': + optional: true + + '@esbuild/linux-arm64@0.21.5': + optional: true + + '@esbuild/linux-arm64@0.25.4': + optional: true + + '@esbuild/linux-arm64@0.25.5': + optional: true + + '@esbuild/linux-arm@0.21.5': + optional: true + + '@esbuild/linux-arm@0.25.4': + optional: true + + '@esbuild/linux-arm@0.25.5': + optional: true + + '@esbuild/linux-ia32@0.21.5': + optional: true + + '@esbuild/linux-ia32@0.25.4': + optional: true + + '@esbuild/linux-ia32@0.25.5': + optional: true + + '@esbuild/linux-loong64@0.21.5': + optional: true + + '@esbuild/linux-loong64@0.25.4': + optional: true + + '@esbuild/linux-loong64@0.25.5': + optional: true + + '@esbuild/linux-mips64el@0.21.5': + optional: true + + '@esbuild/linux-mips64el@0.25.4': + optional: true + + '@esbuild/linux-mips64el@0.25.5': + optional: true + + '@esbuild/linux-ppc64@0.21.5': + optional: true + + '@esbuild/linux-ppc64@0.25.4': + optional: true + + '@esbuild/linux-ppc64@0.25.5': + optional: true + + '@esbuild/linux-riscv64@0.21.5': + optional: true + + '@esbuild/linux-riscv64@0.25.4': + optional: true + + '@esbuild/linux-riscv64@0.25.5': + optional: true + + '@esbuild/linux-s390x@0.21.5': + optional: true + + '@esbuild/linux-s390x@0.25.4': + optional: true + + '@esbuild/linux-s390x@0.25.5': + optional: true + + '@esbuild/linux-x64@0.21.5': + optional: true + + '@esbuild/linux-x64@0.25.4': + optional: true + + '@esbuild/linux-x64@0.25.5': + optional: true + + '@esbuild/netbsd-arm64@0.25.4': + optional: true + + '@esbuild/netbsd-arm64@0.25.5': + optional: true + + '@esbuild/netbsd-x64@0.21.5': + optional: true + + '@esbuild/netbsd-x64@0.25.4': + optional: true + + '@esbuild/netbsd-x64@0.25.5': + optional: true + + '@esbuild/openbsd-arm64@0.25.4': + optional: true + + '@esbuild/openbsd-arm64@0.25.5': + optional: true + + '@esbuild/openbsd-x64@0.21.5': + optional: true + + '@esbuild/openbsd-x64@0.25.4': + optional: true + + '@esbuild/openbsd-x64@0.25.5': + optional: true + + '@esbuild/sunos-x64@0.21.5': + optional: true + + '@esbuild/sunos-x64@0.25.4': + optional: true + + '@esbuild/sunos-x64@0.25.5': + optional: true + + '@esbuild/win32-arm64@0.21.5': + optional: true + + '@esbuild/win32-arm64@0.25.4': + optional: true + + '@esbuild/win32-arm64@0.25.5': + optional: true + + '@esbuild/win32-ia32@0.21.5': + optional: true + + '@esbuild/win32-ia32@0.25.4': + optional: true + + '@esbuild/win32-ia32@0.25.5': + optional: true + + '@esbuild/win32-x64@0.21.5': + optional: true + + '@esbuild/win32-x64@0.25.4': + optional: true + + '@esbuild/win32-x64@0.25.5': + optional: true + + '@ethereumjs/common@3.2.0': + dependencies: + '@ethereumjs/util': 8.1.0 + crc-32: 1.2.2 + + '@ethereumjs/rlp@4.0.1': {} + + '@ethereumjs/tx@4.2.0': + dependencies: + '@ethereumjs/common': 3.2.0 + '@ethereumjs/rlp': 4.0.1 + '@ethereumjs/util': 8.1.0 + ethereum-cryptography: 2.2.1 + + '@ethereumjs/util@8.1.0': + dependencies: + '@ethereumjs/rlp': 4.0.1 + ethereum-cryptography: 2.2.1 + micro-ftch: 0.3.1 + + '@ethersproject/abi@5.7.0': + dependencies: + '@ethersproject/address': 5.7.0 + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/constants': 5.7.0 + '@ethersproject/hash': 5.7.0 + '@ethersproject/keccak256': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/properties': 5.7.0 + '@ethersproject/strings': 5.7.0 + + '@ethersproject/abstract-provider@5.7.0': + dependencies: + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/networks': 5.7.1 + '@ethersproject/properties': 5.7.0 + '@ethersproject/transactions': 5.7.0 + '@ethersproject/web': 5.7.1 + + '@ethersproject/abstract-signer@5.7.0': + dependencies: + '@ethersproject/abstract-provider': 5.7.0 + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/properties': 5.7.0 + + '@ethersproject/address@5.7.0': + dependencies: + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/keccak256': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/rlp': 5.7.0 + + '@ethersproject/base64@5.7.0': + dependencies: + '@ethersproject/bytes': 5.7.0 + + '@ethersproject/bignumber@5.7.0': + dependencies: + '@ethersproject/bytes': 5.7.0 + '@ethersproject/logger': 5.7.0 + bn.js: 5.2.1 + + '@ethersproject/bytes@5.7.0': + dependencies: + '@ethersproject/logger': 5.7.0 + + '@ethersproject/constants@5.7.0': + dependencies: + '@ethersproject/bignumber': 5.7.0 + + '@ethersproject/hash@5.7.0': + dependencies: + '@ethersproject/abstract-signer': 5.7.0 + '@ethersproject/address': 5.7.0 + '@ethersproject/base64': 5.7.0 + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/keccak256': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/properties': 5.7.0 + '@ethersproject/strings': 5.7.0 + + '@ethersproject/keccak256@5.7.0': + dependencies: + '@ethersproject/bytes': 5.7.0 + js-sha3: 0.8.0 + + '@ethersproject/logger@5.7.0': {} + + '@ethersproject/networks@5.7.1': + dependencies: + '@ethersproject/logger': 5.7.0 + + '@ethersproject/properties@5.7.0': + dependencies: + '@ethersproject/logger': 5.7.0 + + '@ethersproject/rlp@5.7.0': + dependencies: + '@ethersproject/bytes': 5.7.0 + '@ethersproject/logger': 5.7.0 + + '@ethersproject/signing-key@5.7.0': + dependencies: + '@ethersproject/bytes': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/properties': 5.7.0 + bn.js: 5.2.1 + elliptic: 6.5.4 + hash.js: 1.1.7 + + '@ethersproject/strings@5.7.0': + dependencies: + '@ethersproject/bytes': 5.7.0 + '@ethersproject/constants': 5.7.0 + '@ethersproject/logger': 5.7.0 + + '@ethersproject/transactions@5.7.0': + dependencies: + '@ethersproject/address': 5.7.0 + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/constants': 5.7.0 + '@ethersproject/keccak256': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/properties': 5.7.0 + '@ethersproject/rlp': 5.7.0 + '@ethersproject/signing-key': 5.7.0 + + '@ethersproject/web@5.7.1': + dependencies: + '@ethersproject/base64': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/properties': 5.7.0 + '@ethersproject/strings': 5.7.0 + + '@fastify/busboy@2.1.0': {} + + '@fastify/busboy@3.1.1': {} + + '@floating-ui/core@1.6.1': + dependencies: + '@floating-ui/utils': 0.2.2 + + '@floating-ui/dom@1.1.1': + dependencies: + '@floating-ui/core': 1.6.1 + + '@floating-ui/utils@0.2.2': {} + + '@iconify-json/simple-icons@1.2.10': + dependencies: + '@iconify/types': 2.0.0 + + '@iconify/types@2.0.0': {} + + '@iconify/utils@2.1.23': + dependencies: + '@antfu/install-pkg': 0.1.1 + '@antfu/utils': 0.7.7 + '@iconify/types': 2.0.0 + debug: 4.4.1 + kolorist: 1.8.0 + local-pkg: 0.5.1 + mlly: 1.7.4 + transitivePeerDependencies: + - supports-color + + '@img/sharp-darwin-arm64@0.34.2': + optionalDependencies: + '@img/sharp-libvips-darwin-arm64': 1.1.0 + optional: true + + '@img/sharp-darwin-x64@0.34.2': + optionalDependencies: + '@img/sharp-libvips-darwin-x64': 1.1.0 + optional: true + + '@img/sharp-libvips-darwin-arm64@1.1.0': + optional: true + + '@img/sharp-libvips-darwin-x64@1.1.0': + optional: true + + '@img/sharp-libvips-linux-arm64@1.1.0': + optional: true + + '@img/sharp-libvips-linux-arm@1.1.0': + optional: true + + '@img/sharp-libvips-linux-ppc64@1.1.0': + optional: true + + '@img/sharp-libvips-linux-s390x@1.1.0': + optional: true + + '@img/sharp-libvips-linux-x64@1.1.0': + optional: true + + '@img/sharp-libvips-linuxmusl-arm64@1.1.0': + optional: true + + '@img/sharp-libvips-linuxmusl-x64@1.1.0': + optional: true + + '@img/sharp-linux-arm64@0.34.2': + optionalDependencies: + '@img/sharp-libvips-linux-arm64': 1.1.0 + optional: true + + '@img/sharp-linux-arm@0.34.2': + optionalDependencies: + '@img/sharp-libvips-linux-arm': 1.1.0 + optional: true + + '@img/sharp-linux-s390x@0.34.2': + optionalDependencies: + '@img/sharp-libvips-linux-s390x': 1.1.0 + optional: true + + '@img/sharp-linux-x64@0.34.2': + optionalDependencies: + '@img/sharp-libvips-linux-x64': 1.1.0 + optional: true + + '@img/sharp-linuxmusl-arm64@0.34.2': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-arm64': 1.1.0 + optional: true + + '@img/sharp-linuxmusl-x64@0.34.2': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-x64': 1.1.0 + optional: true + + '@img/sharp-wasm32@0.34.2': + dependencies: + '@emnapi/runtime': 1.4.3 + optional: true + + '@img/sharp-win32-arm64@0.34.2': + optional: true + + '@img/sharp-win32-ia32@0.34.2': + optional: true + + '@img/sharp-win32-x64@0.34.2': + optional: true + + '@inquirer/confirm@3.1.6': + dependencies: + '@inquirer/core': 8.1.0 + '@inquirer/type': 1.3.1 + + '@inquirer/core@8.1.0': + dependencies: + '@inquirer/figures': 1.0.1 + '@inquirer/type': 1.3.1 + '@types/mute-stream': 0.0.4 + '@types/node': 20.19.0 + '@types/wrap-ansi': 3.0.0 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + cli-spinners: 2.9.2 + cli-width: 4.1.0 + mute-stream: 1.0.0 + signal-exit: 4.1.0 + strip-ansi: 6.0.1 + wrap-ansi: 6.2.0 + + '@inquirer/figures@1.0.1': {} + + '@inquirer/type@1.3.1': {} + + '@ioredis/commands@1.2.0': {} + + '@isaacs/cliui@8.0.2': + dependencies: + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.1.0 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 + + '@isaacs/fs-minipass@4.0.1': + dependencies: + minipass: 7.1.2 + + '@istanbuljs/schema@0.1.3': {} + + '@jridgewell/gen-mapping@0.3.3': + dependencies: + '@jridgewell/set-array': 1.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping': 0.3.17 + + '@jridgewell/gen-mapping@0.3.5': + dependencies: + '@jridgewell/set-array': 1.2.1 + '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping': 0.3.25 + + '@jridgewell/gen-mapping@0.3.8': + dependencies: + '@jridgewell/set-array': 1.2.1 + '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping': 0.3.25 + + '@jridgewell/resolve-uri@3.1.0': {} + + '@jridgewell/set-array@1.1.2': {} + + '@jridgewell/set-array@1.2.1': {} + + '@jridgewell/source-map@0.3.6': + dependencies: + '@jridgewell/gen-mapping': 0.3.8 + '@jridgewell/trace-mapping': 0.3.25 + + '@jridgewell/sourcemap-codec@1.4.14': {} + + '@jridgewell/sourcemap-codec@1.4.15': {} + + '@jridgewell/sourcemap-codec@1.5.0': {} + + '@jridgewell/trace-mapping@0.3.17': + dependencies: + '@jridgewell/resolve-uri': 3.1.0 + '@jridgewell/sourcemap-codec': 1.4.14 + + '@jridgewell/trace-mapping@0.3.25': + dependencies: + '@jridgewell/resolve-uri': 3.1.0 + '@jridgewell/sourcemap-codec': 1.5.0 + + '@kwsites/file-exists@1.1.1': + dependencies: + debug: 4.4.1 + transitivePeerDependencies: + - supports-color + + '@kwsites/promise-deferred@1.1.1': {} + + '@lit-labs/ssr-dom-shim@1.3.0': {} + + '@lit/reactive-element@2.1.0': + dependencies: + '@lit-labs/ssr-dom-shim': 1.3.0 + + '@manypkg/find-root@1.1.0': + dependencies: + '@babel/runtime': 7.26.0 + '@types/node': 12.20.55 + find-up: 4.1.0 + fs-extra: 8.1.0 + + '@manypkg/get-packages@1.1.3': + dependencies: + '@babel/runtime': 7.26.0 + '@changesets/types': 4.1.0 + '@manypkg/find-root': 1.1.0 + fs-extra: 8.1.0 + globby: 11.1.0 + read-yaml-file: 1.1.0 + + '@mapbox/node-pre-gyp@1.0.11(encoding@0.1.13)': + dependencies: + detect-libc: 2.0.4 + https-proxy-agent: 5.0.1 + make-dir: 3.1.0 + node-fetch: 2.7.0(encoding@0.1.13) + nopt: 5.0.0 + npmlog: 5.0.1 + rimraf: 3.0.2 + semver: 7.7.2 + tar: 6.2.1 + transitivePeerDependencies: + - encoding + - supports-color + + '@mapbox/node-pre-gyp@2.0.0(encoding@0.1.13)': + dependencies: + consola: 3.4.2 + detect-libc: 2.0.4 + https-proxy-agent: 7.0.6 + node-fetch: 2.7.0(encoding@0.1.13) + nopt: 8.1.0 + semver: 7.7.2 + tar: 7.4.3 + transitivePeerDependencies: + - encoding + - supports-color + + '@metamask/eth-json-rpc-provider@1.0.1': + dependencies: + '@metamask/json-rpc-engine': 7.3.3 + '@metamask/safe-event-emitter': 3.0.0 + '@metamask/utils': 5.0.2 + transitivePeerDependencies: + - supports-color + + '@metamask/eth-sig-util@4.0.1': + dependencies: + ethereumjs-abi: 0.6.8 + ethereumjs-util: 6.2.1 + ethjs-util: 0.1.6 + tweetnacl: 1.0.3 + tweetnacl-util: 0.15.1 + + '@metamask/json-rpc-engine@7.3.3': + dependencies: + '@metamask/rpc-errors': 6.4.0 + '@metamask/safe-event-emitter': 3.0.0 + '@metamask/utils': 8.5.0 + transitivePeerDependencies: + - supports-color + + '@metamask/json-rpc-engine@8.0.2': + dependencies: + '@metamask/rpc-errors': 6.4.0 + '@metamask/safe-event-emitter': 3.1.2 + '@metamask/utils': 8.5.0 + transitivePeerDependencies: + - supports-color + + '@metamask/json-rpc-middleware-stream@7.0.2': + dependencies: + '@metamask/json-rpc-engine': 8.0.2 + '@metamask/safe-event-emitter': 3.1.2 + '@metamask/utils': 8.5.0 + readable-stream: 3.6.2 + transitivePeerDependencies: + - supports-color + + '@metamask/object-multiplex@2.1.0': + dependencies: + once: 1.4.0 + readable-stream: 3.6.2 + + '@metamask/onboarding@1.0.1': + dependencies: + bowser: 2.11.0 + + '@metamask/providers@16.1.0': + dependencies: + '@metamask/json-rpc-engine': 8.0.2 + '@metamask/json-rpc-middleware-stream': 7.0.2 + '@metamask/object-multiplex': 2.1.0 + '@metamask/rpc-errors': 6.4.0 + '@metamask/safe-event-emitter': 3.1.2 + '@metamask/utils': 8.5.0 + detect-browser: 5.3.0 + extension-port-stream: 3.0.0 + fast-deep-equal: 3.1.3 + is-stream: 2.0.1 + readable-stream: 3.6.2 + webextension-polyfill: 0.10.0 + transitivePeerDependencies: + - supports-color + + '@metamask/rpc-errors@6.4.0': + dependencies: + '@metamask/utils': 9.3.0 + fast-safe-stringify: 2.1.1 + transitivePeerDependencies: + - supports-color + + '@metamask/safe-event-emitter@2.0.0': {} + + '@metamask/safe-event-emitter@3.0.0': {} + + '@metamask/safe-event-emitter@3.1.2': {} + + '@metamask/sdk-communication-layer@0.32.0(cross-fetch@4.1.0(encoding@0.1.13))(eciesjs@0.4.15)(eventemitter2@6.4.9)(readable-stream@3.6.2)(socket.io-client@4.8.1(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + dependencies: + bufferutil: 4.0.9 + cross-fetch: 4.1.0(encoding@0.1.13) + date-fns: 2.30.0 + debug: 4.4.1 + eciesjs: 0.4.15 + eventemitter2: 6.4.9 + readable-stream: 3.6.2 + socket.io-client: 4.8.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) + utf-8-validate: 5.0.10 + uuid: 8.3.2 + transitivePeerDependencies: + - supports-color + + '@metamask/sdk-install-modal-web@0.32.1': + dependencies: + '@paulmillr/qr': 0.2.1 + + '@metamask/sdk@0.32.1(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)': + dependencies: + '@babel/runtime': 7.27.6 + '@metamask/onboarding': 1.0.1 + '@metamask/providers': 16.1.0 + '@metamask/sdk-communication-layer': 0.32.0(cross-fetch@4.1.0(encoding@0.1.13))(eciesjs@0.4.15)(eventemitter2@6.4.9)(readable-stream@3.6.2)(socket.io-client@4.8.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@metamask/sdk-install-modal-web': 0.32.1 + '@paulmillr/qr': 0.2.1 + bowser: 2.11.0 + cross-fetch: 4.1.0(encoding@0.1.13) + debug: 4.4.1 + eciesjs: 0.4.15 + eth-rpc-errors: 4.0.3 + eventemitter2: 6.4.9 + obj-multiplex: 1.0.0 + pump: 3.0.2 + readable-stream: 3.6.2 + socket.io-client: 4.8.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) + tslib: 2.8.1 + util: 0.12.5 + uuid: 8.3.2 + transitivePeerDependencies: + - bufferutil + - encoding + - supports-color + - utf-8-validate + + '@metamask/superstruct@3.2.1': {} + + '@metamask/utils@5.0.2': + dependencies: + '@ethereumjs/tx': 4.2.0 + '@types/debug': 4.1.7 + debug: 4.4.1 + semver: 7.7.2 + superstruct: 1.0.3 + transitivePeerDependencies: + - supports-color + + '@metamask/utils@8.5.0': + dependencies: + '@ethereumjs/tx': 4.2.0 + '@metamask/superstruct': 3.2.1 + '@noble/hashes': 1.8.0 + '@scure/base': 1.2.6 + '@types/debug': 4.1.12 + debug: 4.4.1 + pony-cause: 2.1.11 + semver: 7.7.2 + uuid: 9.0.1 + transitivePeerDependencies: + - supports-color + + '@metamask/utils@9.3.0': + dependencies: + '@ethereumjs/tx': 4.2.0 + '@metamask/superstruct': 3.2.1 + '@noble/hashes': 1.8.0 + '@scure/base': 1.2.6 + '@types/debug': 4.1.12 + debug: 4.4.1 + pony-cause: 2.1.11 + semver: 7.7.2 + uuid: 9.0.1 + transitivePeerDependencies: + - supports-color + + '@mswjs/interceptors@0.35.9': + dependencies: + '@open-draft/deferred-promise': 2.2.0 + '@open-draft/logger': 0.3.0 + '@open-draft/until': 2.1.0 + is-node-process: 1.2.0 + outvariant: 1.4.3 + strict-event-emitter: 0.5.1 + + '@napi-rs/wasm-runtime@0.2.10': + dependencies: + '@emnapi/core': 1.4.3 + '@emnapi/runtime': 1.4.3 + '@tybys/wasm-util': 0.9.0 + optional: true + + '@netlify/binary-info@1.0.0': {} + + '@netlify/blobs@9.1.1': + dependencies: + '@netlify/dev-utils': 2.1.1 + '@netlify/runtime-utils': 1.3.1 + + '@netlify/dev-utils@2.1.1': + dependencies: + '@whatwg-node/server': 0.9.71 + chokidar: 4.0.3 + decache: 4.6.2 + dot-prop: 9.0.0 + env-paths: 3.0.0 + find-up: 7.0.0 + lodash.debounce: 4.0.8 + netlify: 13.3.5 + parse-gitignore: 2.0.0 + uuid: 11.1.0 + write-file-atomic: 6.0.0 + + '@netlify/functions@3.1.8(encoding@0.1.13)(rollup@4.41.0)': + dependencies: + '@netlify/blobs': 9.1.1 + '@netlify/dev-utils': 2.1.1 + '@netlify/serverless-functions-api': 1.41.1 + '@netlify/zip-it-and-ship-it': 10.1.1(encoding@0.1.13)(rollup@4.41.0) + cron-parser: 4.9.0 + decache: 4.6.2 + extract-zip: 2.0.1 + is-stream: 4.0.1 + jwt-decode: 4.0.0 + lambda-local: 2.2.0 + read-package-up: 11.0.0 + source-map-support: 0.5.21 + transitivePeerDependencies: + - encoding + - rollup + - supports-color + + '@netlify/open-api@2.37.0': {} + + '@netlify/runtime-utils@1.3.1': {} + + '@netlify/serverless-functions-api@1.41.1': {} + + '@netlify/zip-it-and-ship-it@10.1.1(encoding@0.1.13)(rollup@4.41.0)': + dependencies: + '@babel/parser': 7.27.2 + '@babel/types': 7.27.1 + '@netlify/binary-info': 1.0.0 + '@netlify/serverless-functions-api': 1.41.1 + '@vercel/nft': 0.27.7(encoding@0.1.13)(rollup@4.41.0) + archiver: 5.3.2 + common-path-prefix: 3.0.0 + cp-file: 10.0.0 + es-module-lexer: 1.7.0 + esbuild: 0.25.4 + execa: 7.2.0 + fast-glob: 3.3.3 + filter-obj: 5.1.0 + find-up: 6.3.0 + glob: 8.1.0 + is-builtin-module: 3.2.1 + is-path-inside: 4.0.0 + junk: 4.0.1 + locate-path: 7.2.0 + merge-options: 3.0.4 + minimatch: 9.0.5 + normalize-path: 3.0.0 + p-map: 7.0.3 + path-exists: 5.0.0 + precinct: 11.0.5 + require-package-name: 2.0.1 + resolve: 2.0.0-next.5 + semver: 7.7.2 + tmp-promise: 3.0.3 + toml: 3.0.0 + unixify: 1.0.0 + urlpattern-polyfill: 8.0.2 + yargs: 17.7.2 + zod: 3.25.20 + transitivePeerDependencies: + - encoding + - rollup + - supports-color + + '@next/bundle-analyzer@15.3.3(bufferutil@4.0.8)(utf-8-validate@6.0.5)': + dependencies: + webpack-bundle-analyzer: 4.10.1(bufferutil@4.0.8)(utf-8-validate@6.0.5) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@next/env@15.3.3': {} + + '@next/swc-darwin-arm64@15.3.3': + optional: true + + '@next/swc-darwin-x64@15.3.3': + optional: true + + '@next/swc-linux-arm64-gnu@15.3.3': + optional: true + + '@next/swc-linux-arm64-musl@15.3.3': + optional: true + + '@next/swc-linux-x64-gnu@15.3.3': + optional: true + + '@next/swc-linux-x64-musl@15.3.3': + optional: true + + '@next/swc-win32-arm64-msvc@15.3.3': + optional: true + + '@next/swc-win32-x64-msvc@15.3.3': + optional: true + + '@noble/ciphers@1.2.1': {} + + '@noble/ciphers@1.3.0': {} + + '@noble/curves@1.2.0': + dependencies: + '@noble/hashes': 1.3.2 + + '@noble/curves@1.4.0': + dependencies: + '@noble/hashes': 1.4.0 + + '@noble/curves@1.4.2': + dependencies: + '@noble/hashes': 1.4.0 + + '@noble/curves@1.8.0': + dependencies: + '@noble/hashes': 1.7.0 + + '@noble/curves@1.8.1': + dependencies: + '@noble/hashes': 1.7.1 + + '@noble/curves@1.8.2': + dependencies: + '@noble/hashes': 1.7.2 + + '@noble/curves@1.9.2': + dependencies: + '@noble/hashes': 1.8.0 + + '@noble/hashes@1.2.0': {} + + '@noble/hashes@1.3.2': {} + + '@noble/hashes@1.4.0': {} + + '@noble/hashes@1.5.0': {} + + '@noble/hashes@1.7.0': {} + + '@noble/hashes@1.7.1': {} + + '@noble/hashes@1.7.2': {} + + '@noble/hashes@1.8.0': {} + + '@noble/secp256k1@1.7.1': {} + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.15.0 + + '@nomicfoundation/edr-darwin-arm64@0.3.7': + optional: true + + '@nomicfoundation/edr-darwin-x64@0.3.7': + optional: true + + '@nomicfoundation/edr-linux-arm64-gnu@0.3.7': + optional: true + + '@nomicfoundation/edr-linux-arm64-musl@0.3.7': + optional: true + + '@nomicfoundation/edr-linux-x64-gnu@0.3.7': + optional: true + + '@nomicfoundation/edr-linux-x64-musl@0.3.7': + optional: true + + '@nomicfoundation/edr-win32-x64-msvc@0.3.7': + optional: true + + '@nomicfoundation/edr@0.3.7': + optionalDependencies: + '@nomicfoundation/edr-darwin-arm64': 0.3.7 + '@nomicfoundation/edr-darwin-x64': 0.3.7 + '@nomicfoundation/edr-linux-arm64-gnu': 0.3.7 + '@nomicfoundation/edr-linux-arm64-musl': 0.3.7 + '@nomicfoundation/edr-linux-x64-gnu': 0.3.7 + '@nomicfoundation/edr-linux-x64-musl': 0.3.7 + '@nomicfoundation/edr-win32-x64-msvc': 0.3.7 + + '@nomicfoundation/ethereumjs-common@4.0.4': + dependencies: + '@nomicfoundation/ethereumjs-util': 9.0.4 + transitivePeerDependencies: + - c-kzg + + '@nomicfoundation/ethereumjs-rlp@5.0.4': {} + + '@nomicfoundation/ethereumjs-tx@5.0.4': + dependencies: + '@nomicfoundation/ethereumjs-common': 4.0.4 + '@nomicfoundation/ethereumjs-rlp': 5.0.4 + '@nomicfoundation/ethereumjs-util': 9.0.4 + ethereum-cryptography: 0.1.3 + + '@nomicfoundation/ethereumjs-util@9.0.4': + dependencies: + '@nomicfoundation/ethereumjs-rlp': 5.0.4 + ethereum-cryptography: 0.1.3 + + '@nomicfoundation/solidity-analyzer-darwin-arm64@0.1.1': + optional: true + + '@nomicfoundation/solidity-analyzer-darwin-x64@0.1.1': + optional: true + + '@nomicfoundation/solidity-analyzer-freebsd-x64@0.1.1': + optional: true + + '@nomicfoundation/solidity-analyzer-linux-arm64-gnu@0.1.1': + optional: true + + '@nomicfoundation/solidity-analyzer-linux-arm64-musl@0.1.1': + optional: true + + '@nomicfoundation/solidity-analyzer-linux-x64-gnu@0.1.1': + optional: true + + '@nomicfoundation/solidity-analyzer-linux-x64-musl@0.1.1': + optional: true + + '@nomicfoundation/solidity-analyzer-win32-arm64-msvc@0.1.1': + optional: true + + '@nomicfoundation/solidity-analyzer-win32-ia32-msvc@0.1.1': + optional: true + + '@nomicfoundation/solidity-analyzer-win32-x64-msvc@0.1.1': + optional: true + + '@nomicfoundation/solidity-analyzer@0.1.1': + optionalDependencies: + '@nomicfoundation/solidity-analyzer-darwin-arm64': 0.1.1 + '@nomicfoundation/solidity-analyzer-darwin-x64': 0.1.1 + '@nomicfoundation/solidity-analyzer-freebsd-x64': 0.1.1 + '@nomicfoundation/solidity-analyzer-linux-arm64-gnu': 0.1.1 + '@nomicfoundation/solidity-analyzer-linux-arm64-musl': 0.1.1 + '@nomicfoundation/solidity-analyzer-linux-x64-gnu': 0.1.1 + '@nomicfoundation/solidity-analyzer-linux-x64-musl': 0.1.1 + '@nomicfoundation/solidity-analyzer-win32-arm64-msvc': 0.1.1 + '@nomicfoundation/solidity-analyzer-win32-ia32-msvc': 0.1.1 + '@nomicfoundation/solidity-analyzer-win32-x64-msvc': 0.1.1 + + '@nuxt/cli@3.25.1(magicast@0.3.5)': + dependencies: + c12: 3.0.4(magicast@0.3.5) + chokidar: 4.0.3 + citty: 0.1.6 + clipboardy: 4.0.0 + consola: 3.4.2 + defu: 6.1.4 + fuse.js: 7.1.0 + giget: 2.0.0 + h3: 1.15.3 + httpxy: 0.1.7 + jiti: 2.4.2 + listhen: 1.9.0 + nypm: 0.6.0 + ofetch: 1.4.1 + ohash: 2.0.11 + pathe: 2.0.3 + perfect-debounce: 1.0.0 + pkg-types: 2.1.0 + scule: 1.3.0 + semver: 7.7.2 + std-env: 3.9.0 + tinyexec: 1.0.1 + ufo: 1.6.1 + youch: 4.1.0-beta.7 + transitivePeerDependencies: + - magicast + + '@nuxt/devalue@2.0.2': {} + + '@nuxt/devtools-kit@2.4.1(magicast@0.3.5)(vite@6.3.5(@types/node@24.0.1)(jiti@2.4.2)(terser@5.39.2)(yaml@2.8.0))': + dependencies: + '@nuxt/kit': 3.17.4(magicast@0.3.5) + '@nuxt/schema': 3.17.4 + execa: 8.0.1 + vite: 6.3.5(@types/node@24.0.1)(jiti@2.4.2)(terser@5.39.2)(yaml@2.8.0) + transitivePeerDependencies: + - magicast + + '@nuxt/devtools-wizard@2.4.1': + dependencies: + consola: 3.4.2 + diff: 7.0.0 + execa: 8.0.1 + magicast: 0.3.5 + pathe: 2.0.3 + pkg-types: 2.1.0 + prompts: 2.4.2 + semver: 7.7.2 + + '@nuxt/devtools@2.4.1(bufferutil@4.0.9)(utf-8-validate@6.0.5)(vite@6.3.5(@types/node@24.0.1)(jiti@2.4.2)(terser@5.39.2)(yaml@2.8.0))(vue@3.5.14(typescript@5.8.3))': + dependencies: + '@nuxt/devtools-kit': 2.4.1(magicast@0.3.5)(vite@6.3.5(@types/node@24.0.1)(jiti@2.4.2)(terser@5.39.2)(yaml@2.8.0)) + '@nuxt/devtools-wizard': 2.4.1 + '@nuxt/kit': 3.17.4(magicast@0.3.5) + '@vue/devtools-core': 7.7.6(vite@6.3.5(@types/node@24.0.1)(jiti@2.4.2)(terser@5.39.2)(yaml@2.8.0))(vue@3.5.14(typescript@5.8.3)) + '@vue/devtools-kit': 7.7.6 + birpc: 2.3.0 + consola: 3.4.2 + destr: 2.0.5 + error-stack-parser-es: 1.0.5 + execa: 8.0.1 + fast-npm-meta: 0.4.3 + get-port-please: 3.1.2 + hookable: 5.5.3 + image-meta: 0.2.1 + is-installed-globally: 1.0.0 + launch-editor: 2.10.0 + local-pkg: 1.1.1 + magicast: 0.3.5 + nypm: 0.6.0 + ohash: 2.0.11 + pathe: 2.0.3 + perfect-debounce: 1.0.0 + pkg-types: 2.1.0 + semver: 7.7.2 + simple-git: 3.27.0 + sirv: 3.0.1 + structured-clone-es: 1.0.0 + tinyglobby: 0.2.13 + vite: 6.3.5(@types/node@24.0.1)(jiti@2.4.2)(terser@5.39.2)(yaml@2.8.0) + vite-plugin-inspect: 11.1.0(@nuxt/kit@3.17.4(magicast@0.3.5))(vite@6.3.5(@types/node@24.0.1)(jiti@2.4.2)(terser@5.39.2)(yaml@2.8.0)) + vite-plugin-vue-tracer: 0.1.3(vite@6.3.5(@types/node@24.0.1)(jiti@2.4.2)(terser@5.39.2)(yaml@2.8.0))(vue@3.5.14(typescript@5.8.3)) + which: 5.0.0 + ws: 8.18.2(bufferutil@4.0.9)(utf-8-validate@6.0.5) + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + - vue + + '@nuxt/kit@3.16.0(magicast@0.3.5)': + dependencies: + c12: 3.0.4(magicast@0.3.5) + consola: 3.4.2 + defu: 6.1.4 + destr: 2.0.5 + errx: 0.1.0 + exsolve: 1.0.5 + globby: 14.1.0 + ignore: 7.0.4 + jiti: 2.4.2 + klona: 2.0.6 + knitwork: 1.2.0 + mlly: 1.7.4 + ohash: 2.0.11 + pathe: 2.0.3 + pkg-types: 2.1.0 + scule: 1.3.0 + semver: 7.7.2 + std-env: 3.9.0 + ufo: 1.6.1 + unctx: 2.4.1 + unimport: 4.2.0 + untyped: 2.0.0 + transitivePeerDependencies: + - magicast + + '@nuxt/kit@3.17.4(magicast@0.3.5)': + dependencies: + c12: 3.0.4(magicast@0.3.5) + consola: 3.4.2 + defu: 6.1.4 + destr: 2.0.5 + errx: 0.1.0 + exsolve: 1.0.5 + ignore: 7.0.4 + jiti: 2.4.2 + klona: 2.0.6 + knitwork: 1.2.0 + mlly: 1.7.4 + ohash: 2.0.11 + pathe: 2.0.3 + pkg-types: 2.1.0 + scule: 1.3.0 + semver: 7.7.2 + std-env: 3.9.0 + tinyglobby: 0.2.13 + ufo: 1.6.1 + unctx: 2.4.1 + unimport: 5.0.1 + untyped: 2.0.0 + transitivePeerDependencies: + - magicast + + '@nuxt/schema@3.11.2(rollup@4.41.0)': + dependencies: + '@nuxt/ui-templates': 1.3.3 + consola: 3.2.3 + defu: 6.1.4 + hookable: 5.5.3 + pathe: 1.1.2 + pkg-types: 1.1.1 + scule: 1.3.0 + std-env: 3.7.0 + ufo: 1.5.3 + unimport: 3.7.1(rollup@4.41.0) + untyped: 1.4.2 + transitivePeerDependencies: + - rollup + - supports-color + + '@nuxt/schema@3.16.0': + dependencies: + consola: 3.4.2 + defu: 6.1.4 + pathe: 2.0.3 + std-env: 3.9.0 + + '@nuxt/schema@3.17.4': + dependencies: + '@vue/shared': 3.5.14 + consola: 3.4.2 + defu: 6.1.4 + pathe: 2.0.3 + std-env: 3.9.0 + + '@nuxt/telemetry@2.6.6(magicast@0.3.5)': + dependencies: + '@nuxt/kit': 3.17.4(magicast@0.3.5) + citty: 0.1.6 + consola: 3.4.2 + destr: 2.0.5 + dotenv: 16.5.0 + git-url-parse: 16.1.0 + is-docker: 3.0.0 + ofetch: 1.4.1 + package-manager-detector: 1.3.0 + pathe: 2.0.3 + rc9: 2.1.2 + std-env: 3.9.0 + transitivePeerDependencies: + - magicast + + '@nuxt/ui-templates@1.3.3': {} + + '@nuxt/vite-builder@3.16.0(@biomejs/biome@1.9.4)(@types/node@24.0.1)(magicast@0.3.5)(rollup@4.41.0)(terser@5.39.2)(typescript@5.8.3)(vue@3.5.14(typescript@5.8.3))(yaml@2.8.0)': + dependencies: + '@nuxt/kit': 3.16.0(magicast@0.3.5) + '@rollup/plugin-replace': 6.0.2(rollup@4.41.0) + '@vitejs/plugin-vue': 5.2.4(vite@6.3.5(@types/node@24.0.1)(jiti@2.4.2)(terser@5.39.2)(yaml@2.8.0))(vue@3.5.14(typescript@5.8.3)) + '@vitejs/plugin-vue-jsx': 4.2.0(vite@6.3.5(@types/node@24.0.1)(jiti@2.4.2)(terser@5.39.2)(yaml@2.8.0))(vue@3.5.14(typescript@5.8.3)) + autoprefixer: 10.4.21(postcss@8.5.3) + consola: 3.4.2 + cssnano: 7.0.7(postcss@8.5.3) + defu: 6.1.4 + esbuild: 0.25.5 + escape-string-regexp: 5.0.0 + exsolve: 1.0.5 + externality: 1.0.2 + get-port-please: 3.1.2 + h3: 1.15.3 + jiti: 2.4.2 + knitwork: 1.2.0 + magic-string: 0.30.17 + mlly: 1.7.4 + ohash: 2.0.11 + pathe: 2.0.3 + perfect-debounce: 1.0.0 + pkg-types: 2.1.0 + postcss: 8.5.3 + rollup-plugin-visualizer: 5.14.0(rollup@4.41.0) + std-env: 3.9.0 + ufo: 1.6.1 + unenv: 2.0.0-rc.17 + unplugin: 2.3.4 + vite: 6.3.5(@types/node@24.0.1)(jiti@2.4.2)(terser@5.39.2)(yaml@2.8.0) + vite-node: 3.1.4(@types/node@24.0.1)(terser@5.39.2) + vite-plugin-checker: 0.9.3(@biomejs/biome@1.9.4)(typescript@5.8.3)(vite@6.3.5(@types/node@24.0.1)(jiti@2.4.2)(terser@5.39.2)(yaml@2.8.0)) + vue: 3.5.14(typescript@5.8.3) + vue-bundle-renderer: 2.1.1 + transitivePeerDependencies: + - '@biomejs/biome' + - '@types/node' + - eslint + - less + - lightningcss + - magicast + - meow + - optionator + - rolldown + - rollup + - sass + - sass-embedded + - stylelint + - stylus + - sugarss + - supports-color + - terser + - tsx + - typescript + - vls + - vti + - vue-tsc + - yaml + + '@one-ini/wasm@0.1.1': {} + + '@open-draft/deferred-promise@2.2.0': {} + + '@open-draft/logger@0.3.0': + dependencies: + is-node-process: 1.2.0 + outvariant: 1.4.3 + + '@open-draft/until@2.1.0': {} + + '@oven/bun-darwin-aarch64@1.1.30': + optional: true + + '@oven/bun-darwin-x64-baseline@1.1.30': + optional: true + + '@oven/bun-darwin-x64@1.1.30': + optional: true + + '@oven/bun-linux-aarch64@1.1.30': + optional: true + + '@oven/bun-linux-x64-baseline@1.1.30': + optional: true + + '@oven/bun-linux-x64@1.1.30': + optional: true + + '@oven/bun-windows-x64-baseline@1.1.30': + optional: true + + '@oven/bun-windows-x64@1.1.30': + optional: true + + '@oxc-parser/binding-darwin-arm64@0.56.5': + optional: true + + '@oxc-parser/binding-darwin-x64@0.56.5': + optional: true + + '@oxc-parser/binding-linux-arm-gnueabihf@0.56.5': + optional: true + + '@oxc-parser/binding-linux-arm64-gnu@0.56.5': + optional: true + + '@oxc-parser/binding-linux-arm64-musl@0.56.5': + optional: true + + '@oxc-parser/binding-linux-x64-gnu@0.56.5': + optional: true + + '@oxc-parser/binding-linux-x64-musl@0.56.5': + optional: true + + '@oxc-parser/binding-wasm32-wasi@0.56.5': + dependencies: + '@napi-rs/wasm-runtime': 0.2.10 + optional: true + + '@oxc-parser/binding-win32-arm64-msvc@0.56.5': + optional: true + + '@oxc-parser/binding-win32-x64-msvc@0.56.5': + optional: true + + '@oxc-parser/wasm@0.56.5': + dependencies: + '@oxc-project/types': 0.56.5 + + '@oxc-project/types@0.56.5': {} + + '@parcel/watcher-android-arm64@2.4.1': + optional: true + + '@parcel/watcher-android-arm64@2.5.1': + optional: true + + '@parcel/watcher-darwin-arm64@2.4.1': + optional: true + + '@parcel/watcher-darwin-arm64@2.5.1': + optional: true + + '@parcel/watcher-darwin-x64@2.4.1': + optional: true + + '@parcel/watcher-darwin-x64@2.5.1': + optional: true + + '@parcel/watcher-freebsd-x64@2.4.1': + optional: true + + '@parcel/watcher-freebsd-x64@2.5.1': + optional: true + + '@parcel/watcher-linux-arm-glibc@2.4.1': + optional: true + + '@parcel/watcher-linux-arm-glibc@2.5.1': + optional: true + + '@parcel/watcher-linux-arm-musl@2.5.1': + optional: true + + '@parcel/watcher-linux-arm64-glibc@2.4.1': + optional: true + + '@parcel/watcher-linux-arm64-glibc@2.5.1': + optional: true + + '@parcel/watcher-linux-arm64-musl@2.4.1': + optional: true + + '@parcel/watcher-linux-arm64-musl@2.5.1': + optional: true + + '@parcel/watcher-linux-x64-glibc@2.4.1': + optional: true + + '@parcel/watcher-linux-x64-glibc@2.5.1': + optional: true + + '@parcel/watcher-linux-x64-musl@2.4.1': + optional: true + + '@parcel/watcher-linux-x64-musl@2.5.1': + optional: true + + '@parcel/watcher-wasm@2.4.1': + dependencies: + is-glob: 4.0.3 + micromatch: 4.0.8 + + '@parcel/watcher-wasm@2.5.1': + dependencies: + is-glob: 4.0.3 + micromatch: 4.0.8 + + '@parcel/watcher-win32-arm64@2.4.1': + optional: true + + '@parcel/watcher-win32-arm64@2.5.1': + optional: true + + '@parcel/watcher-win32-ia32@2.4.1': + optional: true + + '@parcel/watcher-win32-ia32@2.5.1': + optional: true + + '@parcel/watcher-win32-x64@2.4.1': + optional: true + + '@parcel/watcher-win32-x64@2.5.1': + optional: true + + '@parcel/watcher@2.4.1': + dependencies: + detect-libc: 1.0.3 + is-glob: 4.0.3 + micromatch: 4.0.8 + node-addon-api: 7.0.0 + optionalDependencies: + '@parcel/watcher-android-arm64': 2.4.1 + '@parcel/watcher-darwin-arm64': 2.4.1 + '@parcel/watcher-darwin-x64': 2.4.1 + '@parcel/watcher-freebsd-x64': 2.4.1 + '@parcel/watcher-linux-arm-glibc': 2.4.1 + '@parcel/watcher-linux-arm64-glibc': 2.4.1 + '@parcel/watcher-linux-arm64-musl': 2.4.1 + '@parcel/watcher-linux-x64-glibc': 2.4.1 + '@parcel/watcher-linux-x64-musl': 2.4.1 + '@parcel/watcher-win32-arm64': 2.4.1 + '@parcel/watcher-win32-ia32': 2.4.1 + '@parcel/watcher-win32-x64': 2.4.1 + + '@parcel/watcher@2.5.1': + dependencies: + detect-libc: 1.0.3 + is-glob: 4.0.3 + micromatch: 4.0.8 + node-addon-api: 7.1.1 + optionalDependencies: + '@parcel/watcher-android-arm64': 2.5.1 + '@parcel/watcher-darwin-arm64': 2.5.1 + '@parcel/watcher-darwin-x64': 2.5.1 + '@parcel/watcher-freebsd-x64': 2.5.1 + '@parcel/watcher-linux-arm-glibc': 2.5.1 + '@parcel/watcher-linux-arm-musl': 2.5.1 + '@parcel/watcher-linux-arm64-glibc': 2.5.1 + '@parcel/watcher-linux-arm64-musl': 2.5.1 + '@parcel/watcher-linux-x64-glibc': 2.5.1 + '@parcel/watcher-linux-x64-musl': 2.5.1 + '@parcel/watcher-win32-arm64': 2.5.1 + '@parcel/watcher-win32-ia32': 2.5.1 + '@parcel/watcher-win32-x64': 2.5.1 + + '@paulmillr/qr@0.2.1': {} + + '@pkgjs/parseargs@0.11.0': + optional: true + + '@polka/url@1.0.0-next.29': {} + + '@poppinss/colors@4.1.4': + dependencies: + kleur: 4.1.5 + + '@poppinss/dumper@0.6.3': + dependencies: + '@poppinss/colors': 4.1.4 + '@sindresorhus/is': 7.0.1 + supports-color: 10.0.0 + + '@poppinss/exception@1.2.1': {} + + '@publint/pack@0.1.2': {} + + '@reown/appkit-common@1.7.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4)': + dependencies: + big.js: 6.2.2 + dayjs: 1.11.13 + viem: 2.29.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + transitivePeerDependencies: + - bufferutil + - typescript + - utf-8-validate + - zod + + '@reown/appkit-common@1.7.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20)': + dependencies: + big.js: 6.2.2 + dayjs: 1.11.13 + viem: 2.29.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + transitivePeerDependencies: + - bufferutil + - typescript + - utf-8-validate + - zod + + '@reown/appkit-controllers@1.7.3(@types/react@18.3.1)(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20)': + dependencies: + '@reown/appkit-common': 1.7.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + '@reown/appkit-wallet': 1.7.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10) + '@walletconnect/universal-provider': 2.19.2(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + valtio: 1.13.2(@types/react@18.3.1)(react@18.3.1) + viem: 2.29.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + 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-polyfills@1.7.3': + dependencies: + buffer: 6.0.3 + + '@reown/appkit-scaffold-ui@1.7.3(@types/react@18.3.1)(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20)': + dependencies: + '@reown/appkit-common': 1.7.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + '@reown/appkit-controllers': 1.7.3(@types/react@18.3.1)(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + '@reown/appkit-ui': 1.7.3(@types/react@18.3.1)(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + '@reown/appkit-utils': 1.7.3(@types/react@18.3.1)(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + '@reown/appkit-wallet': 1.7.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10) + lit: 3.1.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-ui@1.7.3(@types/react@18.3.1)(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20)': + dependencies: + '@reown/appkit-common': 1.7.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + '@reown/appkit-controllers': 1.7.3(@types/react@18.3.1)(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + '@reown/appkit-wallet': 1.7.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10) + lit: 3.1.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-utils@1.7.3(@types/react@18.3.1)(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20)': + dependencies: + '@reown/appkit-common': 1.7.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + '@reown/appkit-controllers': 1.7.3(@types/react@18.3.1)(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + '@reown/appkit-polyfills': 1.7.3 + '@reown/appkit-wallet': 1.7.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10) + '@walletconnect/logger': 2.1.2 + '@walletconnect/universal-provider': 2.19.2(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + valtio: 1.13.2(@types/react@18.3.1)(react@18.3.1) + viem: 2.29.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + 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-wallet@1.7.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)': + dependencies: + '@reown/appkit-common': 1.7.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + '@reown/appkit-polyfills': 1.7.3 + '@walletconnect/logger': 2.1.2 + zod: 3.22.4 + transitivePeerDependencies: + - bufferutil + - typescript + - utf-8-validate + + '@reown/appkit@1.7.3(@types/react@18.3.1)(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20)': + dependencies: + '@reown/appkit-common': 1.7.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + '@reown/appkit-controllers': 1.7.3(@types/react@18.3.1)(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + '@reown/appkit-polyfills': 1.7.3 + '@reown/appkit-scaffold-ui': 1.7.3(@types/react@18.3.1)(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + '@reown/appkit-ui': 1.7.3(@types/react@18.3.1)(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + '@reown/appkit-utils': 1.7.3(@types/react@18.3.1)(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + '@reown/appkit-wallet': 1.7.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10) + '@walletconnect/types': 2.19.2(ioredis@5.6.1) + '@walletconnect/universal-provider': 2.19.2(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + bs58: 6.0.0 + valtio: 1.13.2(@types/react@18.3.1)(react@18.3.1) + viem: 2.29.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + 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 + + '@rolldown/pluginutils@1.0.0-beta.9': {} + + '@rollup/plugin-alias@5.1.1(rollup@4.41.0)': + optionalDependencies: + rollup: 4.41.0 + + '@rollup/plugin-commonjs@28.0.3(rollup@4.41.0)': + dependencies: + '@rollup/pluginutils': 5.1.4(rollup@4.41.0) + commondir: 1.0.1 + estree-walker: 2.0.2 + fdir: 6.4.4(picomatch@4.0.2) + is-reference: 1.2.1 + magic-string: 0.30.17 + picomatch: 4.0.2 + optionalDependencies: + rollup: 4.41.0 + + '@rollup/plugin-inject@5.0.5(rollup@4.41.0)': + dependencies: + '@rollup/pluginutils': 5.1.4(rollup@4.41.0) + estree-walker: 2.0.2 + magic-string: 0.30.17 + optionalDependencies: + rollup: 4.41.0 + + '@rollup/plugin-json@6.1.0(rollup@4.41.0)': + dependencies: + '@rollup/pluginutils': 5.1.4(rollup@4.41.0) + optionalDependencies: + rollup: 4.41.0 + + '@rollup/plugin-node-resolve@16.0.1(rollup@4.41.0)': + dependencies: + '@rollup/pluginutils': 5.1.4(rollup@4.41.0) + '@types/resolve': 1.20.2 + deepmerge: 4.3.1 + is-module: 1.0.0 + resolve: 1.22.10 + optionalDependencies: + rollup: 4.41.0 + + '@rollup/plugin-replace@6.0.2(rollup@4.41.0)': + dependencies: + '@rollup/pluginutils': 5.1.4(rollup@4.41.0) + magic-string: 0.30.17 + optionalDependencies: + rollup: 4.41.0 + + '@rollup/plugin-terser@0.4.4(rollup@4.41.0)': + dependencies: + serialize-javascript: 6.0.2 + smob: 1.5.0 + terser: 5.39.2 + optionalDependencies: + rollup: 4.41.0 + + '@rollup/pluginutils@5.1.0(rollup@4.41.0)': + dependencies: + '@types/estree': 1.0.5 + estree-walker: 2.0.2 + picomatch: 2.3.1 + optionalDependencies: + rollup: 4.41.0 + + '@rollup/pluginutils@5.1.4(rollup@4.41.0)': + dependencies: + '@types/estree': 1.0.7 + estree-walker: 2.0.2 + picomatch: 4.0.2 + optionalDependencies: + rollup: 4.41.0 + + '@rollup/rollup-android-arm-eabi@4.41.0': + optional: true + + '@rollup/rollup-android-arm64@4.41.0': + optional: true + + '@rollup/rollup-darwin-arm64@4.41.0': + optional: true + + '@rollup/rollup-darwin-x64@4.41.0': + optional: true + + '@rollup/rollup-freebsd-arm64@4.41.0': + optional: true + + '@rollup/rollup-freebsd-x64@4.41.0': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.41.0': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.41.0': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.41.0': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.41.0': + optional: true + + '@rollup/rollup-linux-loongarch64-gnu@4.41.0': + optional: true + + '@rollup/rollup-linux-powerpc64le-gnu@4.41.0': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.41.0': + optional: true + + '@rollup/rollup-linux-riscv64-musl@4.41.0': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.41.0': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.41.0': + optional: true + + '@rollup/rollup-linux-x64-musl@4.41.0': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.41.0': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.41.0': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.41.0': + optional: true + + '@safe-global/safe-apps-provider@0.18.6(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20)': + dependencies: + '@safe-global/safe-apps-sdk': 9.1.0(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + events: 3.3.0 + transitivePeerDependencies: + - bufferutil + - encoding + - typescript + - utf-8-validate + - zod + + '@safe-global/safe-apps-sdk@9.1.0(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20)': + dependencies: + '@safe-global/safe-gateway-typescript-sdk': 3.8.0(encoding@0.1.13) + viem: 2.17.0(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + transitivePeerDependencies: + - bufferutil + - encoding + - typescript + - utf-8-validate + - zod + + '@safe-global/safe-gateway-typescript-sdk@3.8.0(encoding@0.1.13)': + dependencies: + cross-fetch: 3.2.0(encoding@0.1.13) + transitivePeerDependencies: + - encoding + + '@scure/base@1.1.3': {} + + '@scure/base@1.1.9': {} + + '@scure/base@1.2.4': {} + + '@scure/base@1.2.6': {} + + '@scure/bip32@1.1.5': + dependencies: + '@noble/hashes': 1.2.0 + '@noble/secp256k1': 1.7.1 + '@scure/base': 1.1.9 + + '@scure/bip32@1.3.2': + dependencies: + '@noble/curves': 1.2.0 + '@noble/hashes': 1.3.2 + '@scure/base': 1.1.3 + + '@scure/bip32@1.4.0': + dependencies: + '@noble/curves': 1.4.0 + '@noble/hashes': 1.4.0 + '@scure/base': 1.1.9 + + '@scure/bip32@1.6.2': + dependencies: + '@noble/curves': 1.8.2 + '@noble/hashes': 1.7.2 + '@scure/base': 1.2.4 + + '@scure/bip39@1.1.1': + dependencies: + '@noble/hashes': 1.2.0 + '@scure/base': 1.1.9 + + '@scure/bip39@1.2.1': + dependencies: + '@noble/hashes': 1.3.2 + '@scure/base': 1.1.3 + + '@scure/bip39@1.3.0': + dependencies: + '@noble/hashes': 1.4.0 + '@scure/base': 1.1.9 + + '@scure/bip39@1.5.4': + dependencies: + '@noble/hashes': 1.7.2 + '@scure/base': 1.2.4 + + '@sec-ant/readable-stream@0.4.1': {} + + '@sentry/core@5.30.0': + dependencies: + '@sentry/hub': 5.30.0 + '@sentry/minimal': 5.30.0 + '@sentry/types': 5.30.0 + '@sentry/utils': 5.30.0 + tslib: 1.14.1 + + '@sentry/hub@5.30.0': + dependencies: + '@sentry/types': 5.30.0 + '@sentry/utils': 5.30.0 + tslib: 1.14.1 + + '@sentry/minimal@5.30.0': + dependencies: + '@sentry/hub': 5.30.0 + '@sentry/types': 5.30.0 + tslib: 1.14.1 + + '@sentry/node@5.30.0': + dependencies: + '@sentry/core': 5.30.0 + '@sentry/hub': 5.30.0 + '@sentry/tracing': 5.30.0 + '@sentry/types': 5.30.0 + '@sentry/utils': 5.30.0 + cookie: 0.4.2 + https-proxy-agent: 5.0.1 + lru_map: 0.3.3 + tslib: 1.14.1 + transitivePeerDependencies: + - supports-color + + '@sentry/tracing@5.30.0': + dependencies: + '@sentry/hub': 5.30.0 + '@sentry/minimal': 5.30.0 + '@sentry/types': 5.30.0 + '@sentry/utils': 5.30.0 + tslib: 1.14.1 + + '@sentry/types@5.30.0': {} + + '@sentry/utils@5.30.0': + dependencies: + '@sentry/types': 5.30.0 + tslib: 1.14.1 + + '@shikijs/core@1.22.2': + dependencies: + '@shikijs/engine-javascript': 1.22.2 + '@shikijs/engine-oniguruma': 1.22.2 + '@shikijs/types': 1.22.2 + '@shikijs/vscode-textmate': 9.3.0 + '@types/hast': 3.0.4 + hast-util-to-html: 9.0.3 + + '@shikijs/engine-javascript@1.22.2': + dependencies: + '@shikijs/types': 1.22.2 + '@shikijs/vscode-textmate': 9.3.0 + oniguruma-to-js: 0.4.3 + + '@shikijs/engine-oniguruma@1.22.2': + dependencies: + '@shikijs/types': 1.22.2 + '@shikijs/vscode-textmate': 9.3.0 + + '@shikijs/transformers@1.22.2': + dependencies: + shiki: 1.22.2 + + '@shikijs/twoslash@1.22.2(typescript@5.8.3)': + dependencies: + '@shikijs/core': 1.22.2 + '@shikijs/types': 1.22.2 + twoslash: 0.2.12(typescript@5.8.3) + transitivePeerDependencies: + - supports-color + - typescript + + '@shikijs/types@1.22.2': + dependencies: + '@shikijs/vscode-textmate': 9.3.0 + '@types/hast': 3.0.4 + + '@shikijs/vitepress-twoslash@1.22.2(@nuxt/kit@3.17.4(magicast@0.3.5))(typescript@5.8.3)': + dependencies: + '@shikijs/twoslash': 1.22.2(typescript@5.8.3) + floating-vue: 5.2.2(@nuxt/kit@3.17.4(magicast@0.3.5))(vue@3.5.12(typescript@5.8.3)) + mdast-util-from-markdown: 2.0.2 + mdast-util-gfm: 3.0.0 + mdast-util-to-hast: 13.2.0 + shiki: 1.22.2 + twoslash: 0.2.12(typescript@5.8.3) + twoslash-vue: 0.2.12(typescript@5.8.3) + vue: 3.5.12(typescript@5.8.3) + transitivePeerDependencies: + - '@nuxt/kit' + - supports-color + - typescript + + '@shikijs/vscode-textmate@9.3.0': {} + + '@sindresorhus/is@4.6.0': {} + + '@sindresorhus/is@7.0.1': {} + + '@sindresorhus/merge-streams@2.3.0': {} + + '@sindresorhus/merge-streams@4.0.0': {} + + '@snyk/github-codeowners@1.1.0': + dependencies: + commander: 4.1.1 + ignore: 5.3.2 + p-map: 4.0.0 + + '@socket.io/component-emitter@3.1.2': {} + + '@speed-highlight/core@1.2.7': {} + + '@swc/counter@0.1.3': {} + + '@swc/helpers@0.5.15': + dependencies: + tslib: 2.8.1 + + '@tanstack/match-sorter-utils@8.15.1': + dependencies: + remove-accents: 0.5.0 + + '@tanstack/query-core@5.0.5': {} + + '@tanstack/query-core@5.49.1': {} + + '@tanstack/query-devtools@5.0.5': {} + + '@tanstack/query-persist-client-core@5.0.5': + dependencies: + '@tanstack/query-core': 5.0.5 + + '@tanstack/query-sync-storage-persister@5.0.5': + dependencies: + '@tanstack/query-core': 5.0.5 + '@tanstack/query-persist-client-core': 5.0.5 + + '@tanstack/react-query-devtools@5.0.5(@tanstack/react-query@5.49.2(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@tanstack/query-devtools': 5.0.5 + '@tanstack/react-query': 5.49.2(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + '@tanstack/react-query-persist-client@5.0.5(@tanstack/react-query@5.49.2(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@tanstack/query-persist-client-core': 5.0.5 + '@tanstack/react-query': 5.49.2(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + '@tanstack/react-query@5.49.2(react@18.3.1)': + dependencies: + '@tanstack/query-core': 5.49.1 + react: 18.3.1 + + '@tanstack/vue-query@5.49.1(vue@3.4.27(typescript@5.8.3))': + dependencies: + '@tanstack/match-sorter-utils': 8.15.1 + '@tanstack/query-core': 5.49.1 + '@vue/devtools-api': 6.6.1 + vue: 3.4.27(typescript@5.8.3) + vue-demi: 0.14.10(vue@3.4.27(typescript@5.8.3)) + + '@testing-library/dom@10.4.0': + dependencies: + '@babel/code-frame': 7.24.2 + '@babel/runtime': 7.26.0 + '@types/aria-query': 5.0.4 + aria-query: 5.3.0 + chalk: 4.1.2 + dom-accessibility-api: 0.5.16 + lz-string: 1.5.0 + pretty-format: 27.5.1 + + '@testing-library/react@16.0.1(@testing-library/dom@10.4.0)(@types/react-dom@18.3.0)(@types/react@18.3.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@babel/runtime': 7.26.0 + '@testing-library/dom': 10.4.0 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.1 + '@types/react-dom': 18.3.0 + + '@trysound/sax@0.2.0': {} + + '@tybys/wasm-util@0.9.0': + dependencies: + tslib: 2.8.1 + optional: true + + '@types/aria-query@5.0.4': {} + + '@types/babel__core@7.20.5': + dependencies: + '@babel/parser': 7.24.5 + '@babel/types': 7.24.5 + '@types/babel__generator': 7.6.5 + '@types/babel__template': 7.4.2 + '@types/babel__traverse': 7.20.2 + + '@types/babel__generator@7.6.5': + dependencies: + '@babel/types': 7.27.1 + + '@types/babel__template@7.4.2': + dependencies: + '@babel/parser': 7.26.2 + '@babel/types': 7.27.1 + + '@types/babel__traverse@7.20.2': + dependencies: + '@babel/types': 7.27.1 + + '@types/bn.js@4.11.6': + dependencies: + '@types/node': 24.0.1 + + '@types/bn.js@5.1.5': + dependencies: + '@types/node': 24.0.1 + + '@types/bun@1.1.10': + dependencies: + bun-types: 1.1.29 + + '@types/cookie@0.6.0': {} + + '@types/cross-spawn@6.0.6': + dependencies: + '@types/node': 20.12.10 + + '@types/debug@4.1.12': + dependencies: + '@types/ms': 2.1.0 + + '@types/debug@4.1.7': + dependencies: + '@types/ms': 0.7.31 + + '@types/dedent@0.7.2': {} + + '@types/estree@1.0.5': {} + + '@types/estree@1.0.7': {} + + '@types/hast@3.0.4': + dependencies: + '@types/unist': 3.0.2 + + '@types/linkify-it@5.0.0': {} + + '@types/lru-cache@5.1.1': {} + + '@types/markdown-it@14.1.2': + dependencies: + '@types/linkify-it': 5.0.0 + '@types/mdurl': 2.0.0 + + '@types/mdast@4.0.3': + dependencies: + '@types/unist': 3.0.2 + + '@types/mdurl@2.0.0': {} + + '@types/ms@0.7.31': {} + + '@types/ms@2.1.0': {} + + '@types/mute-stream@0.0.4': + dependencies: + '@types/node': 22.15.31 + + '@types/node@12.20.55': {} + + '@types/node@20.12.10': + dependencies: + undici-types: 5.26.5 + + '@types/node@20.12.14': + dependencies: + undici-types: 5.26.5 + + '@types/node@20.19.0': + dependencies: + undici-types: 6.21.0 + + '@types/node@22.15.31': + dependencies: + undici-types: 6.21.0 + + '@types/node@24.0.1': + dependencies: + undici-types: 7.8.0 + + '@types/normalize-package-data@2.4.4': {} + + '@types/parse-path@7.1.0': + dependencies: + parse-path: 7.1.0 + + '@types/pbkdf2@3.1.2': + dependencies: + '@types/node': 24.0.1 + + '@types/prompts@2.4.9': + dependencies: + '@types/node': 20.12.10 + kleur: 3.0.3 + + '@types/prop-types@15.7.5': {} + + '@types/react-dom@18.3.0': + dependencies: + '@types/react': 18.3.1 + + '@types/react@18.3.1': + dependencies: + '@types/prop-types': 15.7.5 + csstype: 3.1.3 + + '@types/resolve@1.20.2': {} + + '@types/secp256k1@4.0.3': + dependencies: + '@types/node': 24.0.1 + + '@types/semver@7.5.3': {} + + '@types/statuses@2.0.4': {} + + '@types/tough-cookie@4.0.5': {} + + '@types/triple-beam@1.3.5': {} + + '@types/trusted-types@2.0.3': {} + + '@types/unist@3.0.2': {} + + '@types/use-sync-external-store@0.0.6': {} + + '@types/web-bluetooth@0.0.20': {} + + '@types/wrap-ansi@3.0.0': {} + + '@types/ws@8.5.10': + dependencies: + '@types/node': 20.12.14 + + '@types/yauzl@2.10.3': + dependencies: + '@types/node': 24.0.1 + optional: true + + '@typescript-eslint/types@5.62.0': {} + + '@typescript-eslint/typescript-estree@5.62.0(typescript@5.8.3)': + dependencies: + '@typescript-eslint/types': 5.62.0 + '@typescript-eslint/visitor-keys': 5.62.0 + debug: 4.4.1 + globby: 11.1.0 + is-glob: 4.0.3 + semver: 7.7.2 + tsutils: 3.21.0(typescript@5.8.3) + optionalDependencies: + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/visitor-keys@5.62.0': + dependencies: + '@typescript-eslint/types': 5.62.0 + eslint-visitor-keys: 3.4.3 + + '@typescript/vfs@1.6.0(typescript@5.8.3)': + dependencies: + debug: 4.4.1 + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + + '@ungap/structured-clone@1.2.0': {} + + '@unhead/vue@2.0.9(vue@3.5.14(typescript@5.8.3))': + dependencies: + hookable: 5.5.3 + unhead: 2.0.9 + vue: 3.5.14(typescript@5.8.3) + + '@unocss/astro@0.59.4(rollup@4.41.0)': + dependencies: + '@unocss/core': 0.59.4 + '@unocss/reset': 0.59.4 + '@unocss/vite': 0.59.4(rollup@4.41.0) + transitivePeerDependencies: + - rollup + + '@unocss/cli@0.59.4(rollup@4.41.0)': + dependencies: + '@ampproject/remapping': 2.3.0 + '@rollup/pluginutils': 5.1.0(rollup@4.41.0) + '@unocss/config': 0.59.4 + '@unocss/core': 0.59.4 + '@unocss/preset-uno': 0.59.4 + cac: 6.7.14 + chokidar: 3.6.0 + colorette: 2.0.20 + consola: 3.4.2 + fast-glob: 3.3.2 + magic-string: 0.30.17 + pathe: 1.1.2 + perfect-debounce: 1.0.0 + transitivePeerDependencies: + - rollup + + '@unocss/config@0.59.4': + dependencies: + '@unocss/core': 0.59.4 + unconfig: 0.3.13 + + '@unocss/core@0.59.4': {} + + '@unocss/extractor-arbitrary-variants@0.59.4': + dependencies: + '@unocss/core': 0.59.4 + + '@unocss/inspector@0.59.4': + dependencies: + '@unocss/core': 0.59.4 + '@unocss/rule-utils': 0.59.4 + gzip-size: 6.0.0 + sirv: 2.0.4 + + '@unocss/postcss@0.59.4': + dependencies: + '@unocss/config': 0.59.4 + '@unocss/core': 0.59.4 + '@unocss/rule-utils': 0.59.4 + css-tree: 2.3.1 + fast-glob: 3.3.2 + magic-string: 0.30.17 + postcss: 8.5.5 + + '@unocss/preset-attributify@0.59.4': + dependencies: + '@unocss/core': 0.59.4 + + '@unocss/preset-icons@0.59.4': + dependencies: + '@iconify/utils': 2.1.23 + '@unocss/core': 0.59.4 + ofetch: 1.4.1 + transitivePeerDependencies: + - supports-color + + '@unocss/preset-mini@0.59.4': + dependencies: + '@unocss/core': 0.59.4 + '@unocss/extractor-arbitrary-variants': 0.59.4 + '@unocss/rule-utils': 0.59.4 + + '@unocss/preset-tagify@0.59.4': + dependencies: + '@unocss/core': 0.59.4 + + '@unocss/preset-typography@0.59.4': + dependencies: + '@unocss/core': 0.59.4 + '@unocss/preset-mini': 0.59.4 + + '@unocss/preset-uno@0.59.4': + dependencies: + '@unocss/core': 0.59.4 + '@unocss/preset-mini': 0.59.4 + '@unocss/preset-wind': 0.59.4 + '@unocss/rule-utils': 0.59.4 + + '@unocss/preset-web-fonts@0.59.4': + dependencies: + '@unocss/core': 0.59.4 + ofetch: 1.4.1 + + '@unocss/preset-wind@0.59.4': + dependencies: + '@unocss/core': 0.59.4 + '@unocss/preset-mini': 0.59.4 + '@unocss/rule-utils': 0.59.4 + + '@unocss/reset@0.59.4': {} + + '@unocss/rule-utils@0.59.4': + dependencies: + '@unocss/core': 0.59.4 + magic-string: 0.30.17 + + '@unocss/scope@0.59.4': {} + + '@unocss/transformer-attributify-jsx-babel@0.59.4': + dependencies: + '@babel/core': 7.24.5 + '@babel/plugin-syntax-jsx': 7.24.1(@babel/core@7.24.5) + '@babel/preset-typescript': 7.24.1(@babel/core@7.24.5) + '@unocss/core': 0.59.4 + transitivePeerDependencies: + - supports-color + + '@unocss/transformer-attributify-jsx@0.59.4': + dependencies: + '@unocss/core': 0.59.4 + + '@unocss/transformer-compile-class@0.59.4': + dependencies: + '@unocss/core': 0.59.4 + + '@unocss/transformer-directives@0.59.4': + dependencies: + '@unocss/core': 0.59.4 + '@unocss/rule-utils': 0.59.4 + css-tree: 2.3.1 + + '@unocss/transformer-variant-group@0.59.4': + dependencies: + '@unocss/core': 0.59.4 + + '@unocss/vite@0.59.4(rollup@4.41.0)': + dependencies: + '@ampproject/remapping': 2.3.0 + '@rollup/pluginutils': 5.1.0(rollup@4.41.0) + '@unocss/config': 0.59.4 + '@unocss/core': 0.59.4 + '@unocss/inspector': 0.59.4 + '@unocss/scope': 0.59.4 + '@unocss/transformer-directives': 0.59.4 + chokidar: 3.6.0 + fast-glob: 3.3.2 + magic-string: 0.30.17 + transitivePeerDependencies: + - rollup + + '@vercel/nft@0.27.7(encoding@0.1.13)(rollup@4.41.0)': + dependencies: + '@mapbox/node-pre-gyp': 1.0.11(encoding@0.1.13) + '@rollup/pluginutils': 5.1.4(rollup@4.41.0) + acorn: 8.15.0 + acorn-import-attributes: 1.9.5(acorn@8.15.0) + async-sema: 3.1.1 + bindings: 1.5.0 + estree-walker: 2.0.2 + glob: 7.2.3 + graceful-fs: 4.2.11 + micromatch: 4.0.8 + node-gyp-build: 4.8.4 + resolve-from: 5.0.0 + transitivePeerDependencies: + - encoding + - rollup + - supports-color + + '@vercel/nft@0.29.3(encoding@0.1.13)(rollup@4.41.0)': + dependencies: + '@mapbox/node-pre-gyp': 2.0.0(encoding@0.1.13) + '@rollup/pluginutils': 5.1.4(rollup@4.41.0) + acorn: 8.14.1 + acorn-import-attributes: 1.9.5(acorn@8.14.1) + async-sema: 3.1.1 + bindings: 1.5.0 + estree-walker: 2.0.2 + glob: 10.4.5 + graceful-fs: 4.2.11 + node-gyp-build: 4.8.4 + picomatch: 4.0.2 + resolve-from: 5.0.0 + transitivePeerDependencies: + - encoding + - rollup + - supports-color + + '@vitejs/plugin-react@4.2.1(vite@5.4.19(@types/node@24.0.1)(terser@5.39.2))': + dependencies: + '@babel/core': 7.24.5 + '@babel/plugin-transform-react-jsx-self': 7.24.5(@babel/core@7.24.5) + '@babel/plugin-transform-react-jsx-source': 7.24.1(@babel/core@7.24.5) + '@types/babel__core': 7.20.5 + react-refresh: 0.14.0 + vite: 5.4.19(@types/node@24.0.1)(terser@5.39.2) + transitivePeerDependencies: + - supports-color + + '@vitejs/plugin-vue-jsx@4.2.0(vite@6.3.5(@types/node@24.0.1)(jiti@2.4.2)(terser@5.39.2)(yaml@2.8.0))(vue@3.5.14(typescript@5.8.3))': + dependencies: + '@babel/core': 7.27.1 + '@babel/plugin-transform-typescript': 7.27.1(@babel/core@7.27.1) + '@rolldown/pluginutils': 1.0.0-beta.9 + '@vue/babel-plugin-jsx': 1.4.0(@babel/core@7.27.1) + vite: 6.3.5(@types/node@24.0.1)(jiti@2.4.2)(terser@5.39.2)(yaml@2.8.0) + vue: 3.5.14(typescript@5.8.3) + transitivePeerDependencies: + - supports-color + + '@vitejs/plugin-vue@5.0.4(vite@5.4.19(@types/node@24.0.1)(terser@5.39.2))(vue@3.4.27(typescript@5.8.3))': + dependencies: + vite: 5.4.19(@types/node@24.0.1)(terser@5.39.2) + vue: 3.4.27(typescript@5.8.3) + + '@vitejs/plugin-vue@5.1.4(vite@5.4.19(@types/node@24.0.1)(terser@5.39.2))(vue@3.5.12(typescript@5.8.3))': + dependencies: + vite: 5.4.19(@types/node@24.0.1)(terser@5.39.2) + vue: 3.5.12(typescript@5.8.3) + + '@vitejs/plugin-vue@5.2.4(vite@6.3.5(@types/node@24.0.1)(jiti@2.4.2)(terser@5.39.2)(yaml@2.8.0))(vue@3.5.14(typescript@5.8.3))': + dependencies: + vite: 6.3.5(@types/node@24.0.1)(jiti@2.4.2)(terser@5.39.2)(yaml@2.8.0) + vue: 3.5.14(typescript@5.8.3) + + '@vitest/coverage-v8@2.1.1(vitest@2.1.9(@types/node@24.0.1)(happy-dom@15.10.2)(msw@2.4.9(typescript@5.8.3))(terser@5.39.2))': + dependencies: + '@ampproject/remapping': 2.3.0 + '@bcoe/v8-coverage': 0.2.3 + debug: 4.3.7 + istanbul-lib-coverage: 3.2.2 + istanbul-lib-report: 3.0.1 + istanbul-lib-source-maps: 5.0.6 + istanbul-reports: 3.1.7 + magic-string: 0.30.11 + magicast: 0.3.4 + std-env: 3.7.0 + test-exclude: 7.0.1 + tinyrainbow: 1.2.0 + vitest: 2.1.9(@types/node@24.0.1)(happy-dom@15.10.2)(msw@2.4.9(typescript@5.8.3))(terser@5.39.2) + transitivePeerDependencies: + - supports-color + + '@vitest/expect@2.1.9': + dependencies: + '@vitest/spy': 2.1.9 + '@vitest/utils': 2.1.9 + chai: 5.2.0 + tinyrainbow: 1.2.0 + + '@vitest/mocker@2.1.9(msw@2.4.9(typescript@5.8.3))(vite@5.4.19(@types/node@24.0.1)(terser@5.39.2))': + dependencies: + '@vitest/spy': 2.1.9 + estree-walker: 3.0.3 + magic-string: 0.30.17 + optionalDependencies: + msw: 2.4.9(typescript@5.8.3) + vite: 5.4.19(@types/node@24.0.1)(terser@5.39.2) + + '@vitest/pretty-format@2.1.9': + dependencies: + tinyrainbow: 1.2.0 + + '@vitest/runner@2.1.9': + dependencies: + '@vitest/utils': 2.1.9 + pathe: 1.1.2 + + '@vitest/snapshot@2.1.9': + dependencies: + '@vitest/pretty-format': 2.1.9 + magic-string: 0.30.17 + pathe: 1.1.2 + + '@vitest/spy@2.1.9': + dependencies: + tinyspy: 3.0.2 + + '@vitest/utils@2.1.9': + dependencies: + '@vitest/pretty-format': 2.1.9 + loupe: 3.1.3 + tinyrainbow: 1.2.0 + + '@volar/language-core@2.2.1': + dependencies: + '@volar/source-map': 2.2.1 + + '@volar/language-core@2.4.8': + dependencies: + '@volar/source-map': 2.4.8 + + '@volar/source-map@2.2.1': + dependencies: + muggle-string: 0.4.1 + + '@volar/source-map@2.4.8': {} + + '@volar/typescript@2.2.1': + dependencies: + '@volar/language-core': 2.2.1 + path-browserify: 1.0.1 + + '@vue-macros/common@1.16.1(vue@3.5.14(typescript@5.8.3))': + dependencies: + '@vue/compiler-sfc': 3.5.14 + ast-kit: 1.4.3 + local-pkg: 1.1.1 + magic-string-ast: 0.7.1 + pathe: 2.0.3 + picomatch: 4.0.2 + optionalDependencies: + vue: 3.5.14(typescript@5.8.3) + + '@vue/babel-helper-vue-transform-on@1.4.0': {} + + '@vue/babel-plugin-jsx@1.4.0(@babel/core@7.27.1)': + dependencies: + '@babel/helper-module-imports': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.27.1) + '@babel/template': 7.27.2 + '@babel/traverse': 7.27.1 + '@babel/types': 7.27.1 + '@vue/babel-helper-vue-transform-on': 1.4.0 + '@vue/babel-plugin-resolve-type': 1.4.0(@babel/core@7.27.1) + '@vue/shared': 3.5.14 + optionalDependencies: + '@babel/core': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@vue/babel-plugin-resolve-type@1.4.0(@babel/core@7.27.1)': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/core': 7.27.1 + '@babel/helper-module-imports': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/parser': 7.27.2 + '@vue/compiler-sfc': 3.5.14 + transitivePeerDependencies: + - supports-color + + '@vue/compiler-core@3.4.27': + dependencies: + '@babel/parser': 7.26.2 + '@vue/shared': 3.4.27 + entities: 4.5.0 + estree-walker: 2.0.2 + source-map-js: 1.2.1 + + '@vue/compiler-core@3.5.12': + dependencies: + '@babel/parser': 7.27.2 + '@vue/shared': 3.5.12 + entities: 4.5.0 + estree-walker: 2.0.2 + source-map-js: 1.2.1 + + '@vue/compiler-core@3.5.14': + dependencies: + '@babel/parser': 7.27.2 + '@vue/shared': 3.5.14 + entities: 4.5.0 + estree-walker: 2.0.2 + source-map-js: 1.2.1 + + '@vue/compiler-dom@3.4.27': + dependencies: + '@vue/compiler-core': 3.4.27 + '@vue/shared': 3.4.27 + + '@vue/compiler-dom@3.5.12': + dependencies: + '@vue/compiler-core': 3.5.12 + '@vue/shared': 3.5.12 + + '@vue/compiler-dom@3.5.14': + dependencies: + '@vue/compiler-core': 3.5.14 + '@vue/shared': 3.5.14 + + '@vue/compiler-sfc@3.4.27': + dependencies: + '@babel/parser': 7.26.2 + '@vue/compiler-core': 3.4.27 + '@vue/compiler-dom': 3.4.27 + '@vue/compiler-ssr': 3.4.27 + '@vue/shared': 3.4.27 + estree-walker: 2.0.2 + magic-string: 0.30.12 + postcss: 8.4.47 + source-map-js: 1.2.1 + + '@vue/compiler-sfc@3.5.12': + dependencies: + '@babel/parser': 7.26.2 + '@vue/compiler-core': 3.5.12 + '@vue/compiler-dom': 3.5.12 + '@vue/compiler-ssr': 3.5.12 + '@vue/shared': 3.5.12 + estree-walker: 2.0.2 + magic-string: 0.30.17 + postcss: 8.5.5 + source-map-js: 1.2.1 + + '@vue/compiler-sfc@3.5.14': + dependencies: + '@babel/parser': 7.27.2 + '@vue/compiler-core': 3.5.14 + '@vue/compiler-dom': 3.5.14 + '@vue/compiler-ssr': 3.5.14 + '@vue/shared': 3.5.14 + estree-walker: 2.0.2 + magic-string: 0.30.17 + postcss: 8.5.5 + source-map-js: 1.2.1 + + '@vue/compiler-ssr@3.4.27': + dependencies: + '@vue/compiler-dom': 3.4.27 + '@vue/shared': 3.4.27 + + '@vue/compiler-ssr@3.5.12': + dependencies: + '@vue/compiler-dom': 3.5.12 + '@vue/shared': 3.5.12 + + '@vue/compiler-ssr@3.5.14': + dependencies: + '@vue/compiler-dom': 3.5.14 + '@vue/shared': 3.5.14 + + '@vue/compiler-vue2@2.7.16': + dependencies: + de-indent: 1.0.2 + he: 1.2.0 + + '@vue/devtools-api@6.6.1': {} + + '@vue/devtools-api@6.6.4': {} + + '@vue/devtools-api@7.6.2': + dependencies: + '@vue/devtools-kit': 7.6.2 + + '@vue/devtools-core@7.7.6(vite@6.3.5(@types/node@24.0.1)(jiti@2.4.2)(terser@5.39.2)(yaml@2.8.0))(vue@3.5.14(typescript@5.8.3))': + dependencies: + '@vue/devtools-kit': 7.7.6 + '@vue/devtools-shared': 7.7.6 + mitt: 3.0.1 + nanoid: 5.1.5 + pathe: 2.0.3 + vite-hot-client: 2.0.4(vite@6.3.5(@types/node@24.0.1)(jiti@2.4.2)(terser@5.39.2)(yaml@2.8.0)) + vue: 3.5.14(typescript@5.8.3) + transitivePeerDependencies: + - vite + + '@vue/devtools-kit@7.6.2': + dependencies: + '@vue/devtools-shared': 7.6.2 + birpc: 0.2.19 + hookable: 5.5.3 + mitt: 3.0.1 + perfect-debounce: 1.0.0 + speakingurl: 14.0.1 + superjson: 2.2.1 + + '@vue/devtools-kit@7.7.6': + dependencies: + '@vue/devtools-shared': 7.7.6 + birpc: 2.3.0 + hookable: 5.5.3 + mitt: 3.0.1 + perfect-debounce: 1.0.0 + speakingurl: 14.0.1 + superjson: 2.2.2 + + '@vue/devtools-shared@7.6.2': + dependencies: + rfdc: 1.4.1 + + '@vue/devtools-shared@7.7.6': + dependencies: + rfdc: 1.4.1 + + '@vue/language-core@2.0.16(typescript@5.8.3)': + dependencies: + '@volar/language-core': 2.2.1 + '@vue/compiler-dom': 3.5.12 + '@vue/shared': 3.5.14 + computeds: 0.0.1 + minimatch: 9.0.4 + path-browserify: 1.0.1 + vue-template-compiler: 2.7.16 + optionalDependencies: + typescript: 5.8.3 + + '@vue/language-core@2.1.10(typescript@5.8.3)': + dependencies: + '@volar/language-core': 2.4.8 + '@vue/compiler-dom': 3.5.14 + '@vue/compiler-vue2': 2.7.16 + '@vue/shared': 3.5.14 + alien-signals: 0.2.0 + minimatch: 9.0.4 + muggle-string: 0.4.1 + path-browserify: 1.0.1 + optionalDependencies: + typescript: 5.8.3 + + '@vue/reactivity@3.4.27': + dependencies: + '@vue/shared': 3.4.27 + + '@vue/reactivity@3.5.12': + dependencies: + '@vue/shared': 3.5.12 + + '@vue/reactivity@3.5.14': + dependencies: + '@vue/shared': 3.5.14 + + '@vue/runtime-core@3.4.27': + dependencies: + '@vue/reactivity': 3.4.27 + '@vue/shared': 3.4.27 + + '@vue/runtime-core@3.5.12': + dependencies: + '@vue/reactivity': 3.5.12 + '@vue/shared': 3.5.12 + + '@vue/runtime-core@3.5.14': + dependencies: + '@vue/reactivity': 3.5.14 + '@vue/shared': 3.5.14 + + '@vue/runtime-dom@3.4.27': + dependencies: + '@vue/runtime-core': 3.4.27 + '@vue/shared': 3.4.27 + csstype: 3.1.3 + + '@vue/runtime-dom@3.5.12': + dependencies: + '@vue/reactivity': 3.5.12 + '@vue/runtime-core': 3.5.12 + '@vue/shared': 3.5.12 + csstype: 3.1.3 + + '@vue/runtime-dom@3.5.14': + dependencies: + '@vue/reactivity': 3.5.14 + '@vue/runtime-core': 3.5.14 + '@vue/shared': 3.5.14 + csstype: 3.1.3 + + '@vue/server-renderer@3.4.27(vue@3.4.27(typescript@5.8.3))': + dependencies: + '@vue/compiler-ssr': 3.4.27 + '@vue/shared': 3.4.27 + vue: 3.4.27(typescript@5.8.3) + + '@vue/server-renderer@3.5.12(vue@3.5.12(typescript@5.8.3))': + dependencies: + '@vue/compiler-ssr': 3.5.12 + '@vue/shared': 3.5.12 + vue: 3.5.12(typescript@5.8.3) + + '@vue/server-renderer@3.5.14(vue@3.5.14(typescript@5.8.3))': + dependencies: + '@vue/compiler-ssr': 3.5.14 + '@vue/shared': 3.5.14 + vue: 3.5.14(typescript@5.8.3) + + '@vue/shared@3.4.27': {} + + '@vue/shared@3.5.12': {} + + '@vue/shared@3.5.14': {} + + '@vue/test-utils@2.4.6': + dependencies: + js-beautify: 1.15.1 + vue-component-type-helpers: 2.0.16 + + '@vueuse/core@11.2.0(vue@3.5.12(typescript@5.8.3))': + dependencies: + '@types/web-bluetooth': 0.0.20 + '@vueuse/metadata': 11.2.0 + '@vueuse/shared': 11.2.0(vue@3.5.12(typescript@5.8.3)) + vue-demi: 0.14.10(vue@3.5.12(typescript@5.8.3)) + transitivePeerDependencies: + - '@vue/composition-api' + - vue + + '@vueuse/integrations@11.2.0(change-case@5.4.4)(focus-trap@7.6.0)(fuse.js@7.1.0)(idb-keyval@6.2.1)(jwt-decode@4.0.0)(qrcode@1.5.3)(vue@3.5.12(typescript@5.8.3))': + dependencies: + '@vueuse/core': 11.2.0(vue@3.5.12(typescript@5.8.3)) + '@vueuse/shared': 11.2.0(vue@3.5.12(typescript@5.8.3)) + vue-demi: 0.14.10(vue@3.5.12(typescript@5.8.3)) + optionalDependencies: + change-case: 5.4.4 + focus-trap: 7.6.0 + fuse.js: 7.1.0 + idb-keyval: 6.2.1 + jwt-decode: 4.0.0 + qrcode: 1.5.3 + transitivePeerDependencies: + - '@vue/composition-api' + - vue + + '@vueuse/metadata@11.2.0': {} + + '@vueuse/shared@11.2.0(vue@3.5.12(typescript@5.8.3))': + dependencies: + vue-demi: 0.14.10(vue@3.5.12(typescript@5.8.3)) + transitivePeerDependencies: + - '@vue/composition-api' + - vue + + '@walletconnect/core@2.19.2(bufferutil@4.0.9)(ioredis@5.6.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20)': + dependencies: + '@walletconnect/heartbeat': 1.2.2 + '@walletconnect/jsonrpc-provider': 1.0.14 + '@walletconnect/jsonrpc-types': 1.0.4 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/jsonrpc-ws-connection': 1.0.16(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@walletconnect/keyvaluestorage': 1.1.1(ioredis@5.6.1) + '@walletconnect/logger': 2.1.2 + '@walletconnect/relay-api': 1.0.11 + '@walletconnect/relay-auth': 1.1.0 + '@walletconnect/safe-json': 1.0.2 + '@walletconnect/time': 1.0.2 + '@walletconnect/types': 2.19.2(ioredis@5.6.1) + '@walletconnect/utils': 2.19.2(bufferutil@4.0.9)(ioredis@5.6.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + '@walletconnect/window-getters': 1.0.1 + es-toolkit: 1.33.0 + events: 3.3.0 + uint8arrays: 3.1.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/kv' + - bufferutil + - ioredis + - typescript + - uWebSockets.js + - utf-8-validate + - zod + + '@walletconnect/core@2.20.2(bufferutil@4.0.9)(ioredis@5.6.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20)': + dependencies: + '@walletconnect/heartbeat': 1.2.2 + '@walletconnect/jsonrpc-provider': 1.0.14 + '@walletconnect/jsonrpc-types': 1.0.4 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/jsonrpc-ws-connection': 1.0.16(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@walletconnect/keyvaluestorage': 1.1.1(ioredis@5.6.1) + '@walletconnect/logger': 2.1.2 + '@walletconnect/relay-api': 1.0.11 + '@walletconnect/relay-auth': 1.1.0 + '@walletconnect/safe-json': 1.0.2 + '@walletconnect/time': 1.0.2 + '@walletconnect/types': 2.20.2(ioredis@5.6.1) + '@walletconnect/utils': 2.20.2(bufferutil@4.0.9)(ioredis@5.6.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + '@walletconnect/window-getters': 1.0.1 + es-toolkit: 1.33.0 + events: 3.3.0 + uint8arrays: 3.1.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/kv' + - bufferutil + - ioredis + - typescript + - uWebSockets.js + - utf-8-validate + - zod + + '@walletconnect/environment@1.0.1': + dependencies: + tslib: 1.14.1 + + '@walletconnect/ethereum-provider@2.20.2(@types/react@18.3.1)(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20)': + dependencies: + '@reown/appkit': 1.7.3(@types/react@18.3.1)(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + '@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(ioredis@5.6.1) + '@walletconnect/sign-client': 2.20.2(bufferutil@4.0.9)(ioredis@5.6.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + '@walletconnect/types': 2.20.2(ioredis@5.6.1) + '@walletconnect/universal-provider': 2.20.2(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + '@walletconnect/utils': 2.20.2(bufferutil@4.0.9)(ioredis@5.6.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + 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/events@1.0.1': + dependencies: + keyvaluestorage-interface: 1.0.0 + tslib: 1.14.1 + + '@walletconnect/heartbeat@1.2.2': + dependencies: + '@walletconnect/events': 1.0.1 + '@walletconnect/time': 1.0.2 + events: 3.3.0 + + '@walletconnect/jsonrpc-http-connection@1.0.8(encoding@0.1.13)': + dependencies: + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/safe-json': 1.0.2 + cross-fetch: 3.1.5(encoding@0.1.13) + events: 3.3.0 + transitivePeerDependencies: + - encoding + + '@walletconnect/jsonrpc-provider@1.0.14': + dependencies: + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/safe-json': 1.0.2 + events: 3.3.0 + + '@walletconnect/jsonrpc-types@1.0.4': + dependencies: + events: 3.3.0 + keyvaluestorage-interface: 1.0.0 + + '@walletconnect/jsonrpc-utils@1.0.8': + dependencies: + '@walletconnect/environment': 1.0.1 + '@walletconnect/jsonrpc-types': 1.0.4 + tslib: 1.14.1 + + '@walletconnect/jsonrpc-ws-connection@1.0.16(bufferutil@4.0.9)(utf-8-validate@5.0.10)': + dependencies: + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/safe-json': 1.0.2 + events: 3.3.0 + ws: 7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@walletconnect/keyvaluestorage@1.1.1(ioredis@5.6.1)': + dependencies: + '@walletconnect/safe-json': 1.0.2 + idb-keyval: 6.2.1 + unstorage: 1.10.2(idb-keyval@6.2.1)(ioredis@5.6.1) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@netlify/blobs' + - '@planetscale/database' + - '@upstash/redis' + - '@vercel/kv' + - ioredis + - uWebSockets.js + + '@walletconnect/logger@2.1.2': + dependencies: + '@walletconnect/safe-json': 1.0.2 + pino: 7.11.0 + + '@walletconnect/relay-api@1.0.11': + dependencies: + '@walletconnect/jsonrpc-types': 1.0.4 + + '@walletconnect/relay-auth@1.1.0': + dependencies: + '@noble/curves': 1.8.0 + '@noble/hashes': 1.7.0 + '@walletconnect/safe-json': 1.0.2 + '@walletconnect/time': 1.0.2 + uint8arrays: 3.1.1 + + '@walletconnect/safe-json@1.0.2': + dependencies: + tslib: 1.14.1 + + '@walletconnect/sign-client@2.19.2(bufferutil@4.0.9)(ioredis@5.6.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20)': + dependencies: + '@walletconnect/core': 2.19.2(bufferutil@4.0.9)(ioredis@5.6.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + '@walletconnect/events': 1.0.1 + '@walletconnect/heartbeat': 1.2.2 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/logger': 2.1.2 + '@walletconnect/time': 1.0.2 + '@walletconnect/types': 2.19.2(ioredis@5.6.1) + '@walletconnect/utils': 2.19.2(bufferutil@4.0.9)(ioredis@5.6.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + 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' + - '@upstash/redis' + - '@vercel/kv' + - bufferutil + - ioredis + - typescript + - uWebSockets.js + - utf-8-validate + - zod + + '@walletconnect/sign-client@2.20.2(bufferutil@4.0.9)(ioredis@5.6.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20)': + dependencies: + '@walletconnect/core': 2.20.2(bufferutil@4.0.9)(ioredis@5.6.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + '@walletconnect/events': 1.0.1 + '@walletconnect/heartbeat': 1.2.2 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/logger': 2.1.2 + '@walletconnect/time': 1.0.2 + '@walletconnect/types': 2.20.2(ioredis@5.6.1) + '@walletconnect/utils': 2.20.2(bufferutil@4.0.9)(ioredis@5.6.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + 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' + - '@upstash/redis' + - '@vercel/kv' + - bufferutil + - ioredis + - typescript + - uWebSockets.js + - utf-8-validate + - zod + + '@walletconnect/time@1.0.2': + dependencies: + tslib: 1.14.1 + + '@walletconnect/types@2.19.2(ioredis@5.6.1)': + dependencies: + '@walletconnect/events': 1.0.1 + '@walletconnect/heartbeat': 1.2.2 + '@walletconnect/jsonrpc-types': 1.0.4 + '@walletconnect/keyvaluestorage': 1.1.1(ioredis@5.6.1) + '@walletconnect/logger': 2.1.2 + events: 3.3.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/kv' + - ioredis + - uWebSockets.js + + '@walletconnect/types@2.20.2(ioredis@5.6.1)': + dependencies: + '@walletconnect/events': 1.0.1 + '@walletconnect/heartbeat': 1.2.2 + '@walletconnect/jsonrpc-types': 1.0.4 + '@walletconnect/keyvaluestorage': 1.1.1(ioredis@5.6.1) + '@walletconnect/logger': 2.1.2 + events: 3.3.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/kv' + - ioredis + - uWebSockets.js + + '@walletconnect/universal-provider@2.19.2(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20)': + dependencies: + '@walletconnect/events': 1.0.1 + '@walletconnect/jsonrpc-http-connection': 1.0.8(encoding@0.1.13) + '@walletconnect/jsonrpc-provider': 1.0.14 + '@walletconnect/jsonrpc-types': 1.0.4 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/keyvaluestorage': 1.1.1(ioredis@5.6.1) + '@walletconnect/logger': 2.1.2 + '@walletconnect/sign-client': 2.19.2(bufferutil@4.0.9)(ioredis@5.6.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + '@walletconnect/types': 2.19.2(ioredis@5.6.1) + '@walletconnect/utils': 2.19.2(bufferutil@4.0.9)(ioredis@5.6.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + es-toolkit: 1.33.0 + events: 3.3.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/kv' + - bufferutil + - encoding + - ioredis + - typescript + - uWebSockets.js + - utf-8-validate + - zod + + '@walletconnect/universal-provider@2.20.2(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20)': + dependencies: + '@walletconnect/events': 1.0.1 + '@walletconnect/jsonrpc-http-connection': 1.0.8(encoding@0.1.13) + '@walletconnect/jsonrpc-provider': 1.0.14 + '@walletconnect/jsonrpc-types': 1.0.4 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/keyvaluestorage': 1.1.1(ioredis@5.6.1) + '@walletconnect/logger': 2.1.2 + '@walletconnect/sign-client': 2.20.2(bufferutil@4.0.9)(ioredis@5.6.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + '@walletconnect/types': 2.20.2(ioredis@5.6.1) + '@walletconnect/utils': 2.20.2(bufferutil@4.0.9)(ioredis@5.6.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + es-toolkit: 1.33.0 + events: 3.3.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/kv' + - bufferutil + - encoding + - ioredis + - typescript + - uWebSockets.js + - utf-8-validate + - zod + + '@walletconnect/utils@2.19.2(bufferutil@4.0.9)(ioredis@5.6.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20)': + dependencies: + '@noble/ciphers': 1.2.1 + '@noble/curves': 1.8.1 + '@noble/hashes': 1.7.1 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/keyvaluestorage': 1.1.1(ioredis@5.6.1) + '@walletconnect/relay-api': 1.0.11 + '@walletconnect/relay-auth': 1.1.0 + '@walletconnect/safe-json': 1.0.2 + '@walletconnect/time': 1.0.2 + '@walletconnect/types': 2.19.2(ioredis@5.6.1) + '@walletconnect/window-getters': 1.0.1 + '@walletconnect/window-metadata': 1.0.1 + bs58: 6.0.0 + detect-browser: 5.3.0 + query-string: 7.1.3 + uint8arrays: 3.1.0 + viem: 2.23.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + 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' + - '@upstash/redis' + - '@vercel/kv' + - bufferutil + - ioredis + - typescript + - uWebSockets.js + - utf-8-validate + - zod + + '@walletconnect/utils@2.20.2(bufferutil@4.0.9)(ioredis@5.6.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20)': + dependencies: + '@noble/ciphers': 1.2.1 + '@noble/curves': 1.8.1 + '@noble/hashes': 1.7.1 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/keyvaluestorage': 1.1.1(ioredis@5.6.1) + '@walletconnect/relay-api': 1.0.11 + '@walletconnect/relay-auth': 1.1.0 + '@walletconnect/safe-json': 1.0.2 + '@walletconnect/time': 1.0.2 + '@walletconnect/types': 2.20.2(ioredis@5.6.1) + '@walletconnect/window-getters': 1.0.1 + '@walletconnect/window-metadata': 1.0.1 + bs58: 6.0.0 + detect-browser: 5.3.0 + query-string: 7.1.3 + uint8arrays: 3.1.0 + viem: 2.23.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + 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' + - '@upstash/redis' + - '@vercel/kv' + - bufferutil + - ioredis + - typescript + - uWebSockets.js + - utf-8-validate + - zod + + '@walletconnect/window-getters@1.0.1': + dependencies: + tslib: 1.14.1 + + '@walletconnect/window-metadata@1.0.1': + dependencies: + '@walletconnect/window-getters': 1.0.1 + tslib: 1.14.1 + + '@whatwg-node/disposablestack@0.0.6': + dependencies: + '@whatwg-node/promise-helpers': 1.3.2 + tslib: 2.8.1 + + '@whatwg-node/fetch@0.10.8': + dependencies: + '@whatwg-node/node-fetch': 0.7.21 + urlpattern-polyfill: 10.1.0 + + '@whatwg-node/node-fetch@0.7.21': + dependencies: + '@fastify/busboy': 3.1.1 + '@whatwg-node/disposablestack': 0.0.6 + '@whatwg-node/promise-helpers': 1.3.2 + tslib: 2.8.1 + + '@whatwg-node/promise-helpers@1.3.2': + dependencies: + tslib: 2.8.1 + + '@whatwg-node/server@0.9.71': + dependencies: + '@whatwg-node/disposablestack': 0.0.6 + '@whatwg-node/fetch': 0.10.8 + '@whatwg-node/promise-helpers': 1.3.2 + tslib: 2.8.1 + + abbrev@1.1.1: {} + + abbrev@2.0.0: {} + + abbrev@3.0.1: {} + + abitype@1.0.0(typescript@5.8.3)(zod@3.25.20): + optionalDependencies: + typescript: 5.8.3 + zod: 3.25.20 + + abitype@1.0.2(typescript@5.8.3)(zod@3.25.20): + optionalDependencies: + typescript: 5.8.3 + zod: 3.25.20 + + abitype@1.0.4(typescript@5.8.3)(zod@3.25.20): + optionalDependencies: + typescript: 5.8.3 + zod: 3.25.20 + + abitype@1.0.5(typescript@5.8.3)(zod@3.25.20): + optionalDependencies: + typescript: 5.8.3 + zod: 3.25.20 + + abitype@1.0.8(typescript@5.8.3)(zod@3.22.4): + optionalDependencies: + typescript: 5.8.3 + zod: 3.22.4 + + abitype@1.0.8(typescript@5.8.3)(zod@3.25.20): + optionalDependencies: + typescript: 5.8.3 + zod: 3.25.20 + + abort-controller@3.0.0: + dependencies: + event-target-shim: 5.0.1 + + acorn-import-attributes@1.9.5(acorn@8.14.1): + dependencies: + acorn: 8.14.1 + + acorn-import-attributes@1.9.5(acorn@8.15.0): + dependencies: + acorn: 8.15.0 + + acorn-walk@8.3.4: + dependencies: + acorn: 8.15.0 + + acorn@8.11.3: {} + + acorn@8.14.1: {} + + acorn@8.15.0: {} + + adm-zip@0.4.16: {} + + agent-base@6.0.2: + dependencies: + debug: 4.3.4(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + + agent-base@7.1.3: {} + + aggregate-error@3.1.0: + dependencies: + clean-stack: 2.2.0 + indent-string: 4.0.0 + + algoliasearch@5.12.0: + dependencies: + '@algolia/client-abtesting': 5.12.0 + '@algolia/client-analytics': 5.12.0 + '@algolia/client-common': 5.12.0 + '@algolia/client-insights': 5.12.0 + '@algolia/client-personalization': 5.12.0 + '@algolia/client-query-suggestions': 5.12.0 + '@algolia/client-search': 5.12.0 + '@algolia/ingestion': 1.12.0 + '@algolia/monitoring': 1.12.0 + '@algolia/recommend': 5.12.0 + '@algolia/requester-browser-xhr': 5.12.0 + '@algolia/requester-fetch': 5.12.0 + '@algolia/requester-node-http': 5.12.0 + + alien-signals@0.2.0: {} + + ansi-align@3.0.1: + dependencies: + string-width: 4.2.3 + + ansi-colors@4.1.1: {} + + ansi-colors@4.1.3: {} + + ansi-escapes@4.3.2: + dependencies: + type-fest: 0.21.3 + + ansi-escapes@7.0.0: + dependencies: + environment: 1.1.0 + + ansi-regex@5.0.1: {} + + ansi-regex@6.1.0: {} + + ansi-styles@3.2.1: + dependencies: + color-convert: 1.9.3 + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@5.2.0: {} + + ansi-styles@6.2.1: {} + + ansis@3.17.0: {} + + any-promise@1.3.0: {} + + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + + aproba@2.0.0: {} + + archiver-utils@2.1.0: + dependencies: + glob: 7.2.3 + graceful-fs: 4.2.11 + lazystream: 1.0.1 + lodash.defaults: 4.2.0 + lodash.difference: 4.5.0 + lodash.flatten: 4.4.0 + lodash.isplainobject: 4.0.6 + lodash.union: 4.6.0 + normalize-path: 3.0.0 + readable-stream: 2.3.8 + + archiver-utils@3.0.4: + dependencies: + glob: 7.2.3 + graceful-fs: 4.2.11 + lazystream: 1.0.1 + lodash.defaults: 4.2.0 + lodash.difference: 4.5.0 + lodash.flatten: 4.4.0 + lodash.isplainobject: 4.0.6 + lodash.union: 4.6.0 + normalize-path: 3.0.0 + readable-stream: 3.6.2 + + archiver-utils@5.0.2: + dependencies: + glob: 10.4.5 + graceful-fs: 4.2.11 + is-stream: 2.0.1 + lazystream: 1.0.1 + lodash: 4.17.21 + normalize-path: 3.0.0 + readable-stream: 4.7.0 + + archiver@5.3.2: + dependencies: + archiver-utils: 2.1.0 + async: 3.2.6 + buffer-crc32: 0.2.13 + readable-stream: 3.6.2 + readdir-glob: 1.1.3 + tar-stream: 2.2.0 + zip-stream: 4.1.1 + + archiver@7.0.1: + dependencies: + archiver-utils: 5.0.2 + async: 3.2.6 + buffer-crc32: 1.0.0 + readable-stream: 4.7.0 + readdir-glob: 1.1.3 + tar-stream: 3.1.7 + zip-stream: 6.0.1 + + are-we-there-yet@2.0.0: + dependencies: + delegates: 1.0.0 + readable-stream: 3.6.2 + + argparse@1.0.10: + dependencies: + sprintf-js: 1.0.3 + + argparse@2.0.1: {} + + aria-query@5.3.0: + dependencies: + dequal: 2.0.3 + + array-union@1.0.2: + dependencies: + array-uniq: 1.0.3 + + array-union@2.1.0: {} + + array-uniq@1.0.3: {} + + assertion-error@2.0.1: {} + + ast-kit@1.4.3: + dependencies: + '@babel/parser': 7.27.2 + pathe: 2.0.3 + + ast-module-types@5.0.0: {} + + ast-walker-scope@0.6.2: + dependencies: + '@babel/parser': 7.27.2 + ast-kit: 1.4.3 + + async-mutex@0.2.6: + dependencies: + tslib: 2.8.1 + + async-sema@3.1.1: {} + + async@3.2.6: {} + + atomic-sleep@1.0.0: {} + + autoprefixer@10.4.21(postcss@8.5.3): + dependencies: + browserslist: 4.24.5 + caniuse-lite: 1.0.30001723 + fraction.js: 4.3.7 + normalize-range: 0.1.2 + picocolors: 1.1.1 + postcss: 8.5.3 + postcss-value-parser: 4.2.0 + + available-typed-arrays@1.0.7: + dependencies: + possible-typed-array-names: 1.1.0 + + b4a@1.6.7: {} + + balanced-match@1.0.2: {} + + bare-events@2.5.4: + optional: true + + base-x@3.0.9: + dependencies: + safe-buffer: 5.2.1 + + base-x@5.0.1: {} + + base64-js@1.5.1: {} + + better-path-resolve@1.0.0: + dependencies: + is-windows: 1.0.2 + + big.js@6.2.2: {} + + binary-extensions@2.2.0: {} + + bindings@1.5.0: + dependencies: + file-uri-to-path: 1.0.0 + + birpc@0.2.19: {} + + birpc@2.3.0: {} + + bl@4.1.0: + dependencies: + buffer: 5.7.1 + inherits: 2.0.4 + readable-stream: 3.6.2 + + blakejs@1.2.1: {} + + bn.js@4.12.0: {} + + bn.js@5.2.1: {} + + boolbase@1.0.0: {} + + bowser@2.11.0: {} + + boxen@5.1.2: + dependencies: + ansi-align: 3.0.1 + camelcase: 6.3.0 + chalk: 4.1.2 + cli-boxes: 2.2.1 + string-width: 4.2.3 + type-fest: 0.20.2 + widest-line: 3.1.0 + wrap-ansi: 7.0.0 + + brace-expansion@1.1.11: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@2.0.1: + dependencies: + balanced-match: 1.0.2 + + braces@3.0.2: + dependencies: + fill-range: 7.0.1 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + brorand@1.1.0: {} + + browser-stdout@1.3.1: {} + + browserify-aes@1.2.0: + dependencies: + buffer-xor: 1.0.3 + cipher-base: 1.0.4 + create-hash: 1.2.0 + evp_bytestokey: 1.0.3 + inherits: 2.0.4 + safe-buffer: 5.2.1 + + browserslist@4.23.0: + dependencies: + caniuse-lite: 1.0.30001723 + electron-to-chromium: 1.4.757 + node-releases: 2.0.14 + update-browserslist-db: 1.0.15(browserslist@4.23.0) + + browserslist@4.24.5: + dependencies: + caniuse-lite: 1.0.30001723 + electron-to-chromium: 1.5.155 + node-releases: 2.0.19 + update-browserslist-db: 1.1.3(browserslist@4.24.5) + + bs58@4.0.1: + dependencies: + base-x: 3.0.9 + + bs58@6.0.0: + dependencies: + base-x: 5.0.1 + + bs58check@2.1.2: + dependencies: + bs58: 4.0.1 + create-hash: 1.2.0 + safe-buffer: 5.2.1 + + buffer-crc32@0.2.13: {} + + buffer-crc32@1.0.0: {} + + buffer-from@1.1.2: {} + + buffer-xor@1.0.3: {} + + buffer@5.7.1: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + + buffer@6.0.3: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + + bufferutil@4.0.8: + dependencies: + node-gyp-build: 4.6.0 + + bufferutil@4.0.9: + dependencies: + node-gyp-build: 4.8.4 + + builtin-modules@3.3.0: {} + + bun-types@1.1.29: + dependencies: + '@types/node': 20.12.14 + '@types/ws': 8.5.10 + + bun@1.1.30: + optionalDependencies: + '@oven/bun-darwin-aarch64': 1.1.30 + '@oven/bun-darwin-x64': 1.1.30 + '@oven/bun-darwin-x64-baseline': 1.1.30 + '@oven/bun-linux-aarch64': 1.1.30 + '@oven/bun-linux-x64': 1.1.30 + '@oven/bun-linux-x64-baseline': 1.1.30 + '@oven/bun-windows-x64': 1.1.30 + '@oven/bun-windows-x64-baseline': 1.1.30 + + bundle-name@4.1.0: + dependencies: + run-applescript: 7.0.0 + + bundle-require@5.1.0(esbuild@0.25.5): + dependencies: + esbuild: 0.25.5 + load-tsconfig: 0.2.5 + + busboy@1.6.0: + dependencies: + streamsearch: 1.1.0 + + bytes@3.1.2: {} + + c12@3.0.4(magicast@0.3.5): + dependencies: + chokidar: 4.0.3 + confbox: 0.2.2 + defu: 6.1.4 + dotenv: 16.5.0 + exsolve: 1.0.5 + giget: 2.0.0 + jiti: 2.4.2 + ohash: 2.0.11 + pathe: 2.0.3 + perfect-debounce: 1.0.0 + pkg-types: 2.1.0 + rc9: 2.1.2 + optionalDependencies: + magicast: 0.3.5 + + cac@6.7.14: {} + + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + call-bind@1.0.8: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + get-intrinsic: 1.3.0 + set-function-length: 1.2.2 + + call-bound@1.0.4: + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 + + callsite@1.0.0: {} + + camelcase@5.3.1: {} + + camelcase@6.3.0: {} + + caniuse-api@3.0.0: + dependencies: + browserslist: 4.24.5 + caniuse-lite: 1.0.30001723 + lodash.memoize: 4.1.2 + lodash.uniq: 4.5.0 + + caniuse-lite@1.0.30001723: {} + + ccount@2.0.1: {} + + chai@5.2.0: + dependencies: + assertion-error: 2.0.1 + check-error: 2.1.1 + deep-eql: 5.0.2 + loupe: 3.1.3 + pathval: 2.0.0 + + chalk@2.4.2: + dependencies: + ansi-styles: 3.2.1 + escape-string-regexp: 1.0.5 + supports-color: 5.5.0 + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + chalk@5.3.0: {} + + change-case@5.4.4: {} + + char-regex@1.0.2: {} + + character-entities-html4@2.1.0: {} + + character-entities-legacy@3.0.0: {} + + character-entities@2.0.2: {} + + chardet@0.7.0: {} + + check-error@2.1.1: {} + + chokidar@3.5.3: + dependencies: + anymatch: 3.1.3 + braces: 3.0.2 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + + chokidar@3.6.0: + dependencies: + anymatch: 3.1.3 + braces: 3.0.2 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + + chokidar@4.0.3: + dependencies: + readdirp: 4.1.2 + + chownr@2.0.0: {} + + chownr@3.0.0: {} + + ci-info@2.0.0: {} + + ci-info@3.9.0: {} + + cipher-base@1.0.4: + dependencies: + inherits: 2.0.4 + safe-buffer: 5.2.1 + + citty@0.1.6: + dependencies: + consola: 3.4.2 + + cjs-module-lexer@1.4.1: {} + + clean-stack@2.2.0: {} + + cli-boxes@2.2.1: {} + + cli-highlight@2.1.11: + dependencies: + chalk: 4.1.2 + highlight.js: 10.7.3 + mz: 2.7.0 + parse5: 5.1.1 + parse5-htmlparser2-tree-adapter: 6.0.1 + yargs: 16.2.0 + + cli-spinners@2.9.2: {} + + cli-table3@0.6.5: + dependencies: + string-width: 4.2.3 + optionalDependencies: + '@colors/colors': 1.5.0 + + cli-width@4.1.0: {} + + client-only@0.0.1: {} + + clipboardy@4.0.0: + dependencies: + execa: 8.0.1 + is-wsl: 3.1.0 + is64bit: 2.0.0 + + cliui@6.0.0: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 6.2.0 + + cliui@7.0.4: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + + cliui@8.0.1: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + + clone@1.0.4: + optional: true + + clsx@1.2.1: {} + + cluster-key-slot@1.1.2: {} + + color-convert@1.9.3: + dependencies: + color-name: 1.1.3 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.3: {} + + color-name@1.1.4: {} + + color-string@1.9.1: + dependencies: + color-name: 1.1.4 + simple-swizzle: 0.2.2 + + color-support@1.1.3: {} + + color@3.2.1: + dependencies: + color-convert: 1.9.3 + color-string: 1.9.1 + + color@4.2.3: + dependencies: + color-convert: 2.0.1 + color-string: 1.9.1 + optional: true + + colord@2.9.3: {} + + colorette@2.0.20: {} + + colorspace@1.1.4: + dependencies: + color: 3.2.1 + text-hex: 1.0.0 + + comma-separated-tokens@2.0.3: {} + + command-exists@1.2.9: {} + + commander@10.0.1: {} + + commander@2.20.3: {} + + commander@3.0.2: {} + + commander@4.1.1: {} + + commander@7.2.0: {} + + common-path-prefix@3.0.0: {} + + commondir@1.0.1: {} + + compatx@0.1.8: {} + + compatx@0.2.0: {} + + compress-commons@4.1.2: + dependencies: + buffer-crc32: 0.2.13 + crc32-stream: 4.0.3 + normalize-path: 3.0.0 + readable-stream: 3.6.2 + + compress-commons@6.0.2: + dependencies: + crc-32: 1.2.2 + crc32-stream: 6.0.0 + is-stream: 2.0.1 + normalize-path: 3.0.0 + readable-stream: 4.7.0 + + computeds@0.0.1: {} + + concat-map@0.0.1: {} + + confbox@0.1.7: {} + + confbox@0.1.8: {} + + confbox@0.2.2: {} + + config-chain@1.1.13: + dependencies: + ini: 1.3.8 + proto-list: 1.2.4 + + consola@3.2.3: {} + + consola@3.4.2: {} + + console-control-strings@1.1.0: {} + + convert-source-map@2.0.0: {} + + cookie-es@1.2.2: {} + + cookie-es@2.0.0: {} + + cookie@0.4.2: {} + + cookie@0.5.0: {} + + cookie@1.0.2: {} + + copy-anything@3.0.5: + dependencies: + is-what: 4.1.16 + + core-util-is@1.0.3: {} + + cp-file@10.0.0: + dependencies: + graceful-fs: 4.2.11 + nested-error-stacks: 2.1.1 + p-event: 5.0.1 + + crc-32@1.2.2: {} + + crc32-stream@4.0.3: + dependencies: + crc-32: 1.2.2 + readable-stream: 3.6.2 + + crc32-stream@6.0.0: + dependencies: + crc-32: 1.2.2 + readable-stream: 4.7.0 + + create-hash@1.2.0: + dependencies: + cipher-base: 1.0.4 + inherits: 2.0.4 + md5.js: 1.3.5 + ripemd160: 2.0.2 + sha.js: 2.4.11 + + create-hmac@1.1.7: + dependencies: + cipher-base: 1.0.4 + create-hash: 1.2.0 + inherits: 2.0.4 + ripemd160: 2.0.2 + safe-buffer: 5.2.1 + sha.js: 2.4.11 + + cron-parser@4.9.0: + dependencies: + luxon: 3.6.1 + + croner@9.0.0: {} + + cross-fetch@3.1.5(encoding@0.1.13): + dependencies: + node-fetch: 2.6.7(encoding@0.1.13) + transitivePeerDependencies: + - encoding + + cross-fetch@3.2.0(encoding@0.1.13): + dependencies: + node-fetch: 2.7.0(encoding@0.1.13) + transitivePeerDependencies: + - encoding + + cross-fetch@4.1.0(encoding@0.1.13): + dependencies: + node-fetch: 2.7.0(encoding@0.1.13) + transitivePeerDependencies: + - encoding + + cross-spawn@5.1.0: + dependencies: + lru-cache: 4.1.5 + shebang-command: 1.2.0 + which: 1.3.1 + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + crossws@0.2.4: {} + + crossws@0.3.5: + dependencies: + uncrypto: 0.1.3 + + crypto-random-string@1.0.0: {} + + css-declaration-sorter@7.2.0(postcss@8.5.3): + dependencies: + postcss: 8.5.3 + + css-select@5.1.0: + dependencies: + boolbase: 1.0.0 + css-what: 6.1.0 + domhandler: 5.0.3 + domutils: 3.2.2 + nth-check: 2.1.1 + + css-tree@2.2.1: + dependencies: + mdn-data: 2.0.28 + source-map-js: 1.2.1 + + css-tree@2.3.1: + dependencies: + mdn-data: 2.0.30 + source-map-js: 1.2.1 + + css-what@6.1.0: {} + + cssesc@3.0.0: {} + + cssnano-preset-default@7.0.7(postcss@8.5.3): + dependencies: + browserslist: 4.24.5 + css-declaration-sorter: 7.2.0(postcss@8.5.3) + cssnano-utils: 5.0.1(postcss@8.5.3) + postcss: 8.5.3 + postcss-calc: 10.1.1(postcss@8.5.3) + postcss-colormin: 7.0.3(postcss@8.5.3) + postcss-convert-values: 7.0.5(postcss@8.5.3) + postcss-discard-comments: 7.0.4(postcss@8.5.3) + postcss-discard-duplicates: 7.0.2(postcss@8.5.3) + postcss-discard-empty: 7.0.1(postcss@8.5.3) + postcss-discard-overridden: 7.0.1(postcss@8.5.3) + postcss-merge-longhand: 7.0.5(postcss@8.5.3) + postcss-merge-rules: 7.0.5(postcss@8.5.3) + postcss-minify-font-values: 7.0.1(postcss@8.5.3) + postcss-minify-gradients: 7.0.1(postcss@8.5.3) + postcss-minify-params: 7.0.3(postcss@8.5.3) + postcss-minify-selectors: 7.0.5(postcss@8.5.3) + postcss-normalize-charset: 7.0.1(postcss@8.5.3) + postcss-normalize-display-values: 7.0.1(postcss@8.5.3) + postcss-normalize-positions: 7.0.1(postcss@8.5.3) + postcss-normalize-repeat-style: 7.0.1(postcss@8.5.3) + postcss-normalize-string: 7.0.1(postcss@8.5.3) + postcss-normalize-timing-functions: 7.0.1(postcss@8.5.3) + postcss-normalize-unicode: 7.0.3(postcss@8.5.3) + postcss-normalize-url: 7.0.1(postcss@8.5.3) + postcss-normalize-whitespace: 7.0.1(postcss@8.5.3) + postcss-ordered-values: 7.0.2(postcss@8.5.3) + postcss-reduce-initial: 7.0.3(postcss@8.5.3) + postcss-reduce-transforms: 7.0.1(postcss@8.5.3) + postcss-svgo: 7.0.2(postcss@8.5.3) + postcss-unique-selectors: 7.0.4(postcss@8.5.3) + + cssnano-utils@5.0.1(postcss@8.5.3): + dependencies: + postcss: 8.5.3 + + cssnano@7.0.7(postcss@8.5.3): + dependencies: + cssnano-preset-default: 7.0.7(postcss@8.5.3) + lilconfig: 3.1.3 + postcss: 8.5.3 + + csso@5.0.5: + dependencies: + css-tree: 2.2.1 + + csstype@3.1.3: {} + + data-uri-to-buffer@4.0.1: {} + + dataloader@1.4.0: {} + + date-fns@2.30.0: + dependencies: + '@babel/runtime': 7.27.6 + + dateformat@4.6.3: {} + + dayjs@1.11.13: {} + + db0@0.3.2: {} + + de-indent@1.0.2: {} + + debounce@1.2.1: {} + + debug@4.3.4(supports-color@8.1.1): + dependencies: + ms: 2.1.2 + optionalDependencies: + supports-color: 8.1.1 + + debug@4.3.7: + dependencies: + ms: 2.1.3 + + debug@4.4.1: + dependencies: + ms: 2.1.3 + + decache@4.6.2: + dependencies: + callsite: 1.0.0 + + decamelize@1.2.0: {} + + decamelize@4.0.0: {} + + decode-named-character-reference@1.0.2: + dependencies: + character-entities: 2.0.2 + + decode-uri-component@0.2.2: {} + + dedent@1.6.0: {} + + deep-eql@5.0.2: {} + + deepmerge@4.3.1: {} + + default-browser-id@5.0.0: {} + + default-browser@5.2.1: + dependencies: + bundle-name: 4.1.0 + default-browser-id: 5.0.0 + + defaults@1.0.4: + dependencies: + clone: 1.0.4 + optional: true + + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.1 + es-errors: 1.3.0 + gopd: 1.2.0 + + define-lazy-prop@2.0.0: {} + + define-lazy-prop@3.0.0: {} + + defu@6.1.4: {} + + delegates@1.0.0: {} + + denque@2.1.0: {} + + depd@2.0.0: {} + + dequal@2.0.3: {} + + derive-valtio@0.1.0(valtio@1.13.2(@types/react@18.3.1)(react@18.3.1)): + dependencies: + valtio: 1.13.2(@types/react@18.3.1)(react@18.3.1) + + destr@2.0.5: {} + + detect-browser@5.3.0: {} + + detect-indent@6.1.0: {} + + detect-libc@1.0.3: {} + + detect-libc@2.0.4: {} + + detective-amd@5.0.2: + dependencies: + ast-module-types: 5.0.0 + escodegen: 2.1.0 + get-amd-module-type: 5.0.1 + node-source-walk: 6.0.2 + + detective-cjs@5.0.1: + dependencies: + ast-module-types: 5.0.0 + node-source-walk: 6.0.2 + + detective-es6@4.0.1: + dependencies: + node-source-walk: 6.0.2 + + detective-postcss@6.1.3: + dependencies: + is-url: 1.2.4 + postcss: 8.5.5 + postcss-values-parser: 6.0.2(postcss@8.5.5) + + detective-sass@5.0.3: + dependencies: + gonzales-pe: 4.3.0 + node-source-walk: 6.0.2 + + detective-scss@4.0.3: + dependencies: + gonzales-pe: 4.3.0 + node-source-walk: 6.0.2 + + detective-stylus@4.0.0: {} + + detective-typescript@11.2.0: + dependencies: + '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.8.3) + ast-module-types: 5.0.0 + node-source-walk: 6.0.2 + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + + devalue@5.1.1: {} + + devlop@1.1.0: + dependencies: + dequal: 2.0.3 + + diff@5.0.0: {} + + diff@7.0.0: {} + + dijkstrajs@1.0.2: {} + + dir-glob@2.2.2: + dependencies: + path-type: 3.0.0 + + dir-glob@3.0.1: + dependencies: + path-type: 4.0.0 + + dom-accessibility-api@0.5.16: {} + + dom-serializer@2.0.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + entities: 4.5.0 + + domelementtype@2.3.0: {} + + domhandler@5.0.3: + dependencies: + domelementtype: 2.3.0 + + domutils@3.2.2: + dependencies: + dom-serializer: 2.0.0 + domelementtype: 2.3.0 + domhandler: 5.0.3 + + dot-prop@9.0.0: + dependencies: + type-fest: 4.41.0 + + dotenv-expand@10.0.0: {} + + dotenv@16.3.1: {} + + dotenv@16.5.0: {} + + dotenv@8.6.0: {} + + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + + duplexer@0.1.2: {} + + duplexify@4.1.2: + dependencies: + end-of-stream: 1.4.4 + inherits: 2.0.4 + readable-stream: 3.6.2 + stream-shift: 1.0.1 + + eastasianwidth@0.2.0: {} + + easy-table@1.2.0: + dependencies: + ansi-regex: 5.0.1 + optionalDependencies: + wcwidth: 1.0.1 + + eciesjs@0.4.15: + dependencies: + '@ecies/ciphers': 0.2.3(@noble/ciphers@1.3.0) + '@noble/ciphers': 1.3.0 + '@noble/curves': 1.9.2 + '@noble/hashes': 1.8.0 + + editorconfig@1.0.4: + dependencies: + '@one-ini/wasm': 0.1.1 + commander: 10.0.1 + minimatch: 9.0.1 + semver: 7.7.2 + + ee-first@1.1.1: {} + + electron-to-chromium@1.4.757: {} + + electron-to-chromium@1.5.155: {} + + elliptic@6.5.4: + dependencies: + bn.js: 4.12.0 + brorand: 1.1.0 + hash.js: 1.1.7 + hmac-drbg: 1.0.1 + inherits: 2.0.4 + minimalistic-assert: 1.0.1 + minimalistic-crypto-utils: 1.0.1 + + elliptic@6.6.0: + dependencies: + bn.js: 4.12.0 + brorand: 1.1.0 + hash.js: 1.1.7 + hmac-drbg: 1.0.1 + inherits: 2.0.4 + minimalistic-assert: 1.0.1 + minimalistic-crypto-utils: 1.0.1 + + elliptic@6.6.1: + dependencies: + bn.js: 4.12.0 + brorand: 1.1.0 + hash.js: 1.1.7 + hmac-drbg: 1.0.1 + inherits: 2.0.4 + minimalistic-assert: 1.0.1 + minimalistic-crypto-utils: 1.0.1 + + emoji-regex@8.0.0: {} + + emoji-regex@9.2.2: {} + + emojilib@2.4.0: {} + + enabled@2.0.0: {} + + encode-utf8@1.0.3: {} + + encodeurl@2.0.0: {} + + encoding@0.1.13: + dependencies: + iconv-lite: 0.6.3 + + end-of-stream@1.4.4: + dependencies: + once: 1.4.0 + + engine.io-client@6.6.3(bufferutil@4.0.9)(utf-8-validate@5.0.10): + dependencies: + '@socket.io/component-emitter': 3.1.2 + debug: 4.3.7 + engine.io-parser: 5.2.3 + ws: 8.17.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) + xmlhttprequest-ssl: 2.1.2 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + engine.io-parser@5.2.3: {} + + enhanced-resolve@5.17.1: + dependencies: + graceful-fs: 4.2.11 + tapable: 2.2.1 + + enhanced-resolve@5.18.1: + dependencies: + graceful-fs: 4.2.11 + tapable: 2.2.2 + + enquirer@2.3.6: + dependencies: + ansi-colors: 4.1.3 + + entities@4.5.0: {} + + env-paths@2.2.1: {} + + env-paths@3.0.0: {} + + environment@1.1.0: {} + + error-stack-parser-es@1.0.5: {} + + errx@0.1.0: {} + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-module-lexer@1.7.0: {} + + es-object-atoms@1.1.1: + dependencies: + es-errors: 1.3.0 + + es-toolkit@1.33.0: {} + + esbuild@0.21.5: + optionalDependencies: + '@esbuild/aix-ppc64': 0.21.5 + '@esbuild/android-arm': 0.21.5 + '@esbuild/android-arm64': 0.21.5 + '@esbuild/android-x64': 0.21.5 + '@esbuild/darwin-arm64': 0.21.5 + '@esbuild/darwin-x64': 0.21.5 + '@esbuild/freebsd-arm64': 0.21.5 + '@esbuild/freebsd-x64': 0.21.5 + '@esbuild/linux-arm': 0.21.5 + '@esbuild/linux-arm64': 0.21.5 + '@esbuild/linux-ia32': 0.21.5 + '@esbuild/linux-loong64': 0.21.5 + '@esbuild/linux-mips64el': 0.21.5 + '@esbuild/linux-ppc64': 0.21.5 + '@esbuild/linux-riscv64': 0.21.5 + '@esbuild/linux-s390x': 0.21.5 + '@esbuild/linux-x64': 0.21.5 + '@esbuild/netbsd-x64': 0.21.5 + '@esbuild/openbsd-x64': 0.21.5 + '@esbuild/sunos-x64': 0.21.5 + '@esbuild/win32-arm64': 0.21.5 + '@esbuild/win32-ia32': 0.21.5 + '@esbuild/win32-x64': 0.21.5 + + esbuild@0.25.4: + optionalDependencies: + '@esbuild/aix-ppc64': 0.25.4 + '@esbuild/android-arm': 0.25.4 + '@esbuild/android-arm64': 0.25.4 + '@esbuild/android-x64': 0.25.4 + '@esbuild/darwin-arm64': 0.25.4 + '@esbuild/darwin-x64': 0.25.4 + '@esbuild/freebsd-arm64': 0.25.4 + '@esbuild/freebsd-x64': 0.25.4 + '@esbuild/linux-arm': 0.25.4 + '@esbuild/linux-arm64': 0.25.4 + '@esbuild/linux-ia32': 0.25.4 + '@esbuild/linux-loong64': 0.25.4 + '@esbuild/linux-mips64el': 0.25.4 + '@esbuild/linux-ppc64': 0.25.4 + '@esbuild/linux-riscv64': 0.25.4 + '@esbuild/linux-s390x': 0.25.4 + '@esbuild/linux-x64': 0.25.4 + '@esbuild/netbsd-arm64': 0.25.4 + '@esbuild/netbsd-x64': 0.25.4 + '@esbuild/openbsd-arm64': 0.25.4 + '@esbuild/openbsd-x64': 0.25.4 + '@esbuild/sunos-x64': 0.25.4 + '@esbuild/win32-arm64': 0.25.4 + '@esbuild/win32-ia32': 0.25.4 + '@esbuild/win32-x64': 0.25.4 + + esbuild@0.25.5: + optionalDependencies: + '@esbuild/aix-ppc64': 0.25.5 + '@esbuild/android-arm': 0.25.5 + '@esbuild/android-arm64': 0.25.5 + '@esbuild/android-x64': 0.25.5 + '@esbuild/darwin-arm64': 0.25.5 + '@esbuild/darwin-x64': 0.25.5 + '@esbuild/freebsd-arm64': 0.25.5 + '@esbuild/freebsd-x64': 0.25.5 + '@esbuild/linux-arm': 0.25.5 + '@esbuild/linux-arm64': 0.25.5 + '@esbuild/linux-ia32': 0.25.5 + '@esbuild/linux-loong64': 0.25.5 + '@esbuild/linux-mips64el': 0.25.5 + '@esbuild/linux-ppc64': 0.25.5 + '@esbuild/linux-riscv64': 0.25.5 + '@esbuild/linux-s390x': 0.25.5 + '@esbuild/linux-x64': 0.25.5 + '@esbuild/netbsd-arm64': 0.25.5 + '@esbuild/netbsd-x64': 0.25.5 + '@esbuild/openbsd-arm64': 0.25.5 + '@esbuild/openbsd-x64': 0.25.5 + '@esbuild/sunos-x64': 0.25.5 + '@esbuild/win32-arm64': 0.25.5 + '@esbuild/win32-ia32': 0.25.5 + '@esbuild/win32-x64': 0.25.5 + + escalade@3.2.0: {} + + escape-html@1.0.3: {} + + escape-string-regexp@1.0.5: {} + + escape-string-regexp@4.0.0: {} + + escape-string-regexp@5.0.0: {} + + escodegen@2.1.0: + dependencies: + esprima: 4.0.1 + estraverse: 5.3.0 + esutils: 2.0.3 + optionalDependencies: + source-map: 0.6.1 + + eslint-visitor-keys@3.4.3: {} + + esprima@4.0.1: {} + + estraverse@5.3.0: {} + + estree-walker@2.0.2: {} + + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.7 + + esutils@2.0.3: {} + + etag@1.8.1: {} + + eth-block-tracker@7.1.0: + dependencies: + '@metamask/eth-json-rpc-provider': 1.0.1 + '@metamask/safe-event-emitter': 3.0.0 + '@metamask/utils': 5.0.2 + json-rpc-random-id: 1.0.1 + pify: 3.0.0 + transitivePeerDependencies: + - supports-color + + eth-json-rpc-filters@6.0.1: + dependencies: + '@metamask/safe-event-emitter': 3.0.0 + async-mutex: 0.2.6 + eth-query: 2.1.2 + json-rpc-engine: 6.1.0 + pify: 5.0.0 + + eth-query@2.1.2: + dependencies: + json-rpc-random-id: 1.0.1 + xtend: 4.0.2 + + eth-rpc-errors@4.0.3: + dependencies: + fast-safe-stringify: 2.1.1 + + ethereum-cryptography@0.1.3: + dependencies: + '@types/pbkdf2': 3.1.2 + '@types/secp256k1': 4.0.3 + blakejs: 1.2.1 + browserify-aes: 1.2.0 + bs58check: 2.1.2 + create-hash: 1.2.0 + create-hmac: 1.1.7 + hash.js: 1.1.7 + keccak: 3.0.3 + pbkdf2: 3.1.2 + randombytes: 2.1.0 + safe-buffer: 5.2.1 + scrypt-js: 3.0.1 + secp256k1: 4.0.3 + setimmediate: 1.0.5 + + ethereum-cryptography@1.2.0: + dependencies: + '@noble/hashes': 1.2.0 + '@noble/secp256k1': 1.7.1 + '@scure/bip32': 1.1.5 + '@scure/bip39': 1.1.1 + + ethereum-cryptography@2.2.1: + dependencies: + '@noble/curves': 1.4.2 + '@noble/hashes': 1.4.0 + '@scure/bip32': 1.4.0 + '@scure/bip39': 1.3.0 + + ethereumjs-abi@0.6.8: + dependencies: + bn.js: 4.12.0 + ethereumjs-util: 6.2.1 + + ethereumjs-util@6.2.1: + dependencies: + '@types/bn.js': 4.11.6 + bn.js: 4.12.0 + create-hash: 1.2.0 + elliptic: 6.6.0 + ethereum-cryptography: 0.1.3 + ethjs-util: 0.1.6 + rlp: 2.2.7 + + ethjs-util@0.1.6: + dependencies: + is-hex-prefixed: 1.0.0 + strip-hex-prefix: 1.0.0 + + event-target-shim@5.0.1: {} + + eventemitter2@6.4.9: {} + + eventemitter3@4.0.7: {} + + eventemitter3@5.0.1: {} + + events@3.3.0: {} + + evp_bytestokey@1.0.3: + dependencies: + md5.js: 1.3.5 + safe-buffer: 5.2.1 + + execa@5.1.1: + dependencies: + cross-spawn: 7.0.6 + get-stream: 6.0.1 + human-signals: 2.1.0 + is-stream: 2.0.1 + merge-stream: 2.0.0 + npm-run-path: 4.0.1 + onetime: 5.1.2 + signal-exit: 3.0.7 + strip-final-newline: 2.0.0 + + execa@7.2.0: + dependencies: + cross-spawn: 7.0.6 + get-stream: 6.0.1 + human-signals: 4.3.1 + is-stream: 3.0.0 + merge-stream: 2.0.0 + npm-run-path: 5.3.0 + onetime: 6.0.0 + signal-exit: 3.0.7 + strip-final-newline: 3.0.0 + + execa@8.0.1: + dependencies: + cross-spawn: 7.0.6 + get-stream: 8.0.1 + human-signals: 5.0.0 + is-stream: 3.0.0 + merge-stream: 2.0.0 + npm-run-path: 5.3.0 + onetime: 6.0.0 + signal-exit: 4.1.0 + strip-final-newline: 3.0.0 + + execa@9.1.0: + dependencies: + '@sindresorhus/merge-streams': 4.0.0 + cross-spawn: 7.0.6 + figures: 6.1.0 + get-stream: 9.0.1 + human-signals: 7.0.0 + is-plain-obj: 4.1.0 + is-stream: 4.0.1 + npm-run-path: 5.3.0 + pretty-ms: 9.0.0 + signal-exit: 4.1.0 + strip-final-newline: 4.0.0 + yoctocolors: 2.0.2 + + expect-type@1.2.1: {} + + exsolve@1.0.5: {} + + extendable-error@0.1.7: {} + + extension-port-stream@3.0.0: + dependencies: + readable-stream: 3.6.2 + webextension-polyfill: 0.10.0 + + external-editor@3.1.0: + dependencies: + chardet: 0.7.0 + iconv-lite: 0.4.24 + tmp: 0.0.33 + + externality@1.0.2: + dependencies: + enhanced-resolve: 5.18.1 + mlly: 1.7.4 + pathe: 1.1.2 + ufo: 1.6.1 + + extract-zip@2.0.1: + dependencies: + debug: 4.4.1 + get-stream: 5.2.0 + yauzl: 2.10.0 + optionalDependencies: + '@types/yauzl': 2.10.3 + transitivePeerDependencies: + - supports-color + + fast-copy@3.0.2: {} + + fast-deep-equal@3.1.3: {} + + fast-fifo@1.3.2: {} + + fast-glob@3.3.2: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.5 + + fast-glob@3.3.3: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fast-npm-meta@0.4.3: {} + + fast-redact@3.1.2: {} + + fast-safe-stringify@2.1.1: {} + + fastq@1.15.0: + dependencies: + reusify: 1.0.4 + + fd-slicer@1.1.0: + dependencies: + pend: 1.2.0 + + fdir@6.1.1(picomatch@4.0.2): + optionalDependencies: + picomatch: 4.0.2 + + fdir@6.4.4(picomatch@4.0.2): + optionalDependencies: + picomatch: 4.0.2 + + fecha@4.2.3: {} + + fetch-blob@3.2.0: + dependencies: + node-domexception: 1.0.0 + web-streams-polyfill: 3.3.3 + + fflate@0.8.2: {} + + figures@6.1.0: + dependencies: + is-unicode-supported: 2.0.0 + + file-uri-to-path@1.0.0: {} + + fill-range@7.0.1: + dependencies: + to-regex-range: 5.0.1 + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + filter-obj@1.1.0: {} + + filter-obj@5.1.0: {} + + find-up-simple@1.0.1: {} + + find-up@2.1.0: + dependencies: + locate-path: 2.0.0 + + find-up@4.1.0: + dependencies: + locate-path: 5.0.0 + path-exists: 4.0.0 + + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + find-up@6.3.0: + dependencies: + locate-path: 7.2.0 + path-exists: 5.0.0 + + find-up@7.0.0: + dependencies: + locate-path: 7.2.0 + path-exists: 5.0.0 + unicorn-magic: 0.1.0 + + fixturez@1.1.0: + dependencies: + fs-extra: 5.0.0 + globby: 7.1.1 + signal-exit: 3.0.7 + tempy: 0.2.1 + + flat@5.0.2: {} + + floating-vue@5.2.2(@nuxt/kit@3.17.4(magicast@0.3.5))(vue@3.5.12(typescript@5.8.3)): + dependencies: + '@floating-ui/dom': 1.1.1 + vue: 3.5.12(typescript@5.8.3) + vue-resize: 2.0.0-alpha.1(vue@3.5.12(typescript@5.8.3)) + optionalDependencies: + '@nuxt/kit': 3.17.4(magicast@0.3.5) + + fn.name@1.1.0: {} + + focus-trap@7.6.0: + dependencies: + tabbable: 6.2.0 + + follow-redirects@1.15.2(debug@4.3.4): + optionalDependencies: + debug: 4.3.4(supports-color@8.1.1) + + for-each@0.3.5: + dependencies: + is-callable: 1.2.7 + + foreground-child@3.1.1: + dependencies: + cross-spawn: 7.0.6 + signal-exit: 4.1.0 + + formdata-polyfill@4.0.10: + dependencies: + fetch-blob: 3.2.0 + + fp-ts@1.19.3: {} + + fraction.js@4.3.7: {} + + fresh@2.0.0: {} + + fs-constants@1.0.0: {} + + fs-extra@0.30.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 2.4.0 + klaw: 1.3.1 + path-is-absolute: 1.0.1 + rimraf: 2.7.1 + + fs-extra@5.0.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 4.0.0 + universalify: 0.1.2 + + fs-extra@7.0.1: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 4.0.0 + universalify: 0.1.2 + + fs-extra@8.1.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 4.0.0 + universalify: 0.1.2 + + fs-minipass@2.1.0: + dependencies: + minipass: 3.3.6 + + fs.realpath@1.0.0: {} + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + fuse.js@7.1.0: {} + + gauge@3.0.2: + dependencies: + aproba: 2.0.0 + color-support: 1.1.3 + console-control-strings: 1.1.0 + has-unicode: 2.0.1 + object-assign: 4.1.1 + signal-exit: 3.0.7 + string-width: 4.2.3 + strip-ansi: 6.0.1 + wide-align: 1.1.5 + + gensync@1.0.0-beta.2: {} + + get-amd-module-type@5.0.1: + dependencies: + ast-module-types: 5.0.0 + node-source-walk: 6.0.2 + + get-caller-file@2.0.5: {} + + get-intrinsic@1.3.0: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + math-intrinsics: 1.1.0 + + get-port-please@3.1.2: {} + + get-port@7.1.0: {} + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.1 + + get-stream@5.2.0: + dependencies: + pump: 3.0.2 + + get-stream@6.0.1: {} + + get-stream@8.0.1: {} + + get-stream@9.0.1: + dependencies: + '@sec-ant/readable-stream': 0.4.1 + is-stream: 4.0.1 + + giget@2.0.0: + dependencies: + citty: 0.1.6 + consola: 3.4.2 + defu: 6.1.4 + node-fetch-native: 1.6.6 + nypm: 0.6.0 + pathe: 2.0.3 + + git-up@8.1.1: + dependencies: + is-ssh: 1.4.1 + parse-url: 9.2.0 + + git-url-parse@16.1.0: + dependencies: + git-up: 8.1.1 + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob@10.4.5: + dependencies: + foreground-child: 3.1.1 + jackspeak: 3.4.3 + minimatch: 9.0.4 + minipass: 7.1.2 + package-json-from-dist: 1.0.1 + path-scurry: 1.11.1 + + glob@7.2.0: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + + glob@7.2.3: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + + glob@8.1.0: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 5.1.6 + once: 1.4.0 + + global-directory@4.0.1: + dependencies: + ini: 4.1.1 + + globals@11.12.0: {} + + globby@11.1.0: + dependencies: + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.3.3 + ignore: 5.3.2 + merge2: 1.4.1 + slash: 3.0.0 + + globby@14.1.0: + dependencies: + '@sindresorhus/merge-streams': 2.3.0 + fast-glob: 3.3.3 + ignore: 7.0.4 + path-type: 6.0.0 + slash: 5.1.0 + unicorn-magic: 0.3.0 + + globby@7.1.1: + dependencies: + array-union: 1.0.2 + dir-glob: 2.2.2 + glob: 7.2.3 + ignore: 3.3.10 + pify: 3.0.0 + slash: 1.0.0 + + gonzales-pe@4.3.0: + dependencies: + minimist: 1.2.8 + + gopd@1.2.0: {} + + graceful-fs@4.2.11: {} + + graphql@16.8.1: {} + + gzip-size@6.0.0: + dependencies: + duplexer: 0.1.2 + + gzip-size@7.0.0: + dependencies: + duplexer: 0.1.2 + + h3@1.15.3: + dependencies: + cookie-es: 1.2.2 + crossws: 0.3.5 + defu: 6.1.4 + destr: 2.0.5 + iron-webcrypto: 1.2.1 + node-mock-http: 1.0.0 + radix3: 1.1.2 + ufo: 1.6.1 + uncrypto: 0.1.3 + + happy-dom@15.10.2: + dependencies: + entities: 4.5.0 + webidl-conversions: 7.0.0 + whatwg-mimetype: 3.0.0 + + hardhat@2.22.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10): + dependencies: + '@ethersproject/abi': 5.7.0 + '@metamask/eth-sig-util': 4.0.1 + '@nomicfoundation/edr': 0.3.7 + '@nomicfoundation/ethereumjs-common': 4.0.4 + '@nomicfoundation/ethereumjs-tx': 5.0.4 + '@nomicfoundation/ethereumjs-util': 9.0.4 + '@nomicfoundation/solidity-analyzer': 0.1.1 + '@sentry/node': 5.30.0 + '@types/bn.js': 5.1.5 + '@types/lru-cache': 5.1.1 + adm-zip: 0.4.16 + aggregate-error: 3.1.0 + ansi-escapes: 4.3.2 + boxen: 5.1.2 + chalk: 2.4.2 + chokidar: 3.6.0 + ci-info: 2.0.0 + debug: 4.3.4(supports-color@8.1.1) + enquirer: 2.3.6 + env-paths: 2.2.1 + ethereum-cryptography: 1.2.0 + ethereumjs-abi: 0.6.8 + find-up: 2.1.0 + fp-ts: 1.19.3 + fs-extra: 7.0.1 + glob: 7.2.0 + immutable: 4.3.5 + io-ts: 1.10.4 + keccak: 3.0.3 + lodash: 4.17.21 + mnemonist: 0.38.5 + mocha: 10.2.0 + p-map: 4.0.0 + raw-body: 2.5.1 + resolve: 1.17.0 + semver: 6.3.1 + solc: 0.7.3(debug@4.3.4) + source-map-support: 0.5.21 + stacktrace-parser: 0.1.10 + tsort: 0.0.1 + undici: 5.28.3 + uuid: 8.3.2 + ws: 7.5.9(bufferutil@4.0.9)(utf-8-validate@5.0.10) + optionalDependencies: + typescript: 5.8.3 + transitivePeerDependencies: + - bufferutil + - c-kzg + - supports-color + - utf-8-validate + + has-flag@3.0.0: {} + + has-flag@4.0.0: {} + + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.1 + + has-symbols@1.1.0: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.1.0 + + has-unicode@2.0.1: {} + + hash-base@3.1.0: + dependencies: + inherits: 2.0.4 + readable-stream: 3.6.2 + safe-buffer: 5.2.1 + + hash.js@1.1.7: + dependencies: + inherits: 2.0.4 + minimalistic-assert: 1.0.1 + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + hast-util-to-html@9.0.3: + dependencies: + '@types/hast': 3.0.4 + '@types/unist': 3.0.2 + ccount: 2.0.1 + comma-separated-tokens: 2.0.3 + hast-util-whitespace: 3.0.0 + html-void-elements: 3.0.0 + mdast-util-to-hast: 13.1.0 + property-information: 6.5.0 + space-separated-tokens: 2.0.2 + stringify-entities: 4.0.4 + zwitch: 2.0.4 + + hast-util-whitespace@3.0.0: + dependencies: + '@types/hast': 3.0.4 + + he@1.2.0: {} + + headers-polyfill@4.0.2: {} + + help-me@5.0.0: {} + + highlight.js@10.7.3: {} + + hmac-drbg@1.0.1: + dependencies: + hash.js: 1.1.7 + minimalistic-assert: 1.0.1 + minimalistic-crypto-utils: 1.0.1 + + hookable@5.5.3: {} + + hosted-git-info@7.0.2: + dependencies: + lru-cache: 10.4.3 + + html-escaper@2.0.2: {} + + html-void-elements@3.0.0: {} + + http-errors@2.0.0: + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.1 + toidentifier: 1.0.1 + + http-proxy@1.18.1: + dependencies: + eventemitter3: 4.0.7 + follow-redirects: 1.15.2(debug@4.3.4) + requires-port: 1.0.0 + transitivePeerDependencies: + - debug + + http-shutdown@1.2.2: {} + + https-proxy-agent@5.0.1: + dependencies: + agent-base: 6.0.2 + debug: 4.3.4(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + + https-proxy-agent@7.0.6: + dependencies: + agent-base: 7.1.3 + debug: 4.4.1 + transitivePeerDependencies: + - supports-color + + httpxy@0.1.7: {} + + human-id@1.0.2: {} + + human-signals@2.1.0: {} + + human-signals@4.3.1: {} + + human-signals@5.0.0: {} + + human-signals@7.0.0: {} + + iconv-lite@0.4.24: + dependencies: + safer-buffer: 2.1.2 + + iconv-lite@0.6.3: + dependencies: + safer-buffer: 2.1.2 + + idb-keyval@6.2.1: {} + + ieee754@1.2.1: {} + + ignore@3.3.10: {} + + ignore@5.3.2: {} + + ignore@7.0.4: {} + + image-meta@0.2.1: {} + + immutable@4.3.5: {} + + impound@0.2.2(rollup@4.41.0): + dependencies: + '@rollup/pluginutils': 5.1.4(rollup@4.41.0) + mlly: 1.7.4 + mocked-exports: 0.1.1 + pathe: 2.0.3 + unplugin: 2.3.4 + transitivePeerDependencies: + - rollup + + imurmurhash@0.1.4: {} + + indent-string@4.0.0: {} + + index-to-position@1.1.0: {} + + inflight@1.0.6: + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + + inherits@2.0.4: {} + + ini@1.3.8: {} + + ini@4.1.1: {} + + io-ts@1.10.4: + dependencies: + fp-ts: 1.19.3 + + ioredis@5.6.1: + dependencies: + '@ioredis/commands': 1.2.0 + cluster-key-slot: 1.1.2 + debug: 4.4.1 + denque: 2.1.0 + lodash.defaults: 4.2.0 + lodash.isarguments: 3.1.0 + redis-errors: 1.2.0 + redis-parser: 3.0.0 + standard-as-callback: 2.1.0 + transitivePeerDependencies: + - supports-color + + iron-webcrypto@1.2.1: {} + + is-arguments@1.2.0: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-arrayish@0.3.2: {} + + is-binary-path@2.1.0: + dependencies: + binary-extensions: 2.2.0 + + is-builtin-module@3.2.1: + dependencies: + builtin-modules: 3.3.0 + + is-callable@1.2.7: {} + + is-core-module@2.16.1: + dependencies: + hasown: 2.0.2 + + is-docker@2.2.1: {} + + is-docker@3.0.0: {} + + is-extglob@2.1.1: {} + + is-fullwidth-code-point@3.0.0: {} + + is-generator-function@1.1.0: + dependencies: + call-bound: 1.0.4 + get-proto: 1.0.1 + has-tostringtag: 1.0.2 + safe-regex-test: 1.1.0 + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-hex-prefixed@1.0.0: {} + + is-inside-container@1.0.0: + dependencies: + is-docker: 3.0.0 + + is-installed-globally@1.0.0: + dependencies: + global-directory: 4.0.1 + is-path-inside: 4.0.0 + + is-module@1.0.0: {} + + is-node-process@1.2.0: {} + + is-number@7.0.0: {} + + is-path-inside@4.0.0: {} + + is-plain-obj@2.1.0: {} + + is-plain-obj@4.1.0: {} + + is-plain-object@5.0.0: {} + + is-reference@1.2.1: + dependencies: + '@types/estree': 1.0.7 + + is-regex@1.2.1: + dependencies: + call-bound: 1.0.4 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + is-ssh@1.4.1: + dependencies: + protocols: 2.0.2 + + is-stream@2.0.1: {} + + is-stream@3.0.0: {} + + is-stream@4.0.1: {} + + is-subdir@1.2.0: + dependencies: + better-path-resolve: 1.0.0 + + is-typed-array@1.1.15: + dependencies: + which-typed-array: 1.1.19 + + is-unicode-supported@0.1.0: {} + + is-unicode-supported@2.0.0: {} + + is-url-superb@4.0.0: {} + + is-url@1.2.4: {} + + is-what@4.1.16: {} + + is-windows@1.0.2: {} + + is-wsl@2.2.0: + dependencies: + is-docker: 2.2.1 + + is-wsl@3.1.0: + dependencies: + is-inside-container: 1.0.0 + + is64bit@2.0.0: + dependencies: + system-architecture: 0.1.0 + + isarray@1.0.0: {} + + isexe@2.0.0: {} + + isexe@3.1.1: {} + + isows@1.0.4(ws@8.13.0(bufferutil@4.0.8)(utf-8-validate@6.0.5)): + dependencies: + ws: 8.13.0(bufferutil@4.0.8)(utf-8-validate@6.0.5) + + isows@1.0.4(ws@8.13.0(bufferutil@4.0.9)(utf-8-validate@6.0.5)): + dependencies: + ws: 8.13.0(bufferutil@4.0.9)(utf-8-validate@6.0.5) + + isows@1.0.4(ws@8.17.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)): + dependencies: + ws: 8.17.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) + + isows@1.0.6(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)): + dependencies: + ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + + isows@1.0.6(ws@8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)): + dependencies: + ws: 8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) + + isows@1.0.6(ws@8.18.1(bufferutil@4.0.9)(utf-8-validate@6.0.5)): + dependencies: + ws: 8.18.1(bufferutil@4.0.9)(utf-8-validate@6.0.5) + + istanbul-lib-coverage@3.2.2: {} + + istanbul-lib-report@3.0.1: + dependencies: + istanbul-lib-coverage: 3.2.2 + make-dir: 4.0.0 + supports-color: 7.2.0 + + istanbul-lib-source-maps@5.0.6: + dependencies: + '@jridgewell/trace-mapping': 0.3.25 + debug: 4.3.7 + istanbul-lib-coverage: 3.2.2 + transitivePeerDependencies: + - supports-color + + istanbul-reports@3.1.7: + dependencies: + html-escaper: 2.0.2 + istanbul-lib-report: 3.0.1 + + jackspeak@3.4.3: + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + + jiti@1.21.0: {} + + jiti@1.21.6: {} + + jiti@1.21.7: {} + + jiti@2.4.2: {} + + joycon@3.1.1: {} + + js-beautify@1.15.1: + dependencies: + config-chain: 1.1.13 + editorconfig: 1.0.4 + glob: 10.4.5 + js-cookie: 3.0.5 + nopt: 7.2.1 + + js-cookie@3.0.5: {} + + js-sha3@0.8.0: {} + + js-tokens@4.0.0: {} + + js-tokens@9.0.1: {} + + js-yaml@3.14.1: + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + + js-yaml@4.1.0: + dependencies: + argparse: 2.0.1 + + jsesc@2.5.2: {} + + jsesc@3.1.0: {} + + json-rpc-engine@6.1.0: + dependencies: + '@metamask/safe-event-emitter': 2.0.0 + eth-rpc-errors: 4.0.3 + + json-rpc-random-id@1.0.1: {} + + json5@2.2.3: {} + + jsonfile@2.4.0: + optionalDependencies: + graceful-fs: 4.2.11 + + jsonfile@4.0.0: + optionalDependencies: + graceful-fs: 4.2.11 + + junk@4.0.1: {} + + jwt-decode@4.0.0: {} + + keccak@3.0.3: + dependencies: + node-addon-api: 2.0.2 + node-gyp-build: 4.6.0 + readable-stream: 3.6.2 + + keyvaluestorage-interface@1.0.0: {} + + klaw@1.3.1: + optionalDependencies: + graceful-fs: 4.2.11 + + kleur@3.0.3: {} + + kleur@4.1.5: {} + + klona@2.0.6: {} + + knip@5.30.6(@types/node@24.0.1)(typescript@5.8.3): + dependencies: + '@nodelib/fs.walk': 1.2.8 + '@snyk/github-codeowners': 1.1.0 + '@types/node': 24.0.1 + easy-table: 1.2.0 + enhanced-resolve: 5.17.1 + fast-glob: 3.3.2 + jiti: 1.21.6 + js-yaml: 4.1.0 + minimist: 1.2.8 + picocolors: 1.1.0 + picomatch: 4.0.2 + pretty-ms: 9.0.0 + smol-toml: 1.3.0 + strip-json-comments: 5.0.1 + summary: 2.1.0 + typescript: 5.8.3 + zod: 3.25.20 + zod-validation-error: 3.2.0(zod@3.25.20) + + knitwork@1.2.0: {} + + kolorist@1.8.0: {} + + kuler@2.0.0: {} + + lambda-local@2.2.0: + dependencies: + commander: 10.0.1 + dotenv: 16.5.0 + winston: 3.17.0 + + launch-editor@2.10.0: + dependencies: + picocolors: 1.1.1 + shell-quote: 1.8.2 + + lazystream@1.0.1: + dependencies: + readable-stream: 2.3.8 + + lilconfig@3.1.3: {} + + listhen@1.7.2: + dependencies: + '@parcel/watcher': 2.4.1 + '@parcel/watcher-wasm': 2.4.1 + citty: 0.1.6 + clipboardy: 4.0.0 + consola: 3.4.2 + crossws: 0.2.4 + defu: 6.1.4 + get-port-please: 3.1.2 + h3: 1.15.3 + http-shutdown: 1.2.2 + jiti: 1.21.7 + mlly: 1.7.4 + node-forge: 1.3.1 + pathe: 1.1.2 + std-env: 3.9.0 + ufo: 1.6.1 + untun: 0.1.3 + uqr: 0.1.2 + transitivePeerDependencies: + - uWebSockets.js + + listhen@1.9.0: + dependencies: + '@parcel/watcher': 2.5.1 + '@parcel/watcher-wasm': 2.5.1 + citty: 0.1.6 + clipboardy: 4.0.0 + consola: 3.4.2 + crossws: 0.3.5 + defu: 6.1.4 + get-port-please: 3.1.2 + h3: 1.15.3 + http-shutdown: 1.2.2 + jiti: 2.4.2 + mlly: 1.7.4 + node-forge: 1.3.1 + pathe: 1.1.2 + std-env: 3.9.0 + ufo: 1.6.1 + untun: 0.1.3 + uqr: 0.1.2 + + lit-element@4.2.0: + dependencies: + '@lit-labs/ssr-dom-shim': 1.3.0 + '@lit/reactive-element': 2.1.0 + lit-html: 3.3.0 + + lit-html@3.3.0: + dependencies: + '@types/trusted-types': 2.0.3 + + lit@3.1.0: + dependencies: + '@lit/reactive-element': 2.1.0 + lit-element: 4.2.0 + lit-html: 3.3.0 + + load-tsconfig@0.2.5: {} + + local-pkg@0.5.0: + dependencies: + mlly: 1.7.4 + pkg-types: 1.3.1 + + local-pkg@0.5.1: + dependencies: + mlly: 1.7.4 + pkg-types: 1.3.1 + + local-pkg@1.1.1: + dependencies: + mlly: 1.7.4 + pkg-types: 2.1.0 + quansync: 0.2.10 + + locate-path@2.0.0: + dependencies: + p-locate: 2.0.0 + path-exists: 3.0.0 + + locate-path@5.0.0: + dependencies: + p-locate: 4.1.0 + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + locate-path@7.2.0: + dependencies: + p-locate: 6.0.0 + + lodash-es@4.17.21: {} + + lodash.debounce@4.0.8: {} + + lodash.defaults@4.2.0: {} + + lodash.difference@4.5.0: {} + + lodash.flatten@4.4.0: {} + + lodash.isarguments@3.1.0: {} + + lodash.isplainobject@4.0.6: {} + + lodash.memoize@4.1.2: {} + + lodash.startcase@4.4.0: {} + + lodash.union@4.6.0: {} + + lodash.uniq@4.5.0: {} + + lodash@4.17.21: {} + + log-symbols@4.1.0: + dependencies: + chalk: 4.1.2 + is-unicode-supported: 0.1.0 + + logform@2.7.0: + dependencies: + '@colors/colors': 1.6.0 + '@types/triple-beam': 1.3.5 + fecha: 4.2.3 + ms: 2.1.3 + safe-stable-stringify: 2.5.0 + triple-beam: 1.4.1 + + lokijs@1.5.12: {} + + longest-streak@3.1.0: {} + + loose-envify@1.4.0: + dependencies: + js-tokens: 4.0.0 + + loupe@3.1.3: {} + + lru-cache@10.2.2: {} + + lru-cache@10.4.3: {} + + lru-cache@4.1.5: + dependencies: + pseudomap: 1.0.2 + yallist: 2.1.2 + + lru-cache@5.1.1: + dependencies: + yallist: 3.1.1 + + lru-cache@6.0.0: + dependencies: + yallist: 4.0.0 + + lru_map@0.3.3: {} + + luxon@3.6.1: {} + + lz-string@1.5.0: {} + + magic-string-ast@0.7.1: + dependencies: + magic-string: 0.30.17 + + magic-string@0.30.10: + dependencies: + '@jridgewell/sourcemap-codec': 1.4.15 + + magic-string@0.30.11: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.0 + + magic-string@0.30.12: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.0 + + magic-string@0.30.17: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.0 + + magicast@0.3.4: + dependencies: + '@babel/parser': 7.24.5 + '@babel/types': 7.24.5 + source-map-js: 1.2.0 + + magicast@0.3.5: + dependencies: + '@babel/parser': 7.27.2 + '@babel/types': 7.27.1 + source-map-js: 1.2.1 + + make-dir@3.1.0: + dependencies: + semver: 6.3.1 + + make-dir@4.0.0: + dependencies: + semver: 7.7.2 + + mark.js@8.11.1: {} + + markdown-table@3.0.3: {} + + marked-terminal@7.1.0(marked@9.1.6): + dependencies: + ansi-escapes: 7.0.0 + chalk: 5.3.0 + cli-highlight: 2.1.11 + cli-table3: 0.6.5 + marked: 9.1.6 + node-emoji: 2.1.3 + supports-hyperlinks: 3.0.0 + + marked@9.1.6: {} + + math-intrinsics@1.1.0: {} + + md5.js@1.3.5: + dependencies: + hash-base: 3.1.0 + inherits: 2.0.4 + safe-buffer: 5.2.1 + + mdast-util-find-and-replace@3.0.1: + dependencies: + '@types/mdast': 4.0.3 + escape-string-regexp: 5.0.0 + unist-util-is: 6.0.0 + unist-util-visit-parents: 6.0.1 + + mdast-util-from-markdown@2.0.2: + dependencies: + '@types/mdast': 4.0.3 + '@types/unist': 3.0.2 + decode-named-character-reference: 1.0.2 + devlop: 1.1.0 + mdast-util-to-string: 4.0.0 + micromark: 4.0.0 + micromark-util-decode-numeric-character-reference: 2.0.1 + micromark-util-decode-string: 2.0.0 + micromark-util-normalize-identifier: 2.0.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + unist-util-stringify-position: 4.0.0 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-autolink-literal@2.0.0: + dependencies: + '@types/mdast': 4.0.3 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-find-and-replace: 3.0.1 + micromark-util-character: 2.1.0 + + mdast-util-gfm-footnote@2.0.0: + dependencies: + '@types/mdast': 4.0.3 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.0 + micromark-util-normalize-identifier: 2.0.0 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-strikethrough@2.0.0: + dependencies: + '@types/mdast': 4.0.3 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.0 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-table@2.0.0: + dependencies: + '@types/mdast': 4.0.3 + devlop: 1.1.0 + markdown-table: 3.0.3 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.0 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-task-list-item@2.0.0: + dependencies: + '@types/mdast': 4.0.3 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.0 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm@3.0.0: + dependencies: + mdast-util-from-markdown: 2.0.2 + mdast-util-gfm-autolink-literal: 2.0.0 + mdast-util-gfm-footnote: 2.0.0 + mdast-util-gfm-strikethrough: 2.0.0 + mdast-util-gfm-table: 2.0.0 + mdast-util-gfm-task-list-item: 2.0.0 + mdast-util-to-markdown: 2.1.0 + transitivePeerDependencies: + - supports-color + + mdast-util-phrasing@4.1.0: + dependencies: + '@types/mdast': 4.0.3 + unist-util-is: 6.0.0 + + mdast-util-to-hast@13.1.0: + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.3 + '@ungap/structured-clone': 1.2.0 + devlop: 1.1.0 + micromark-util-sanitize-uri: 2.0.0 + trim-lines: 3.0.1 + unist-util-position: 5.0.0 + unist-util-visit: 5.0.0 + vfile: 6.0.1 + + mdast-util-to-hast@13.2.0: + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.3 + '@ungap/structured-clone': 1.2.0 + devlop: 1.1.0 + micromark-util-sanitize-uri: 2.0.0 + trim-lines: 3.0.1 + unist-util-position: 5.0.0 + unist-util-visit: 5.0.0 + vfile: 6.0.1 + + mdast-util-to-markdown@2.1.0: + dependencies: + '@types/mdast': 4.0.3 + '@types/unist': 3.0.2 + longest-streak: 3.1.0 + mdast-util-phrasing: 4.1.0 + mdast-util-to-string: 4.0.0 + micromark-util-decode-string: 2.0.0 + unist-util-visit: 5.0.0 + zwitch: 2.0.4 + + mdast-util-to-string@4.0.0: + dependencies: + '@types/mdast': 4.0.3 + + mdn-data@2.0.28: {} + + mdn-data@2.0.30: {} + + memorystream@0.3.1: {} + + merge-options@3.0.4: + dependencies: + is-plain-obj: 2.1.0 + + merge-stream@2.0.0: {} + + merge2@1.4.1: {} + + micro-api-client@3.3.0: {} + + micro-ftch@0.3.1: {} + + micromark-core-commonmark@2.0.1: + dependencies: + decode-named-character-reference: 1.0.2 + devlop: 1.1.0 + micromark-factory-destination: 2.0.0 + micromark-factory-label: 2.0.0 + micromark-factory-space: 2.0.0 + micromark-factory-title: 2.0.0 + micromark-factory-whitespace: 2.0.0 + micromark-util-character: 2.1.0 + micromark-util-chunked: 2.0.0 + micromark-util-classify-character: 2.0.0 + micromark-util-html-tag-name: 2.0.0 + micromark-util-normalize-identifier: 2.0.0 + micromark-util-resolve-all: 2.0.0 + micromark-util-subtokenize: 2.0.1 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + + micromark-factory-destination@2.0.0: + dependencies: + micromark-util-character: 2.1.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + + micromark-factory-label@2.0.0: + dependencies: + devlop: 1.1.0 + micromark-util-character: 2.1.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + + micromark-factory-space@2.0.0: + dependencies: + micromark-util-character: 2.1.0 + micromark-util-types: 2.0.0 + + micromark-factory-title@2.0.0: + dependencies: + micromark-factory-space: 2.0.0 + micromark-util-character: 2.1.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + + micromark-factory-whitespace@2.0.0: + dependencies: + micromark-factory-space: 2.0.0 + micromark-util-character: 2.1.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + + micromark-util-character@2.1.0: + dependencies: + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + + micromark-util-chunked@2.0.0: + dependencies: + micromark-util-symbol: 2.0.0 + + micromark-util-classify-character@2.0.0: + dependencies: + micromark-util-character: 2.1.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + + micromark-util-combine-extensions@2.0.0: + dependencies: + micromark-util-chunked: 2.0.0 + micromark-util-types: 2.0.0 + + micromark-util-decode-numeric-character-reference@2.0.1: + dependencies: + micromark-util-symbol: 2.0.0 + + micromark-util-decode-string@2.0.0: + dependencies: + decode-named-character-reference: 1.0.2 + micromark-util-character: 2.1.0 + micromark-util-decode-numeric-character-reference: 2.0.1 + micromark-util-symbol: 2.0.0 + + micromark-util-encode@2.0.0: {} + + micromark-util-html-tag-name@2.0.0: {} + + micromark-util-normalize-identifier@2.0.0: + dependencies: + micromark-util-symbol: 2.0.0 + + micromark-util-resolve-all@2.0.0: + dependencies: + micromark-util-types: 2.0.0 + + micromark-util-sanitize-uri@2.0.0: + dependencies: + micromark-util-character: 2.1.0 + micromark-util-encode: 2.0.0 + micromark-util-symbol: 2.0.0 + + micromark-util-subtokenize@2.0.1: + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + + micromark-util-symbol@2.0.0: {} + + micromark-util-types@2.0.0: {} + + micromark@4.0.0: + dependencies: + '@types/debug': 4.1.7 + debug: 4.4.1 + decode-named-character-reference: 1.0.2 + devlop: 1.1.0 + micromark-core-commonmark: 2.0.1 + micromark-factory-space: 2.0.0 + micromark-util-character: 2.1.0 + micromark-util-chunked: 2.0.0 + micromark-util-combine-extensions: 2.0.0 + micromark-util-decode-numeric-character-reference: 2.0.1 + micromark-util-encode: 2.0.0 + micromark-util-normalize-identifier: 2.0.0 + micromark-util-resolve-all: 2.0.0 + micromark-util-sanitize-uri: 2.0.0 + micromark-util-subtokenize: 2.0.1 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + transitivePeerDependencies: + - supports-color + + micromatch@4.0.5: + dependencies: + braces: 3.0.2 + picomatch: 2.3.1 + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + + mime-db@1.54.0: {} + + mime-types@3.0.1: + dependencies: + mime-db: 1.54.0 + + mime@3.0.0: {} + + mime@4.0.7: {} + + mimic-fn@2.1.0: {} + + mimic-fn@4.0.0: {} + + minimalistic-assert@1.0.1: {} + + minimalistic-crypto-utils@1.0.1: {} + + minimatch@3.1.2: + dependencies: + brace-expansion: 1.1.11 + + minimatch@5.0.1: + dependencies: + brace-expansion: 2.0.1 + + minimatch@5.1.6: + dependencies: + brace-expansion: 2.0.1 + + minimatch@9.0.1: + dependencies: + brace-expansion: 2.0.1 + + minimatch@9.0.4: + dependencies: + brace-expansion: 2.0.1 + + minimatch@9.0.5: + dependencies: + brace-expansion: 2.0.1 + + minimist@1.2.8: {} + + minipass@3.3.6: + dependencies: + yallist: 4.0.0 + + minipass@5.0.0: {} + + minipass@7.1.2: {} + + minisearch@7.1.0: {} + + minizlib@2.1.2: + dependencies: + minipass: 3.3.6 + yallist: 4.0.0 + + minizlib@3.0.1: + dependencies: + minipass: 7.1.2 + rimraf: 5.0.10 + + minizlib@3.0.2: + dependencies: + minipass: 7.1.2 + + mipd@0.0.7(typescript@5.8.3): + optionalDependencies: + typescript: 5.8.3 + + mitt@3.0.1: {} + + mkdirp@1.0.4: {} + + mkdirp@3.0.1: {} + + mlly@1.7.0: + dependencies: + acorn: 8.11.3 + pathe: 1.1.2 + pkg-types: 1.3.1 + ufo: 1.6.1 + + mlly@1.7.4: + dependencies: + acorn: 8.14.1 + pathe: 2.0.3 + pkg-types: 1.3.1 + ufo: 1.6.1 + + mnemonist@0.38.5: + dependencies: + obliterator: 2.0.4 + + mocha@10.2.0: + dependencies: + ansi-colors: 4.1.1 + browser-stdout: 1.3.1 + chokidar: 3.5.3 + debug: 4.3.4(supports-color@8.1.1) + diff: 5.0.0 + escape-string-regexp: 4.0.0 + find-up: 5.0.0 + glob: 7.2.0 + he: 1.2.0 + js-yaml: 4.1.0 + log-symbols: 4.1.0 + minimatch: 5.0.1 + ms: 2.1.3 + nanoid: 3.3.3 + serialize-javascript: 6.0.0 + strip-json-comments: 3.1.1 + supports-color: 8.1.1 + workerpool: 6.2.1 + yargs: 16.2.0 + yargs-parser: 20.2.4 + yargs-unparser: 2.0.0 + + mocked-exports@0.1.1: {} + + module-definition@5.0.1: + dependencies: + ast-module-types: 5.0.0 + node-source-walk: 6.0.2 + + mri@1.2.0: {} + + mrmime@2.0.1: {} + + ms@2.1.2: {} + + ms@2.1.3: {} + + msw@2.4.9(typescript@5.8.3): + dependencies: + '@bundled-es-modules/cookie': 2.0.0 + '@bundled-es-modules/statuses': 1.0.1 + '@bundled-es-modules/tough-cookie': 0.1.6 + '@inquirer/confirm': 3.1.6 + '@mswjs/interceptors': 0.35.9 + '@open-draft/until': 2.1.0 + '@types/cookie': 0.6.0 + '@types/statuses': 2.0.4 + chalk: 4.1.2 + graphql: 16.8.1 + headers-polyfill: 4.0.2 + is-node-process: 1.2.0 + outvariant: 1.4.2 + path-to-regexp: 6.3.0 + strict-event-emitter: 0.5.1 + type-fest: 4.18.2 + yargs: 17.7.2 + optionalDependencies: + typescript: 5.8.3 + + muggle-string@0.4.1: {} + + multiformats@9.9.0: {} + + mute-stream@1.0.0: {} + + mz@2.7.0: + dependencies: + any-promise: 1.3.0 + object-assign: 4.1.1 + thenify-all: 1.6.0 + + nanoid@3.3.11: {} + + nanoid@3.3.3: {} + + nanoid@3.3.7: {} + + nanoid@5.1.5: {} + + nanospinner@1.2.2: + dependencies: + picocolors: 1.1.1 + + nanotar@0.2.0: {} + + nested-error-stacks@2.1.1: {} + + netlify@13.3.5: + dependencies: + '@netlify/open-api': 2.37.0 + lodash-es: 4.17.21 + micro-api-client: 3.3.0 + node-fetch: 3.3.2 + p-wait-for: 5.0.2 + qs: 6.14.0 + + next@15.3.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@next/env': 15.3.3 + '@swc/counter': 0.1.3 + '@swc/helpers': 0.5.15 + busboy: 1.6.0 + caniuse-lite: 1.0.30001723 + postcss: 8.4.31 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + styled-jsx: 5.1.6(react@18.3.1) + optionalDependencies: + '@next/swc-darwin-arm64': 15.3.3 + '@next/swc-darwin-x64': 15.3.3 + '@next/swc-linux-arm64-gnu': 15.3.3 + '@next/swc-linux-arm64-musl': 15.3.3 + '@next/swc-linux-x64-gnu': 15.3.3 + '@next/swc-linux-x64-musl': 15.3.3 + '@next/swc-win32-arm64-msvc': 15.3.3 + '@next/swc-win32-x64-msvc': 15.3.3 + sharp: 0.34.2 + transitivePeerDependencies: + - '@babel/core' + - babel-plugin-macros + + nitropack@2.11.12(encoding@0.1.13)(idb-keyval@6.2.1): + dependencies: + '@cloudflare/kv-asset-handler': 0.4.0 + '@netlify/functions': 3.1.8(encoding@0.1.13)(rollup@4.41.0) + '@rollup/plugin-alias': 5.1.1(rollup@4.41.0) + '@rollup/plugin-commonjs': 28.0.3(rollup@4.41.0) + '@rollup/plugin-inject': 5.0.5(rollup@4.41.0) + '@rollup/plugin-json': 6.1.0(rollup@4.41.0) + '@rollup/plugin-node-resolve': 16.0.1(rollup@4.41.0) + '@rollup/plugin-replace': 6.0.2(rollup@4.41.0) + '@rollup/plugin-terser': 0.4.4(rollup@4.41.0) + '@vercel/nft': 0.29.3(encoding@0.1.13)(rollup@4.41.0) + archiver: 7.0.1 + c12: 3.0.4(magicast@0.3.5) + chokidar: 4.0.3 + citty: 0.1.6 + compatx: 0.2.0 + confbox: 0.2.2 + consola: 3.4.2 + cookie-es: 2.0.0 + croner: 9.0.0 + crossws: 0.3.5 + db0: 0.3.2 + defu: 6.1.4 + destr: 2.0.5 + dot-prop: 9.0.0 + esbuild: 0.25.5 + escape-string-regexp: 5.0.0 + etag: 1.8.1 + exsolve: 1.0.5 + globby: 14.1.0 + gzip-size: 7.0.0 + h3: 1.15.3 + hookable: 5.5.3 + httpxy: 0.1.7 + ioredis: 5.6.1 + jiti: 2.4.2 + klona: 2.0.6 + knitwork: 1.2.0 + listhen: 1.9.0 + magic-string: 0.30.17 + magicast: 0.3.5 + mime: 4.0.7 + mlly: 1.7.4 + node-fetch-native: 1.6.6 + node-mock-http: 1.0.0 + ofetch: 1.4.1 + ohash: 2.0.11 + pathe: 2.0.3 + perfect-debounce: 1.0.0 + pkg-types: 2.1.0 + pretty-bytes: 6.1.1 + radix3: 1.1.2 + rollup: 4.41.0 + rollup-plugin-visualizer: 5.14.0(rollup@4.41.0) + scule: 1.3.0 + semver: 7.7.2 + serve-placeholder: 2.0.2 + serve-static: 2.2.0 + source-map: 0.7.4 + std-env: 3.9.0 + ufo: 1.6.1 + ultrahtml: 1.6.0 + uncrypto: 0.1.3 + unctx: 2.4.1 + unenv: 2.0.0-rc.17 + unimport: 5.0.1 + unplugin-utils: 0.2.4 + unstorage: 1.16.0(db0@0.3.2)(idb-keyval@6.2.1)(ioredis@5.6.1) + untyped: 2.0.0 + unwasm: 0.3.9 + youch: 4.1.0-beta.7 + youch-core: 0.3.2 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@electric-sql/pglite' + - '@libsql/client' + - '@netlify/blobs' + - '@planetscale/database' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/kv' + - aws4fetch + - better-sqlite3 + - drizzle-orm + - encoding + - idb-keyval + - mysql2 + - rolldown + - sqlite3 + - supports-color + - uploadthing + + node-addon-api@2.0.2: {} + + node-addon-api@7.0.0: {} + + node-addon-api@7.1.1: {} + + node-domexception@1.0.0: {} + + node-emoji@2.1.3: + dependencies: + '@sindresorhus/is': 4.6.0 + char-regex: 1.0.2 + emojilib: 2.4.0 + skin-tone: 2.0.0 + + node-fetch-native@1.6.4: {} + + node-fetch-native@1.6.6: {} + + node-fetch@2.6.7(encoding@0.1.13): + dependencies: + whatwg-url: 5.0.0 + optionalDependencies: + encoding: 0.1.13 + + node-fetch@2.6.9(encoding@0.1.13): + dependencies: + whatwg-url: 5.0.0 + optionalDependencies: + encoding: 0.1.13 + + node-fetch@2.7.0(encoding@0.1.13): + dependencies: + whatwg-url: 5.0.0 + optionalDependencies: + encoding: 0.1.13 + + node-fetch@3.3.2: + dependencies: + data-uri-to-buffer: 4.0.1 + fetch-blob: 3.2.0 + formdata-polyfill: 4.0.10 + + node-forge@1.3.1: {} + + node-gyp-build@4.6.0: {} + + node-gyp-build@4.8.4: {} + + node-mock-http@1.0.0: {} + + node-releases@2.0.14: {} + + node-releases@2.0.19: {} + + node-source-walk@6.0.2: + dependencies: + '@babel/parser': 7.27.2 + + nopt@5.0.0: + dependencies: + abbrev: 1.1.1 + + nopt@7.2.1: + dependencies: + abbrev: 2.0.0 + + nopt@8.1.0: + dependencies: + abbrev: 3.0.1 + + normalize-package-data@6.0.2: + dependencies: + hosted-git-info: 7.0.2 + semver: 7.7.2 + validate-npm-package-license: 3.0.4 + + normalize-path@2.1.1: + dependencies: + remove-trailing-separator: 1.1.0 + + normalize-path@3.0.0: {} + + normalize-range@0.1.2: {} + + npm-run-path@4.0.1: + dependencies: + path-key: 3.1.1 + + npm-run-path@5.3.0: + dependencies: + path-key: 4.0.0 + + npm-run-path@6.0.0: + dependencies: + path-key: 4.0.0 + unicorn-magic: 0.3.0 + + npmlog@5.0.1: + dependencies: + are-we-there-yet: 2.0.0 + console-control-strings: 1.1.0 + gauge: 3.0.2 + set-blocking: 2.0.0 + + nth-check@2.1.1: + dependencies: + boolbase: 1.0.0 + + nuxt@3.16.0(@biomejs/biome@1.9.4)(@parcel/watcher@2.5.1)(@types/node@24.0.1)(bufferutil@4.0.9)(db0@0.3.2)(encoding@0.1.13)(idb-keyval@6.2.1)(ioredis@5.6.1)(magicast@0.3.5)(rollup@4.41.0)(terser@5.39.2)(typescript@5.8.3)(utf-8-validate@6.0.5)(vite@6.3.5(@types/node@24.0.1)(jiti@2.4.2)(terser@5.39.2)(yaml@2.8.0))(yaml@2.8.0): + dependencies: + '@nuxt/cli': 3.25.1(magicast@0.3.5) + '@nuxt/devalue': 2.0.2 + '@nuxt/devtools': 2.4.1(bufferutil@4.0.9)(utf-8-validate@6.0.5)(vite@6.3.5(@types/node@24.0.1)(jiti@2.4.2)(terser@5.39.2)(yaml@2.8.0))(vue@3.5.14(typescript@5.8.3)) + '@nuxt/kit': 3.16.0(magicast@0.3.5) + '@nuxt/schema': 3.16.0 + '@nuxt/telemetry': 2.6.6(magicast@0.3.5) + '@nuxt/vite-builder': 3.16.0(@biomejs/biome@1.9.4)(@types/node@24.0.1)(magicast@0.3.5)(rollup@4.41.0)(terser@5.39.2)(typescript@5.8.3)(vue@3.5.14(typescript@5.8.3))(yaml@2.8.0) + '@oxc-parser/wasm': 0.56.5 + '@unhead/vue': 2.0.9(vue@3.5.14(typescript@5.8.3)) + '@vue/shared': 3.5.14 + c12: 3.0.4(magicast@0.3.5) + chokidar: 4.0.3 + compatx: 0.1.8 + consola: 3.4.2 + cookie-es: 2.0.0 + defu: 6.1.4 + destr: 2.0.5 + devalue: 5.1.1 + errx: 0.1.0 + esbuild: 0.25.5 + escape-string-regexp: 5.0.0 + estree-walker: 3.0.3 + exsolve: 1.0.5 + globby: 14.1.0 + h3: 1.15.3 + hookable: 5.5.3 + ignore: 7.0.4 + impound: 0.2.2(rollup@4.41.0) + jiti: 2.4.2 + klona: 2.0.6 + knitwork: 1.2.0 + magic-string: 0.30.17 + mlly: 1.7.4 + nanotar: 0.2.0 + nitropack: 2.11.12(encoding@0.1.13)(idb-keyval@6.2.1) + nypm: 0.6.0 + ofetch: 1.4.1 + ohash: 2.0.11 + on-change: 5.0.1 + oxc-parser: 0.56.5 + pathe: 2.0.3 + perfect-debounce: 1.0.0 + pkg-types: 2.1.0 + radix3: 1.1.2 + scule: 1.3.0 + semver: 7.7.2 + std-env: 3.9.0 + strip-literal: 3.0.0 + tinyglobby: 0.2.12 + ufo: 1.6.1 + ultrahtml: 1.6.0 + uncrypto: 0.1.3 + unctx: 2.4.1 + unenv: 2.0.0-rc.17 + unimport: 4.2.0 + unplugin: 2.3.4 + unplugin-vue-router: 0.12.0(vue-router@4.5.1(vue@3.5.14(typescript@5.8.3)))(vue@3.5.14(typescript@5.8.3)) + unstorage: 1.16.0(db0@0.3.2)(idb-keyval@6.2.1)(ioredis@5.6.1) + untyped: 2.0.0 + vue: 3.5.14(typescript@5.8.3) + vue-bundle-renderer: 2.1.1 + vue-devtools-stub: 0.1.0 + vue-router: 4.5.1(vue@3.5.14(typescript@5.8.3)) + optionalDependencies: + '@parcel/watcher': 2.5.1 + '@types/node': 24.0.1 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@biomejs/biome' + - '@capacitor/preferences' + - '@deno/kv' + - '@electric-sql/pglite' + - '@libsql/client' + - '@netlify/blobs' + - '@planetscale/database' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/kv' + - aws4fetch + - better-sqlite3 + - bufferutil + - db0 + - drizzle-orm + - encoding + - eslint + - idb-keyval + - ioredis + - less + - lightningcss + - magicast + - meow + - mysql2 + - optionator + - rolldown + - rollup + - sass + - sass-embedded + - sqlite3 + - stylelint + - stylus + - sugarss + - supports-color + - terser + - tsx + - typescript + - uploadthing + - utf-8-validate + - vite + - vls + - vti + - vue-tsc + - xml2js + - yaml + + nypm@0.6.0: + dependencies: + citty: 0.1.6 + consola: 3.4.2 + pathe: 2.0.3 + pkg-types: 2.1.0 + tinyexec: 0.3.2 + + obj-multiplex@1.0.0: + dependencies: + end-of-stream: 1.4.4 + once: 1.4.0 + readable-stream: 2.3.8 + + object-assign@4.1.1: {} + + object-inspect@1.13.4: {} + + obliterator@2.0.4: {} + + ofetch@1.4.1: + dependencies: + destr: 2.0.5 + node-fetch-native: 1.6.6 + ufo: 1.6.1 + + ohash@2.0.11: {} + + on-change@5.0.1: {} + + on-exit-leak-free@0.2.0: {} + + on-exit-leak-free@2.1.2: {} + + on-finished@2.4.1: + dependencies: + ee-first: 1.1.1 + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + one-time@1.0.0: + dependencies: + fn.name: 1.1.0 + + onetime@5.1.2: + dependencies: + mimic-fn: 2.1.0 + + onetime@6.0.0: + dependencies: + mimic-fn: 4.0.0 + + oniguruma-to-js@0.4.3: + dependencies: + regex: 4.4.0 + + open@10.1.2: + dependencies: + default-browser: 5.2.1 + define-lazy-prop: 3.0.0 + is-inside-container: 1.0.0 + is-wsl: 3.1.0 + + open@8.4.2: + dependencies: + define-lazy-prop: 2.0.0 + is-docker: 2.2.1 + is-wsl: 2.2.0 + + opener@1.5.2: {} + + os-tmpdir@1.0.2: {} + + outdent@0.5.0: {} + + outvariant@1.4.2: {} + + outvariant@1.4.3: {} + + ox@0.6.7(typescript@5.8.3)(zod@3.25.20): + dependencies: + '@adraffy/ens-normalize': 1.11.0 + '@noble/curves': 1.8.1 + '@noble/hashes': 1.7.1 + '@scure/bip32': 1.6.2 + '@scure/bip39': 1.5.4 + abitype: 1.0.8(typescript@5.8.3)(zod@3.25.20) + eventemitter3: 5.0.1 + optionalDependencies: + typescript: 5.8.3 + transitivePeerDependencies: + - zod + + ox@0.6.9(typescript@5.8.3)(zod@3.22.4): + dependencies: + '@adraffy/ens-normalize': 1.11.0 + '@noble/curves': 1.8.2 + '@noble/hashes': 1.7.2 + '@scure/bip32': 1.6.2 + '@scure/bip39': 1.5.4 + abitype: 1.0.8(typescript@5.8.3)(zod@3.22.4) + eventemitter3: 5.0.1 + optionalDependencies: + typescript: 5.8.3 + transitivePeerDependencies: + - zod + + ox@0.6.9(typescript@5.8.3)(zod@3.25.20): + dependencies: + '@adraffy/ens-normalize': 1.11.0 + '@noble/curves': 1.8.2 + '@noble/hashes': 1.7.2 + '@scure/bip32': 1.6.2 + '@scure/bip39': 1.5.4 + abitype: 1.0.8(typescript@5.8.3)(zod@3.25.20) + eventemitter3: 5.0.1 + optionalDependencies: + typescript: 5.8.3 + transitivePeerDependencies: + - zod + + oxc-parser@0.56.5: + dependencies: + '@oxc-project/types': 0.56.5 + optionalDependencies: + '@oxc-parser/binding-darwin-arm64': 0.56.5 + '@oxc-parser/binding-darwin-x64': 0.56.5 + '@oxc-parser/binding-linux-arm-gnueabihf': 0.56.5 + '@oxc-parser/binding-linux-arm64-gnu': 0.56.5 + '@oxc-parser/binding-linux-arm64-musl': 0.56.5 + '@oxc-parser/binding-linux-x64-gnu': 0.56.5 + '@oxc-parser/binding-linux-x64-musl': 0.56.5 + '@oxc-parser/binding-wasm32-wasi': 0.56.5 + '@oxc-parser/binding-win32-arm64-msvc': 0.56.5 + '@oxc-parser/binding-win32-x64-msvc': 0.56.5 + + p-event@5.0.1: + dependencies: + p-timeout: 5.1.0 + + p-filter@2.1.0: + dependencies: + p-map: 2.1.0 + + p-limit@1.3.0: + dependencies: + p-try: 1.0.0 + + p-limit@2.3.0: + dependencies: + p-try: 2.2.0 + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-limit@4.0.0: + dependencies: + yocto-queue: 1.2.1 + + p-locate@2.0.0: + dependencies: + p-limit: 1.3.0 + + p-locate@4.1.0: + dependencies: + p-limit: 2.3.0 + + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + + p-locate@6.0.0: + dependencies: + p-limit: 4.0.0 + + p-map@2.1.0: {} + + p-map@4.0.0: + dependencies: + aggregate-error: 3.1.0 + + p-map@7.0.3: {} + + p-timeout@5.1.0: {} + + p-timeout@6.1.4: {} + + p-try@1.0.0: {} + + p-try@2.2.0: {} + + p-wait-for@5.0.2: + dependencies: + p-timeout: 6.1.4 + + package-json-from-dist@1.0.1: {} + + package-manager-detector@0.2.0: {} + + package-manager-detector@1.3.0: {} + + parse-gitignore@2.0.0: {} + + parse-json@8.3.0: + dependencies: + '@babel/code-frame': 7.27.1 + index-to-position: 1.1.0 + type-fest: 4.41.0 + + parse-ms@4.0.0: {} + + parse-path@7.1.0: + dependencies: + protocols: 2.0.2 + + parse-url@9.2.0: + dependencies: + '@types/parse-path': 7.1.0 + parse-path: 7.1.0 + + parse5-htmlparser2-tree-adapter@6.0.1: + dependencies: + parse5: 6.0.1 + + parse5@5.1.1: {} + + parse5@6.0.1: {} + + parseurl@1.3.3: {} + + path-browserify@1.0.1: {} + + path-exists@3.0.0: {} + + path-exists@4.0.0: {} + + path-exists@5.0.0: {} + + path-is-absolute@1.0.1: {} + + path-key@3.1.1: {} + + path-key@4.0.0: {} + + path-parse@1.0.7: {} + + path-scurry@1.11.1: + dependencies: + lru-cache: 10.4.3 + minipass: 7.1.2 + + path-to-regexp@6.3.0: {} + + path-type@3.0.0: + dependencies: + pify: 3.0.0 + + path-type@4.0.0: {} + + path-type@6.0.0: {} + + pathe@1.1.2: {} + + pathe@2.0.3: {} + + pathval@2.0.0: {} + + pbkdf2@3.1.2: + dependencies: + create-hash: 1.2.0 + create-hmac: 1.1.7 + ripemd160: 2.0.2 + safe-buffer: 5.2.1 + sha.js: 2.4.11 + + pend@1.2.0: {} + + perfect-debounce@1.0.0: {} + + picocolors@1.0.0: {} + + picocolors@1.1.0: {} + + picocolors@1.1.1: {} + + picomatch@2.3.1: {} + + picomatch@4.0.2: {} + + pify@3.0.0: {} + + pify@4.0.1: {} + + pify@5.0.0: {} + + pino-abstract-transport@0.5.0: + dependencies: + duplexify: 4.1.2 + split2: 4.2.0 + + pino-abstract-transport@2.0.0: + dependencies: + split2: 4.2.0 + + pino-pretty@13.0.0: + dependencies: + colorette: 2.0.20 + dateformat: 4.6.3 + fast-copy: 3.0.2 + fast-safe-stringify: 2.1.1 + help-me: 5.0.0 + joycon: 3.1.1 + minimist: 1.2.8 + on-exit-leak-free: 2.1.2 + pino-abstract-transport: 2.0.0 + pump: 3.0.2 + secure-json-parse: 2.7.0 + sonic-boom: 4.2.0 + strip-json-comments: 3.1.1 + + pino-std-serializers@4.0.0: {} + + pino@7.11.0: + dependencies: + atomic-sleep: 1.0.0 + fast-redact: 3.1.2 + on-exit-leak-free: 0.2.0 + pino-abstract-transport: 0.5.0 + pino-std-serializers: 4.0.0 + process-warning: 1.0.0 + quick-format-unescaped: 4.0.4 + real-require: 0.1.0 + safe-stable-stringify: 2.4.3 + sonic-boom: 2.8.0 + thread-stream: 0.15.2 + + pkg-types@1.1.0: + dependencies: + confbox: 0.1.7 + mlly: 1.7.4 + pathe: 1.1.2 + + pkg-types@1.1.1: + dependencies: + confbox: 0.1.7 + mlly: 1.7.0 + pathe: 1.1.2 + + pkg-types@1.3.1: + dependencies: + confbox: 0.1.8 + mlly: 1.7.4 + pathe: 2.0.3 + + pkg-types@2.1.0: + dependencies: + confbox: 0.2.2 + exsolve: 1.0.5 + pathe: 2.0.3 + + pngjs@5.0.0: {} + + pony-cause@2.1.11: {} + + possible-typed-array-names@1.1.0: {} + + postcss-calc@10.1.1(postcss@8.5.3): + dependencies: + postcss: 8.5.3 + postcss-selector-parser: 7.1.0 + postcss-value-parser: 4.2.0 + + postcss-colormin@7.0.3(postcss@8.5.3): + dependencies: + browserslist: 4.24.5 + caniuse-api: 3.0.0 + colord: 2.9.3 + postcss: 8.5.3 + postcss-value-parser: 4.2.0 + + postcss-convert-values@7.0.5(postcss@8.5.3): + dependencies: + browserslist: 4.24.5 + postcss: 8.5.3 + postcss-value-parser: 4.2.0 + + postcss-discard-comments@7.0.4(postcss@8.5.3): + dependencies: + postcss: 8.5.3 + postcss-selector-parser: 7.1.0 + + postcss-discard-duplicates@7.0.2(postcss@8.5.3): + dependencies: + postcss: 8.5.3 + + postcss-discard-empty@7.0.1(postcss@8.5.3): + dependencies: + postcss: 8.5.3 + + postcss-discard-overridden@7.0.1(postcss@8.5.3): + dependencies: + postcss: 8.5.3 + + postcss-merge-longhand@7.0.5(postcss@8.5.3): + dependencies: + postcss: 8.5.3 + postcss-value-parser: 4.2.0 + stylehacks: 7.0.5(postcss@8.5.3) + + postcss-merge-rules@7.0.5(postcss@8.5.3): + dependencies: + browserslist: 4.24.5 + caniuse-api: 3.0.0 + cssnano-utils: 5.0.1(postcss@8.5.3) + postcss: 8.5.3 + postcss-selector-parser: 7.1.0 + + postcss-minify-font-values@7.0.1(postcss@8.5.3): + dependencies: + postcss: 8.5.3 + postcss-value-parser: 4.2.0 + + postcss-minify-gradients@7.0.1(postcss@8.5.3): + dependencies: + colord: 2.9.3 + cssnano-utils: 5.0.1(postcss@8.5.3) + postcss: 8.5.3 + postcss-value-parser: 4.2.0 + + postcss-minify-params@7.0.3(postcss@8.5.3): + dependencies: + browserslist: 4.24.5 + cssnano-utils: 5.0.1(postcss@8.5.3) + postcss: 8.5.3 + postcss-value-parser: 4.2.0 + + postcss-minify-selectors@7.0.5(postcss@8.5.3): + dependencies: + cssesc: 3.0.0 + postcss: 8.5.3 + postcss-selector-parser: 7.1.0 + + postcss-normalize-charset@7.0.1(postcss@8.5.3): + dependencies: + postcss: 8.5.3 + + postcss-normalize-display-values@7.0.1(postcss@8.5.3): + dependencies: + postcss: 8.5.3 + postcss-value-parser: 4.2.0 + + postcss-normalize-positions@7.0.1(postcss@8.5.3): + dependencies: + postcss: 8.5.3 + postcss-value-parser: 4.2.0 + + postcss-normalize-repeat-style@7.0.1(postcss@8.5.3): + dependencies: + postcss: 8.5.3 + postcss-value-parser: 4.2.0 + + postcss-normalize-string@7.0.1(postcss@8.5.3): + dependencies: + postcss: 8.5.3 + postcss-value-parser: 4.2.0 + + postcss-normalize-timing-functions@7.0.1(postcss@8.5.3): + dependencies: + postcss: 8.5.3 + postcss-value-parser: 4.2.0 + + postcss-normalize-unicode@7.0.3(postcss@8.5.3): + dependencies: + browserslist: 4.24.5 + postcss: 8.5.3 + postcss-value-parser: 4.2.0 + + postcss-normalize-url@7.0.1(postcss@8.5.3): + dependencies: + postcss: 8.5.3 + postcss-value-parser: 4.2.0 + + postcss-normalize-whitespace@7.0.1(postcss@8.5.3): + dependencies: + postcss: 8.5.3 + postcss-value-parser: 4.2.0 + + postcss-ordered-values@7.0.2(postcss@8.5.3): + dependencies: + cssnano-utils: 5.0.1(postcss@8.5.3) + postcss: 8.5.3 + postcss-value-parser: 4.2.0 + + postcss-reduce-initial@7.0.3(postcss@8.5.3): + dependencies: + browserslist: 4.24.5 + caniuse-api: 3.0.0 + postcss: 8.5.3 + + postcss-reduce-transforms@7.0.1(postcss@8.5.3): + dependencies: + postcss: 8.5.3 + postcss-value-parser: 4.2.0 + + postcss-selector-parser@7.1.0: + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + + postcss-svgo@7.0.2(postcss@8.5.3): + dependencies: + postcss: 8.5.3 + postcss-value-parser: 4.2.0 + svgo: 3.3.2 + + postcss-unique-selectors@7.0.4(postcss@8.5.3): + dependencies: + postcss: 8.5.3 + postcss-selector-parser: 7.1.0 + + postcss-value-parser@4.2.0: {} + + postcss-values-parser@6.0.2(postcss@8.5.5): + dependencies: + color-name: 1.1.4 + is-url-superb: 4.0.0 + postcss: 8.5.5 + quote-unquote: 1.0.0 + + postcss@8.4.31: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + postcss@8.4.47: + dependencies: + nanoid: 3.3.7 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + postcss@8.5.3: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + postcss@8.5.5: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + preact@10.17.1: {} + + preact@10.24.3: {} + + precinct@11.0.5: + dependencies: + '@dependents/detective-less': 4.1.0 + commander: 10.0.1 + detective-amd: 5.0.2 + detective-cjs: 5.0.1 + detective-es6: 4.0.1 + detective-postcss: 6.1.3 + detective-sass: 5.0.3 + detective-scss: 4.0.3 + detective-stylus: 4.0.0 + detective-typescript: 11.2.0 + module-definition: 5.0.1 + node-source-walk: 6.0.2 + transitivePeerDependencies: + - supports-color + + prettier@2.8.8: {} + + prettier@3.0.3: {} + + pretty-bytes@6.1.1: {} + + pretty-format@27.5.1: + dependencies: + ansi-regex: 5.0.1 + ansi-styles: 5.2.0 + react-is: 17.0.2 + + pretty-ms@9.0.0: + dependencies: + parse-ms: 4.0.0 + + process-nextick-args@2.0.1: {} + + process-warning@1.0.0: {} + + process@0.11.10: {} + + prompts@2.4.2: + dependencies: + kleur: 3.0.3 + sisteransi: 1.0.5 + + prool@0.0.23: + dependencies: + change-case: 5.4.4 + eventemitter3: 5.0.1 + execa: 9.1.0 + get-port: 7.1.0 + http-proxy: 1.18.1 + tar: 7.2.0 + transitivePeerDependencies: + - debug + + property-information@6.5.0: {} + + proto-list@1.2.4: {} + + protocols@2.0.2: {} + + proxy-compare@2.6.0: {} + + pseudomap@1.0.2: {} + + psl@1.9.0: {} + + publint@0.3.12: + dependencies: + '@publint/pack': 0.1.2 + package-manager-detector: 1.3.0 + picocolors: 1.1.1 + sade: 1.8.1 + + pump@3.0.2: + dependencies: + end-of-stream: 1.4.4 + once: 1.4.0 + + punycode@2.3.1: {} + + qrcode@1.5.3: + dependencies: + dijkstrajs: 1.0.2 + encode-utf8: 1.0.3 + pngjs: 5.0.0 + yargs: 15.4.1 + + qs@6.14.0: + dependencies: + side-channel: 1.1.0 + + quansync@0.2.10: {} + + query-string@7.1.3: + dependencies: + decode-uri-component: 0.2.2 + filter-obj: 1.1.0 + split-on-first: 1.1.0 + strict-uri-encode: 2.0.0 + + querystringify@2.2.0: {} + + queue-microtask@1.2.3: {} + + quick-format-unescaped@4.0.4: {} + + quote-unquote@1.0.0: {} + + radix3@1.1.2: {} + + randombytes@2.1.0: + dependencies: + safe-buffer: 5.2.1 + + range-parser@1.2.1: {} + + raw-body@2.5.1: + dependencies: + bytes: 3.1.2 + http-errors: 2.0.0 + iconv-lite: 0.4.24 + unpipe: 1.0.0 + + rc9@2.1.2: + dependencies: + defu: 6.1.4 + destr: 2.0.5 + + react-dom@18.3.1(react@18.3.1): + dependencies: + loose-envify: 1.4.0 + react: 18.3.1 + scheduler: 0.23.2 + + react-is@17.0.2: {} + + react-refresh@0.14.0: {} + + react@18.3.1: + dependencies: + loose-envify: 1.4.0 + + read-package-up@11.0.0: + dependencies: + find-up-simple: 1.0.1 + read-pkg: 9.0.1 + type-fest: 4.41.0 + + read-pkg@9.0.1: + dependencies: + '@types/normalize-package-data': 2.4.4 + normalize-package-data: 6.0.2 + parse-json: 8.3.0 + type-fest: 4.41.0 + unicorn-magic: 0.1.0 + + read-yaml-file@1.1.0: + dependencies: + graceful-fs: 4.2.11 + js-yaml: 3.14.1 + pify: 4.0.1 + strip-bom: 3.0.0 + + readable-stream@2.3.8: + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + + readable-stream@3.6.2: + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + + readable-stream@4.7.0: + dependencies: + abort-controller: 3.0.0 + buffer: 6.0.3 + events: 3.3.0 + process: 0.11.10 + string_decoder: 1.3.0 + + readdir-glob@1.1.3: + dependencies: + minimatch: 5.1.6 + + readdirp@3.6.0: + dependencies: + picomatch: 2.3.1 + + readdirp@4.1.2: {} + + real-require@0.1.0: {} + + redis-errors@1.2.0: {} + + redis-parser@3.0.0: + dependencies: + redis-errors: 1.2.0 + + regenerator-runtime@0.14.0: {} + + regex@4.4.0: {} + + remove-accents@0.5.0: {} + + remove-trailing-separator@1.1.0: {} + + require-directory@2.1.1: {} + + require-from-string@2.0.2: {} + + require-main-filename@2.0.0: {} + + require-package-name@2.0.1: {} + + requires-port@1.0.0: {} + + resolve-from@5.0.0: {} + + resolve@1.17.0: + dependencies: + path-parse: 1.0.7 + + resolve@1.22.10: + dependencies: + is-core-module: 2.16.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + resolve@2.0.0-next.5: + dependencies: + is-core-module: 2.16.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + reusify@1.0.4: {} + + rfdc@1.4.1: {} + + rimraf@2.7.1: + dependencies: + glob: 7.2.3 + + rimraf@3.0.2: + dependencies: + glob: 7.2.3 + + rimraf@5.0.10: + dependencies: + glob: 10.4.5 + + ripemd160@2.0.2: + dependencies: + hash-base: 3.1.0 + inherits: 2.0.4 + + rlp@2.2.7: + dependencies: + bn.js: 5.2.1 + + rollup-plugin-visualizer@5.14.0(rollup@4.41.0): + dependencies: + open: 8.4.2 + picomatch: 4.0.2 + source-map: 0.7.4 + yargs: 17.7.2 + optionalDependencies: + rollup: 4.41.0 + + rollup@4.41.0: + dependencies: + '@types/estree': 1.0.7 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.41.0 + '@rollup/rollup-android-arm64': 4.41.0 + '@rollup/rollup-darwin-arm64': 4.41.0 + '@rollup/rollup-darwin-x64': 4.41.0 + '@rollup/rollup-freebsd-arm64': 4.41.0 + '@rollup/rollup-freebsd-x64': 4.41.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.41.0 + '@rollup/rollup-linux-arm-musleabihf': 4.41.0 + '@rollup/rollup-linux-arm64-gnu': 4.41.0 + '@rollup/rollup-linux-arm64-musl': 4.41.0 + '@rollup/rollup-linux-loongarch64-gnu': 4.41.0 + '@rollup/rollup-linux-powerpc64le-gnu': 4.41.0 + '@rollup/rollup-linux-riscv64-gnu': 4.41.0 + '@rollup/rollup-linux-riscv64-musl': 4.41.0 + '@rollup/rollup-linux-s390x-gnu': 4.41.0 + '@rollup/rollup-linux-x64-gnu': 4.41.0 + '@rollup/rollup-linux-x64-musl': 4.41.0 + '@rollup/rollup-win32-arm64-msvc': 4.41.0 + '@rollup/rollup-win32-ia32-msvc': 4.41.0 + '@rollup/rollup-win32-x64-msvc': 4.41.0 + fsevents: 2.3.3 + + run-applescript@7.0.0: {} + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + sade@1.8.1: + dependencies: + mri: 1.2.0 + + safe-buffer@5.1.2: {} + + safe-buffer@5.2.1: {} + + safe-regex-test@1.1.0: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-regex: 1.2.1 + + safe-stable-stringify@2.4.3: {} + + safe-stable-stringify@2.5.0: {} + + safer-buffer@2.1.2: {} + + scheduler@0.23.2: + dependencies: + loose-envify: 1.4.0 + + scrypt-js@3.0.1: {} + + scule@1.3.0: {} + + secp256k1@4.0.3: + dependencies: + elliptic: 6.6.1 + node-addon-api: 2.0.2 + node-gyp-build: 4.8.4 + + secure-json-parse@2.7.0: {} + + semver@5.7.1: {} + + semver@6.3.1: {} + + semver@7.5.4: + dependencies: + lru-cache: 6.0.0 + + semver@7.6.2: {} + + semver@7.7.2: {} + + send@1.2.0: + dependencies: + debug: 4.4.1 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 2.0.0 + http-errors: 2.0.0 + mime-types: 3.0.1 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.2.1 + statuses: 2.0.1 + transitivePeerDependencies: + - supports-color + + serialize-javascript@6.0.0: + dependencies: + randombytes: 2.1.0 + + serialize-javascript@6.0.2: + dependencies: + randombytes: 2.1.0 + + serve-placeholder@2.0.2: + dependencies: + defu: 6.1.4 + + serve-static@2.2.0: + dependencies: + encodeurl: 2.0.0 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 1.2.0 + transitivePeerDependencies: + - supports-color + + set-blocking@2.0.0: {} + + set-function-length@1.2.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.3.0 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + + setimmediate@1.0.5: {} + + setprototypeof@1.2.0: {} + + sha.js@2.4.11: + dependencies: + inherits: 2.0.4 + safe-buffer: 5.2.1 + + sharp@0.34.2: + dependencies: + color: 4.2.3 + detect-libc: 2.0.4 + semver: 7.7.2 + optionalDependencies: + '@img/sharp-darwin-arm64': 0.34.2 + '@img/sharp-darwin-x64': 0.34.2 + '@img/sharp-libvips-darwin-arm64': 1.1.0 + '@img/sharp-libvips-darwin-x64': 1.1.0 + '@img/sharp-libvips-linux-arm': 1.1.0 + '@img/sharp-libvips-linux-arm64': 1.1.0 + '@img/sharp-libvips-linux-ppc64': 1.1.0 + '@img/sharp-libvips-linux-s390x': 1.1.0 + '@img/sharp-libvips-linux-x64': 1.1.0 + '@img/sharp-libvips-linuxmusl-arm64': 1.1.0 + '@img/sharp-libvips-linuxmusl-x64': 1.1.0 + '@img/sharp-linux-arm': 0.34.2 + '@img/sharp-linux-arm64': 0.34.2 + '@img/sharp-linux-s390x': 0.34.2 + '@img/sharp-linux-x64': 0.34.2 + '@img/sharp-linuxmusl-arm64': 0.34.2 + '@img/sharp-linuxmusl-x64': 0.34.2 + '@img/sharp-wasm32': 0.34.2 + '@img/sharp-win32-arm64': 0.34.2 + '@img/sharp-win32-ia32': 0.34.2 + '@img/sharp-win32-x64': 0.34.2 + optional: true + + shebang-command@1.2.0: + dependencies: + shebang-regex: 1.0.0 + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@1.0.0: {} + + shebang-regex@3.0.0: {} + + shell-quote@1.8.2: {} + + sherif-darwin-arm64@1.0.0: + optional: true + + sherif-darwin-x64@1.0.0: + optional: true + + sherif-linux-arm64@1.0.0: + optional: true + + sherif-linux-x64@1.0.0: + optional: true + + sherif-windows-arm64@1.0.0: + optional: true + + sherif-windows-x64@1.0.0: + optional: true + + sherif@1.0.0: + optionalDependencies: + sherif-darwin-arm64: 1.0.0 + sherif-darwin-x64: 1.0.0 + sherif-linux-arm64: 1.0.0 + sherif-linux-x64: 1.0.0 + sherif-windows-arm64: 1.0.0 + sherif-windows-x64: 1.0.0 + + shiki@1.22.2: + dependencies: + '@shikijs/core': 1.22.2 + '@shikijs/engine-javascript': 1.22.2 + '@shikijs/engine-oniguruma': 1.22.2 + '@shikijs/types': 1.22.2 + '@shikijs/vscode-textmate': 9.3.0 + '@types/hast': 3.0.4 + + side-channel-list@1.0.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + + side-channel-map@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + + side-channel-weakmap@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + side-channel-map: 1.0.1 + + side-channel@1.1.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + side-channel-list: 1.0.0 + side-channel-map: 1.0.1 + side-channel-weakmap: 1.0.2 + + siginfo@2.0.0: {} + + signal-exit@3.0.7: {} + + signal-exit@4.1.0: {} + + simple-git-hooks@2.11.1: {} + + simple-git@3.27.0: + dependencies: + '@kwsites/file-exists': 1.1.1 + '@kwsites/promise-deferred': 1.1.1 + debug: 4.4.1 + transitivePeerDependencies: + - supports-color + + simple-swizzle@0.2.2: + dependencies: + is-arrayish: 0.3.2 + + sirv@2.0.4: + dependencies: + '@polka/url': 1.0.0-next.29 + mrmime: 2.0.1 + totalist: 3.0.1 + + sirv@3.0.1: + dependencies: + '@polka/url': 1.0.0-next.29 + mrmime: 2.0.1 + totalist: 3.0.1 + + sisteransi@1.0.5: {} + + skin-tone@2.0.0: + dependencies: + unicode-emoji-modifier-base: 1.0.0 + + slash@1.0.0: {} + + slash@3.0.0: {} + + slash@5.1.0: {} + + smob@1.5.0: {} + + smol-toml@1.3.0: {} + + socket.io-client@4.8.1(bufferutil@4.0.9)(utf-8-validate@5.0.10): + dependencies: + '@socket.io/component-emitter': 3.1.2 + debug: 4.3.7 + engine.io-client: 6.6.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) + socket.io-parser: 4.2.4 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + socket.io-parser@4.2.4: + dependencies: + '@socket.io/component-emitter': 3.1.2 + debug: 4.3.7 + transitivePeerDependencies: + - supports-color + + solc@0.7.3(debug@4.3.4): + dependencies: + command-exists: 1.2.9 + commander: 3.0.2 + follow-redirects: 1.15.2(debug@4.3.4) + fs-extra: 0.30.0 + js-sha3: 0.8.0 + memorystream: 0.3.1 + require-from-string: 2.0.2 + semver: 5.7.1 + tmp: 0.0.33 + transitivePeerDependencies: + - debug + + sonic-boom@2.8.0: + dependencies: + atomic-sleep: 1.0.0 + + sonic-boom@4.2.0: + dependencies: + atomic-sleep: 1.0.0 + + source-map-js@1.2.0: {} + + source-map-js@1.2.1: {} + + source-map-support@0.5.21: + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + + source-map@0.6.1: {} + + source-map@0.7.4: {} + + space-separated-tokens@2.0.2: {} + + spawndamnit@2.0.0: + dependencies: + cross-spawn: 5.1.0 + signal-exit: 3.0.7 + + spdx-correct@3.2.0: + dependencies: + spdx-expression-parse: 3.0.1 + spdx-license-ids: 3.0.21 + + spdx-exceptions@2.5.0: {} + + spdx-expression-parse@3.0.1: + dependencies: + spdx-exceptions: 2.5.0 + spdx-license-ids: 3.0.21 + + spdx-license-ids@3.0.21: {} + + speakingurl@14.0.1: {} + + split-on-first@1.1.0: {} + + split2@4.2.0: {} + + sprintf-js@1.0.3: {} + + stack-trace@0.0.10: {} + + stackback@0.0.2: {} + + stacktrace-parser@0.1.10: + dependencies: + type-fest: 0.7.1 + + standard-as-callback@2.1.0: {} + + statuses@2.0.1: {} + + std-env@3.7.0: {} + + std-env@3.9.0: {} + + stream-shift@1.0.1: {} + + streamsearch@1.1.0: {} + + streamx@2.22.0: + dependencies: + fast-fifo: 1.3.2 + text-decoder: 1.2.3 + optionalDependencies: + bare-events: 2.5.4 + + strict-event-emitter@0.5.1: {} + + strict-uri-encode@2.0.0: {} + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string-width@5.1.2: + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.1.0 + + string_decoder@1.1.1: + dependencies: + safe-buffer: 5.1.2 + + string_decoder@1.3.0: + dependencies: + safe-buffer: 5.2.1 + + stringify-entities@4.0.4: + dependencies: + character-entities-html4: 2.1.0 + character-entities-legacy: 3.0.0 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-ansi@7.1.0: + dependencies: + ansi-regex: 6.1.0 + + strip-bom@3.0.0: {} + + strip-final-newline@2.0.0: {} + + strip-final-newline@3.0.0: {} + + strip-final-newline@4.0.0: {} + + strip-hex-prefix@1.0.0: + dependencies: + is-hex-prefixed: 1.0.0 + + strip-json-comments@3.1.1: {} + + strip-json-comments@5.0.1: {} + + strip-literal@1.3.0: + dependencies: + acorn: 8.11.3 + + strip-literal@3.0.0: + dependencies: + js-tokens: 9.0.1 + + structured-clone-es@1.0.0: {} + + styled-jsx@5.1.6(react@18.3.1): + dependencies: + client-only: 0.0.1 + react: 18.3.1 + + stylehacks@7.0.5(postcss@8.5.3): + dependencies: + browserslist: 4.24.5 + postcss: 8.5.3 + postcss-selector-parser: 7.1.0 + + summary@2.1.0: {} + + superjson@2.2.1: + dependencies: + copy-anything: 3.0.5 + + superjson@2.2.2: + dependencies: + copy-anything: 3.0.5 + + superstruct@1.0.3: {} + + supports-color@10.0.0: {} + + supports-color@5.5.0: + dependencies: + has-flag: 3.0.0 + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + supports-color@8.1.1: + dependencies: + has-flag: 4.0.0 + + supports-color@9.4.0: {} + + supports-hyperlinks@3.0.0: + dependencies: + has-flag: 4.0.0 + supports-color: 7.2.0 + + supports-preserve-symlinks-flag@1.0.0: {} + + svgo@3.3.2: + dependencies: + '@trysound/sax': 0.2.0 + commander: 7.2.0 + css-select: 5.1.0 + css-tree: 2.3.1 + css-what: 6.1.0 + csso: 5.0.5 + picocolors: 1.1.1 + + system-architecture@0.1.0: {} + + tabbable@6.2.0: {} + + tapable@2.2.1: {} + + tapable@2.2.2: {} + + tar-stream@2.2.0: + dependencies: + bl: 4.1.0 + end-of-stream: 1.4.4 + fs-constants: 1.0.0 + inherits: 2.0.4 + readable-stream: 3.6.2 + + tar-stream@3.1.7: + dependencies: + b4a: 1.6.7 + fast-fifo: 1.3.2 + streamx: 2.22.0 + + tar@6.2.1: + dependencies: + chownr: 2.0.0 + fs-minipass: 2.1.0 + minipass: 5.0.0 + minizlib: 2.1.2 + mkdirp: 1.0.4 + yallist: 4.0.0 + + tar@7.2.0: + dependencies: + '@isaacs/fs-minipass': 4.0.1 + chownr: 3.0.0 + minipass: 7.1.2 + minizlib: 3.0.1 + mkdirp: 3.0.1 + yallist: 5.0.0 + + tar@7.4.3: + dependencies: + '@isaacs/fs-minipass': 4.0.1 + chownr: 3.0.0 + minipass: 7.1.2 + minizlib: 3.0.2 + mkdirp: 3.0.1 + yallist: 5.0.0 + + temp-dir@1.0.0: {} + + tempy@0.2.1: + dependencies: + temp-dir: 1.0.0 + unique-string: 1.0.0 + + term-size@2.2.1: {} + + terser@5.39.2: + dependencies: + '@jridgewell/source-map': 0.3.6 + acorn: 8.15.0 + commander: 2.20.3 + source-map-support: 0.5.21 + + test-exclude@7.0.1: + dependencies: + '@istanbuljs/schema': 0.1.3 + glob: 10.4.5 + minimatch: 9.0.4 + + text-decoder@1.2.3: + dependencies: + b4a: 1.6.7 + + text-hex@1.0.0: {} + + thenify-all@1.6.0: + dependencies: + thenify: 3.3.1 + + thenify@3.3.1: + dependencies: + any-promise: 1.3.0 + + thread-stream@0.15.2: + dependencies: + real-require: 0.1.0 + + tiny-invariant@1.3.3: {} + + tinybench@2.9.0: {} + + tinyexec@0.3.2: {} + + tinyexec@1.0.1: {} + + tinyglobby@0.2.12: + dependencies: + fdir: 6.4.4(picomatch@4.0.2) + picomatch: 4.0.2 + + tinyglobby@0.2.13: + dependencies: + fdir: 6.4.4(picomatch@4.0.2) + picomatch: 4.0.2 + + tinypool@1.0.2: {} + + tinyrainbow@1.2.0: {} + + tinyspy@3.0.2: {} + + tmp-promise@3.0.3: + dependencies: + tmp: 0.2.3 + + tmp@0.0.33: + dependencies: + os-tmpdir: 1.0.2 + + tmp@0.2.3: {} + + to-fast-properties@2.0.0: {} + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + toidentifier@1.0.1: {} + + toml@3.0.0: {} + + totalist@3.0.1: {} + + tough-cookie@4.1.4: + dependencies: + psl: 1.9.0 + punycode: 2.3.1 + universalify: 0.2.0 + url-parse: 1.5.10 + + tr46@0.0.3: {} + + trim-lines@3.0.1: {} + + triple-beam@1.4.1: {} + + tslib@1.14.1: {} + + tslib@2.8.1: {} + + tsort@0.0.1: {} + + tsutils@3.21.0(typescript@5.8.3): + dependencies: + tslib: 1.14.1 + typescript: 5.8.3 + + tweetnacl-util@0.15.1: {} + + tweetnacl@1.0.3: {} + + twoslash-protocol@0.2.12: {} + + twoslash-vue@0.2.12(typescript@5.8.3): + dependencies: + '@vue/language-core': 2.1.10(typescript@5.8.3) + twoslash: 0.2.12(typescript@5.8.3) + twoslash-protocol: 0.2.12 + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + + twoslash@0.2.12(typescript@5.8.3): + dependencies: + '@typescript/vfs': 1.6.0(typescript@5.8.3) + twoslash-protocol: 0.2.12 + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + + type-fest@0.20.2: {} + + type-fest@0.21.3: {} + + type-fest@0.7.1: {} + + type-fest@4.18.2: {} + + type-fest@4.41.0: {} + + typescript@5.6.1-rc: {} + + typescript@5.8.3: {} + + ufo@1.5.3: {} + + ufo@1.6.1: {} + + uint8arrays@3.1.0: + dependencies: + multiformats: 9.9.0 + + uint8arrays@3.1.1: + dependencies: + multiformats: 9.9.0 + + ultrahtml@1.6.0: {} + + unconfig@0.3.13: + dependencies: + '@antfu/utils': 0.7.7 + defu: 6.1.4 + jiti: 1.21.7 + + uncrypto@0.1.3: {} + + unctx@2.4.1: + dependencies: + acorn: 8.14.1 + estree-walker: 3.0.3 + magic-string: 0.30.17 + unplugin: 2.3.4 + + undici-types@5.26.5: {} + + undici-types@6.21.0: {} + + undici-types@7.8.0: {} + + undici@5.28.3: + dependencies: + '@fastify/busboy': 2.1.0 + + unenv@2.0.0-rc.17: + dependencies: + defu: 6.1.4 + exsolve: 1.0.5 + ohash: 2.0.11 + pathe: 2.0.3 + ufo: 1.6.1 + + unhead@2.0.9: + dependencies: + hookable: 5.5.3 + + unicode-emoji-modifier-base@1.0.0: {} + + unicorn-magic@0.1.0: {} + + unicorn-magic@0.3.0: {} + + unimport@3.7.1(rollup@4.41.0): + dependencies: + '@rollup/pluginutils': 5.1.0(rollup@4.41.0) + acorn: 8.11.3 + escape-string-regexp: 5.0.0 + estree-walker: 3.0.3 + fast-glob: 3.3.2 + local-pkg: 0.5.0 + magic-string: 0.30.10 + mlly: 1.7.0 + pathe: 1.1.2 + pkg-types: 1.1.0 + scule: 1.3.0 + strip-literal: 1.3.0 + unplugin: 1.10.1 + transitivePeerDependencies: + - rollup + + unimport@4.2.0: + dependencies: + acorn: 8.14.1 + escape-string-regexp: 5.0.0 + estree-walker: 3.0.3 + local-pkg: 1.1.1 + magic-string: 0.30.17 + mlly: 1.7.4 + pathe: 2.0.3 + picomatch: 4.0.2 + pkg-types: 2.1.0 + scule: 1.3.0 + strip-literal: 3.0.0 + tinyglobby: 0.2.13 + unplugin: 2.3.4 + unplugin-utils: 0.2.4 + + unimport@5.0.1: + dependencies: + acorn: 8.14.1 + escape-string-regexp: 5.0.0 + estree-walker: 3.0.3 + local-pkg: 1.1.1 + magic-string: 0.30.17 + mlly: 1.7.4 + pathe: 2.0.3 + picomatch: 4.0.2 + pkg-types: 2.1.0 + scule: 1.3.0 + strip-literal: 3.0.0 + tinyglobby: 0.2.13 + unplugin: 2.3.4 + unplugin-utils: 0.2.4 + + unique-string@1.0.0: + dependencies: + crypto-random-string: 1.0.0 + + unist-util-is@6.0.0: + dependencies: + '@types/unist': 3.0.2 + + unist-util-position@5.0.0: + dependencies: + '@types/unist': 3.0.2 + + unist-util-stringify-position@4.0.0: + dependencies: + '@types/unist': 3.0.2 + + unist-util-visit-parents@6.0.1: + dependencies: + '@types/unist': 3.0.2 + unist-util-is: 6.0.0 + + unist-util-visit@5.0.0: + dependencies: + '@types/unist': 3.0.2 + unist-util-is: 6.0.0 + unist-util-visit-parents: 6.0.1 + + universalify@0.1.2: {} + + universalify@0.2.0: {} + + unixify@1.0.0: + dependencies: + normalize-path: 2.1.1 + + unocss@0.59.4(rollup@4.41.0): + dependencies: + '@unocss/astro': 0.59.4(rollup@4.41.0) + '@unocss/cli': 0.59.4(rollup@4.41.0) + '@unocss/core': 0.59.4 + '@unocss/extractor-arbitrary-variants': 0.59.4 + '@unocss/postcss': 0.59.4 + '@unocss/preset-attributify': 0.59.4 + '@unocss/preset-icons': 0.59.4 + '@unocss/preset-mini': 0.59.4 + '@unocss/preset-tagify': 0.59.4 + '@unocss/preset-typography': 0.59.4 + '@unocss/preset-uno': 0.59.4 + '@unocss/preset-web-fonts': 0.59.4 + '@unocss/preset-wind': 0.59.4 + '@unocss/reset': 0.59.4 + '@unocss/transformer-attributify-jsx': 0.59.4 + '@unocss/transformer-attributify-jsx-babel': 0.59.4 + '@unocss/transformer-compile-class': 0.59.4 + '@unocss/transformer-directives': 0.59.4 + '@unocss/transformer-variant-group': 0.59.4 + '@unocss/vite': 0.59.4(rollup@4.41.0) + transitivePeerDependencies: + - rollup + - supports-color + + unpipe@1.0.0: {} + + unplugin-utils@0.2.4: + dependencies: + pathe: 2.0.3 + picomatch: 4.0.2 + + unplugin-vue-router@0.12.0(vue-router@4.5.1(vue@3.5.14(typescript@5.8.3)))(vue@3.5.14(typescript@5.8.3)): + dependencies: + '@babel/types': 7.27.1 + '@vue-macros/common': 1.16.1(vue@3.5.14(typescript@5.8.3)) + ast-walker-scope: 0.6.2 + chokidar: 4.0.3 + fast-glob: 3.3.3 + json5: 2.2.3 + local-pkg: 1.1.1 + magic-string: 0.30.17 + micromatch: 4.0.8 + mlly: 1.7.4 + pathe: 2.0.3 + scule: 1.3.0 + unplugin: 2.3.4 + unplugin-utils: 0.2.4 + yaml: 2.8.0 + optionalDependencies: + vue-router: 4.5.1(vue@3.5.14(typescript@5.8.3)) + transitivePeerDependencies: + - vue + + unplugin@1.10.1: + dependencies: + acorn: 8.11.3 + chokidar: 3.6.0 + webpack-sources: 3.2.3 + webpack-virtual-modules: 0.6.1 + + unplugin@1.16.1: + dependencies: + acorn: 8.15.0 + webpack-virtual-modules: 0.6.2 + + unplugin@2.3.4: + dependencies: + acorn: 8.14.1 + picomatch: 4.0.2 + webpack-virtual-modules: 0.6.2 + + unstorage@1.10.2(idb-keyval@6.2.1)(ioredis@5.6.1): + dependencies: + anymatch: 3.1.3 + chokidar: 3.6.0 + destr: 2.0.5 + h3: 1.15.3 + listhen: 1.7.2 + lru-cache: 10.2.2 + mri: 1.2.0 + node-fetch-native: 1.6.4 + ofetch: 1.4.1 + ufo: 1.6.1 + optionalDependencies: + idb-keyval: 6.2.1 + ioredis: 5.6.1 + transitivePeerDependencies: + - uWebSockets.js + + unstorage@1.16.0(db0@0.3.2)(idb-keyval@6.2.1)(ioredis@5.6.1): + dependencies: + anymatch: 3.1.3 + chokidar: 4.0.3 + destr: 2.0.5 + h3: 1.15.3 + lru-cache: 10.4.3 + node-fetch-native: 1.6.6 + ofetch: 1.4.1 + ufo: 1.6.1 + optionalDependencies: + db0: 0.3.2 + idb-keyval: 6.2.1 + ioredis: 5.6.1 + + untun@0.1.3: + dependencies: + citty: 0.1.6 + consola: 3.4.2 + pathe: 1.1.2 + + untyped@1.4.2: + dependencies: + '@babel/core': 7.24.5 + '@babel/standalone': 7.24.5 + '@babel/types': 7.24.5 + defu: 6.1.4 + jiti: 1.21.0 + mri: 1.2.0 + scule: 1.3.0 + transitivePeerDependencies: + - supports-color + + untyped@2.0.0: + dependencies: + citty: 0.1.6 + defu: 6.1.4 + jiti: 2.4.2 + knitwork: 1.2.0 + scule: 1.3.0 + + unwasm@0.3.9: + dependencies: + knitwork: 1.2.0 + magic-string: 0.30.17 + mlly: 1.7.4 + pathe: 1.1.2 + pkg-types: 1.3.1 + unplugin: 1.16.1 + + update-browserslist-db@1.0.15(browserslist@4.23.0): + dependencies: + browserslist: 4.23.0 + escalade: 3.2.0 + picocolors: 1.1.1 + + update-browserslist-db@1.1.3(browserslist@4.24.5): + dependencies: + browserslist: 4.24.5 + escalade: 3.2.0 + picocolors: 1.1.1 + + uqr@0.1.2: {} + + url-parse@1.5.10: + dependencies: + querystringify: 2.2.0 + requires-port: 1.0.0 + + urlpattern-polyfill@10.1.0: {} + + urlpattern-polyfill@8.0.2: {} + + use-sync-external-store@1.2.0(react@18.3.1): + dependencies: + react: 18.3.1 + + use-sync-external-store@1.4.0(react@18.3.1): + dependencies: + react: 18.3.1 + + utf-8-validate@5.0.10: + dependencies: + node-gyp-build: 4.8.4 + + utf-8-validate@6.0.5: + dependencies: + node-gyp-build: 4.8.4 + + util-deprecate@1.0.2: {} + + util@0.12.5: + dependencies: + inherits: 2.0.4 + is-arguments: 1.2.0 + is-generator-function: 1.1.0 + is-typed-array: 1.1.15 + which-typed-array: 1.1.19 + + uuid@11.1.0: {} + + uuid@8.3.2: {} + + uuid@9.0.1: {} + + validate-npm-package-license@3.0.4: + dependencies: + spdx-correct: 3.2.0 + spdx-expression-parse: 3.0.1 + + validate-npm-package-name@5.0.1: {} + + valtio@1.13.2(@types/react@18.3.1)(react@18.3.1): + dependencies: + derive-valtio: 0.1.0(valtio@1.13.2(@types/react@18.3.1)(react@18.3.1)) + proxy-compare: 2.6.0 + use-sync-external-store: 1.2.0(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.1 + react: 18.3.1 + + vfile-message@4.0.2: + dependencies: + '@types/unist': 3.0.2 + unist-util-stringify-position: 4.0.0 + + vfile@6.0.1: + dependencies: + '@types/unist': 3.0.2 + unist-util-stringify-position: 4.0.0 + vfile-message: 4.0.2 + + viem@2.10.8(bufferutil@4.0.8)(typescript@5.8.3)(utf-8-validate@6.0.5)(zod@3.25.20): + dependencies: + '@adraffy/ens-normalize': 1.10.0 + '@noble/curves': 1.2.0 + '@noble/hashes': 1.3.2 + '@scure/bip32': 1.3.2 + '@scure/bip39': 1.2.1 + abitype: 1.0.0(typescript@5.8.3)(zod@3.25.20) + isows: 1.0.4(ws@8.13.0(bufferutil@4.0.8)(utf-8-validate@6.0.5)) + ws: 8.13.0(bufferutil@4.0.8)(utf-8-validate@6.0.5) + optionalDependencies: + typescript: 5.8.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + - zod + + viem@2.10.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@6.0.5)(zod@3.25.20): + dependencies: + '@adraffy/ens-normalize': 1.10.0 + '@noble/curves': 1.2.0 + '@noble/hashes': 1.3.2 + '@scure/bip32': 1.3.2 + '@scure/bip39': 1.2.1 + abitype: 1.0.0(typescript@5.8.3)(zod@3.25.20) + isows: 1.0.4(ws@8.13.0(bufferutil@4.0.9)(utf-8-validate@6.0.5)) + ws: 8.13.0(bufferutil@4.0.9)(utf-8-validate@6.0.5) + optionalDependencies: + typescript: 5.8.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + - zod + + viem@2.17.0(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20): + dependencies: + '@adraffy/ens-normalize': 1.10.0 + '@noble/curves': 1.4.0 + '@noble/hashes': 1.4.0 + '@scure/bip32': 1.4.0 + '@scure/bip39': 1.3.0 + abitype: 1.0.5(typescript@5.8.3)(zod@3.25.20) + isows: 1.0.4(ws@8.17.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + ws: 8.17.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) + optionalDependencies: + typescript: 5.8.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + - zod + + viem@2.23.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20): + dependencies: + '@noble/curves': 1.8.1 + '@noble/hashes': 1.7.1 + '@scure/bip32': 1.6.2 + '@scure/bip39': 1.5.4 + abitype: 1.0.8(typescript@5.8.3)(zod@3.25.20) + isows: 1.0.6(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + ox: 0.6.7(typescript@5.8.3)(zod@3.25.20) + ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + optionalDependencies: + typescript: 5.8.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + - zod + + viem@2.29.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4): + dependencies: + '@noble/curves': 1.8.2 + '@noble/hashes': 1.7.2 + '@scure/bip32': 1.6.2 + '@scure/bip39': 1.5.4 + abitype: 1.0.8(typescript@5.8.3)(zod@3.22.4) + isows: 1.0.6(ws@8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + ox: 0.6.9(typescript@5.8.3)(zod@3.22.4) + ws: 8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) + optionalDependencies: + typescript: 5.8.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + - zod + + viem@2.29.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20): + dependencies: + '@noble/curves': 1.8.2 + '@noble/hashes': 1.7.2 + '@scure/bip32': 1.6.2 + '@scure/bip39': 1.5.4 + abitype: 1.0.8(typescript@5.8.3)(zod@3.25.20) + isows: 1.0.6(ws@8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + ox: 0.6.9(typescript@5.8.3)(zod@3.25.20) + ws: 8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) + optionalDependencies: + typescript: 5.8.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + - zod + + viem@2.29.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@6.0.5)(zod@3.25.20): + dependencies: + '@noble/curves': 1.8.2 + '@noble/hashes': 1.7.2 + '@scure/bip32': 1.6.2 + '@scure/bip39': 1.5.4 + abitype: 1.0.8(typescript@5.8.3)(zod@3.25.20) + isows: 1.0.6(ws@8.18.1(bufferutil@4.0.9)(utf-8-validate@6.0.5)) + ox: 0.6.9(typescript@5.8.3)(zod@3.25.20) + ws: 8.18.1(bufferutil@4.0.9)(utf-8-validate@6.0.5) + optionalDependencies: + typescript: 5.8.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + - zod + + vite-dev-rpc@1.0.7(vite@6.3.5(@types/node@24.0.1)(jiti@2.4.2)(terser@5.39.2)(yaml@2.8.0)): + dependencies: + birpc: 2.3.0 + vite: 6.3.5(@types/node@24.0.1)(jiti@2.4.2)(terser@5.39.2)(yaml@2.8.0) + vite-hot-client: 2.0.4(vite@6.3.5(@types/node@24.0.1)(jiti@2.4.2)(terser@5.39.2)(yaml@2.8.0)) + + vite-hot-client@2.0.4(vite@6.3.5(@types/node@24.0.1)(jiti@2.4.2)(terser@5.39.2)(yaml@2.8.0)): + dependencies: + vite: 6.3.5(@types/node@24.0.1)(jiti@2.4.2)(terser@5.39.2)(yaml@2.8.0) + + vite-node@2.1.9(@types/node@24.0.1)(terser@5.39.2): + dependencies: + cac: 6.7.14 + debug: 4.4.1 + es-module-lexer: 1.7.0 + pathe: 1.1.2 + vite: 5.4.19(@types/node@24.0.1)(terser@5.39.2) + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + + vite-node@3.1.4(@types/node@24.0.1)(terser@5.39.2): + dependencies: + cac: 6.7.14 + debug: 4.4.1 + es-module-lexer: 1.7.0 + pathe: 2.0.3 + vite: 5.4.19(@types/node@24.0.1)(terser@5.39.2) + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + + vite-plugin-checker@0.9.3(@biomejs/biome@1.9.4)(typescript@5.8.3)(vite@6.3.5(@types/node@24.0.1)(jiti@2.4.2)(terser@5.39.2)(yaml@2.8.0)): + dependencies: + '@babel/code-frame': 7.27.1 + chokidar: 4.0.3 + npm-run-path: 6.0.0 + picocolors: 1.1.1 + picomatch: 4.0.2 + strip-ansi: 7.1.0 + tiny-invariant: 1.3.3 + tinyglobby: 0.2.13 + vite: 6.3.5(@types/node@24.0.1)(jiti@2.4.2)(terser@5.39.2)(yaml@2.8.0) + vscode-uri: 3.1.0 + optionalDependencies: + '@biomejs/biome': 1.9.4 + typescript: 5.8.3 + + vite-plugin-inspect@11.1.0(@nuxt/kit@3.17.4(magicast@0.3.5))(vite@6.3.5(@types/node@24.0.1)(jiti@2.4.2)(terser@5.39.2)(yaml@2.8.0)): + dependencies: + ansis: 3.17.0 + debug: 4.4.1 + error-stack-parser-es: 1.0.5 + ohash: 2.0.11 + open: 10.1.2 + perfect-debounce: 1.0.0 + sirv: 3.0.1 + unplugin-utils: 0.2.4 + vite: 6.3.5(@types/node@24.0.1)(jiti@2.4.2)(terser@5.39.2)(yaml@2.8.0) + vite-dev-rpc: 1.0.7(vite@6.3.5(@types/node@24.0.1)(jiti@2.4.2)(terser@5.39.2)(yaml@2.8.0)) + optionalDependencies: + '@nuxt/kit': 3.17.4(magicast@0.3.5) + transitivePeerDependencies: + - supports-color + + vite-plugin-vue-tracer@0.1.3(vite@6.3.5(@types/node@24.0.1)(jiti@2.4.2)(terser@5.39.2)(yaml@2.8.0))(vue@3.5.14(typescript@5.8.3)): + dependencies: + estree-walker: 3.0.3 + exsolve: 1.0.5 + magic-string: 0.30.17 + pathe: 2.0.3 + source-map-js: 1.2.1 + vite: 6.3.5(@types/node@24.0.1)(jiti@2.4.2)(terser@5.39.2)(yaml@2.8.0) + vue: 3.5.14(typescript@5.8.3) + + vite@5.4.19(@types/node@24.0.1)(terser@5.39.2): + dependencies: + esbuild: 0.21.5 + postcss: 8.5.3 + rollup: 4.41.0 + optionalDependencies: + '@types/node': 24.0.1 + fsevents: 2.3.3 + terser: 5.39.2 + + vite@6.3.5(@types/node@24.0.1)(jiti@2.4.2)(terser@5.39.2)(yaml@2.8.0): + dependencies: + esbuild: 0.25.5 + fdir: 6.4.4(picomatch@4.0.2) + picomatch: 4.0.2 + postcss: 8.5.5 + rollup: 4.41.0 + tinyglobby: 0.2.13 + optionalDependencies: + '@types/node': 24.0.1 + fsevents: 2.3.3 + jiti: 2.4.2 + terser: 5.39.2 + yaml: 2.8.0 + + vitepress@1.5.0(@algolia/client-search@5.12.0)(@types/node@24.0.1)(@types/react@18.3.1)(change-case@5.4.4)(fuse.js@7.1.0)(idb-keyval@6.2.1)(jwt-decode@4.0.0)(postcss@8.5.5)(qrcode@1.5.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(terser@5.39.2)(typescript@5.8.3): + dependencies: + '@docsearch/css': 3.6.3 + '@docsearch/js': 3.6.3(@algolia/client-search@5.12.0)(@types/react@18.3.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@iconify-json/simple-icons': 1.2.10 + '@shikijs/core': 1.22.2 + '@shikijs/transformers': 1.22.2 + '@shikijs/types': 1.22.2 + '@types/markdown-it': 14.1.2 + '@vitejs/plugin-vue': 5.1.4(vite@5.4.19(@types/node@24.0.1)(terser@5.39.2))(vue@3.5.12(typescript@5.8.3)) + '@vue/devtools-api': 7.6.2 + '@vue/shared': 3.5.12 + '@vueuse/core': 11.2.0(vue@3.5.12(typescript@5.8.3)) + '@vueuse/integrations': 11.2.0(change-case@5.4.4)(focus-trap@7.6.0)(fuse.js@7.1.0)(idb-keyval@6.2.1)(jwt-decode@4.0.0)(qrcode@1.5.3)(vue@3.5.12(typescript@5.8.3)) + focus-trap: 7.6.0 + mark.js: 8.11.1 + minisearch: 7.1.0 + shiki: 1.22.2 + vite: 5.4.19(@types/node@24.0.1)(terser@5.39.2) + vue: 3.5.12(typescript@5.8.3) + optionalDependencies: + postcss: 8.5.5 + transitivePeerDependencies: + - '@algolia/client-search' + - '@types/node' + - '@types/react' + - '@vue/composition-api' + - async-validator + - axios + - change-case + - drauu + - fuse.js + - idb-keyval + - jwt-decode + - less + - lightningcss + - nprogress + - qrcode + - react + - react-dom + - sass + - sass-embedded + - search-insights + - sortablejs + - stylus + - sugarss + - terser + - typescript + - universal-cookie + + vitest@2.1.9(@types/node@24.0.1)(happy-dom@15.10.2)(msw@2.4.9(typescript@5.8.3))(terser@5.39.2): + dependencies: + '@vitest/expect': 2.1.9 + '@vitest/mocker': 2.1.9(msw@2.4.9(typescript@5.8.3))(vite@5.4.19(@types/node@24.0.1)(terser@5.39.2)) + '@vitest/pretty-format': 2.1.9 + '@vitest/runner': 2.1.9 + '@vitest/snapshot': 2.1.9 + '@vitest/spy': 2.1.9 + '@vitest/utils': 2.1.9 + chai: 5.2.0 + debug: 4.4.1 + expect-type: 1.2.1 + magic-string: 0.30.17 + pathe: 1.1.2 + std-env: 3.9.0 + tinybench: 2.9.0 + tinyexec: 0.3.2 + tinypool: 1.0.2 + tinyrainbow: 1.2.0 + vite: 5.4.19(@types/node@24.0.1)(terser@5.39.2) + vite-node: 2.1.9(@types/node@24.0.1)(terser@5.39.2) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/node': 24.0.1 + happy-dom: 15.10.2 + transitivePeerDependencies: + - less + - lightningcss + - msw + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + + vscode-uri@3.1.0: {} + + vue-bundle-renderer@2.1.1: + dependencies: + ufo: 1.6.1 + + vue-component-type-helpers@2.0.16: {} + + vue-demi@0.14.10(vue@3.4.27(typescript@5.8.3)): + dependencies: + vue: 3.4.27(typescript@5.8.3) + + vue-demi@0.14.10(vue@3.5.12(typescript@5.8.3)): + dependencies: + vue: 3.5.12(typescript@5.8.3) + + vue-devtools-stub@0.1.0: {} + + vue-resize@2.0.0-alpha.1(vue@3.5.12(typescript@5.8.3)): + dependencies: + vue: 3.5.12(typescript@5.8.3) + + vue-router@4.3.2(vue@3.4.27(typescript@5.8.3)): + dependencies: + '@vue/devtools-api': 6.6.1 + vue: 3.4.27(typescript@5.8.3) + + vue-router@4.5.1(vue@3.5.14(typescript@5.8.3)): + dependencies: + '@vue/devtools-api': 6.6.4 + vue: 3.5.14(typescript@5.8.3) + + vue-template-compiler@2.7.16: + dependencies: + de-indent: 1.0.2 + he: 1.2.0 + + vue-tsc@2.0.16(typescript@5.8.3): + dependencies: + '@volar/typescript': 2.2.1 + '@vue/language-core': 2.0.16(typescript@5.8.3) + semver: 7.5.4 + typescript: 5.8.3 + + vue@3.4.27(typescript@5.8.3): + dependencies: + '@vue/compiler-dom': 3.4.27 + '@vue/compiler-sfc': 3.4.27 + '@vue/runtime-dom': 3.4.27 + '@vue/server-renderer': 3.4.27(vue@3.4.27(typescript@5.8.3)) + '@vue/shared': 3.4.27 + optionalDependencies: + typescript: 5.8.3 + + vue@3.5.12(typescript@5.8.3): + dependencies: + '@vue/compiler-dom': 3.5.12 + '@vue/compiler-sfc': 3.5.12 + '@vue/runtime-dom': 3.5.12 + '@vue/server-renderer': 3.5.12(vue@3.5.12(typescript@5.8.3)) + '@vue/shared': 3.5.12 + optionalDependencies: + typescript: 5.8.3 + + vue@3.5.14(typescript@5.8.3): + dependencies: + '@vue/compiler-dom': 3.5.14 + '@vue/compiler-sfc': 3.5.14 + '@vue/runtime-dom': 3.5.14 + '@vue/server-renderer': 3.5.14(vue@3.5.14(typescript@5.8.3)) + '@vue/shared': 3.5.14 + optionalDependencies: + typescript: 5.8.3 + + wcwidth@1.0.1: + dependencies: + defaults: 1.0.4 + optional: true + + web-streams-polyfill@3.3.3: {} + + webextension-polyfill@0.10.0: {} + + webidl-conversions@3.0.1: {} + + webidl-conversions@7.0.0: {} + + webpack-bundle-analyzer@4.10.1(bufferutil@4.0.8)(utf-8-validate@6.0.5): + dependencies: + '@discoveryjs/json-ext': 0.5.7 + acorn: 8.15.0 + acorn-walk: 8.3.4 + commander: 7.2.0 + debounce: 1.2.1 + escape-string-regexp: 4.0.0 + gzip-size: 6.0.0 + html-escaper: 2.0.2 + is-plain-object: 5.0.0 + opener: 1.5.2 + picocolors: 1.1.1 + sirv: 2.0.4 + ws: 7.5.10(bufferutil@4.0.8)(utf-8-validate@6.0.5) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + webpack-sources@3.2.3: {} + + webpack-virtual-modules@0.6.1: {} + + webpack-virtual-modules@0.6.2: {} + + whatwg-mimetype@3.0.0: {} + + whatwg-url@5.0.0: + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + + which-module@2.0.0: {} + + which-typed-array@1.1.19: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.8 + call-bound: 1.0.4 + for-each: 0.3.5 + get-proto: 1.0.1 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + + which@1.3.1: + dependencies: + isexe: 2.0.0 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + which@5.0.0: + dependencies: + isexe: 3.1.1 + + why-is-node-running@2.3.0: + dependencies: + siginfo: 2.0.0 + stackback: 0.0.2 + + wide-align@1.1.5: + dependencies: + string-width: 4.2.3 + + widest-line@3.1.0: + dependencies: + string-width: 4.2.3 + + winston-transport@4.9.0: + dependencies: + logform: 2.7.0 + readable-stream: 3.6.2 + triple-beam: 1.4.1 + + winston@3.17.0: + dependencies: + '@colors/colors': 1.6.0 + '@dabh/diagnostics': 2.0.3 + async: 3.2.6 + is-stream: 2.0.1 + logform: 2.7.0 + one-time: 1.0.0 + readable-stream: 3.6.2 + safe-stable-stringify: 2.5.0 + stack-trace: 0.0.10 + triple-beam: 1.4.1 + winston-transport: 4.9.0 + + workerpool@6.2.1: {} + + wrap-ansi@6.2.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@8.1.0: + dependencies: + ansi-styles: 6.2.1 + string-width: 5.1.2 + strip-ansi: 7.1.0 + + wrappy@1.0.2: {} + + write-file-atomic@6.0.0: + dependencies: + imurmurhash: 0.1.4 + signal-exit: 4.1.0 + + ws@7.5.10(bufferutil@4.0.8)(utf-8-validate@6.0.5): + optionalDependencies: + bufferutil: 4.0.8 + utf-8-validate: 6.0.5 + + ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10): + optionalDependencies: + bufferutil: 4.0.9 + utf-8-validate: 5.0.10 + + ws@7.5.9(bufferutil@4.0.9)(utf-8-validate@5.0.10): + optionalDependencies: + bufferutil: 4.0.9 + utf-8-validate: 5.0.10 + + ws@8.13.0(bufferutil@4.0.8)(utf-8-validate@6.0.5): + optionalDependencies: + bufferutil: 4.0.8 + utf-8-validate: 6.0.5 + + ws@8.13.0(bufferutil@4.0.9)(utf-8-validate@6.0.5): + optionalDependencies: + bufferutil: 4.0.9 + utf-8-validate: 6.0.5 + + ws@8.17.1(bufferutil@4.0.9)(utf-8-validate@5.0.10): + optionalDependencies: + bufferutil: 4.0.9 + utf-8-validate: 5.0.10 + + ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10): + optionalDependencies: + bufferutil: 4.0.9 + utf-8-validate: 5.0.10 + + ws@8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10): + optionalDependencies: + bufferutil: 4.0.9 + utf-8-validate: 5.0.10 + + ws@8.18.1(bufferutil@4.0.9)(utf-8-validate@6.0.5): + optionalDependencies: + bufferutil: 4.0.9 + utf-8-validate: 6.0.5 + + ws@8.18.2(bufferutil@4.0.9)(utf-8-validate@6.0.5): + optionalDependencies: + bufferutil: 4.0.9 + utf-8-validate: 6.0.5 + + xmlhttprequest-ssl@2.1.2: {} + + xtend@4.0.2: {} + + y18n@4.0.3: {} + + y18n@5.0.8: {} + + yallist@2.1.2: {} + + yallist@3.1.1: {} + + yallist@4.0.0: {} + + yallist@5.0.0: {} + + yaml@2.8.0: {} + + yargs-parser@18.1.3: + dependencies: + camelcase: 5.3.1 + decamelize: 1.2.0 + + yargs-parser@20.2.4: {} + + yargs-parser@21.1.1: {} + + yargs-unparser@2.0.0: + dependencies: + camelcase: 6.3.0 + decamelize: 4.0.0 + flat: 5.0.2 + is-plain-obj: 2.1.0 + + yargs@15.4.1: + dependencies: + cliui: 6.0.0 + decamelize: 1.2.0 + find-up: 4.1.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + require-main-filename: 2.0.0 + set-blocking: 2.0.0 + string-width: 4.2.3 + which-module: 2.0.0 + y18n: 4.0.3 + yargs-parser: 18.1.3 + + yargs@16.2.0: + dependencies: + cliui: 7.0.4 + escalade: 3.2.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 20.2.4 + + yargs@17.7.2: + dependencies: + cliui: 8.0.1 + escalade: 3.2.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + + yauzl@2.10.0: + dependencies: + buffer-crc32: 0.2.13 + fd-slicer: 1.1.0 + + yocto-queue@0.1.0: {} + + yocto-queue@1.2.1: {} + + yoctocolors@2.0.2: {} + + youch-core@0.3.2: + dependencies: + '@poppinss/exception': 1.2.1 + error-stack-parser-es: 1.0.5 + + youch@4.1.0-beta.7: + dependencies: + '@poppinss/dumper': 0.6.3 + '@speed-highlight/core': 1.2.7 + cookie: 1.0.2 + youch-core: 0.3.2 + + zip-stream@4.1.1: + dependencies: + archiver-utils: 3.0.4 + compress-commons: 4.1.2 + readable-stream: 3.6.2 + + zip-stream@6.0.1: + dependencies: + archiver-utils: 5.0.2 + compress-commons: 6.0.2 + readable-stream: 4.7.0 + + zod-validation-error@3.2.0(zod@3.25.20): + dependencies: + zod: 3.25.20 + + zod@3.22.4: {} + + zod@3.25.20: {} + + zustand@5.0.0(@types/react@18.3.1)(react@18.3.1)(use-sync-external-store@1.4.0(react@18.3.1)): + optionalDependencies: + '@types/react': 18.3.1 + react: 18.3.1 + use-sync-external-store: 1.4.0(react@18.3.1) + + zwitch@2.0.4: {} diff --git a/wagmi-project/pnpm-workspace.yaml b/wagmi-project/pnpm-workspace.yaml new file mode 100644 index 000000000..b1f32102e --- /dev/null +++ b/wagmi-project/pnpm-workspace.yaml @@ -0,0 +1,19 @@ +packages: + - packages/* + - "!packages/register-tests" + - packages/cli/src/plugins/__fixtures__/hardhat + - packages/register-tests/* + - playgrounds/* + - site + +catalog: + "@tanstack/query-core": "5.49.1" + "@tanstack/react-query": "5.49.2" + "@tanstack/vue-query": "5.49.1" + "@testing-library/dom": "10.4.0" + "@testing-library/react": "16.0.1" + "@types/react": "18.3.1" + "@types/react-dom": "18.3.0" + react-dom: "18.3.1" + react: "18.3.1" + vue: "3.4.27" diff --git a/wagmi-project/scripts/formatPackageJson.ts b/wagmi-project/scripts/formatPackageJson.ts new file mode 100644 index 000000000..a4d5a13e3 --- /dev/null +++ b/wagmi-project/scripts/formatPackageJson.ts @@ -0,0 +1,36 @@ +import path from 'node:path' + +// Generates package.json files to be published to NPM with only the necessary fields. + +console.log('Formatting package.json files.') + +// Get all package.json files +const packagePaths = await Array.fromAsync( + new Bun.Glob('packages/**/package.json').scan(), +) + +let count = 0 +for (const packagePath of packagePaths) { + type Package = Record & { + name?: string | undefined + private?: boolean | undefined + } + const file = Bun.file(packagePath) + const packageJson = (await file.json()) as Package + + // Skip private packages + if (packageJson.private) continue + + count += 1 + console.log(`${packageJson.name} — ${path.dirname(packagePath)}`) + + await Bun.write( + `${packagePath}.tmp`, + `${JSON.stringify(packageJson, undefined, 2)}\n`, + ) + + const { devDependencies: _dD, scripts: _s, ...rest } = packageJson + await Bun.write(packagePath, `${JSON.stringify(rest, undefined, 2)}\n`) +} + +console.log(`Done. Formatted ${count} ${count === 1 ? 'file' : 'files'}.`) diff --git a/wagmi-project/scripts/generateProxyPackages.ts b/wagmi-project/scripts/generateProxyPackages.ts new file mode 100644 index 000000000..a53a7167b --- /dev/null +++ b/wagmi-project/scripts/generateProxyPackages.ts @@ -0,0 +1,57 @@ +import fs from 'node:fs/promises' +import path from 'node:path' + +// Generates proxy packages for package.json#exports. + +console.log('Generating proxy packages.') + +// Get all package.json files +const packagePaths = await Array.fromAsync( + new Bun.Glob('packages/**/package.json').scan(), +) + +let count = 0 +for (const packagePath of packagePaths) { + type Package = Record & { + name?: string | undefined + private?: boolean | undefined + exports?: + | Record + | undefined + } + const file = Bun.file(packagePath) + const packageJson = (await file.json()) as Package + + // Skip private packages + if (packageJson.private) continue + if (!packageJson.exports) continue + + count += 1 + console.log(`${packageJson.name} — ${path.dirname(packagePath)}`) + + const dir = path.resolve(path.dirname(packagePath)) + + for (const [key, exports] of Object.entries(packageJson.exports)) { + // Skip `package.json` export + if (/package\.json$/.test(key)) continue + if (key === '.') continue + if (typeof exports === 'string') continue + if (!exports.default) continue + + const proxyDir = path.resolve(dir, key) + await fs.mkdir(proxyDir, { recursive: true }) + + const types = path.relative(key, exports.types) + const main = path.relative(key, exports.default) + await Bun.write( + `${proxyDir}/package.json`, + `${JSON.stringify({ type: 'module', types, main }, undefined, 2)}\n`, + ) + } +} + +console.log( + `Done. Generated proxy packages for ${count} ${ + count === 1 ? 'package' : 'packages' + }.`, +) diff --git a/wagmi-project/scripts/preconstruct.ts b/wagmi-project/scripts/preconstruct.ts new file mode 100644 index 000000000..9580924f1 --- /dev/null +++ b/wagmi-project/scripts/preconstruct.ts @@ -0,0 +1,87 @@ +import fs from 'node:fs/promises' +import path from 'node:path' + +// Symlinks package sources to dist for local development + +console.log('Setting up packages for development.') + +// Get all package.json files +const packagePaths = await Array.fromAsync( + new Bun.Glob('**/package.json').scan(), +) + +let count = 0 +for (const packagePath of packagePaths) { + type Package = { + bin?: Record | undefined + exports?: + | Record + | undefined + name?: string | undefined + private?: boolean | undefined + } + const file = Bun.file(packagePath) + const packageJson = (await file.json()) as Package + + // Skip private packages + if (packageJson.private && packageJson.name !== '@wagmi/test') continue + if (!packageJson.exports) continue + if (packageJson.bin) continue + + count += 1 + console.log(`${packageJson.name} — ${path.dirname(packagePath)}`) + + const dir = path.resolve(path.dirname(packagePath)) + + // Empty dist directory + const dist = path.resolve(dir, 'dist') + let files: string[] = [] + try { + files = await fs.readdir(dist) + } catch { + await fs.mkdir(dist) + } + + const promises = [] + for (const file of files) { + promises.push( + fs.rm(path.join(dist, file), { recursive: true, force: true }), + ) + } + await Promise.all(promises) + + // Link exports to dist locations + for (const [key, exports] of Object.entries(packageJson.exports)) { + // Skip `package.json` exports + if (/package\.json$/.test(key)) continue + if (typeof exports === 'string') continue + + // Link exports to dist locations + for (const [type, value] of Object.entries(exports) as [ + type: 'types' | 'default', + value: string, + ][]) { + const srcDir = path.resolve( + dir, + path + .dirname(value) + .replace(`dist/${type === 'default' ? 'esm' : type}`, 'src'), + ) + let srcFileName: string + if (key === '.') srcFileName = 'index.ts' + else srcFileName = path.basename(`${key}.ts`) + const srcFilePath = path.resolve(srcDir, srcFileName) + + const distDir = path.resolve(dir, path.dirname(value)) + const distFileName = path.basename(value) + const distFilePath = path.resolve(distDir, distFileName) + + await fs.mkdir(distDir, { recursive: true }) + + // Symlink src to dist file + await fs.symlink(srcFilePath, distFilePath, 'file') + } + } +} + +console.log(`Done. Set up ${count} ${count === 1 ? 'package' : 'packages'}.`) diff --git a/wagmi-project/scripts/restorePackageJson.ts b/wagmi-project/scripts/restorePackageJson.ts new file mode 100644 index 000000000..c0019a340 --- /dev/null +++ b/wagmi-project/scripts/restorePackageJson.ts @@ -0,0 +1,29 @@ +import fs from 'node:fs/promises' +import path from 'node:path' + +// Restores package.json files from package.json.tmp files. + +console.log('Restoring package.json files.') + +// Get all package.json files +const packagePaths = await Array.fromAsync( + new Bun.Glob('packages/**/package.json.tmp').scan(), +) + +let count = 0 +for (const packagePath of packagePaths) { + type Package = { name?: string | undefined } & Record + const file = Bun.file(packagePath) + const packageJson = (await file.json()) as Package + + count += 1 + console.log(`${packageJson.name} — ${path.dirname(packagePath)}`) + + await Bun.write( + packagePath.replace('.tmp', ''), + `${JSON.stringify(packageJson, undefined, 2)}\n`, + ) + await fs.rm(packagePath) +} + +console.log(`Done. Restored ${count} ${count === 1 ? 'file' : 'files'}.`) diff --git a/wagmi-project/scripts/updateBlockExplorerPluginChains.ts b/wagmi-project/scripts/updateBlockExplorerPluginChains.ts new file mode 100644 index 000000000..d61790fd3 --- /dev/null +++ b/wagmi-project/scripts/updateBlockExplorerPluginChains.ts @@ -0,0 +1,53 @@ +// Fetches supported chains for Etherscan and Sourcify + +console.log('Updating block explorer plugins chains.') + +let count = 0 +{ + console.log('etherscan - https://api.etherscan.io/v2/chainlist') + const res = (await fetch('https://api.etherscan.io/v2/chainlist').then( + (res) => res.json(), + )) as { + totalcount: number + result: { + chainname: string + chainid: number + blockexplorer: string + apiurl: string + status: 0 | 1 + }[] + } + + let content = 'type ChainId =\n' + for (const chain of res.result) + content += ` | ${chain.chainid} // ${chain.chainname}\n` + + await writeContent('./packages/cli/src/plugins/etherscan.ts', content) + count += 1 +} + +{ + console.log('sourcify - https://sourcify.dev/server/chains') + const res = (await fetch('https://sourcify.dev/server/chains').then((res) => + res.json(), + )) as { + name: string + chainId: number + }[] + + let content = 'type ChainId =\n' + for (const chain of res) content += ` | ${chain.chainId} // ${chain.name}\n` + + await writeContent('./packages/cli/src/plugins/sourcify.ts', content) + count += 1 +} + +console.log(`Done. Updated chains for ${count} plugins.`) + +async function writeContent(pluginPath: string, content: string) { + const file = Bun.file(pluginPath) + const text = await file + .text() + .then((text) => text.replace(/type ChainId =[\s\S]*$/, content)) + await Bun.write(pluginPath, text) +} diff --git a/wagmi-project/scripts/updateVersion.ts b/wagmi-project/scripts/updateVersion.ts new file mode 100644 index 000000000..4ec949cc1 --- /dev/null +++ b/wagmi-project/scripts/updateVersion.ts @@ -0,0 +1,43 @@ +import path from 'node:path' + +// Updates package version.ts files (so you can use the version in code without importing package.json). + +console.log('Updating version files.') + +// Get all package.json files +const packagePaths = await Array.fromAsync( + new Bun.Glob('**/package.json').scan(), +) + +let count = 0 +for (const packagePath of packagePaths) { + type Package = { + name?: string | undefined + private?: boolean | undefined + version?: string | undefined + } + const file = Bun.file(packagePath) + const packageJson = (await file.json()) as Package + + // Skip private packages + if (packageJson.private) continue + + count += 1 + console.log(`${packageJson.name} — ${packageJson.version}`) + + const versionFilePath = path.resolve( + path.dirname(packagePath), + 'src', + 'version.ts', + ) + await Bun.write( + versionFilePath, + `export const version = '${packageJson.version}'\n`, + ) +} + +console.log( + `Done. Updated version file for ${count} ${ + count === 1 ? 'package' : 'packages' + }.`, +) diff --git a/wagmi-project/scripts/updateViemVersion.ts b/wagmi-project/scripts/updateViemVersion.ts new file mode 100644 index 000000000..5731394ba --- /dev/null +++ b/wagmi-project/scripts/updateViemVersion.ts @@ -0,0 +1,44 @@ +// Updates viem version in Vitest snapshots, etc. + +console.log('Updating Viem version.') + +const file = Bun.file('package.json') +const packageJson = await file.json() +const viemVersion = packageJson.devDependencies.viem + +// Update Vitest snapshots +// Get all *.test.ts files +const testPaths = await Array.fromAsync( + new Bun.Glob('packages/**/*.test.ts').scan(), +) + +let count = 0 +for (const testPath of testPaths) { + const file = Bun.file(testPath) + const testFile = await file.text() + + // Skip files that don't contain viem version + if (!testFile.includes('Version: viem@')) continue + // Skip files that contain current version + if (testFile.includes(`Version: viem@${viemVersion}`)) continue + + console.log(testPath) + const updatedTestFile = testFile.replace( + /Version: viem@[A-Za-z0-9\-\.]+/g, + `Version: viem@${viemVersion}`, + ) + await Bun.write(testPath, updatedTestFile) + + count += 1 +} + +// // Update package.json#pnpm.overrides.viem +// if (packageJson.pnpm?.overrides?.viem !== viemVersion) { +// const path = 'package.json' +// console.log(path) +// packageJson.pnpm.overrides.viem = viemVersion +// await Bun.write(path, `${JSON.stringify(packageJson, undefined, 2)}\n`) +// count += 1 +// } + +console.log(`Done. Updated ${count} ${count === 1 ? 'file' : 'files'}.`) diff --git a/wagmi-project/site/.vitepress/config.ts b/wagmi-project/site/.vitepress/config.ts new file mode 100644 index 000000000..77f242cb0 --- /dev/null +++ b/wagmi-project/site/.vitepress/config.ts @@ -0,0 +1,151 @@ +import { + defaultHoverInfoProcessor, + transformerTwoslash, +} from '@shikijs/vitepress-twoslash' +import { presetAttributify, presetIcons, presetUno } from 'unocss' +import Unocss from 'unocss/vite' +import { defineConfig } from 'vitepress' + +import { farcasterIcon } from './constants' +import { getSidebar } from './sidebar' + +// https://vitepress.dev/reference/site-config +export default defineConfig({ + cleanUrls: true, + description: 'Reactivity for Ethereum apps', + head: [ + [ + 'meta', + { + name: 'keywords', + content: 'react, ethereum, typescript, react, react hooks, open source', + }, + ], + ['link', { rel: 'icon', href: '/favicon.svg' }], + ['meta', { name: 'theme-color', content: '#646cff' }], + // Open Graph + ['meta', { property: 'og:type', content: 'website' }], + ['meta', { property: 'og:image', content: 'https://wagmi.sh/og.png' }], + ['meta', { property: 'og:url', content: 'https://wagmi.sh' }], + // Twitter + ['meta', { name: 'twitter:card', content: 'summary_large_image' }], + ['meta', { name: 'twitter:creator', content: '@wevm_dev' }], + ['meta', { name: 'twitter:image', content: 'https://wagmi.sh/og.png' }], + ['meta', { name: 'twitter:site', content: 'wagmi.sh' }], + // Fathom + [ + 'script', + { + src: 'https://cdn.usefathom.com/script.js', + 'data-site': 'QWAXSUPT', + defer: '', + }, + ], + ], + ignoreDeadLinks: false, + lang: 'en-US', + lastUpdated: true, + markdown: { + codeTransformers: [ + transformerTwoslash({ + processHoverInfo(info) { + return ( + defaultHoverInfoProcessor(info) + // Remove shiki_core namespace + .replace(/_shikijs_core[\w_]*\./g, '') + ) + }, + }), + ], + theme: { + light: 'vitesse-light', + dark: 'vitesse-dark', + }, + }, + themeConfig: { + editLink: { + pattern: 'https://github.com/wevm/wagmi/edit/main/site/:path', + text: 'Suggest changes to this page', + }, + footer: { + message: + 'Released under the MIT License.', + copyright: 'Copyright © 2022-present Weth, LLC', + }, + logo: { + light: '/logo-light.svg', + dark: '/logo-dark.svg', + alt: 'wagmi logo', + }, + nav: [ + { text: 'React', link: '/react/getting-started' }, + { text: 'Vue', link: '/vue/getting-started' }, + { text: 'Core', link: '/core/getting-started' }, + { text: 'CLI', link: '/cli/getting-started' }, + // { text: 'Examples', link: '/examples/connect-wallet' }, + { + text: 'More', + items: [ + { + text: 'Discussions ', + link: 'https://github.com/wevm/wagmi/discussions', + }, + { + text: 'Release Notes ', + link: 'https://github.com/wevm/wagmi/releases', + }, + { + text: 'Contributing ', + link: '/dev/contributing', + }, + ], + }, + ], + outline: [2, 3], + search: { + provider: 'local', + options: { + _render(src, env, md) { + const html = md.render(src, env) + if (env.frontmatter?.search === false) return '' + if (env.relativePath.startsWith('shared')) return '' + return html + }, + }, + }, + sidebar: getSidebar(), + siteTitle: false, + socialLinks: [ + { + icon: 'github', + link: 'https://github.com/wevm/wagmi', + }, + { icon: 'bluesky', link: 'https://bsky.app/profile/wevm.dev' }, + { icon: 'x', link: 'https://twitter.com/wevm_dev' }, + { icon: { svg: farcasterIcon }, link: 'https://warpcast.com/wevm' }, + { icon: 'discord', link: 'https://discord.gg/9zHPXuBpqy' }, + ], + }, + title: 'Wagmi', + vite: { + plugins: [ + Unocss({ + shortcuts: [ + [ + 'btn', + 'px-4 py-1 rounded inline-flex justify-center gap-2 text-white leading-30px children:mya !no-underline cursor-pointer disabled:cursor-default disabled:bg-gray-600 disabled:opacity-50', + ], + ], + presets: [ + presetUno({ + dark: 'media', + }), + presetAttributify(), + presetIcons({ + scale: 1.2, + }), + ], + }), + ], + }, +}) diff --git a/wagmi-project/site/.vitepress/constants.ts b/wagmi-project/site/.vitepress/constants.ts new file mode 100644 index 000000000..981f8df3e --- /dev/null +++ b/wagmi-project/site/.vitepress/constants.ts @@ -0,0 +1,2 @@ +export const farcasterIcon = + '' diff --git a/wagmi-project/site/.vitepress/sidebar.ts b/wagmi-project/site/.vitepress/sidebar.ts new file mode 100644 index 000000000..29ea14bc5 --- /dev/null +++ b/wagmi-project/site/.vitepress/sidebar.ts @@ -0,0 +1,1085 @@ +import type { DefaultTheme } from 'vitepress' + +export function getSidebar() { + return { + '/react': [ + { + text: 'Introduction', + items: [ + { text: 'Why Wagmi', link: '/react/why' }, + { text: 'Installation', link: '/react/installation' }, + { text: 'Getting Started', link: '/react/getting-started' }, + { text: 'TypeScript', link: '/react/typescript' }, + { text: 'Comparisons', link: '/react/comparisons' }, + ], + }, + { + text: 'Guides', + items: [ + { + text: 'TanStack Query', + link: '/react/guides/tanstack-query', + }, + { + text: 'Viem', + link: '/react/guides/viem', + }, + { + text: 'Error Handling', + link: '/react/guides/error-handling', + }, + { + text: 'Ethers.js Adapters', + link: '/react/guides/ethers', + }, + // { + // text: 'Testing', + // link: '/react/guides/testing', + // }, + { + text: 'Chain Properties', + link: '/react/guides/chain-properties', + }, + { + text: 'SSR', + link: '/react/guides/ssr', + }, + { + text: 'Connect Wallet', + link: '/react/guides/connect-wallet', + }, + { + text: 'Send Transaction', + link: '/react/guides/send-transaction', + }, + { + text: 'Read from Contract', + link: '/react/guides/read-from-contract', + }, + { + text: 'Write to Contract', + link: '/react/guides/write-to-contract', + }, + { + text: 'FAQ / Troubleshooting', + link: '/react/guides/faq', + }, + { + text: 'Migrate from v1 to v2', + link: '/react/guides/migrate-from-v1-to-v2', + }, + ], + }, + { + text: 'Configuration', + items: [ + { text: 'createConfig', link: '/react/api/createConfig' }, + { text: 'createStorage', link: '/react/api/createStorage' }, + { text: 'Chains', link: '/react/api/chains' }, + { + text: 'Connectors', + collapsed: true, + link: '/react/api/connectors', + items: [ + { + text: 'coinbaseWallet', + link: '/react/api/connectors/coinbaseWallet', + }, + { text: 'injected', link: '/react/api/connectors/injected' }, + { + text: 'metaMask', + link: '/react/api/connectors/metaMask', + }, + { + text: 'mock', + link: '/react/api/connectors/mock', + }, + { + text: 'safe', + link: '/react/api/connectors/safe', + }, + { + text: 'walletConnect', + link: '/react/api/connectors/walletConnect', + }, + ], + }, + { + text: 'Transports', + collapsed: true, + link: '/react/api/transports', + items: [ + { + text: 'custom (EIP-1193)', + link: '/react/api/transports/custom', + }, + { + text: 'fallback', + link: '/react/api/transports/fallback', + }, + { + text: 'http', + link: '/react/api/transports/http', + }, + { + text: 'unstable_connector', + link: '/react/api/transports/unstable_connector', + }, + { + text: 'webSocket', + link: '/react/api/transports/webSocket', + }, + ], + }, + { text: 'WagmiProvider', link: '/react/api/WagmiProvider' }, + ], + }, + { + text: 'Hooks', + link: '/react/api/hooks', + items: [ + { text: 'useAccount', link: '/react/api/hooks/useAccount' }, + { + text: 'useAccountEffect', + link: '/react/api/hooks/useAccountEffect', + }, + { text: 'useBalance', link: '/react/api/hooks/useBalance' }, + { + text: 'useBlockNumber', + link: '/react/api/hooks/useBlockNumber', + }, + { + text: 'useBlock', + link: '/react/api/hooks/useBlock', + }, + { + text: 'useBlockTransactionCount', + link: '/react/api/hooks/useBlockTransactionCount', + }, + { + text: 'useBytecode', + link: '/react/api/hooks/useBytecode', + }, + { text: 'useCall', link: '/react/api/hooks/useCall' }, + { + text: 'useCallsStatus', + link: '/react/api/hooks/useCallsStatus', + }, + { + text: 'useCapabilities', + link: '/react/api/hooks/useCapabilities', + }, + { text: 'useChainId', link: '/react/api/hooks/useChainId' }, + { text: 'useChains', link: '/react/api/hooks/useChains' }, + { text: 'useClient', link: '/react/api/hooks/useClient' }, + { text: 'useConfig', link: '/react/api/hooks/useConfig' }, + { text: 'useConnect', link: '/react/api/hooks/useConnect' }, + { + text: 'useConnections', + link: '/react/api/hooks/useConnections', + }, + { + text: 'useConnectorClient', + link: '/react/api/hooks/useConnectorClient', + }, + { + text: 'useConnectors', + link: '/react/api/hooks/useConnectors', + }, + { + text: 'useDeployContract', + link: '/react/api/hooks/useDeployContract', + }, + { text: 'useDisconnect', link: '/react/api/hooks/useDisconnect' }, + { text: 'useEnsAddress', link: '/react/api/hooks/useEnsAddress' }, + { text: 'useEnsAvatar', link: '/react/api/hooks/useEnsAvatar' }, + { text: 'useEnsName', link: '/react/api/hooks/useEnsName' }, + { + text: 'useEnsResolver', + link: '/react/api/hooks/useEnsResolver', + }, + { + text: 'useEnsText', + link: '/react/api/hooks/useEnsText', + }, + { + text: 'useFeeHistory', + link: '/react/api/hooks/useFeeHistory', + }, + { + text: 'useProof', + link: '/react/api/hooks/useProof', + }, + { + text: 'usePublicClient', + link: '/react/api/hooks/usePublicClient', + }, + { + text: 'useEstimateFeesPerGas', + link: '/react/api/hooks/useEstimateFeesPerGas', + }, + { + text: 'useEstimateGas', + link: '/react/api/hooks/useEstimateGas', + }, + { + text: 'useEstimateMaxPriorityFeePerGas', + link: '/react/api/hooks/useEstimateMaxPriorityFeePerGas', + }, + { + text: 'useGasPrice', + link: '/react/api/hooks/useGasPrice', + }, + { + text: 'useInfiniteReadContracts', + link: '/react/api/hooks/useInfiniteReadContracts', + }, + { + text: 'usePrepareTransactionRequest', + link: '/react/api/hooks/usePrepareTransactionRequest', + }, + { + text: 'useReadContract', + link: '/react/api/hooks/useReadContract', + }, + { + text: 'useReadContracts', + link: '/react/api/hooks/useReadContracts', + }, + { text: 'useReconnect', link: '/react/api/hooks/useReconnect' }, + { + text: 'useSendCalls', + link: '/react/api/hooks/useSendCalls', + }, + { + text: 'useSendTransaction', + link: '/react/api/hooks/useSendTransaction', + }, + { + text: 'useShowCallsStatus', + link: '/react/api/hooks/useShowCallsStatus', + }, + { + text: 'useSignMessage', + link: '/react/api/hooks/useSignMessage', + }, + { + text: 'useSignTypedData', + link: '/react/api/hooks/useSignTypedData', + }, + { + text: 'useSimulateContract', + link: '/react/api/hooks/useSimulateContract', + }, + { + text: 'useStorageAt', + link: '/react/api/hooks/useStorageAt', + }, + { + text: 'useSwitchAccount', + link: '/react/api/hooks/useSwitchAccount', + }, + { + text: 'useSwitchChain', + link: '/react/api/hooks/useSwitchChain', + }, + { + text: 'useTransaction', + link: '/react/api/hooks/useTransaction', + }, + { + text: 'useTransactionConfirmations', + link: '/react/api/hooks/useTransactionConfirmations', + }, + { + text: 'useTransactionCount', + link: '/react/api/hooks/useTransactionCount', + }, + { + text: 'useTransactionReceipt', + link: '/react/api/hooks/useTransactionReceipt', + }, + { + text: 'useToken', + link: '/react/api/hooks/useToken', + }, + { + text: 'useWaitForCallsStatus', + link: '/react/api/hooks/useWaitForCallsStatus', + }, + { + text: 'useWaitForTransactionReceipt', + link: '/react/api/hooks/useWaitForTransactionReceipt', + }, + { + text: 'useVerifyMessage', + link: '/react/api/hooks/useVerifyMessage', + }, + { + text: 'useVerifyTypedData', + link: '/react/api/hooks/useVerifyTypedData', + }, + { + text: 'useWalletClient', + link: '/react/api/hooks/useWalletClient', + }, + { + text: 'useWatchAsset', + link: '/react/api/hooks/useWatchAsset', + }, + { + text: 'useWatchBlocks', + link: '/react/api/hooks/useWatchBlocks', + }, + { + text: 'useWatchBlockNumber', + link: '/react/api/hooks/useWatchBlockNumber', + }, + { + text: 'useWatchContractEvent', + link: '/react/api/hooks/useWatchContractEvent', + }, + { + text: 'useWatchPendingTransactions', + link: '/react/api/hooks/useWatchPendingTransactions', + }, + { + text: 'useWriteContract', + link: '/react/api/hooks/useWriteContract', + }, + ], + }, + { + text: 'Miscellaneous', + items: [ + { text: 'Actions', link: '/react/api/actions' }, + { text: 'Errors', link: '/react/api/errors' }, + { + text: 'Utilities', + collapsed: true, + items: [ + { + text: 'cookieToInitialState', + link: '/react/api/utilities/cookieToInitialState', + }, + { text: 'deserialize', link: '/react/api/utilities/deserialize' }, + { + text: 'normalizeChainId', + link: '/react/api/utilities/normalizeChainId', + }, + { text: 'serialize', link: '/react/api/utilities/serialize' }, + ], + }, + ], + }, + ], + '/vue': [ + { + text: 'Introduction', + items: [ + { text: 'Why Wagmi', link: '/vue/why' }, + { text: 'Installation', link: '/vue/installation' }, + { text: 'Getting Started', link: '/vue/getting-started' }, + { text: 'TypeScript', link: '/vue/typescript' }, + ], + }, + { + text: 'Guides', + items: [ + { + text: 'TanStack Query', + link: '/vue/guides/tanstack-query', + }, + { + text: 'Viem', + link: '/vue/guides/viem', + }, + { + text: 'Error Handling', + link: '/vue/guides/error-handling', + }, + { + text: 'Chain Properties', + link: '/vue/guides/chain-properties', + }, + { + text: 'SSR', + link: '/vue/guides/ssr', + }, + { + text: 'Connect Wallet', + link: '/vue/guides/connect-wallet', + }, + { + text: 'Send Transaction', + link: '/vue/guides/send-transaction', + }, + { + text: 'Read from Contract', + link: '/vue/guides/read-from-contract', + }, + { + text: 'Write to Contract', + link: '/vue/guides/write-to-contract', + }, + { + text: 'FAQ / Troubleshooting', + link: '/vue/guides/faq', + }, + ], + }, + { + text: 'Configuration', + items: [ + { text: 'createConfig', link: '/vue/api/createConfig' }, + { text: 'createStorage', link: '/vue/api/createStorage' }, + { text: 'Chains', link: '/vue/api/chains' }, + { + text: 'Connectors', + collapsed: true, + link: '/vue/api/connectors', + items: [ + { + text: 'coinbaseWallet', + link: '/vue/api/connectors/coinbaseWallet', + }, + { text: 'injected', link: '/vue/api/connectors/injected' }, + { + text: 'metaMask', + link: '/vue/api/connectors/metaMask', + }, + { + text: 'mock', + link: '/vue/api/connectors/mock', + }, + { + text: 'safe', + link: '/vue/api/connectors/safe', + }, + { + text: 'walletConnect', + link: '/vue/api/connectors/walletConnect', + }, + ], + }, + { + text: 'Transports', + collapsed: true, + link: '/vue/api/transports', + items: [ + { + text: 'custom (EIP-1193)', + link: '/vue/api/transports/custom', + }, + { + text: 'fallback', + link: '/vue/api/transports/fallback', + }, + { + text: 'http', + link: '/vue/api/transports/http', + }, + { + text: 'unstable_connector', + link: '/vue/api/transports/unstable_connector', + }, + { + text: 'webSocket', + link: '/vue/api/transports/webSocket', + }, + ], + }, + { text: 'WagmiPlugin', link: '/vue/api/WagmiPlugin' }, + { text: 'Nuxt', link: '/vue/api/Nuxt' }, + ], + }, + { + text: 'Composables', + link: '/vue/api/composables', + items: [ + { text: 'useAccount', link: '/vue/api/composables/useAccount' }, + { + text: 'useAccountEffect', + link: '/vue/api/composables/useAccountEffect', + }, + { + text: 'useBalance', + link: '/vue/api/composables/useBalance', + }, + { + text: 'useBlockNumber', + link: '/vue/api/composables/useBlockNumber', + }, + { + text: 'useBytecode', + link: '/vue/api/composables/useBytecode', + }, + { text: 'useChainId', link: '/vue/api/composables/useChainId' }, + { text: 'useChains', link: '/vue/api/composables/useChains' }, + { text: 'useClient', link: '/vue/api/composables/useClient' }, + { text: 'useConfig', link: '/vue/api/composables/useConfig' }, + { text: 'useConnect', link: '/vue/api/composables/useConnect' }, + { + text: 'useConnections', + link: '/vue/api/composables/useConnections', + }, + { + text: 'useConnectorClient', + link: '/vue/api/composables/useConnectorClient', + }, + { + text: 'useConnectors', + link: '/vue/api/composables/useConnectors', + }, + { + text: 'useDisconnect', + link: '/vue/api/composables/useDisconnect', + }, + { + text: 'useEnsAddress', + link: '/vue/api/composables/useEnsAddress', + }, + { + text: 'useEnsAvatar', + link: '/vue/api/composables/useEnsAvatar', + }, + { + text: 'useEstimateGas', + link: '/vue/api/composables/useEstimateGas', + }, + { + text: 'useReadContract', + link: '/vue/api/composables/useReadContract', + }, + { + text: 'useReconnect', + link: '/vue/api/composables/useReconnect', + }, + { + text: 'useSendTransaction', + link: '/vue/api/composables/useSendTransaction', + }, + { + text: 'useSignMessage', + link: '/vue/api/composables/useSignMessage', + }, + { + text: 'useSignTypedData', + link: '/vue/api/composables/useSignTypedData', + }, + { + text: 'useSimulateContract', + link: '/vue/api/composables/useSimulateContract', + }, + { + text: 'useSwitchAccount', + link: '/vue/api/composables/useSwitchAccount', + }, + { + text: 'useSwitchChain', + link: '/vue/api/composables/useSwitchChain', + }, + { + text: 'useTransaction', + link: '/vue/api/composables/useTransaction', + }, + { + text: 'useTransactionReceipt', + link: '/vue/api/composables/useTransactionReceipt', + }, + { + text: 'useWaitForTransactionReceipt', + link: '/vue/api/composables/useWaitForTransactionReceipt', + }, + { + text: 'useWatchBlockNumber', + link: '/vue/api/composables/useWatchBlockNumber', + }, + { + text: 'useWatchContractEvent', + link: '/vue/api/composables/useWatchContractEvent', + }, + { + text: 'useWriteContract', + link: '/vue/api/composables/useWriteContract', + }, + ], + }, + { + text: 'Miscellaneous', + items: [ + { text: 'Actions', link: '/vue/api/actions' }, + { text: 'Errors', link: '/vue/api/errors' }, + { + text: 'Utilities', + collapsed: true, + items: [ + { + text: 'deserialize', + link: '/vue/api/utilities/deserialize', + }, + { text: 'serialize', link: '/vue/api/utilities/serialize' }, + ], + }, + ], + }, + ], + '/core': [ + { + text: 'Introduction', + items: [ + { text: 'Why Wagmi', link: '/core/why' }, + { text: 'Installation', link: '/core/installation' }, + { text: 'Getting Started', link: '/core/getting-started' }, + { text: 'TypeScript', link: '/core/typescript' }, + ], + }, + { + text: 'Guides', + items: [ + { + text: 'Viem', + link: '/core/guides/viem', + }, + { + text: 'Framework Adapters', + link: '/core/guides/framework-adapters', + }, + { + text: 'Error Handling', + link: '/core/guides/error-handling', + }, + { + text: 'Ethers.js Adapters', + link: '/core/guides/ethers', + }, + // { + // text: 'Testing', + // link: '/core/guides/testing', + // }, + { + text: 'Chain Properties', + link: '/core/guides/chain-properties', + }, + { + text: 'FAQ / Troubleshooting', + link: '/core/guides/faq', + }, + { + text: 'Migrate from v1 to v2', + link: '/core/guides/migrate-from-v1-to-v2', + }, + ], + }, + { + text: 'Configuration', + items: [ + { text: 'createConfig', link: '/core/api/createConfig' }, + { text: 'createConnector', link: '/core/api/createConnector' }, + { text: 'createStorage', link: '/core/api/createStorage' }, + { text: 'Chains', link: '/core/api/chains' }, + { + text: 'Connectors', + collapsed: true, + link: '/core/api/connectors', + items: [ + { + text: 'coinbaseWallet', + link: '/core/api/connectors/coinbaseWallet', + }, + { text: 'injected', link: '/core/api/connectors/injected' }, + { + text: 'metaMask', + link: '/core/api/connectors/metaMask', + }, + { + text: 'mock', + link: '/core/api/connectors/mock', + }, + { + text: 'safe', + link: '/core/api/connectors/safe', + }, + { + text: 'walletConnect', + link: '/core/api/connectors/walletConnect', + }, + ], + }, + { + text: 'Transports', + collapsed: true, + link: '/core/api/transports', + items: [ + { + text: 'custom (EIP-1193)', + link: '/core/api/transports/custom', + }, + { + text: 'fallback', + link: '/core/api/transports/fallback', + }, + { + text: 'http', + link: '/core/api/transports/http', + }, + { + text: 'unstable_connector', + link: '/core/api/transports/unstable_connector', + }, + { + text: 'webSocket', + link: '/core/api/transports/webSocket', + }, + ], + }, + ], + }, + { + text: 'Actions', + link: '/core/api/actions', + items: [ + { + text: 'call', + link: '/core/api/actions/call', + }, + { text: 'connect', link: '/core/api/actions/connect' }, + { text: 'deployContract', link: '/core/api/actions/deployContract' }, + { text: 'disconnect', link: '/core/api/actions/disconnect' }, + { + text: 'estimateFeesPerGas', + link: '/core/api/actions/estimateFeesPerGas', + }, + { text: 'estimateGas', link: '/core/api/actions/estimateGas' }, + { + text: 'estimateMaxPriorityFeePerGas', + link: '/core/api/actions/estimateMaxPriorityFeePerGas', + }, + { text: 'getAccount', link: '/core/api/actions/getAccount' }, + { text: 'getBalance', link: '/core/api/actions/getBalance' }, + { + text: 'getBlock', + link: '/core/api/actions/getBlock', + }, + { + text: 'getBlockNumber', + link: '/core/api/actions/getBlockNumber', + }, + { + text: 'getBlockTransactionCount', + link: '/core/api/actions/getBlockTransactionCount', + }, + { + text: 'getBytecode', + link: '/core/api/actions/getBytecode', + }, + { + text: 'getCallsStatus', + link: '/core/api/actions/getCallsStatus', + }, + { + text: 'getCapabilities', + link: '/core/api/actions/getCapabilities', + }, + { text: 'getChainId', link: '/core/api/actions/getChainId' }, + { text: 'getChains', link: '/core/api/actions/getChains' }, + { + text: 'getClient', + link: '/core/api/actions/getClient', + }, + { + text: 'getConnections', + link: '/core/api/actions/getConnections', + }, + { + text: 'getConnectorClient', + link: '/core/api/actions/getConnectorClient', + }, + { + text: 'getConnectors', + link: '/core/api/actions/getConnectors', + }, + { + text: 'getEnsAddress', + link: '/core/api/actions/getEnsAddress', + }, + { text: 'getEnsAvatar', link: '/core/api/actions/getEnsAvatar' }, + { text: 'getEnsName', link: '/core/api/actions/getEnsName' }, + { + text: 'getEnsResolver', + link: '/core/api/actions/getEnsResolver', + }, + { + text: 'getEnsText', + link: '/core/api/actions/getEnsText', + }, + { + text: 'getFeeHistory', + link: '/core/api/actions/getFeeHistory', + }, + { + text: 'getGasPrice', + link: '/core/api/actions/getGasPrice', + }, + { + text: 'getProof', + link: '/core/api/actions/getProof', + }, + { + text: 'getPublicClient', + link: '/core/api/actions/getPublicClient', + }, + { + text: 'getStorageAt', + link: '/core/api/actions/getStorageAt', + }, + { text: 'getToken', link: '/core/api/actions/getToken' }, + { + text: 'getTransaction', + link: '/core/api/actions/getTransaction', + }, + { + text: 'getTransactionConfirmations', + link: '/core/api/actions/getTransactionConfirmations', + }, + { + text: 'getTransactionCount', + link: '/core/api/actions/getTransactionCount', + }, + { + text: 'getTransactionReceipt', + link: '/core/api/actions/getTransactionReceipt', + }, + { + text: 'getWalletClient', + link: '/core/api/actions/getWalletClient', + }, + { + text: 'multicall', + link: '/core/api/actions/multicall', + }, + { + text: 'prepareTransactionRequest', + link: '/core/api/actions/prepareTransactionRequest', + }, + { text: 'reconnect', link: '/core/api/actions/reconnect' }, + { + text: 'readContract', + link: '/core/api/actions/readContract', + }, + { + text: 'readContracts', + link: '/core/api/actions/readContracts', + }, + { + text: 'sendCalls', + link: '/core/api/actions/sendCalls', + }, + { + text: 'sendTransaction', + link: '/core/api/actions/sendTransaction', + }, + { + text: 'showCallsStatus', + link: '/core/api/actions/showCallsStatus', + }, + { + text: 'signMessage', + link: '/core/api/actions/signMessage', + }, + { + text: 'signTypedData', + link: '/core/api/actions/signTypedData', + }, + { + text: 'simulateContract', + link: '/core/api/actions/simulateContract', + }, + { + text: 'switchAccount', + link: '/core/api/actions/switchAccount', + }, + { + text: 'switchChain', + link: '/core/api/actions/switchChain', + }, + { + text: 'verifyMessage', + link: '/core/api/actions/verifyMessage', + }, + { + text: 'verifyTypedData', + link: '/core/api/actions/verifyTypedData', + }, + { + text: 'waitForCallsStatus', + link: '/core/api/actions/waitForCallsStatus', + }, + { + text: 'waitForTransactionReceipt', + link: '/core/api/actions/waitForTransactionReceipt', + }, + { + text: 'watchAccount', + link: '/core/api/actions/watchAccount', + }, + { + text: 'watchAsset', + link: '/core/api/actions/watchAsset', + }, + { + text: 'watchBlocks', + link: '/core/api/actions/watchBlocks', + }, + { + text: 'watchBlockNumber', + link: '/core/api/actions/watchBlockNumber', + }, + { + text: 'watchChainId', + link: '/core/api/actions/watchChainId', + }, + { + text: 'watchClient', + link: '/core/api/actions/watchClient', + }, + { + text: 'watchConnections', + link: '/core/api/actions/watchConnections', + }, + { + text: 'watchConnectors', + link: '/core/api/actions/watchConnectors', + }, + { + text: 'watchContractEvent', + link: '/core/api/actions/watchContractEvent', + }, + { + text: 'watchPendingTransactions', + link: '/core/api/actions/watchPendingTransactions', + }, + { + text: 'watchPublicClient', + link: '/core/api/actions/watchPublicClient', + }, + { + text: 'writeContract', + link: '/core/api/actions/writeContract', + }, + ], + }, + { + text: 'Miscellaneous', + items: [ + { text: 'Errors', link: '/core/api/errors' }, + { + text: 'Utilities', + collapsed: true, + items: [ + { + text: 'cookieToInitialState', + link: '/core/api/utilities/cookieToInitialState', + }, + { text: 'deserialize', link: '/core/api/utilities/deserialize' }, + { + text: 'normalizeChainId', + link: '/core/api/utilities/normalizeChainId', + }, + { text: 'serialize', link: '/core/api/utilities/serialize' }, + ], + }, + ], + }, + ], + '/cli': [ + { + text: 'Introduction', + items: [ + { text: 'Why Wagmi CLI', link: '/cli/why' }, + { text: 'Installation', link: '/cli/installation' }, + { text: 'Getting Started', link: '/cli/getting-started' }, + ], + }, + { + text: 'Guides', + items: [ + { + text: 'Migrate from v1 to v2', + link: '/cli/guides/migrate-from-v1-to-v2', + }, + ], + }, + { + text: 'Config File', + items: [ + { + text: 'Configuring CLI', + link: '/cli/config/configuring-cli', + }, + { text: 'Config Options', link: '/cli/config/options' }, + ], + }, + { + text: 'Commands', + link: '/cli/api/commands', + items: [ + { + text: 'generate', + link: '/cli/api/commands/generate', + }, + { + text: 'init', + link: '/cli/api/commands/init', + }, + ], + }, + { + text: 'Plugins', + link: '/cli/api/plugins', + items: [ + { text: 'actions', link: '/cli/api/plugins/actions' }, + { text: 'blockExplorer', link: '/cli/api/plugins/blockExplorer' }, + { text: 'etherscan', link: '/cli/api/plugins/etherscan' }, + { text: 'fetch', link: '/cli/api/plugins/fetch' }, + { text: 'foundry', link: '/cli/api/plugins/foundry' }, + { text: 'hardhat', link: '/cli/api/plugins/hardhat' }, + { text: 'react', link: '/cli/api/plugins/react' }, + { text: 'sourcify', link: '/cli/api/plugins/sourcify' }, + ], + }, + { + text: 'create-wagmi', + link: '/cli/create-wagmi', + }, + ], + '/dev': [ + { + text: 'Dev', + items: [ + { text: 'Contributing', link: '/dev/contributing' }, + { text: 'Creating Connectors', link: '/dev/creating-connectors' }, + ], + }, + ], + '/examples': [ + { + text: 'React', + items: [ + { text: 'Connect Wallet', link: '/examples/connect-wallet' }, + { text: 'Send Transaction', link: '/examples/send-transaction' }, + { text: 'Write Contract', link: '/examples/contract-write' }, + { + text: 'Write Contract (Dynamic Args)', + link: '/examples/contract-write-dynamic', + }, + { text: 'Sign Message', link: '/examples/sign-message' }, + { + text: 'Sign In With Ethereum', + link: '/examples/sign-in-with-ethereum', + }, + ], + }, + ], + } satisfies DefaultTheme.Sidebar +} diff --git a/wagmi-project/site/.vitepress/theme/components/AsideSponsors.vue b/wagmi-project/site/.vitepress/theme/components/AsideSponsors.vue new file mode 100644 index 000000000..09e1075ab --- /dev/null +++ b/wagmi-project/site/.vitepress/theme/components/AsideSponsors.vue @@ -0,0 +1,27 @@ + + + + diff --git a/wagmi-project/site/.vitepress/theme/components/Banner.vue b/wagmi-project/site/.vitepress/theme/components/Banner.vue new file mode 100644 index 000000000..14ccf48b9 --- /dev/null +++ b/wagmi-project/site/.vitepress/theme/components/Banner.vue @@ -0,0 +1,16 @@ +// TODO: Dismissable, a11y, etc. +// https://github.com/faker-js/faker/pull/1487 + + + + diff --git a/wagmi-project/site/.vitepress/theme/components/HomeBanner.vue b/wagmi-project/site/.vitepress/theme/components/HomeBanner.vue new file mode 100644 index 000000000..dbbf1c4f8 --- /dev/null +++ b/wagmi-project/site/.vitepress/theme/components/HomeBanner.vue @@ -0,0 +1,13 @@ + + + + diff --git a/wagmi-project/site/.vitepress/theme/components/HomePage.vue b/wagmi-project/site/.vitepress/theme/components/HomePage.vue new file mode 100644 index 000000000..31e1e1057 --- /dev/null +++ b/wagmi-project/site/.vitepress/theme/components/HomePage.vue @@ -0,0 +1,118 @@ + + + + + diff --git a/wagmi-project/site/.vitepress/theme/composables/useSponsors.ts b/wagmi-project/site/.vitepress/theme/composables/useSponsors.ts new file mode 100644 index 000000000..571a2b7df --- /dev/null +++ b/wagmi-project/site/.vitepress/theme/composables/useSponsors.ts @@ -0,0 +1,212 @@ +import { onMounted, ref } from 'vue' + +type Sponsor = { + name: string + img: string + url: string +} + +type Data = { + size: 'big' | 'medium' | 'small' + items: Sponsor[] + tier: string + type: 'platinum' | 'gold' | 'silver' +}[] + +// shared data across instances so we load only once. +const data = ref() + +// TODO: Data powered +// const dataHost = 'https://sponsors.vuejs.org' +// const dataUrl = `${dataHost}/vite.json` + +export function useSponsors() { + onMounted(async () => { + if (data.value) return + + // const result = await fetch(dataUrl) + // const json = await result.json() + // console.log(json) + const sponsors = { + platinum: [ + { + name: 'Paradigm', + url: 'https://paradigm.xyz', + img: 'paradigm-light.svg', + }, + { + name: 'Ithaca', + url: 'https://ithaca.xyz', + img: 'ithaca-light.svg', + }, + ], + gold: [ + { + name: 'Stripe', + url: 'https://www.stripe.com', + img: 'stripe-light.svg', + }, + { + name: 'zkSync', + url: 'https://zksync.io', + img: 'zksync-light.svg', + }, + { + name: 'Linea', + url: 'https://linea.build', + img: 'linea-light.svg', + }, + { + name: 'Routescan', + url: 'https://routescan.io', + img: 'routescan-light.svg', + }, + ], + silver: [ + { + name: 'Family', + url: 'https://twitter.com/family', + img: 'family-light.svg', + }, + { + name: 'Context', + url: 'https://twitter.com/context', + img: 'context-light.svg', + }, + { + name: 'WalletConnect', + url: 'https://walletconnect.com', + img: 'walletconnect-light.svg', + }, + { + name: 'PartyDAO', + url: 'https://twitter.com/prtyDAO', + img: 'partydao-light.svg', + }, + { + name: 'SushiSwap', + url: 'https://www.sushi.com', + img: 'sushi-light.svg', + }, + { + name: 'Dynamic', + url: 'https://www.dynamic.xyz', + img: 'dynamic-light.svg', + }, + { + name: 'Privy', + url: 'https://privy.io', + img: 'privy-light.svg', + }, + { + name: 'PancakeSwap', + url: 'https://pancakeswap.finance', + img: 'pancake-light.svg', + }, + { + name: 'Celo', + url: 'https://celo.org', + img: 'celo-light.svg', + }, + { + name: 'Rainbow', + url: 'https://rainbow.me', + img: 'rainbow-light.svg', + }, + { + name: 'Pimlico', + url: 'https://pimlico.io', + img: 'pimlico-light.svg', + }, + { + name: 'Zora', + url: 'https://zora.co', + img: 'zora-light.svg', + }, + { + name: 'Lattice', + url: 'https://lattice.xyz', + img: 'lattice-light.svg', + }, + { + name: 'Supa', + url: 'https://twitter.com/supafinance', + img: 'supa-light.svg', + }, + { + name: 'Syndicate', + url: 'https://syndicate.io', + img: 'syndicate-light.svg', + }, + { + name: 'Reservoir', + url: 'https://reservoir.tools', + img: 'reservoir-light.svg', + }, + { + name: 'Uniswap', + url: 'https://uniswap.org', + img: 'uniswap-light.svg', + }, + { + name: 'Biconomy', + url: 'https://biconomy.io', + img: 'biconomy-light.svg', + }, + { + name: 'Thirdweb', + url: 'https://thirdweb.com', + img: 'thirdweb-light.svg', + }, + { + name: 'Polymarket', + url: 'https://polymarket.com', + img: 'polymarket-light.svg', + }, + { + name: 'Sequence', + url: 'https://sequence.xyz', + img: 'sequence-light.svg', + }, + ], + } + + data.value = mapSponsors(sponsors) + }) + + return { data } +} + +function mapSponsors(sponsors: { + platinum: Sponsor[] + gold: Sponsor[] + silver: Sponsor[] +}) { + return [ + { + size: 'big', + items: mapImgPath(sponsors.platinum), + tier: 'Collaborators', + type: 'platinum', + }, + { + size: 'medium', + items: mapImgPath(sponsors.gold), + tier: 'Large Enterprises', + type: 'gold', + }, + { + size: 'small', + items: mapImgPath(sponsors.silver), + tier: 'Small Enterprises', + type: 'silver', + }, + ] satisfies Data +} + +function mapImgPath(sponsors: Sponsor[]) { + return sponsors.map((sponsor) => ({ + ...sponsor, + img: `https://raw.githubusercontent.com/wevm/.github/main/content/sponsors/${sponsor.img}`, + })) +} diff --git a/wagmi-project/site/.vitepress/theme/index.ts b/wagmi-project/site/.vitepress/theme/index.ts new file mode 100644 index 000000000..abcc80217 --- /dev/null +++ b/wagmi-project/site/.vitepress/theme/index.ts @@ -0,0 +1,30 @@ +import TwoslashFloatingVue from '@shikijs/vitepress-twoslash/client' +import type { Theme } from 'vitepress' +import DefaultTheme from 'vitepress/theme' +// https://vitepress.dev/guide/custom-theme +import { h } from 'vue' + +import '@shikijs/vitepress-twoslash/style.css' +import 'uno.css' +import './style.css' + +import AsideSponsors from './components/AsideSponsors.vue' +// import Banner from './components/Banner.vue' +import HomeBanner from './components/HomeBanner.vue' +import HomePage from './components/HomePage.vue' + +export default { + extends: DefaultTheme, + Layout() { + return h(DefaultTheme.Layout, null, { + // https://vitepress.dev/guide/extending-default-theme#layout-slots + 'aside-ads-before': () => h(AsideSponsors), + // 'doc-before': () => h(Banner), + 'home-features-after': () => h(HomePage), + 'home-hero-before': () => h(HomeBanner), + }) + }, + enhanceApp({ app }) { + app.use(TwoslashFloatingVue) + }, +} satisfies Theme diff --git a/wagmi-project/site/.vitepress/theme/style.css b/wagmi-project/site/.vitepress/theme/style.css new file mode 100644 index 000000000..4ec569cf0 --- /dev/null +++ b/wagmi-project/site/.vitepress/theme/style.css @@ -0,0 +1,148 @@ +/** + * Customize default theme styling by overriding CSS variables: + * https://github.com/vuejs/vitepress/blob/main/src/client/theme-default/styles/vars.css + */ + +/** + * Colors + * + * Each colors have exact same color scale system with 3 levels of solid + * colors with different brightness, and 1 soft color. + * + * - `XXX-1`: The most solid color used mainly for colored text. It must + * satisfy the contrast ratio against when used on top of `XXX-soft`. + * + * - `XXX-2`: The color used mainly for hover state of the button. + * + * - `XXX-3`: The color for solid background, such as bg color of the button. + * It must satisfy the contrast ratio with pure white (#ffffff) text on + * top of it. + * + * - `XXX-soft`: The color used for subtle background such as custom container + * or badges. It must satisfy the contrast ratio when putting `XXX-1` colors + * on top of it. + * + * The soft color must be semi transparent alpha channel. This is crucial + * because it allows adding multiple "soft" colors on top of each other + * to create a accent, such as when having inline code block inside + * custom containers. + * + * - `default`: The color used purely for subtle indication without any + * special meanings attached to it such as bg color for menu hover state. + * + * - `brand`: Used for primary brand colors, such as link text, button with + * brand theme, etc. + * + * - `tip`: Used to indicate useful information. The default theme uses the + * brand color for this by default. + * + * - `warning`: Used to indicate warning to the users. Used in custom + * container, badges, etc. + * + * - `danger`: Used to show error, or dangerous message to the users. Used + * in custom container, badges, etc. + * -------------------------------------------------------------------------- */ + +:root { + --vp-c-default-1: var(--vp-c-gray-1); + --vp-c-default-2: var(--vp-c-gray-2); + --vp-c-default-3: var(--vp-c-gray-3); + --vp-c-default-soft: var(--vp-c-gray-soft); + + --vp-c-brand-1: var(--vp-c-indigo-1); + --vp-c-brand-2: var(--vp-c-indigo-2); + --vp-c-brand-3: var(--vp-c-indigo-3); + --vp-c-brand-soft: var(--vp-c-indigo-soft); + + --vp-c-tip-1: var(--vp-c-brand-1); + --vp-c-tip-2: var(--vp-c-brand-2); + --vp-c-tip-3: var(--vp-c-brand-3); + --vp-c-tip-soft: var(--vp-c-brand-soft); + + --vp-c-warning-1: var(--vp-c-yellow-1); + --vp-c-warning-2: var(--vp-c-yellow-2); + --vp-c-warning-3: var(--vp-c-yellow-3); + --vp-c-warning-soft: var(--vp-c-yellow-soft); + + --vp-c-danger-1: var(--vp-c-red-1); + --vp-c-danger-2: var(--vp-c-red-2); + --vp-c-danger-3: var(--vp-c-red-3); + --vp-c-danger-soft: var(--vp-c-red-soft); +} + +/** + * Component: Button + * -------------------------------------------------------------------------- */ + +:root { + --vp-button-brand-border: transparent; + --vp-button-brand-text: var(--vp-c-white); + --vp-button-brand-bg: var(--vp-c-brand-3); + --vp-button-brand-hover-border: transparent; + --vp-button-brand-hover-text: var(--vp-c-white); + --vp-button-brand-hover-bg: var(--vp-c-brand-2); + --vp-button-brand-active-border: transparent; + --vp-button-brand-active-text: var(--vp-c-white); + --vp-button-brand-active-bg: var(--vp-c-brand-1); +} + +/** + * Component: Home + * -------------------------------------------------------------------------- */ + +:root { + --vp-home-hero-name-color: transparent; + --vp-home-hero-name-background: -webkit-linear-gradient( + 120deg, + #bd34fe 30%, + #41d1ff + ); + + --vp-home-hero-image-background-image: linear-gradient( + -45deg, + #bd34fe 50%, + #47caff 50% + ); + --vp-home-hero-image-filter: blur(44px); +} + +@media (min-width: 640px) { + :root { + --vp-home-hero-image-filter: blur(56px); + } +} + +@media (min-width: 960px) { + :root { + --vp-home-hero-image-filter: blur(68px); + } +} + +/** + * Component: Custom Block + * -------------------------------------------------------------------------- */ + +:root { + --vp-custom-block-tip-border: transparent; + --vp-custom-block-tip-text: var(--vp-c-text-1); + --vp-custom-block-tip-bg: var(--vp-c-brand-soft); + --vp-custom-block-tip-code-bg: var(--vp-c-brand-soft); +} + +/** + * Component: Algolia + * -------------------------------------------------------------------------- */ + +.DocSearch { + --docsearch-primary-color: var(--vp-c-brand-1) !important; +} + +.vp-doc [class*="language-"] .has-focused-lines .line:not(.has-focus) { + filter: unset; + opacity: 0.3; +} + +.twoslash-error-line { + max-width: min-content; + white-space: wrap; +} diff --git a/wagmi-project/site/cli/api/commands.md b/wagmi-project/site/cli/api/commands.md new file mode 100644 index 000000000..643397560 --- /dev/null +++ b/wagmi-project/site/cli/api/commands.md @@ -0,0 +1,53 @@ +# Commands + +## Available Commands + +- [`init`](/cli/api/commands/init) Creates configuration file. +- [`generate`](/cli/api/commands/generate) Generates code based on configuration, using `contracts` and `plugins`. + +## Display Info + +### `-h`, `--help` + +Show help message when `-h`, `--help` flags appear. + +::: code-group +```bash [pnpm] +pnpm wagmi --help +``` + +```bash [npm] +npx wagmi --help +``` + +```bash [yarn] +yarn wagmi --help +``` + +```bash [bun] +bun wagmi --help +``` +::: + +### `-v`, `--version` + +Show version number when `-v`, `--version` flags appear. + +::: code-group +```bash [pnpm] +pnpm wagmi --version +``` + +```bash [npm] +npx wagmi --version +``` + +```bash [yarn] +yarn wagmi --version +``` + +```bash [bun] +bun wagmi --version +``` +::: + diff --git a/wagmi-project/site/cli/api/commands/generate.md b/wagmi-project/site/cli/api/commands/generate.md new file mode 100644 index 000000000..d1f88e90a --- /dev/null +++ b/wagmi-project/site/cli/api/commands/generate.md @@ -0,0 +1,49 @@ +# generate + +Generates code based on configuration, using `contracts` and `plugins`. + +## Usage + +```bash +wagmi generate +``` + +## Options + +### -c, --config \ + +`string` + +Path to config file. + +```bash +wagmi generate --config wagmi.config.ts +``` + +### -r, --root \ + +`string` + +Root path to resolve config from. + +```bash +wagmi generate --root path/to/root +``` + +### -w, --watch + +`boolean` + +Watch for changes (for plugins that support watch mode). + +```bash +wagmi generate --watch +``` + +### -h, --help + +Displays help message. + +```bash +wagmi generate --help +``` \ No newline at end of file diff --git a/wagmi-project/site/cli/api/commands/init.md b/wagmi-project/site/cli/api/commands/init.md new file mode 100644 index 000000000..440315e9c --- /dev/null +++ b/wagmi-project/site/cli/api/commands/init.md @@ -0,0 +1,40 @@ +# init + +Creates configuration file. If TypeScript is detected, the config file will use TypeScript and be named `wagmi.config.ts`. Otherwise, the config file will use JavaScript and be named `wagmi.config.js`. + +## Usage + +```bash +wagmi init +``` + +## Options + +### -c, --config \ + +`string` + +Path to config file. + +```bash +wagmi init --config wagmi.config.ts +``` + +### -r, --root \ + +`string` + +Root path to resolve config from. + +```bash +wagmi init --root path/to/root +``` + +### -h, --help + +Displays help message. + +```bash +wagmi init --help +``` + diff --git a/wagmi-project/site/cli/api/plugins.md b/wagmi-project/site/cli/api/plugins.md new file mode 100644 index 000000000..54afdb19e --- /dev/null +++ b/wagmi-project/site/cli/api/plugins.md @@ -0,0 +1,42 @@ +# Plugins + +Plugins for managing ABIs, generating code, and more. + +## Import + +Import via the `'@wagmi/cli/plugins'` entrypoint. + +```ts +import { etherscan } from '@wagmi/cli/plugins' +``` + +## Available Plugins + +- [`actions`](/cli/api/plugins/actions) Generate type-safe VanillaJS actions from configuration `contracts`. +- [`blockExplorer`](/cli/api/plugins/blockExplorer) Fetch ABIs from Block Explorers that support `?module=contract&action=getabi`. +- [`etherscan`](/cli/api/plugins/etherscan) Fetch ABIs from Etherscan and add into configuration. +- [`fetch`](/cli/api/plugins/fetch) Fetch and parse ABIs from network resource with `fetch`. +- [`foundry`](/cli/api/plugins/foundry) Generate ABIs and watch for Foundry project changes. +- [`hardhat`](/cli/api/plugins/hardhat) Generate ABIs and watch for Hardhat projects changes. +- [`react`](/cli/api/plugins/react) Generate type-safe React Hooks from configuration `contracts`. +- [`sourcify`](/cli/api/plugins/sourcify) Fetch ABIs from Sourcify from configuration `contracts`. + +## Create Plugin + +Creating plugins to hook into the CLI is quite simple. Plugins most commonly inject contracts into `contracts` config, e.g. [`etherscan`](/cli/api/plugins/etherscan), and/or generate code using the `run` option, e.g. [`react`](/cli/api/plugins/react). All you need to do is write a function that returns the `Plugin` type. + +```ts{3-8} +import { type Plugin, defineConfig } from '@wagmi/cli' + +function myPlugin(): Plugin { + // `name` is the only required property. + name: 'MyPlugin', + // You likely want to at least include `contracts` or `run`. + // ... +} + +export default defineConfig({ + out: 'src/generated.ts', + plugins: [myPlugin()], +}) +``` diff --git a/wagmi-project/site/cli/api/plugins/actions.md b/wagmi-project/site/cli/api/plugins/actions.md new file mode 100644 index 000000000..d62a29a6b --- /dev/null +++ b/wagmi-project/site/cli/api/plugins/actions.md @@ -0,0 +1,72 @@ +# actions + +Plugin for type-safe VanillaJS actions. + +## Import + +```ts +import { actions } from '@wagmi/cli/plugins' +``` + +## Usage + +```ts{2,6} +import { defineConfig } from '@wagmi/cli' +import { actions } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + actions(), + ], +}) +``` + +## Configuration + +```ts +import { type ActionsConfig } from '@wagmi/cli/plugins' +``` + +### getActionName + +`` 'legacy' | ((options: { contractName: string; type: 'read' | 'simulate' | 'watch' | 'write' }) => `use${string}`) `` + +- Function for setting custom hook names. +- Defaults to `` `${type}${contractName}` ``. For example, `readErc20`, `simulateErc20`, `watchErc20Event`, `writeErc20`. +- When `'legacy'` (deprecated), hook names are set to `@wagmi/cli@1` format. + +```ts +import { defineConfig } from '@wagmi/cli' +import { actions } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + actions({ + getActionName({ contractName, type }) { // [!code focus] + return `${contractName}__${type}` // [!code focus] + }, // [!code focus] + }), + ], +}) +``` + +### overridePackageName + +`'@wagmi/core' | 'wagmi'` + +- Override detected import source. +- Defaults to `'wagmi'` or `'@wagmi/core'` depending on which package is installed. + +```ts +import { defineConfig } from '@wagmi/cli' +import { actions } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + actions({ + overridePackageName: 'wagmi', // [!code focus] + }), + ], +}) +``` + diff --git a/wagmi-project/site/cli/api/plugins/blockExplorer.md b/wagmi-project/site/cli/api/plugins/blockExplorer.md new file mode 100644 index 000000000..462e37bdd --- /dev/null +++ b/wagmi-project/site/cli/api/plugins/blockExplorer.md @@ -0,0 +1,223 @@ +# blockExplorer + +Plugin for fetching ABIs from block explorers that supports the `?module=contract&action=getabi` API format. + +## Import + +```ts +import { blockExplorer } from '@wagmi/cli/plugins' +``` + +## Usage + +```ts{2,6-14} +import { defineConfig } from '@wagmi/cli' +import { blockExplorer } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + blockExplorer({ + baseUrl: 'https://api.etherscan.io/v2/api', + contracts: [ + { + name: 'Wagmigotchi', + address: '0xecb504d39723b0be0e3a9aa33d646642d1051ee1', + }, + ], + }), + ], +}) +``` + +## Configuration + +```ts +import { type BlockExplorerConfig } from '@wagmi/cli/plugins' +``` + +### apiKey + +`string | undefined` + +API key for block explorer. Appended to the request URL as query param `&apikey=${apiKey}`. + +```ts +import { defineConfig } from '@wagmi/cli' +import { blockExplorer } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + blockExplorer({ + apiKey: process.env.ETHERSCAN_API_KEY, // [!code focus] + baseUrl: 'https://api.etherscan.io/v2/api', + contracts: [ + { + name: 'Wagmigotchi', + address: '0xecb504d39723b0be0e3a9aa33d646642d1051ee1', + }, + ], + }), + ], +}) +``` + +### baseUrl + +`string` + +Base URL for block explorer. + +```ts +import { defineConfig } from '@wagmi/cli' +import { blockExplorer } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + blockExplorer({ + baseUrl: 'https://api.etherscan.io/v2/api', // [!code focus] + contracts: [ + { + name: 'Wagmigotchi', + address: '0xecb504d39723b0be0e3a9aa33d646642d1051ee1', + }, + ], + }), + ], +}) +``` + +### cacheDuration + +`number | undefined` + +Duration in milliseconds to cache ABIs. Defaults to `1_800_000` (30 minutes). + +```ts +import { defineConfig } from '@wagmi/cli' +import { blockExplorer } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + blockExplorer({ + baseUrl: 'https://api.etherscan.io/v2/api', + cacheDuration: 300_000, // [!code focus] + contracts: [ + { + name: 'Wagmigotchi', + address: '0xecb504d39723b0be0e3a9aa33d646642d1051ee1', + }, + ], + }), + ], +}) +``` + +### chainId + +`number | undefined` + +Chain ID for block explorer. Appended to the request URL as query param `&chainId=${chainId}`. + +```ts +import { defineConfig } from '@wagmi/cli' +import { blockExplorer } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + blockExplorer({ + apiKey: process.env.ETHERSCAN_API_KEY, + baseUrl: 'https://api.etherscan.io/v2/api', + chainId: 1, // [!code focus] + contracts: [ + { + name: 'Wagmigotchi', + address: '0xecb504d39723b0be0e3a9aa33d646642d1051ee1', + }, + ], + }), + ], +}) +``` + + +### contracts + +`{ name: string; address?: Address | Record | undefined }[]` + +Contracts to fetch ABIs for. + +```ts +import { defineConfig } from '@wagmi/cli' +import { blockExplorer } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + blockExplorer({ + baseUrl: 'https://api.etherscan.io/v2/api', + contracts: [ // [!code focus] + { // [!code focus] + name: 'Wagmigotchi', // [!code focus] + address: '0xecb504d39723b0be0e3a9aa33d646642d1051ee1', // [!code focus] + }, // [!code focus] + ], // [!code focus] + }), + ], +}) +``` + +### getAddress + +`((config: { address: Address | Record }) => Address) | undefined` + +- Function to get address from contract config. +- Defaults to `({ address }) => typeof address === 'string' ? address : Object.values(address)[0]`. + +```ts +import { defineConfig } from '@wagmi/cli' +import { blockExplorer } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + blockExplorer({ + baseUrl: 'https://api.etherscan.io/v2/api', + contracts: [ + { + name: 'Wagmigotchi', + address: '0xecb504d39723b0be0e3a9aa33d646642d1051ee1', + }, + ], + getAddress({ address }) { // [!code focus] + if (typeof address === 'string') return address // [!code focus] + return Object.values(address)[0] // [!code focus] + }, // [!code focus] + }), + ], +}) +``` + +### name + +`string` + +- Name of source. +- Defaults to `'Block Explorer'`. + +```ts +import { defineConfig } from '@wagmi/cli' +import { blockExplorer } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + blockExplorer({ + baseUrl: 'https://api.etherscan.io/v2/api', + contracts: [ + { + name: 'Wagmigotchi', + address: '0xecb504d39723b0be0e3a9aa33d646642d1051ee1', + }, + ], + name: 'Etherscan', // [!code focus] + }), + ], +}) +``` diff --git a/wagmi-project/site/cli/api/plugins/etherscan.md b/wagmi-project/site/cli/api/plugins/etherscan.md new file mode 100644 index 000000000..ec52fd679 --- /dev/null +++ b/wagmi-project/site/cli/api/plugins/etherscan.md @@ -0,0 +1,182 @@ +# etherscan + +Plugin for fetching ABIs from [Etherscan](https://etherscan.io) and adding into `contracts` config. + +## Import + +```ts +import { etherscan } from '@wagmi/cli/plugins' +``` + +## Usage + +```ts{2,6-14} +import { defineConfig } from '@wagmi/cli' +import { etherscan } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + etherscan({ + apiKey: process.env.ETHERSCAN_API_KEY, + chainId: 1, + contracts: [ + { + name: 'Wagmigotchi', + address: '0xecb504d39723b0be0e3a9aa33d646642d1051ee1', + }, + ], + }), + ], +}) +``` + +## Configuration + +```ts +import { type EtherscanConfig } from '@wagmi/cli/plugins' +``` + +### apiKey + +`string` + +Etherscan API key. Etherscan API keys are specific per network and include testnets (e.g. Ethereum Mainnet and Sepolia share same API key). + +```ts +import { defineConfig } from '@wagmi/cli' +import { etherscan } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + etherscan({ + apiKey: process.env.ETHERSCAN_API_KEY, // [!code focus] + chainId: 1, + contracts: [ + { + name: 'Wagmigotchi', + address: '0xecb504d39723b0be0e3a9aa33d646642d1051ee1', + }, + ], + }), + ], +}) +``` + +### cacheDuration + +`number | undefined` + +- Duration in milliseconds to cache ABIs. +- Defaults to `1_800_000` (30 minutes). + +```ts +import { defineConfig } from '@wagmi/cli' +import { etherscan } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + etherscan({ + apiKey: process.env.ETHERSCAN_API_KEY, + cacheDuration: 300_000, // [!code focus] + chainId: 1, + contracts: [ + { + name: 'Wagmigotchi', + address: '0xecb504d39723b0be0e3a9aa33d646642d1051ee1', + }, + ], + }), + ], +}) +``` + +### chainId + +`number` + +Chain ID to use for fetching ABI. If [`address`](/cli/config/options#address) is an object, `chainId` is used to select the address. + +View supported chains on the [Etherscan docs](https://docs.etherscan.io/etherscan-v2/getting-started/supported-chains). + +```ts +import { defineConfig } from '@wagmi/cli' +import { blockExplorer } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + etherscan({ + apiKey: process.env.ETHERSCAN_API_KEY, + chainId: 1, // [!code focus] + contracts: [ + { + name: 'Wagmigotchi', + address: '0xecb504d39723b0be0e3a9aa33d646642d1051ee1', + }, + { + name: 'EnsRegistry', + address: { + 1: '0x314159265dd8dbb310642f98f50c066173c1259b', + 5: '0x112234455c3a32fd11230c42e7bccd4a84e02010', + }, + }, + ], + }), + ], +}) +``` + +### contracts + +`{ name: string; address?: Address | Record | undefined }[]` + +Contracts to fetch ABIs for. + +```ts +import { defineConfig } from '@wagmi/cli' +import { etherscan } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + etherscan({ + apiKey: process.env.ETHERSCAN_API_KEY, + chainId: 1, + contracts: [ // [!code focus] + { // [!code focus] + name: 'Wagmigotchi', // [!code focus] + address: '0xecb504d39723b0be0e3a9aa33d646642d1051ee1', // [!code focus] + }, // [!code focus] + ], // [!code focus] + }), + ], +}) +``` + +### tryFetchProxyImplementation + +`boolean | undefined` + +- Whether to try fetching proxy implementation address of the contract. +- Defaults to `false`. + +```ts +import { defineConfig } from '@wagmi/cli' +import { blockExplorer } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + etherscan({ + apiKey: process.env.ETHERSCAN_API_KEY, + chainId: 1, + contracts: [ + { + name: 'FiatToken', + address: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', + }, + ], + tryFetchProxyImplementation: true, // [!code focus] + }), + ], +}) +``` + + diff --git a/wagmi-project/site/cli/api/plugins/fetch.md b/wagmi-project/site/cli/api/plugins/fetch.md new file mode 100644 index 000000000..8d463a7ab --- /dev/null +++ b/wagmi-project/site/cli/api/plugins/fetch.md @@ -0,0 +1,269 @@ +# fetch + +Plugin for fetching and parsing ABIs from network resource with `fetch`. + +## Import + +```ts +import { fetch } from '@wagmi/cli/plugins' +``` + +## Usage + +```ts{2,6-23} +import { defineConfig } from '@wagmi/cli' +import { fetch } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + fetch({ + contracts: [ + { + name: 'Wagmigotchi', + address: '0xecb504d39723b0be0e3a9aa33d646642d1051ee1', + }, + ], + request(contract) { + if (!contract.address) throw new Error('address is required') + const address = + typeof contract.address === 'string' + ? contract.address + : Object.values(contract.address)[0] + return { + url: `https://api.etherscan.io/api?module=contract&action=getabi&address=${address}`, + } + }, + }), + ], +}) +``` + + +## Configuration + +```ts +import { type FetchConfig } from '@wagmi/cli/plugins' +``` + +### cacheDuration + +`number | undefined` + +- Duration in milliseconds to cache ABIs. +- Defaults to `1_800_000` (30 minutes). + +```ts +import { defineConfig } from '@wagmi/cli' +import { fetch } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + fetch({ + cacheDuration: 300_000, // [!code focus] + contracts: [ + { + name: 'Wagmigotchi', + address: '0xecb504d39723b0be0e3a9aa33d646642d1051ee1', + }, + ], + request(contract) { + if (!contract.address) throw new Error('address is required') + const address = + typeof contract.address === 'string' + ? contract.address + : Object.values(contract.address)[0] + return { + url: `https://api.etherscan.io/api?module=contract&action=getabi&address=${address}`, + } + }, + }), + ], +}) +``` + +### contracts + +`{ name: string; address?: Address | Record | undefined }[]` + +Contracts to fetch ABIs for. + +```ts +import { defineConfig } from '@wagmi/cli' +import { fetch } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + fetch({ + contracts: [ // [!code focus] + { // [!code focus] + name: 'Wagmigotchi', // [!code focus] + address: '0xecb504d39723b0be0e3a9aa33d646642d1051ee1', // [!code focus] + }, // [!code focus] + ], // [!code focus] + request(contract) { + if (!contract.address) throw new Error('address is required') + const address = + typeof contract.address === 'string' + ? contract.address + : Object.values(contract.address)[0] + return { + url: `https://api.etherscan.io/api?module=contract&action=getabi&address=${address}`, + } + }, + }), + ], +}) + +``` + +### getCacheKey + +`((config: { contract: { address: Address | Record | undefined; name: string } }) => string) | undefined` + +- Function for creating a cache key for contract. Contract data is cached at `~/.wagmi-cli/plugins/fetch/cache/`. +- Defaults to `({ contract }) => JSON.stringify(contract)`. + +```ts +import { defineConfig } from '@wagmi/cli' +import { fetch } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + fetch({ + contracts: [ + { + name: 'wagmigotchi', + address: '0xecb504d39723b0be0e3a9aa33d646642d1051ee1', + }, + ], + getCacheKey({ contract }) { // [!code focus] + if (typeof contract.address === 'string') // [!code focus] + return `${name}:${contract.address}` // [!code focus] + return `${name}:${JSON.stringify(contract.address)}` // [!code focus] + }, // [!code focus] + request(contract) { + if (!contract.address) throw new Error('address is required') + const address = + typeof contract.address === 'string' + ? contract.address + : Object.values(contract.address)[0] + return { + url: `https://api.etherscan.io/api?module=contract&action=getabi&address=${address}`, + } + }, + }), + ], +}) + +``` + +### name + +`string` + +- Name of source. +- Defaults to `'Fetch'`. + +```ts +import { defineConfig } from '@wagmi/cli' +import { fetch } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + fetch({ + contracts: [ + { + name: 'Wagmigotchi', + address: '0xecb504d39723b0be0e3a9aa33d646642d1051ee1', + }, + ], + name: 'Etherscan', // [!code focus] + request(contract) { + if (!contract.address) throw new Error('address is required') + const address = + typeof contract.address === 'string' + ? contract.address + : Object.values(contract.address)[0] + return { + url: `https://api.etherscan.io/api?module=contract&action=getabi&address=${address}`, + } + }, + }), + ], +}) +``` + +### parse + +`((config: { response: Response }) => Abi | Promise) | undefined` + +- Function for parsing ABI from fetch response. +- Defaults to `({ response }) => response.json()` + +```ts +import { defineConfig } from '@wagmi/cli' +import { fetch } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + fetch({ + contracts: [ + { + name: 'Wagmigotchi', + address: '0xecb504d39723b0be0e3a9aa33d646642d1051ee1', + }, + ], + async parse({ response }) { // [!code focus] + const json = await response.json() // [!code focus] + if (json.status === '0') throw new Error(json.message) // [!code focus] + return json.result // [!code focus] + }, // [!code focus] + request(contract) { + if (!contract.address) throw new Error('address is required') + const address = + typeof contract.address === 'string' + ? contract.address + : Object.values(contract.address)[0] + return { + url: `https://api.etherscan.io/api?module=contract&action=getabi&address=${address}`, + } + }, + }), + ], +}) +``` + +### request + +`(config: { address?: Address | Record | undefined }) => { url: RequestInfo; init?: RequestInit | undefined } | Promise<{ url: RequestInfo; init?: RequestInit | undefined }>` + +Function for returning a request to fetch ABI from. + +```ts +import { defineConfig } from '@wagmi/cli' +import { fetch } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + fetch({ + contracts: [ + { + name: 'Wagmigotchi', + address: '0xecb504d39723b0be0e3a9aa33d646642d1051ee1', + }, + ], + request(contract) { // [!code focus] + if (!contract.address) throw new Error('address is required') // [!code focus] + const address = // [!code focus] + typeof contract.address === 'string' // [!code focus] + ? contract.address // [!code focus] + : Object.values(contract.address)[0] // [!code focus] + return { // [!code focus] + url: `https://api.etherscan.io/api?module=contract&action=getabi&address=${address}`, // [!code focus] + } // [!code focus] + }, // [!code focus] + }), + ], +}) + +``` diff --git a/wagmi-project/site/cli/api/plugins/foundry.md b/wagmi-project/site/cli/api/plugins/foundry.md new file mode 100644 index 000000000..d24677b5c --- /dev/null +++ b/wagmi-project/site/cli/api/plugins/foundry.md @@ -0,0 +1,217 @@ +# foundry + +Plugin for resolving ABIs from [Foundry](https://github.com/foundry-rs/foundry) projects. Supports [`watch`](/cli/api/commands/generate#w-watch) mode. + +## Import + +```ts +import { foundry } from '@wagmi/cli/plugins' +``` + +## Usage + +```ts{2,6-8} +import { defineConfig } from '@wagmi/cli' +import { foundry } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + foundry({ + project: '../hello_foundry', + }), + ], +}) +``` + +## Configuration + +```ts +import { type FoundryConfig } from '@wagmi/cli/plugins' +``` + +### artifacts + +`string | undefined` + +- Project's artifacts directory. Same as your `foundry.toml`/`forge`s `--out` (`-o`) option. +- Defaults to `'out/'`. + +```ts +import { defineConfig } from '@wagmi/cli' +import { foundry } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + foundry({ + artifacts: 'out/', // [!code focus] + }), + ], +}) +``` + +### deployments + +`{ [key: string]: address?: Address | Record | undefined } | undefined` + +Mapping of addresses to attach to artifacts. + +```ts +import { defineConfig } from '@wagmi/cli' +import { foundry } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + foundry({ + deployments: { // [!code focus] + Counter: { // [!code focus] + 1: '0x314159265dd8dbb310642f98f50c066173c1259b', // [!code focus] + 5: '0x112234455c3a32fd11230c42e7bccd4a84e02010', // [!code focus] + }, // [!code focus] + }, // [!code focus] + }), + ], +}) +``` + +### exclude + +`string[] | undefined` + +Artifact files to exclude relative to `artifacts`. Supports glob patterns. + +```ts +import { defineConfig } from '@wagmi/cli' +import { foundry } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + foundry({ + exclude: [ // [!code focus] + // the following patterns are excluded by default // [!code focus] + 'Common.sol/**', // [!code focus] + 'Components.sol/**', // [!code focus] + 'Script.sol/**', // [!code focus] + 'StdAssertions.sol/**', // [!code focus] + 'StdInvariant.sol/**', // [!code focus] + 'StdError.sol/**', // [!code focus] + 'StdCheats.sol/**', // [!code focus] + 'StdMath.sol/**', // [!code focus] + 'StdJson.sol/**', // [!code focus] + 'StdStorage.sol/**', // [!code focus] + 'StdUtils.sol/**', // [!code focus] + 'Vm.sol/**', // [!code focus] + 'console.sol/**', // [!code focus] + 'console2.sol/**', // [!code focus] + 'test.sol/**', // [!code focus] + '**.s.sol/*.json', // [!code focus] + '**.t.sol/*.json', // [!code focus] + ], // [!code focus] + }), + ], +}) +``` + +### forge + +`{ clean?: boolean | undefined; build?: boolean | undefined; path?: string | undefined; rebuild?: boolean | undefined } | undefined` + +Options for `forge`. + +```ts +import { defineConfig } from '@wagmi/cli' +import { foundry } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + foundry({ + forge: { // [!code focus] + clean: true, // [!code focus] + build: true, // [!code focus] + path: 'path/to/forge', // [!code focus] + rebuild: true, // [!code focus] + }, // [!code focus] + }), + ], +}) +``` + +#### clean + +- Remove build artifacts and cache directories on start up. +- Defaults to `false`. + +#### build + +- Build Foundry project before fetching artifacts. +- Defaults to `true`. + +#### path + +- Path to `forge` executable command. +- Defaults to `forge`. + +#### rebuild + +- Rebuild every time a watched file or directory is changed. Used for setting up [`watch`](/cli/api/commands/generate#w-watch) mode. +- Defaults to `true`. + +### include + +`string[] | undefined` + +Artifact files to include relative to `artifacts`. Supports glob patterns. + +```ts +import { defineConfig } from '@wagmi/cli' +import { foundry } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + foundry({ + include: [ // [!code focus] + // the following patterns are included by default // [!code focus] + '*.json', // [!code focus] + ], // [!code focus] + }), + ], +}) +``` + +### namePrefix + +`string | undefined` + +Prefix to prepend to artifact names. Useful for preventing name collisions between contracts from other sources. + +```ts +import { defineConfig } from '@wagmi/cli' +import { foundry } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + foundry({ // [!code focus] + namePrefix: 'HelloFoundry', // [!code focus] + }), // [!code focus] + ], +}) +``` + +### project + +`string | undefined` + +- Path to Foundry project. +- Defaults to Foundry configuration using `forge config --json` command. + +```ts +import { defineConfig } from '@wagmi/cli' +import { foundry } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + foundry({ // [!code focus] + project: '../hello_foundry', // [!code focus] + }), // [!code focus] + ], +}) +``` \ No newline at end of file diff --git a/wagmi-project/site/cli/api/plugins/hardhat.md b/wagmi-project/site/cli/api/plugins/hardhat.md new file mode 100644 index 000000000..38cca9aeb --- /dev/null +++ b/wagmi-project/site/cli/api/plugins/hardhat.md @@ -0,0 +1,199 @@ +# hardhat + +Plugin for resolving ABIs from [Hardhat](https://hardhat.org) projects. Supports [`watch`](/cli/api/commands/generate#w-watch) mode. + +```ts +import { hardhat } from '@wagmi/cli/plugins' +``` + +## Usage + +```ts{2,6-8} +import { defineConfig } from '@wagmi/cli' +import { hardhat } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + hardhat({ + project: '../hello_hardhat', + }), + ], +}) +``` + +## Configuration + +```ts +import { type HardhatConfig } from '@wagmi/cli/plugins' +``` + +### artifacts + +`string | undefined` + +- Project's artifacts directory. Same as your project's `artifacts` [path configuration](https://hardhat.org/hardhat-runner/docs/config#path-configuration) option. +- Defaults to `'artifacts/'`. + +```ts +import { defineConfig } from '@wagmi/cli' +import { hardhat } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + hardhat({ + artifacts: 'out/', // [!code focus] + project: '../hello_hardhat', + }), + ], +}) +``` + +### deployments + +`{ [key: string]: address?: Address | Record | undefined } | undefined` + +Mapping of addresses to attach to artifacts. + +```ts +import { defineConfig } from '@wagmi/cli' +import { hardhat } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + hardhat({ + project: '../hello_hardhat', + deployments: { // [!code focus] + Counter: { // [!code focus] + 1: '0x314159265dd8dbb310642f98f50c066173c1259b', // [!code focus] + 5: '0x112234455c3a32fd11230c42e7bccd4a84e02010', // [!code focus] + }, // [!code focus] + }, // [!code focus] + }), + ], +}) +``` + +### exclude + +`string[] | undefined` + +Artifact files to exclude relative to `artifacts`. Supports glob patterns. + +```ts +import { defineConfig } from '@wagmi/cli' +import { hardhat } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + hardhat({ + exclude: [ // [!code focus] + // the following patterns are excluded by default // [!code focus] + 'build-info/**', // [!code focus] + '*.dbg.json', // [!code focus] + ], // [!code focus] + project: '../hello_hardhat', + }), + ], +}) +``` + +### commands + +`{ clean?: string | boolean | undefined; build?: string | boolean | undefined; rebuild?: string | boolean | undefined } | undefined` + +Hardhat command options. + +```ts +import { defineConfig } from '@wagmi/cli' +import { hardhat } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + hardhat({ + commands: { // [!code focus] + clean: 'pnpm hardhat clean', // [!code focus] + build: 'pnpm hardhat compile', // [!code focus] + rebuild: 'pnpm hardhat compile', // [!code focus] + }, // [!code focus] + project: '../hello_hardhat', + }), + ], +}) +``` + +#### clean + +- Remove build artifacts and cache directories on start up. +- Defaults to `'${packageManger} hardhat clean'`. + +#### build + +- Build Foundry project before fetching artifacts. +- Defaults to `'${packageManger} hardhat compile'`. + +#### rebuild + +- Command to run when watched file or directory is changed. Used for setting up [`watch`](/cli/api/commands/generate#w-watch) mode. +- Defaults to `'${packageManger} hardhat compile'`. + +### include + +`string[] | undefined` + +Artifact files to include relative to `artifacts`. Supports glob patterns. + +```ts +import { defineConfig } from '@wagmi/cli' +import { hardhat } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + hardhat({ + include: [ // [!code focus] + // the following patterns are included by default // [!code focus] + '*.json', // [!code focus] + ], // [!code focus] + project: '../hello_hardhat', + }), + ], +}) +``` + +### namePrefix + +`string | undefined` + +Prefix to prepend to artifact names. Useful for preventing name collisions between contracts from other sources. + +```ts +import { defineConfig } from '@wagmi/cli' +import { hardhat } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + hardhat({ + namePrefix: 'HelloHardhat', // [!code focus] + project: '../hello_hardhat', + }), + ], +}) +``` + +### project + +`string` + +Path to Hardhat project. + +```ts +import { defineConfig } from '@wagmi/cli' +import { hardhat } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + hardhat({ + project: '../hello_hardhat', // [!code focus] + }), + ], +}) +``` \ No newline at end of file diff --git a/wagmi-project/site/cli/api/plugins/react.md b/wagmi-project/site/cli/api/plugins/react.md new file mode 100644 index 000000000..e78f782c6 --- /dev/null +++ b/wagmi-project/site/cli/api/plugins/react.md @@ -0,0 +1,52 @@ +# react + +Plugin for generating type-safe [Wagmi Hooks](/react/api/hooks). + +## Import + +```ts +import { react } from '@wagmi/cli/plugins' +``` + +## Usage + +```ts{2,6} +import { defineConfig } from '@wagmi/cli' +import { react } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + react(), + ], +}) +``` + +## Configuration + +```ts +import { type ReactConfig } from '@wagmi/cli/plugins' +``` + +### getHookName + +`` 'legacy' | ((options: { contractName: string; type: 'read' | 'simulate' | 'watch' | 'write' }) => `use${string}`) `` + +- Function for setting custom hook names. +- Defaults to `` `use${type}${contractName}` ``. For example, `useReadErc20`, `useSimulateErc20`, `useWatchErc20Event`, `useWriteErc20`. +- When `'legacy'` (deprecated), hook names are set to `@wagmi/cli@1` format. + +```ts +import { defineConfig } from '@wagmi/cli' +import { react } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + react({ + getHookName({ contractName, type }) { // [!code focus] + return `use${contractName}__${type}` // [!code focus] + }, // [!code focus] + }), + ], +}) +``` + diff --git a/wagmi-project/site/cli/api/plugins/sourcify.md b/wagmi-project/site/cli/api/plugins/sourcify.md new file mode 100644 index 000000000..d965fdde0 --- /dev/null +++ b/wagmi-project/site/cli/api/plugins/sourcify.md @@ -0,0 +1,115 @@ +# sourcify + +Plugin for fetching ABIs from [Sourcify](https://sourcify.dev/). Sourcify is a decentralized, open-source, smart contract verification and metadata repository. + +## Import + +```ts +import { sourcify } from '@wagmi/cli/plugins' +``` + +## Usage + +```ts{2,6-13} +import { defineConfig } from '@wagmi/cli' +import { sourcify } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + sourcify({ + contracts: [ + { + name: 'deposit', + address: '0x00000000219ab540356cbb839cbe05303d7705fa', + }, + ], + }), + ], +}) +``` + +## Configuration + +```ts +import { type SourcifyConfig } from '@wagmi/cli/plugins' +``` + +### cacheDuration + +`number | undefined` + +- Duration in milliseconds to cache ABIs. +- Defaults to `1_800_000` (30 minutes). + +```ts +import { defineConfig } from '@wagmi/cli' +import { sourcify } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + sourcify({ + cacheDuration: 300_000, // [!code focus] + chainId: 100, + contracts: [ + { + name: 'Deposit', + address: '0x00000000219ab540356cbb839cbe05303d7705fa', + }, + ], + }), + ], +}) +``` + +### chainId + +`number` + +Chain ID to use for fetching ABI. If `address` is an object, `chainId` is used to select the address. See [Sourcify docs](https://docs.sourcify.dev/docs/chains) for supported chains. + +```ts +import { defineConfig } from '@wagmi/cli' +import { sourcify } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + sourcify({ + chainId: 100, // [!code focus] + contracts: [ + { + name: 'Community', + address: { + 100: '0xC4c622862a8F548997699bE24EA4bc504e5cA865', + 137: '0xC4c622862a8F548997699bE24EA4bc504e5cA865', + }, + }, + ], + }), + ], +}) +``` + +### contracts + +`{ name: string; address?: Address | Record | undefined }[]` + +Contracts to fetch ABIs for. + +```ts +import { defineConfig } from '@wagmi/cli' +import { sourcify } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + sourcify({ + chainId: 100, + contracts: [ // [!code focus] + { // [!code focus] + name: 'Deposit', // [!code focus] + address: '0x00000000219ab540356cbb839cbe05303d7705fa', // [!code focus] + }, // [!code focus] + ], // [!code focus] + }), + ], +}) +``` diff --git a/wagmi-project/site/cli/config/configuring-cli.md b/wagmi-project/site/cli/config/configuring-cli.md new file mode 100644 index 000000000..9e8e11fae --- /dev/null +++ b/wagmi-project/site/cli/config/configuring-cli.md @@ -0,0 +1,124 @@ +# Configuring CLI + +When running `wagmi` from the command line, `@wagmi/cli` will automatically try to resolve a config file named `wagmi.config.js` or `wagmi.config.ts` inside the project root. The most basic config file looks like this: + +::: code-group +```js [wagmi.config.js] +export default { + // config options +} +``` +::: + +Note `@wagmi/cli` supports using ES modules syntax in the config file even if the project is not using native Node ESM, e.g. `"type": "module"` in package.json. In this case, the config file is auto pre-processed before load. + +You can also explicitly specify a config file to use with the `--config`/`-c` CLI option (resolved relative to the current directory): + +```bash +wagmi --config my-config.js +``` + +To scaffold a config file quickly, check out the [`init`](/cli/api/commands/init) command. + +## Config Intellisense + +Since Wagmi CLI ships with TypeScript typings, you can use your editor's intellisense with [JSDoc](https://jsdoc.app) type hints: + +::: code-group +```js [wagmi.config.js] +/** @type {import('@wagmi/cli').Config} */ +export default { + // ... +} +``` +::: + +Alternatively, you can use the `defineConfig` utility which should provide intellisense without the need for JSDoc annotations: + +::: code-group +```js [wagmi.config.js] +import { defineConfig } from '@wagmi/cli' + +export default defineConfig({ + // ... +}) +``` +::: + +Wagmi CLI also directly supports TypeScript config files. You can use `wagmi.config.ts` with the `defineConfig` helper as well. + +## Conditional Config + +If the config needs to conditionally determine options based on the environment, it can export a function instead: + +::: code-group +```js [wagmi.config.js] +export default defineConfig(() => { + if (process.env.NODE_ENV === 'dev') { + return { + // dev specific config + } + } else { + return { + // production specific config + } + } +}) +``` +::: + +## Async Config + +If the config needs to call async function, it can export a async function instead: + +::: code-group +```js [wagmi.config.js] +export default defineConfig(async () => { + const data = await asyncFunction() + return { + // ... + } +}) +``` +::: + +This can be useful for resolving external resources from the network or filesystem that are required for configuration ahead of running a command. + +## Array Config + +The config can also be represented either as a pre-defined array or returned as an array from a function: + +::: code-group +```js [wagmi.config.js] +export default defineConfig([ + { + // config 1 + }, + { + // config 2 + }, +]) +``` +::: + +## Environment Variables + +Environmental Variables can be obtained from `process.env` as usual. + +Note that Wagmi CLI doesn't load `.env` files by default as the files to load can only be determined after evaluating the config. However, you can use the exported `loadEnv` utility to load the specific `.env` files if needed. + +::: code-group +```js [wagmi.config.js] +import { defineConfig, loadEnv } from '@wagmi/cli' + +export default defineConfig(() => { + const env = loadEnv({ + mode: process.env.NODE_ENV, + envDir: process.cwd(), + }) + return { + // ... + } +}) +``` +::: \ No newline at end of file diff --git a/wagmi-project/site/cli/config/options.md b/wagmi-project/site/cli/config/options.md new file mode 100644 index 000000000..04a2cd2d5 --- /dev/null +++ b/wagmi-project/site/cli/config/options.md @@ -0,0 +1,132 @@ +# Config Options + +Configuration options for Wagmi CLI. + +## contracts + +`ContractConfig[] | undefined` + +Array of contracts to use when running [commands](/cli/api/commands). `abi` and `name` are required, all other properties are optional. + +### address + +`Address | Record | undefined` + +Contract address or addresses. Accepts an object `{ [chainId]: address }` for targeting specific chains. + +::: code-group +```ts {6,11-14} [wagmi.config.ts] +export default { + out: 'src/generated.ts', + contracts: [ + { + abi: […], + address: '0x…', + name: 'MyCoolContract', + }, + { + abi: […], + address: { + 1: '0xfoo…', + 5: '0xbar…', + }, + name: 'MyCoolMultichainContract' + } + ], +} +``` +::: + +### abi + +`Abi` + +ABI for contract. Used by [plugins](/cli/api/plugins) to generate code base on properties. + +::: code-group +```ts {5} [wagmi.config.ts] +export default { + out: 'src/generated.ts', + contracts: [ + { + abi: […], + name: 'MyCoolContract' + }, + ], +} +``` +::: + +### name + +`string` + +Name of contract. Must be unique. Used by [plugins](/cli/api/plugins) to name generated code. + +::: code-group +```ts {6} [wagmi.config.ts] +export default { + out: 'src/generated.ts', + contracts: [ + { + abi: […], + name: 'MyCoolContract' + }, + ], +} +``` +::: + +## out + +`string` + +Path to output generated code. Must be unique per config. Use an [Array Config](/cli/config/configuring-cli#array-config) for multiple outputs. + +::: code-group +```ts {2} [wagmi.config.ts] +export default { + out: 'src/generated.ts', + contracts: [ + { + abi: […], + name: 'MyCoolContract' + }, + ], +} +``` +::: + +## plugins + +`Plugin[] | undefined` + +Plugins to use and their configuration. + +Wagmi CLI has multiple [built-in plugins](/cli/api/plugins) that are used to manage ABIs, generate code, etc. + +::: code-group +```ts {1,5-20} [wagmi.config.ts] +import { etherscan, react } from '@wagmi/cli/plugins' + +export default { + out: 'src/generated.js', + plugins: [ + etherscan({ + apiKey: process.env.ETHERSCAN_API_KEY, + chainId: 5, + contracts: [ + { + name: 'EnsRegistry', + address: { + 1: '0x314159265dd8dbb310642f98f50c066173c1259b', + 5: '0x112234455c3a32fd11230c42e7bccd4a84e02010', + }, + }, + ], + }), + react(), + ], +} +``` +::: diff --git a/wagmi-project/site/cli/create-wagmi.md b/wagmi-project/site/cli/create-wagmi.md new file mode 100644 index 000000000..bdf8dda30 --- /dev/null +++ b/wagmi-project/site/cli/create-wagmi.md @@ -0,0 +1,75 @@ +# create-wagmi + +## Overview + +create-wagmi is a command line interface (CLI) for scaffolding new Wagmi projects. + +## Usage + +::: code-group +```bash [pnpm] +pnpm create wagmi +``` +```bash [npm] +npm create wagmi@latest +``` +```bash [yarn] +yarn create wagmi +``` +```bash [bun] +bun create wagmi +``` +::: + +## Options + +### `-t`, `--template` + +You can specify a custom [template](#templates) by passing the `--template`/`-t` flag: + +::: code-group +```bash [pnpm] +pnpm create wagmi --template next +``` +```bash [npm] +npm create wagmi@latest --template next +``` +```bash [yarn] +yarn create wagmi --template next +``` +```bash [bun] +bun create wagmi --template next +``` +::: + +### `--bun`/`--npm`/`--pnpm`/`--yarn` + +Use a specific package manager to install dependencies. By default, `create-wagmi` will use the package manager you used to run the command. + +### `-h`, `--help` + +Prints the help message. + +### `-v`, `--version` + +Prints the CLI version. + +## Templates + +`create-wagmi` currently comes with the following templates: + +- `next`: A Next.js Wagmi project. +- `nuxt`: A Nuxt Wagmi project. +- `vite-react`: A Vite (React) Wagmi project. +- `vite-vanilla`: A Vite Wagmi Core project. +- `vite-vue`: A Vite (Vue) Wagmi project. + +If you do not specify the template on the command line, you will be prompted to select a framework and variant. + +- **React** : A React project. + - **Vite** : A React + Vite Wagmi project (`vite-react`). + - **Next** : A React + Next Wagmi project (`next`). +- **Vue**: A Vue project. + - **Vite**: A Vue + Vite Wagmi project (`vite-vue`). + - **Nuxt**: A Vue + Nuxt Wagmi project (`nuxt`). +- **Vanilla**: A Vite Wagmi project without React (`vite-vanilla`). diff --git a/wagmi-project/site/cli/getting-started.md b/wagmi-project/site/cli/getting-started.md new file mode 100644 index 000000000..ccf2d2b60 --- /dev/null +++ b/wagmi-project/site/cli/getting-started.md @@ -0,0 +1,167 @@ +# Getting Started + +## Overview + +Wagmi CLI is a command line interface for managing ABIs (from Etherscan/block explorers, Foundry/Hardhat projects, etc.), generating code (e.g. React Hooks), and much more. It makes working with Ethereum easier by automating manual work so you can build faster. You can learn more about the rationale behind the project in the [Why Wagmi CLI](/cli/why) section. + +## Manual Installation + +To manually add Wagmi CLI to your project, install the required packages. + +::: code-group +```bash [pnpm] +pnpm add -D @wagmi/cli +``` + +```bash [npm] +npm install --save-dev @wagmi/cli +``` + +```bash [yarn] +yarn add -D @wagmi/cli +``` + +```bash [bun] +bun add -D @wagmi/cli +``` +::: + +## Create Config File + +Run the `init` command to generate a configuration file: either `wagmi.config.ts` if TypeScript is detected, otherwise `wagmi.config.js`. You can also create the configuration file manually. See [Configuring CLI](/cli/config/configuring-cli) for more info. + +::: code-group +```bash [pnpm] +pnpm wagmi init +``` + +```bash [npm] +npx wagmi init +``` + +```bash [yarn] +yarn wagmi init +``` + +```bash [bun] +bun wagmi init +``` +::: + +The generated configuration file will look something like this: + +::: code-group +```ts [wagmi.config.ts] +import { defineConfig } from '@wagmi/cli' + +export default defineConfig({ + out: 'src/generated.ts', + contracts: [], + plugins: [], +}) +``` +::: + +## Add Contracts And Plugins + +Once the configuration file is set up, you can add contracts and plugins to it. These contracts and plugins are used to manage ABIs (fetch from block explorers, resolve from the file system, etc.), generate code (React hooks, etc.), and much more! + +For example, we can add the ERC-20 contract from Viem, and the [`etherscan`](/cli/api/plugins/etherscan) and [`react`](/cli/api/plugins/react) plugins. + +::: code-group +```ts{2,3,9-12,15-27,28} [wagmi.config.ts] +import { defineConfig } from '@wagmi/cli' +import { etherscan, react } from '@wagmi/cli/plugins' +import { erc20Abi } from 'viem' +import { mainnet, sepolia } from 'wagmi/chains' + +export default defineConfig({ + out: 'src/generated.ts', + contracts: [ + { + name: 'erc20', + abi: erc20Abi, + }, + ], + plugins: [ + etherscan({ + apiKey: process.env.ETHERSCAN_API_KEY!, + chainId: mainnet.id, + contracts: [ + { + name: 'EnsRegistry', + address: { + [mainnet.id]: '0x314159265dd8dbb310642f98f50c066173c1259b', + [sepolia.id]: '0x112234455c3a32fd11230c42e7bccd4a84e02010', + }, + }, + ], + }), + react(), + ], +}) +``` +::: + +## Run Code Generation + +Now that we added a few contracts and plugins to the configuration file, we can run the [`generate`](/cli/api/commands/generate) command to resolve ABIs and generate code to the `out` file. + +::: code-group +```bash [pnpm] +pnpm wagmi generate +``` + +```bash [npm] +npx wagmi generate +``` + +```bash [yarn] +yarn wagmi generate +``` + +```bash [bun] +bun wagmi generate +``` +::: + +In this example, the `generate` command will do the following: + +- Validate the `etherscan` and `react` plugins +- Fetch and cache the ENS Registry ABI from the Mainnet Etherscan API +- Pull in the `erc20Abi` using the name `'ERC20'` +- Generate React Hooks for both ABIs +- Save ABIs, ENS Registry deployment addresses, and React Hooks to the `out` file + +## Use Generated Code + +Once `out` is created, you can start using the generated code in your project. + +```ts +import { useReadErc20, useReadErc20BalanceOf } from './generated' + +// Use the generated ERC-20 read hook +const { data } = useReadErc20({ + address: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', + functionName: 'balanceOf', + args: ['0xA0Cf798816D4b9b9866b5330EEa46a18382f251e'], +}) + +// Use the generated ERC-20 "balanceOf" hook +const { data } = useReadErc20BalanceOf({ + address: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', + args: ['0xA0Cf798816D4b9b9866b5330EEa46a18382f251e'], +}) +``` + +::: tip +Instead of committing the `out` file, you likely want to add `out` to your `.gitignore` and run `generate` during the build process or before you start your dev server in a `"predev"` script. +::: + +## Next Steps + +For more information on what to do next, check out the following topics. + +- [**Configuring CLI**](/cli/config/configuring-cli) Learn how to configure the CLI to work best for your project. +- [**Commands**](/cli/api/commands) Learn more about the CLI commands and how to use them. +- [**Plugins**](/cli/api/plugins) Browse the collection of plugins and set them up with your config. diff --git a/wagmi-project/site/cli/guides/migrate-from-v1-to-v2.md b/wagmi-project/site/cli/guides/migrate-from-v1-to-v2.md new file mode 100644 index 000000000..2db0fef56 --- /dev/null +++ b/wagmi-project/site/cli/guides/migrate-from-v1-to-v2.md @@ -0,0 +1,51 @@ +--- +title: Migrate from v1 to v2 +titleTemplate: Wagmi CLI +description: Guide for migrating from Wagmi CLI v1 to v2. +--- + +# Migrate from v1 to v2 + +To get started, install the latest version of the Wagmi CLI. + +::: code-group +```bash-vue [pnpm] +pnpm add @wagmi/cli +``` + +```bash-vue [npm] +npm install @wagmi/cli +``` + +```bash-vue [yarn] +yarn add @wagmi/cli +``` + +```bash-vue [bun] +bun add @wagmi/cli +``` +::: + +::: info Not ready to migrate yet? +The Wagmi CLI v1 docs are still available at [1.x.wagmi.sh/cli](https://1.x.wagmi.sh/cli). +::: + +## Changed generated action and hook names + +Generated action and hook names now align with [Wagmi v2 naming conventions](/react/guides/migrate-from-v1-to-v2#renamed-hooks). If you want hooks to still follow Wagmi v1 naming conventions, set [`getActionName`](/cli/api/plugins/actions#getactionname) and [`getHookName`](/cli/api/plugins/react#gethookname) to `'legacy'`. + +```ts +import { defineConfig } from '@wagmi/cli' +import { actions, react } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + actions({ + getActionName: 'legacy', // [!code focus] + }), + react({ + getHookName: 'legacy', // [!code focus] + }), + ], +}) +``` diff --git a/wagmi-project/site/cli/installation.md b/wagmi-project/site/cli/installation.md new file mode 100644 index 000000000..649565ca3 --- /dev/null +++ b/wagmi-project/site/cli/installation.md @@ -0,0 +1,60 @@ +# Installation + +Install Wagmi CLI via your package manager. + +## Package Manager + +Install the required package. + +::: code-group +```bash [pnpm] +pnpm add @wagmi/cli +``` + +```bash [npm] +npm install @wagmi/cli +``` + +```bash [yarn] +yarn add @wagmi/cli +``` + +```bash [bun] +bun add @wagmi/cli +``` +::: + +## Using Unreleased Commits + +If you can't wait for a new release to test the latest features, you can either install from the `canary` tag (tracks the [`main`](https://github.com/wevm/wagmi/tree/main) branch). + +::: code-group +```bash [pnpm] +pnpm add @wagmi/cli@canary +``` + +```bash [npm] +npm install @wagmi/cli@canary +``` + +```bash [yarn] +yarn add @wagmi/cli@canary +``` + +```bash [bun] +bun add @wagmi/cli@canary +``` +::: + +Or clone the [Wagmi repo](https://github.com/wevm/wagmi) to your local machine, build, and link it yourself. + +```bash +git clone https://github.com/wevm/wagmi.git +cd wagmi +pnpm install +pnpm build +cd packages/cli +pnpm link --global +``` + +Then go to the project where you are using the Wagmi CLI and run `pnpm link --global @wagmi/cli` (or the package manager that you used to link Wagmi CLI globally). \ No newline at end of file diff --git a/wagmi-project/site/cli/why.md b/wagmi-project/site/cli/why.md new file mode 100644 index 000000000..a626c4600 --- /dev/null +++ b/wagmi-project/site/cli/why.md @@ -0,0 +1,92 @@ +# Why Wagmi CLI + +## The Problem + +The most common way to interact with smart contracts is through [Application Binary Interfaces](https://docs.soliditylang.org/en/latest/abi-spec.html). ABIs describe smart contracts' public functionality (e.g. functions, events, errors) as well as how to encode and decode related data (e.g. arguments and results). + +While ABIs are extremely powerful, there isn't a uniform way developers manage them in their apps. Developers do a bunch of different things, like: + +- Publish packages on npm containing ABIs +- Write custom scripts to fetch ABIs from external sources +- Compile contracts into application project +- Copy and paste ABIs from local projects or block explorers + +All these approaches take time that you could spend doing more important things, like interacting with your smart contracts! + +## The Solution + +The Wagmi CLI is an attempt to automate manual work so you can build faster. In short, the CLI manages ABIs and generates code. It takes ABIs as inputs and outputs ABIs and generated code. For example, the [Etherscan plugin](/cli/api/plugins/etherscan) allows you to fetch ABIs across multiple chains and deployments and immediately start importing them into your project. + +Code generation is another big advantage of the CLI. Using the [React plugin](/cli/api/plugins/react), you can generate [Wagmi Hooks](/react/api/hooks) for ABIs. When you combine this with the CLI's different ABI sources, like Etherscan, Foundry/Hardhat, and more, you reduce a lot of boilerplate code. + +::: code-group +```ts [Diff] +import { useReadContract, useWriteContract } from 'wagmi' // [!code --] +import { froggyFriendsAbi, froggyFriendsAddress } from './generated' // [!code --] +import { useReadFroggyFriends, useWriteFroggyFriends } from './generated' // [!code ++] + +function App() { + const { data } = useReadContract({ // [!code --] + const { data } = useReadFroggyFriends({ // [!code ++] + abi: froggyFriendsAbi, // [!code --] + address: froggyFriendsAddress, // [!code --] + functionName: 'tokenURI', + args: [123n], + }) + + const { write } = useWriteContract() // [!code --] + const { write } = useWriteFroggyFriends() // [!code ++] + const onClick = React.useCallback(() => { + write({ + abi: froggyFriendsAbi, // [!code --] + address: froggyFriendsAddress, // [!code --] + functionName: 'mint', + args: ['foo', 123n], + }) + }, [write]) +} +``` +```ts [Before] +import { useReadContract, useWriteContract } from 'wagmi' +import { froggyFriendsAbi, froggyFriendsAddress } from './generated' + +function App() { + const { data } = useReadContract({ + abi: froggyFriendsAbi, + address: froggyFriendsAddress, + functionName: 'tokenURI', + args: [123n], + }) + + const { write } = useWriteContract() + const onClick = React.useCallback(() => { + write({ + abi: froggyFriendsAbi, + address: froggyFriendsAddress, + functionName: 'mint', + args: ['foo', 123n], + }) + }, [write]) +} +``` +```ts [After] +import { useReadFroggyFriends, useWriteFroggyFriends } from './generated' + +function App() { + const { data } = useReadFroggyFriends({ + functionName: 'tokenURI', + args: [123n], + }) + + const { write } = useWriteFroggyFriends() + const onClick = React.useCallback(() => { + write({ + functionName: 'mint', + args: ['foo', 123n], + }) + }, [write]) +} +``` +::: + +Finally, the Wagmi CLI supports popular smart contract development tools, [Foundry](/cli/api/plugins/foundry) and [Hardhat](/cli/api/plugins/hardhat). You can run the CLI in [watch mode](/cli/api/commands/generate#w-watch), make changes to your contracts, and the CLI will automatically pick up ABI changes and run plugins over those changes. A major boon to working a monorepo and shortening the feedback loop across your stack. diff --git a/wagmi-project/site/components/Browsers.vue b/wagmi-project/site/components/Browsers.vue new file mode 100644 index 000000000..4367018bc --- /dev/null +++ b/wagmi-project/site/components/Browsers.vue @@ -0,0 +1,9 @@ + + + diff --git a/wagmi-project/site/components/SearchChains.vue b/wagmi-project/site/components/SearchChains.vue new file mode 100644 index 000000000..b649a6202 --- /dev/null +++ b/wagmi-project/site/components/SearchChains.vue @@ -0,0 +1,82 @@ + + + + + diff --git a/wagmi-project/site/core/api/actions.md b/wagmi-project/site/core/api/actions.md new file mode 100644 index 000000000..664cd9a86 --- /dev/null +++ b/wagmi-project/site/core/api/actions.md @@ -0,0 +1,25 @@ + + +# Actions + +Actions for accounts, wallets, contracts, transactions, signing, ENS, and more. + +## Import + +```ts +import { getAccount } from '@wagmi/core' +``` + +## Available Actions + + diff --git a/wagmi-project/site/core/api/actions/call.md b/wagmi-project/site/core/api/actions/call.md new file mode 100644 index 000000000..52f202a57 --- /dev/null +++ b/wagmi-project/site/core/api/actions/call.md @@ -0,0 +1,340 @@ + + +# call + +Action for executing a new message call immediately without submitting a transaction to the network. + +## Import + +```ts +import { call } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { call } from '@wagmi/core' +import { config } from './config' + +await call(config, { + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts twoslash +import { type CallParameters } from '@wagmi/core' +``` + +### account + +`Account | Address | undefined` + +The Account to call from. + +::: code-group +```ts [index.ts] +import { call } from '@wagmi/core' +import { config } from './config' + +await call(config, { + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', // [!code focus] + data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### data + +`` `0x${string}` | undefined `` + +A contract hashed method call with encoded args. + +::: code-group +```ts [index.ts] +import { call } from '@wagmi/core' +import { config } from './config' + +await call(config, { + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', // [!code focus] + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### to + +`Address | undefined` + +The contract address or recipient. + +::: code-group +```ts [index.ts] +import { call } from '@wagmi/core' +import { config } from './config' + +await call(config, { + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### accessList + +`AccessList | undefined` + +The access list. + +::: code-group +```ts [index.ts] +import { call } from '@wagmi/core' +import { config } from './config' + +await call(config, { + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + accessList: [ // [!code focus:6] + { + address: '0x1', + storageKeys: ['0x1'], + }, + ], + data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### gas + +`bigint | undefined` + +The gas provided for transaction execution. + +::: code-group +```ts [index.ts] +import { call } from '@wagmi/core' +import { config } from './config' + +await call(config, { + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + gas: 1_000_000n, // [!code focus] + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### gasPrice + +`bigint | undefined` + +The price (in wei) to pay per gas. Only applies to [Legacy Transactions](https://viem.sh/docs/glossary/terms.html#legacy-transaction). + +::: code-group +```ts [index.ts] +import { call } from '@wagmi/core' +import { parseGwei } from 'viem' +import { config } from './config' + +await call(config, { + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + gasPrice: parseGwei('20'), // [!code focus] + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### maxFeePerGas + +`bigint | undefined` + +Total fee per gas (in wei), inclusive of `maxPriorityFeePerGas`. Only applies to [EIP-1559 Transactions](https://viem.sh/docs/glossary/terms.html#eip-1559-transaction). + +::: code-group +```ts [index.ts] +import { call } from '@wagmi/core' +import { parseGwei } from 'viem' +import { config } from './config' + +await call(config, { + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + maxFeePerGas: parseGwei('20'), // [!code focus] + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### maxPriorityFeePerGas + +`bigint | undefined` + +Max priority fee per gas (in wei). Only applies to [EIP-1559 Transactions](https://viem.sh/docs/glossary/terms.html#eip-1559-transaction). + +::: code-group +```ts [index.ts] +import { call } from '@wagmi/core' +import { parseGwei } from 'viem' +import { config } from './config' + +await call(config, { + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + maxFeePerGas: parseGwei('20'), + maxPriorityFeePerGas: parseGwei('2'), // [!code focus] + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### nonce + +`number | undefined` + +Unique number identifying this transaction. + +::: code-group +```ts [index.ts] +import { call } from '@wagmi/core' +import { config } from './config' + +await call(config, { + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + nonce: 420, // [!code focus] + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### value + +`bigint | undefined` + +Value (in wei) sent with this transaction. + +::: code-group +```ts [index.ts] +import { call } from '@wagmi/core' +import { parseEther } from 'viem' +import { config } from './config' + +await call(config, { + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + value: parseEther('1'), // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### blockNumber + +`number | undefined` + +The block number to perform the call against. + +::: code-group +```ts [index.ts] +import { call } from '@wagmi/core' +import { config } from './config' + +await call(config, { + blockNumber: 15121123n, // [!code focus] + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +The block tag to perform the call against. + +::: code-group +```ts [index.ts] +import { call } from '@wagmi/core' +import { config } from './config' + +await call(config, { + blockTag: 'safe', // [!code focus] + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +The block tag to perform the call against. + +::: code-group +```ts [index.ts] +import { call } from '@wagmi/core' +import { config } from './config' +import { mainnet } from '@wagmi/core/chains' + +await call(config, { + chainId: mainnet.id, // [!code focus] + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts twoslash +import { type CallReturnType } from '@wagmi/core' +``` + +`{ data: 0x${string} }` + +The call data. + +## Error + +```ts twoslash +import { type CallErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`call`](https://viem.sh/docs/actions/public/call.html) diff --git a/wagmi-project/site/core/api/actions/connect.md b/wagmi-project/site/core/api/actions/connect.md new file mode 100644 index 000000000..30d04a85e --- /dev/null +++ b/wagmi-project/site/core/api/actions/connect.md @@ -0,0 +1,102 @@ + + +# connect + +Action for connecting accounts with [connectors](/core/api/connectors). + +## Import + +```ts +import { connect } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { connect } from '@wagmi/core' +import { injected } from '@wagmi/connectors' +import { config } from './config' + +const result = await connect(config, { connector: injected() }) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type ConnectParameters } from '@wagmi/core' +``` + +### chainId + +`number | undefined` + +Chain ID to connect to. + +Not all connectors support connecting directly to a `chainId` (e.g. they don't support programmatic chain switching). In those cases, the connector will connect to whatever chain the connector's provider is connected to. + +::: code-group +```ts [index.ts] +import { connect } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { injected } from '@wagmi/connectors' +import { config } from './config' + +const result = await connect(config, { + chainId: mainnet.id, // [!code focus] + connector: injected(), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### connector + +`CreateConnectorFn | Connector` + +[Connector](/core/api/connectors) to connect with. + +::: code-group +```ts [index.ts] +import { connect } from '@wagmi/core' +import { injected } from '@wagmi/connectors' // [!code focus] +import { config } from './config' + +const result = await connect(config, { + connector: injected(), // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type ConnectReturnType } from '@wagmi/core' +``` + +### accounts + +`readonly [Address, ...Address[]]` + +Connected accounts from connector. + +### chainId + +`number` + +Connected chain ID from connector. + +## Error + +```ts +import { type ConnectErrorType } from '@wagmi/core' +``` + + diff --git a/wagmi-project/site/core/api/actions/deployContract.md b/wagmi-project/site/core/api/actions/deployContract.md new file mode 100644 index 000000000..3cdbfd130 --- /dev/null +++ b/wagmi-project/site/core/api/actions/deployContract.md @@ -0,0 +1,264 @@ + + +# deployContract + +Action for deploying a contract to the network, given bytecode, and constructor arguments. + +## Import + +```ts +import { deployContract } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { deployContract } from '@wagmi/core' +import { wagmiAbi } from './abi' +import { config } from './config' + +const result = await deployContract(config, { + abi: wagmiAbi, + bytecode: '0x608060405260405161083e38038061083e833981016040819052610...', +}) +``` +```ts [abi.ts] +export const wagmiAbi = [ + ... + { + inputs: [], + stateMutability: "nonpayable", + type: "constructor", + }, + ... +] as const +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Deploying with Constructor Args + +::: code-group +```ts [index.ts] +import { deployContract } from '@wagmi/core' +import { wagmiAbi } from './abi' +import { config } from './config' + +const result = await deployContract(config, { + abi: wagmiAbi, + args: [69420], + bytecode: '0x608060405260405161083e38038061083e833981016040819052610...', +}) +``` +```ts [abi.ts] +export const wagmiAbi = [ + ... + { + inputs: [{ name: "x", type: "uint32" }], + stateMutability: "nonpayable", + type: "constructor", + }, + ... +] as const; +``` +<<< @/snippets/core/config.ts[config.ts] +::: + + +## Parameters + +```ts +import { type DeployContractParameters } from '@wagmi/core' +``` + +### abi + +`Abi` + +The contract's ABI. + +::: code-group +```ts [index.ts] +import { deployContract } from '@wagmi/core' +import { wagmiAbi } from './abi' +import { config } from './config' + +const result = await deployContract(config, { + abi: wagmiAbi, // [!code focus] + args: [69420], + bytecode: '0x608060405260405161083e38038061083e833981016040819052610...', +}) +``` +```ts [abi.ts] +export const wagmiAbi = [ + ... + { + inputs: [{ name: "x", type: "uint32" }], + stateMutability: "nonpayable", + type: "constructor", + }, + ... +] as const; +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### account + +`Address | Account | undefined` + +Account to use when deploying a contract. Throws if account is not found on [`connector`](#connector). + +::: code-group +```ts [index.ts] +import { deployContract } from '@wagmi/core' +import { wagmiAbi } from './abi' +import { config } from './config' + +const result = await deployContract(config, { + abi: wagmiAbi, + account: '0xd2135CfB216b74109775236E36d4b433F1DF507B', // [!code focus] + args: [69420], + bytecode: '0x608060405260405161083e38038061083e833981016040819052610...', +}) +``` +```ts [abi.ts] +export const wagmiAbi = [ + ... + { + inputs: [{ name: "x", type: "uint32" }], + stateMutability: "nonpayable", + type: "constructor", + }, + ... +] as const; +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### args + +`readonly unknown[] | undefined` + +- Arguments to pass when deploying the contract. +- Inferred from [`abi`](#abi). + +::: code-group +```ts [index.ts] +import { deployContract } from '@wagmi/core' +import { wagmiAbi } from './abi' +import { config } from './config' + +const result = await deployContract(config, { + abi: wagmiAbi, + args: [69420], // [!code focus] + bytecode: '0x608060405260405161083e38038061083e833981016040819052610...', +}) +``` +```ts [abi.ts] +export const wagmiAbi = [ + ... + { + inputs: [{ name: "x", type: "uint32" }], + stateMutability: "nonpayable", + type: "constructor", + }, + ... +] as const; +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### bytecode + +`Hex` + +The contract's bytecode. + +::: code-group +```ts [index.ts] +import { deployContract } from '@wagmi/core' +import { wagmiAbi } from './abi' +import { config } from './config' + +const result = await deployContract(config, { + abi: wagmiAbi, + args: [69420], + bytecode: '0x608060405260405161083e38038061083e833981016040819052610...', // [!code focus] +}) +``` +```ts [abi.ts] +export const wagmiAbi = [ + ... + { + inputs: [{ name: "x", type: "uint32" }], + stateMutability: "nonpayable", + type: "constructor", + }, + ... +] as const; +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### connector + +`Connector | undefined` + +- Connector to use when deploying a contract. +- Defaults to current connector. + +::: code-group +```ts [index.ts] +import { getAccount, deployContract } from '@wagmi/core' +import { wagmiAbi } from './abi' +import { config } from './config' + +const { connector } = getAccount(config) +const result = await deployContract(config, { + abi: wagmiAbi, + args: [69420], + bytecode: '0x608060405260405161083e38038061083e833981016040819052610...', + connector, // [!code focus] +}) +``` +```ts [abi.ts] +export const wagmiAbi = [ + ... + { + inputs: [{ name: "x", type: "uint32" }], + stateMutability: "nonpayable", + type: "constructor", + }, + ... +] as const; +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type DeployContractReturnType } from '@wagmi/core' +``` + +[`Hash`](https://viem.sh/docs/glossary/types.html#hash) + +Transaction hash. + +## Error + +```ts +import { type DeployContractErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`deployContract`](https://viem.sh/docs/contract/deployContract) diff --git a/wagmi-project/site/core/api/actions/disconnect.md b/wagmi-project/site/core/api/actions/disconnect.md new file mode 100644 index 000000000..6c77fb5c7 --- /dev/null +++ b/wagmi-project/site/core/api/actions/disconnect.md @@ -0,0 +1,60 @@ + + +# disconnect + +Action for disconnecting connections. + +## Import + +```ts +import { disconnect } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { disconnect } from '@wagmi/core' +import { config } from './config' + +await disconnect(config) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type DisconnectParameters } from '@wagmi/core' +``` + +### connector + +`Connector | undefined` + +[Connector](/core/api/connectors) to disconnect with. + +::: code-group +```ts [index.ts] +import { disconnect, getAccount } from '@wagmi/core' +import { config } from './config' + +const { connector } = getAccount(config) +const result = await disconnect(config, { + connector, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Error + +```ts +import { type DisconnectErrorType } from '@wagmi/core' +``` + + diff --git a/wagmi-project/site/core/api/actions/estimateFeesPerGas.md b/wagmi-project/site/core/api/actions/estimateFeesPerGas.md new file mode 100644 index 000000000..ce804efeb --- /dev/null +++ b/wagmi-project/site/core/api/actions/estimateFeesPerGas.md @@ -0,0 +1,139 @@ + + +# estimateFeesPerGas + +Returns an estimate for the fees per gas (in wei) for a transaction to be likely included in the next block. + +## Import + +```ts +import { estimateFeesPerGas } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { estimateFeesPerGas } from '@wagmi/core' +import { config } from './config' + +const result = await estimateFeesPerGas(config) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type EstimateFeesPerGasParameters } from '@wagmi/core' +``` + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```ts [index.ts] +import { estimateFeesPerGas } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { config } from './config' + +const result = await estimateFeesPerGas(config, { + chainId: mainnet.id, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### formatUnits + +`'ether' | 'gwei' | 'wei' | number | undefined` + +- Units to use when formatting result. +- Defaults to `'ether'`. + +::: code-group +```ts [index.ts] +import { estimateFeesPerGas } from '@wagmi/core' +import { config } from './config' + +const feesPerGas = estimateFeesPerGas(config, { + formatUnits: 'ether', // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### type + +`'legacy' | 'eip1559'` + +- Fee value type. +- Defaults to `'eip1559'` + +::: code-group +```ts [index.ts] +import { estimateFeesPerGas } from '@wagmi/core' +import { config } from './config' + +const result = estimateFeesPerGas(config, { + type: 'legacy', // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type EstimateFeesPerGasReturnType } from '@wagmi/core' +``` + +[`FeeValues`](https://viem.sh/docs/glossary/types.html#feevalues) + +An estimate (in wei) for the fees per gas. + +### formatted + +`{ gasPrice: string | undefined; maxFeePerGas: string | undefined; maxPriorityFeePerGas: string | undefined; }` + +Object of formatted values using [`formatUnits`](#formatunits). + +### gasPrice + +`bigint | undefined` + +- Gas price. +- When [`type`](#type) is `'eip1559'`, value is `undefined`. + +### maxFeePerGas + +`bigint | undefined` + +- Max fee per gas. +- When [`type`](#type) is `'legacy'`, value is `undefined`. + +### maxPriorityFeePerGas + +`bigint | undefined` + +- Max priority fee per gas. +- When [`type`](#type) is `'legacy'`, value is `undefined`. + +## Error + +```ts +import { type EstimateFeesPerGasErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`estimateFeesPerGas`](https://viem.sh/docs/actions/public/estimateFeesPerGas.html) diff --git a/wagmi-project/site/core/api/actions/estimateGas.md b/wagmi-project/site/core/api/actions/estimateGas.md new file mode 100644 index 000000000..cbeb1ba40 --- /dev/null +++ b/wagmi-project/site/core/api/actions/estimateGas.md @@ -0,0 +1,340 @@ + + +# estimateGas + +Action for estimating the gas necessary to complete a transaction without submitting it to the network. + +## Import + +```ts +import { estimateGas } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { estimateGas } from '@wagmi/core' +import { parseEther } from 'viem' +import { config } from './config' + +const result = await estimateGas(config, { + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type EstimateGasParameters } from '@wagmi/core' +``` + +### accessList + +`AccessList | undefined` + +The access list. + +::: code-group +```ts [index.ts] +import { estimateGas } from '@wagmi/core' +import { parseEther } from 'viem' +import { config } from './config' + +const result = await estimateGas(config, { + accessList: [{ // [!code focus] + address: '0x1', // [!code focus] + storageKeys: ['0x1'], // [!code focus] + }], // [!code focus] + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### account + +`Address | Account | undefined` + +Account to use when estimating gas. + +::: code-group +```ts [index.ts] +import { estimateGas } from '@wagmi/core' +import { parseEther } from 'viem' +import { config } from './config' + +const result = await estimateGas(config, { + account: '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', // [!code focus] + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +Chain ID to target when estimating gas. + +::: code-group +```ts [index.ts] +import { estimateGas } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { parseEther } from 'viem' +import { config } from './config' + +const result = await estimateGas(config, { + chainId: mainnet.id, // [!code focus] + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### connector + +`Connector | undefined` + +Connector to estimate with. If no [`account`](#account) is provided, will use default account from connector. + +::: code-group +```ts [index.ts] +import { getConnections, estimateGas } from '@wagmi/core' +import { parseEther } from 'viem' +import { config } from './config' + +const connections = getConnections(config) +const result = await estimateGas(config, { + connector: connections[0]?.connector, // [!code focus] + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### data + +`` `0x${string}` | undefined `` + +A contract hashed method call with encoded args. + +::: code-group +```ts [index.ts] +import { estimateGas } from '@wagmi/core' +import { parseEther } from 'viem' +import { config } from './config' + +const result = await estimateGas(config, { + data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', // [!code focus] + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### gas + +`bigint | undefined` + +Gas provided for transaction execution. + +::: code-group +```ts [index.ts] +import { estimateGas } from '@wagmi/core' +import { parseEther, parseGwei } from 'viem' +import { config } from './config' + +const result = await estimateGas(config, { + gas: parseGwei('20'), // [!code focus] + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +--- + +### gasPrice + +`bigint | undefined` + +The price in wei to pay per gas. Only applies to [Legacy Transactions](https://viem.sh/docs/glossary/terms.html#legacy-transaction). + +::: code-group +```ts [index.ts] +import { estimateGas } from '@wagmi/core' +import { parseEther, parseGwei } from 'viem' +import { config } from './config' + +const result = await estimateGas(config, { + gasPrice: parseGwei('20'), // [!code focus] + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### maxFeePerGas + +`bigint | undefined` + +Total fee per gas in wei, inclusive of [`maxPriorityFeePerGas`](#maxPriorityFeePerGas). Only applies to [EIP-1559 Transactions](https://viem.sh/docs/glossary/terms.html#eip-1559-transaction). + +::: code-group +```ts [index.ts] +import { estimateGas } from '@wagmi/core' +import { parseEther, parseGwei } from 'viem' +import { config } from './config' + +const result = await estimateGas(config, { + maxFeePerGas: parseGwei('20'), // [!code focus] + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### maxPriorityFeePerGas + +`bigint | undefined` + +Max priority fee per gas in wei. Only applies to [EIP-1559 Transactions](https://viem.sh/docs/glossary/terms.html#eip-1559-transaction). + +::: code-group +```ts [index.ts] +import { estimateGas } from '@wagmi/core' +import { parseEther, parseGwei } from 'viem' +import { config } from './config' + +const result = await estimateGas(config, { + maxFeePerGas: parseGwei('20'), + maxPriorityFeePerGas: parseGwei('2'), // [!code focus] + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +--- + +### nonce + +`number` + +Unique number identifying this transaction. + +::: code-group +```ts [index.ts] +import { estimateGas } from '@wagmi/core' +import { parseEther } from 'viem' +import { config } from './config' + +const result = await estimateGas(config, { + nonce: 123, // [!code focus] + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### to + +`Address | undefined` + +The transaction recipient or contract address. + +::: code-group +```ts [index.ts] +import { estimateGas } from '@wagmi/core' +import { parseEther } from 'viem' +import { config } from './config' + +const result = await estimateGas(config, { + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', // [!code focus] + value: parseEther('0.01'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### type + +`'legacy' | 'eip1559' | 'eip2930' | undefined` + +Optional transaction request type to narrow parameters. + +::: code-group +```ts [index.ts] +import { estimateGas } from '@wagmi/core' +import { parseEther } from 'viem' +import { config } from './config' + +const result = await estimateGas(config, { + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + type: 'eip1559', // [!code focus] + value: parseEther('0.01'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### value + +`bigint | undefined` + +Value in wei sent with this transaction. + +::: code-group +```ts [index.ts] +import { estimateGas } from '@wagmi/core' +import { parseEther } from 'viem' +import { config } from './config' + +const result = await estimateGas(config, { + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type EstimateGasReturnType } from '@wagmi/core' +``` + +`bigint` + +The gas estimate in wei. + +## Error + +```ts +import { type EstimateGasErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`estimateGas`](https://viem.sh/docs/actions/public/estimateGas.html) diff --git a/wagmi-project/site/core/api/actions/estimateMaxPriorityFeePerGas.md b/wagmi-project/site/core/api/actions/estimateMaxPriorityFeePerGas.md new file mode 100644 index 000000000..906e98b93 --- /dev/null +++ b/wagmi-project/site/core/api/actions/estimateMaxPriorityFeePerGas.md @@ -0,0 +1,74 @@ + + +# estimateMaxPriorityFeePerGas + +Returns an estimate for the max priority fee per gas (in wei) for a transaction to be likely included in the next block. + +## Import + +```ts +import { estimateMaxPriorityFeePerGas } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { estimateMaxPriorityFeePerGas } from '@wagmi/core' +import { config } from './config' + +const result = await estimateMaxPriorityFeePerGas(config) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type EstimateFeesPerGasParameters } from '@wagmi/core' +``` + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```ts [index.ts] +import { estimateMaxPriorityFeePerGas } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { config } from './config' + +const result = await estimateMaxPriorityFeePerGas(config, { + chainId: mainnet.id, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type EstimateFeesPerGasReturnType } from '@wagmi/core' +``` + +`bigint` + +An estimate (in wei) for the max priority fee per gas. + +## Error + +```ts +import { type EstimateFeesPerGasErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`estimateMaxPriorityFeePerGas`](https://viem.sh/docs/actions/public/estimateMaxPriorityFeePerGas.html) diff --git a/wagmi-project/site/core/api/actions/getAccount.md b/wagmi-project/site/core/api/actions/getAccount.md new file mode 100644 index 000000000..a8dde7602 --- /dev/null +++ b/wagmi-project/site/core/api/actions/getAccount.md @@ -0,0 +1,29 @@ +# getAccount + +Action for getting current account. + +## Import + +```ts +import { getAccount } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { getAccount } from '@wagmi/core' +import { config } from './config' + +const account = getAccount(config) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type GetAccountReturnType } from '@wagmi/core' +``` + + diff --git a/wagmi-project/site/core/api/actions/getBalance.md b/wagmi-project/site/core/api/actions/getBalance.md new file mode 100644 index 000000000..192d5a69c --- /dev/null +++ b/wagmi-project/site/core/api/actions/getBalance.md @@ -0,0 +1,197 @@ + + +# getBalance + +Action for fetching native currency or token balance. + +## Import + +```ts +import { getBalance } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { getBalance } from '@wagmi/core' +import { config } from './config' + +const balance = getBalance(config, { + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type GetBalanceParameters } from '@wagmi/core' +``` + +### address + +`Address` + +Address to get balance for. + +::: code-group +```ts [index.ts] +import { getBalance } from '@wagmi/core' +import { config } from './config' + +const balance = getBalance(config, { + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +--- + +### blockNumber + +`bigint | undefined` + +Block number to get balance at. + +::: code-group +```ts [index.ts] +import { getBalance } from '@wagmi/core' +import { config } from './config' + +const balance = getBalance(config, { + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', + blockNumber: 17829139n, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Block tag to get balance at. + +::: code-group +```ts [index.ts] +import { getBalance } from '@wagmi/core' +import { config } from './config' + +const balance = getBalance(config, { + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', + blockTag: 'latest', // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +--- + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```ts [index.ts] +import { getBalance } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { config } from './config' + +const balance = await getBalance(config, { + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', + chainId: mainnet.id, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### token + +`Address | undefined` + +ERC-20 token address to get balance for. + +::: code-group +```ts [index.ts] +import { getBalance } from '@wagmi/core' +import { config } from './config' + +const balance = getBalance(config, { + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', + token: '0x6B175474E89094C44Da98b954EedeAC495271d0F', // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### unit + +`'ether' | 'gwei' | 'wei' | number | undefined` + +- Units to use when formatting result. +- Defaults to `'ether'`. + +::: code-group +```ts [index.ts] +import { getBalance } from '@wagmi/core' +import { config } from './config' + +const balance = getBalance(config, { + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', + unit: 'ether', // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type GetBalanceReturnType } from '@wagmi/core' +``` + +### decimals + +`number` + +Number of decimals for balance [`value`](#value). + +### formatted + +`string` + +Formatted value of balance using [`unit`](#unit). + +### symbol + +`string` + +Symbol of native currency or token. + +### value + +`bigint` + +Raw value of balance. + +## Error + +```ts +import { type GetBalanceErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`getBalance`](https://viem.sh/docs/actions/public/getBalance.html) for native currency balances +- [`multicall`](https://viem.sh/docs/actions/public/multicall.html) for token balances diff --git a/wagmi-project/site/core/api/actions/getBlock.md b/wagmi-project/site/core/api/actions/getBlock.md new file mode 100644 index 000000000..980b02624 --- /dev/null +++ b/wagmi-project/site/core/api/actions/getBlock.md @@ -0,0 +1,146 @@ + + +# getBlock + +Action for fetching information about a block at a block number, hash or tag. + +## Import + +```ts +import { getBlock } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { getBlock } from '@wagmi/core' +import { config } from './config' + +const blockNumber = await getBlock(config) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type GetBlockParameters } from '@wagmi/core' +``` + +### blockHash + +`` `0x${string}` `` + +Information at a given block hash. + +::: code-group +```ts [index.ts] +import { getBlock } from '@wagmi/core' +import { config } from './config' + +const blockNumber = await getBlock(config, { + blockHash: '0x89644bbd5c8d682a2e9611170e6c1f02573d866d286f006cbf517eec7254ec2d' // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### blockNumber + +`` bigint `` + +Information at a given block number. + +::: code-group +```ts [index.ts] +import { getBlock } from '@wagmi/core' +import { config } from './config' + +const blockNumber = await getBlock(config, { + blockNumber: 42069n // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### blockTag + +`` 'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' `` + +Information at a given block tag. Defaults to `'latest'`. + +::: code-group +```ts [index.ts] +import { getBlock } from '@wagmi/core' +import { config } from './config' + +const blockNumber = await getBlock(config, { + blockTag: 'pending' // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```ts [index.ts] +import { getBlock } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { config } from './config' + +const blockNumber = await getBlock(config, { + chainId: mainnet.id, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### includeTransactions + +`boolean` + +Whether or not to include transactions as objects. + +::: code-group +```ts [index.ts] +import { getBlock } from '@wagmi/core' +import { config } from './config' + +const blockNumber = await getBlock(config, { + includeTransactions: true // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type GetBlockReturnType } from '@wagmi/core' +``` + +[`Block`](https://viem.sh/docs/glossary/types.html#block) + +Information about the block. + +## Error + +```ts +import { type GetBlockErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`getBlock`](https://viem.sh/docs/actions/public/getBlock.html) diff --git a/wagmi-project/site/core/api/actions/getBlockNumber.md b/wagmi-project/site/core/api/actions/getBlockNumber.md new file mode 100644 index 000000000..ce13cbb14 --- /dev/null +++ b/wagmi-project/site/core/api/actions/getBlockNumber.md @@ -0,0 +1,93 @@ + + +# getBlockNumber + +Action for fetching the number of the most recent block seen. + +## Import + +```ts +import { getBlockNumber } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { getBlockNumber } from '@wagmi/core' +import { config } from './config' + +const blockNumber = await getBlockNumber(config) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type GetBlockNumberParameters } from '@wagmi/core' +``` + +### cacheTime + +`number | undefined` + +Time in milliseconds that cached block number will remain in memory. + +::: code-group +```ts [index.ts] +import { getBlockNumber } from '@wagmi/core' +import { config } from './config' + +const blockNumber = await getBlockNumber(config, { + cacheTime: 4_000, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```ts [index.ts] +import { getBlockNumber } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { config } from './config' + +const blockNumber = await getBlockNumber(config, { + chainId: mainnet.id, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type GetBlockNumberReturnType } from '@wagmi/core' +``` + +`bigint` + +Most recent block number seen. + +## Error + +```ts +import { type GetBlockNumberErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`getBlockNumber`](https://viem.sh/docs/actions/public/getBlockNumber.html) +- [`watchBlockNumber`](https://viem.sh/docs/actions/public/watchBlockNumber.html) diff --git a/wagmi-project/site/core/api/actions/getBlockTransactionCount.md b/wagmi-project/site/core/api/actions/getBlockTransactionCount.md new file mode 100644 index 000000000..c35127220 --- /dev/null +++ b/wagmi-project/site/core/api/actions/getBlockTransactionCount.md @@ -0,0 +1,92 @@ + + +# getBlockTransactionCount + +Action for fetching the number of Transactions at a block number, hash or tag. + +## Import + +```ts +import { getBlockTransactionCount } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { getBlockTransactionCount } from '@wagmi/core' +import { config } from './config' + +const blockTransactionCount = await getBlockTransactionCount(config) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type GetBlockTransactionCountParameters } from '@wagmi/core' +``` + +### cacheTime + +`number | undefined` + +Time in milliseconds that cached block transaction count will remain in memory. + +::: code-group +```ts [index.ts] +import { getBlockTransactionCount } from '@wagmi/core' +import { config } from './config' + +const blockTransactionCount = await getBlockTransactionCount(config, { + cacheTime: 4_000, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```ts [index.ts] +import { getBlockTransactionCount } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { config } from './config' + +const blockTransactionCount = await getBlockTransactionCount(config, { + chainId: mainnet.id, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type GetBlockTransactionCountReturnType } from '@wagmi/core' +``` + +`number` + +The number of Transactions at a block number + +## Error + +```ts +import { type GetBlockTransactionCountErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`getBlockTransactionCount`](https://viem.sh/docs/actions/public/getBlockTransactionCount.html) diff --git a/wagmi-project/site/core/api/actions/getBytecode.md b/wagmi-project/site/core/api/actions/getBytecode.md new file mode 100644 index 000000000..3a926d6ee --- /dev/null +++ b/wagmi-project/site/core/api/actions/getBytecode.md @@ -0,0 +1,133 @@ + + +# getBytecode + +Action for retrieving the bytecode at an address. + +## Import + +```ts +import { getBytecode } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { getBytecode } from '@wagmi/core' +import { config } from './config' + +await getBytecode(config, { + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type GetBytecodeParameters } from '@wagmi/core' +``` + +### address + +`Address` + +The contract address. + +::: code-group +```ts [index.ts] +import { getBytecode } from '@wagmi/core' +import { config } from './config' + +await getBytecode(config, { + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### blockNumber + +`bigint | undefined` + +The block number to check the bytecode at. + +::: code-group +```ts [index.ts] +import { getBytecode } from '@wagmi/core' +import { config } from './config' + +await getBytecode(config, { + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + blockNumber: 16280770n, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +The block tag to check the bytecode at. + +::: code-group +```ts [index.ts] +import { getBytecode } from '@wagmi/core' +import { config } from './config' + +await getBytecode(config, { + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + blockTag: 'safe', // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +The chain ID to check the bytecode at. + +::: code-group +```ts [index.ts] +import { getBytecode } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { config } from './config' + +await getBytecode(config, { + chainId: mainnet.id, // [!code focus] + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type GetBytecodeReturnType } from '@wagmi/core' +``` + +`Hex` + +The contract's bytecode. + +## Error + +```ts +import { type GetBytecodeErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`getCode`](https://viem.sh/docs/contract/getCode) diff --git a/wagmi-project/site/core/api/actions/getCallsStatus.md b/wagmi-project/site/core/api/actions/getCallsStatus.md new file mode 100644 index 000000000..dc03862b1 --- /dev/null +++ b/wagmi-project/site/core/api/actions/getCallsStatus.md @@ -0,0 +1,97 @@ + + +# getCallsStatus + +Action to fetch the status and receipts of a call batch that was sent via [`sendCalls`](/core/api/actions/sendCalls). + +[Read more.](https://github.com/ethereum/EIPs/blob/1663ea2e7a683285f977eda51c32cec86553f585/EIPS/eip-5792.md#wallet_getcallsstatus) + +## Import + +```ts +import { getCallsStatus } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { getCallsStatus } from '@wagmi/core' +import { config } from './config' + +const status = await getCallsStatus(config, { + id: '0x1234567890abcdef', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type GetCallsStatusParameters } from '@wagmi/core' +``` + +### connector + +`Connector | undefined` + +Connector to get call statuses with. + +::: code-group +```ts [index.ts] +import { getConnections, getCallsStatus } from '@wagmi/core' +import { config } from './config' + +const connections = getConnections(config) +const status = await getCallsStatus(config, { + connector: connections[0]?.connector, // [!code focus] + id: '0x1234567890abcdef', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### id + +`string` + +Identifier of the call batch. + +::: code-group +```ts [index.ts] +import { getCallsStatus } from '@wagmi/core' +import { config } from './config' + +const status = await getCallsStatus(config, { + id: '0x1234567890abcdef', // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type GetCallsStatusReturnType } from '@wagmi/core' +``` + +`{ status: 'PENDING' | 'CONFIRMED', receipts: TransactionReceipt[] }` + +The status and receipts of the call batch. + +## Error + +```ts +import { type GetCallsStatusErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`getCallsStatus`](https://viem.sh/experimental/eip5792/getCallsStatus) diff --git a/wagmi-project/site/core/api/actions/getCapabilities.md b/wagmi-project/site/core/api/actions/getCapabilities.md new file mode 100644 index 000000000..36bad2bdd --- /dev/null +++ b/wagmi-project/site/core/api/actions/getCapabilities.md @@ -0,0 +1,96 @@ + + +# getCapabilities + +Action to extract capabilities (grouped by chain ID) that a connected wallet supports (e.g. paymasters, session keys, etc). + +[Read more.](https://github.com/ethereum/EIPs/blob/815028dc634463e1716fc5ce44c019a6040f0bef/EIPS/eip-5792.md#wallet_getcapabilities) + + + +## Import + +```ts +import { getCapabilities } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { getCapabilities } from '@wagmi/core' +import { config } from './config' + +const capabilities = await getCapabilities(config) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type GetCapabilitiesParameters } from '@wagmi/core' +``` + +### account + +`Account | Address | undefined` + +Fetch capabilities for the provided account. + +::: code-group +```ts [index.ts] +import { getCapabilities } from '@wagmi/core' +import { config } from './config' + +const capabilities = await getCapabilities(config, { + account: '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### connector + +`Connector | undefined` + +Connector to get capabilities from. + +::: code-group +```ts [index.ts] +import { getConnections, getCapabilities } from '@wagmi/core' +import { config } from './config' + +const connections = getConnections(config) +const capabilities = await getCapabilities(config, { + connector: connections[0]?.connector, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type GetCapabilitiesReturnType } from '@wagmi/core' +``` + +`bigint` + +Most recent block number seen. + +## Error + +```ts +import { type GetCapabilitiesErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`getCapabilities`](https://viem.sh/experimental/eip5792/getCapabilities) diff --git a/wagmi-project/site/core/api/actions/getChainId.md b/wagmi-project/site/core/api/actions/getChainId.md new file mode 100644 index 000000000..9d03f8468 --- /dev/null +++ b/wagmi-project/site/core/api/actions/getChainId.md @@ -0,0 +1,38 @@ +# getChainId + +Action for getting current chain ID. + + +## Import + +```ts +import { getChainId } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { getChainId } from '@wagmi/core' +import { config } from './config' + +const chainId = getChainId(config) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type GetChainIdReturnType } from '@wagmi/core' +``` + +`number` + +Current chain ID from [`config.state.chainId`](/core/api/createConfig#chainid). + +::: info +Only returns chain IDs for chains configured via `createConfig`'s [`chains`](/core/api/createConfig#chains) parameter. + +If the active [connection](/core/api/createConfig#connection) [`chainId`](/core/api/createConfig#chainid-1) is not from a chain included in your Wagmi `Config`, `getChainId` will return the last configured chain ID. +::: diff --git a/wagmi-project/site/core/api/actions/getChains.md b/wagmi-project/site/core/api/actions/getChains.md new file mode 100644 index 000000000..c70334e02 --- /dev/null +++ b/wagmi-project/site/core/api/actions/getChains.md @@ -0,0 +1,31 @@ +# getChains + +Action for getting configured chains. + +## Import + +```ts +import { getChains } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { getChains } from '@wagmi/core' +import { config } from './config' + +const chains = getChains(config) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type GetChainsReturnType } from '@wagmi/core' +``` + +`readonly [Chain, ...Chain[]]` + +Chains from [`config.chains`](/core/api/createConfig#chains). diff --git a/wagmi-project/site/core/api/actions/getClient.md b/wagmi-project/site/core/api/actions/getClient.md new file mode 100644 index 000000000..9f29f7323 --- /dev/null +++ b/wagmi-project/site/core/api/actions/getClient.md @@ -0,0 +1,56 @@ +# getClient + +Action for getting Viem [`Client`](https://viem.sh/docs/clients/custom.html) instance. + +## Import + +```ts +import { getClient } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { getClient } from '@wagmi/core' +import { config } from './config' + +const client = getClient(config) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type GetClientParameters } from '@wagmi/core' +``` + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when getting Viem Client. + +::: code-group +```ts [index.ts] +import { getClient } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { config } from './config' + +const client = await getClient(config, { + chainId: mainnet.id, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type GetClientReturnType } from '@wagmi/core' +``` + +`Client` + +Viem [`Client`](https://viem.sh/docs/clients/custom.html) instance. diff --git a/wagmi-project/site/core/api/actions/getConnections.md b/wagmi-project/site/core/api/actions/getConnections.md new file mode 100644 index 000000000..513d0d017 --- /dev/null +++ b/wagmi-project/site/core/api/actions/getConnections.md @@ -0,0 +1,31 @@ +# getConnections + +Action for getting active connections. + +## Import + +```ts +import { getConnections } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { getConnections } from '@wagmi/core' +import { config } from './config' + +const connections = getConnections(config) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type GetConnectionsReturnType } from '@wagmi/core' +``` + +[`Connection[]`](/core/api/createConfig#connection) + +Active connections. diff --git a/wagmi-project/site/core/api/actions/getConnectorClient.md b/wagmi-project/site/core/api/actions/getConnectorClient.md new file mode 100644 index 000000000..46d2795c7 --- /dev/null +++ b/wagmi-project/site/core/api/actions/getConnectorClient.md @@ -0,0 +1,108 @@ + + +# getConnectorClient + +Action for getting a Viem [`Client`](https://viem.sh/docs/clients/custom.html) object for the current or provided connector. + +## Import + +```ts +import { getConnectorClient } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { getConnectorClient } from '@wagmi/core' +import { config } from './config' + +const client = await getConnectorClient(config) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type GetConnectorClientParameters } from '@wagmi/core' +``` + +### account + +`Address | Account | undefined` + +Account to use with client. Throws if account is not found on [`connector`](#connector). + +::: code-group +```ts [index.ts] +import { getConnectorClient } from '@wagmi/core' +import { config } from './config' + +const client = await getConnectorClient(config, { + account: '0xd2135CfB216b74109775236E36d4b433F1DF507B', // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use with client. + +::: code-group +```ts [index.ts] +import { getConnectorClient } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { config } from './config' + +const client = await getConnectorClient(config, { + chainId: mainnet.id, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### connector + +`Connector | undefined` + +- Connector to get client for. +- Defaults to current connector. + +::: code-group +```ts [index.ts] +import { getConnections, getConnectorClient } from '@wagmi/core' +import { config } from './config' + +const connections = getConnections(config) +const client = await getConnectorClient(config, { + connector: connections[0]?.connector, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type GetChainIdReturnType } from '@wagmi/core' +``` + +`Client` + +Viem [`Client`](https://viem.sh/docs/clients/custom.html) object for the current or provided connector. + +## Error + +```ts +import { type GetConnectorClientErrorType } from '@wagmi/core' +``` + + diff --git a/wagmi-project/site/core/api/actions/getConnectors.md b/wagmi-project/site/core/api/actions/getConnectors.md new file mode 100644 index 000000000..ddbb049be --- /dev/null +++ b/wagmi-project/site/core/api/actions/getConnectors.md @@ -0,0 +1,31 @@ +# getConnectors + +Action for getting configured connectors. + +## Import + +```ts +import { getConnectors } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { getConnectors } from '@wagmi/core' +import { config } from './config' + +const connectors = getConnectors(config) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type GetConnectorsReturnType } from '@wagmi/core' +``` + +`readonly Connector[]` + +Connectors from [`config.connectors`](/core/api/createConfig#connectors-1). diff --git a/wagmi-project/site/core/api/actions/getEnsAddress.md b/wagmi-project/site/core/api/actions/getEnsAddress.md new file mode 100644 index 000000000..dc44dbb73 --- /dev/null +++ b/wagmi-project/site/core/api/actions/getEnsAddress.md @@ -0,0 +1,187 @@ + + +# getEnsAddress + +Action for fetching ENS address for name. + +## Import + +```ts +import { getEnsAddress } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { getEnsAddress } from '@wagmi/core' +import { normalize } from 'viem/ens' +import { config } from './config' + +const ensAddress = getEnsAddress(config, { + name: normalize('wevm.eth'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +::: warning +Since ENS names prohibit certain forbidden characters (e.g. underscore) and have other validation rules, you likely want to [normalize ENS names](https://docs.ens.domains/contract-api-reference/name-processing#normalising-names) with [UTS-46 normalization](https://unicode.org/reports/tr46) before passing them to `getEnsAddress`. You can use Viem's built-in [`normalize`](https://viem.sh/docs/ens/utilities/normalize) function for this. +::: + +## Parameters + +```ts +import { type GetEnsAddressParameters } from '@wagmi/core' +``` + +--- + +### blockNumber + +`bigint | undefined` + +Block number to get ENS address at. + +::: code-group +```ts [index.ts] +import { getEnsAddress } from '@wagmi/core' +import { normalize } from 'viem/ens' +import { config } from './config' + +const ensAddress = getEnsAddress(config, { + blockNumber: 17829139n, // [!code focus] + name: normalize('wevm.eth'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Block tag to get ENS address at. + +::: code-group +```ts [index.ts] +import { getEnsAddress } from '@wagmi/core' +import { normalize } from 'viem/ens' +import { config } from './config' + +const ensAddress = getEnsAddress(config, { + blockTag: 'latest', // [!code focus] + name: normalize('wevm.eth'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +--- + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```ts [index.ts] +import { getEnsAddress } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { normalize } from 'viem/ens' +import { config } from './config' + +const ensAddress = await getEnsAddress(config, { + chainId: mainnet.id, // [!code focus] + name: normalize('wevm.eth'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### coinType + +`number | undefined` + +The [ENSIP-9](https://docs.ens.domains/ens-improvement-proposals/ensip-9-multichain-address-resolution) coin type to fetch the address for. + +::: code-group +```ts [index.ts] +import { getEnsAddress } from '@wagmi/core' +import { normalize } from 'viem/ens' +import { config } from './config' + +const ensAddress = await getEnsAddress(config, { + coinType: 60, // [!code focus] + name: normalize('wevm.eth'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### name + +`string` + +Name to get the address for. + +::: code-group +```ts [index.ts] +import { getEnsAddress } from '@wagmi/core' +import { normalize } from 'viem/ens' +import { config } from './config' + +const ensAddress = await getEnsAddress(config, { + name: normalize('wevm.eth'), // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### universalResolverAddress + +`Address | undefined` + +- Address of ENS Universal Resolver Contract. +- Defaults to current chain's Universal Resolver Contract address. + +::: code-group +```ts [index.ts] +import { getEnsAddress } from '@wagmi/core' +import { normalize } from 'viem/ens' +import { config } from './config' + +const ensAddress = await getEnsAddress(config, { + name: normalize('wevm.eth'), + universalResolverAddress: '0x74E20Bd2A1fE0cdbe45b9A1d89cb7e0a45b36376', // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type GetEnsAddressReturnType } from '@wagmi/core' +``` + +`string` + +ENS address. + +## Error + +```ts +import { type GetEnsAddressErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`getEnsAddress`](https://viem.sh/docs/ens/actions/getEnsAddress.html) diff --git a/wagmi-project/site/core/api/actions/getEnsAvatar.md b/wagmi-project/site/core/api/actions/getEnsAvatar.md new file mode 100644 index 000000000..b7da4aa0f --- /dev/null +++ b/wagmi-project/site/core/api/actions/getEnsAvatar.md @@ -0,0 +1,210 @@ + + +# getEnsAvatar + +Action for fetching ENS address for avatar. + +## Import + +```ts +import { getEnsAvatar } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { getEnsAvatar } from '@wagmi/core' +import { normalize } from 'viem/ens' +import { config } from './config' + +const ensAvatar = await getEnsAvatar(config, { + name: normalize('wevm.eth'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +::: warning +Since ENS names prohibit certain forbidden characters (e.g. underscore) and have other validation rules, you likely want to [normalize ENS names](https://docs.ens.domains/contract-api-reference/name-processing#normalising-names) with [UTS-46 normalization](https://unicode.org/reports/tr46) before passing them to `getEnsAvatar`. You can use Viem's built-in [`normalize`](https://viem.sh/docs/ens/utilities/normalize) function for this. +::: + +## Parameters + +```ts +import { type GetEnsAvatarParameters } from '@wagmi/core' +``` + +--- + +### assetGatewayUrls + +`{ ipfs?: string | undefined; arweave?: string | undefined } | undefined` + +Gateway urls to resolve IPFS and/or Arweave assets. + +::: code-group +```ts [index.ts] +import { getEnsAvatar } from '@wagmi/core' +import { normalize } from 'viem/ens' +import { config } from './config' + +const ensAvatar = await getEnsAvatar(config, { + assetGatewayUrls: { // [!code focus] + ipfs: 'https://cloudflare-ipfs.com', // [!code focus] + }, // [!code focus] + name: normalize('wevm.eth'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + + +### blockNumber + +`bigint | undefined` + +Block number to get avatar at. + +::: code-group +```ts [index.ts] +import { getEnsAvatar } from '@wagmi/core' +import { normalize } from 'viem/ens' +import { config } from './config' + +const ensAvatar = await getEnsAvatar(config, { + blockNumber: 17829139n, // [!code focus] + name: normalize('wevm.eth'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Block tag to get avatar at. + +::: code-group +```ts [index.ts] +import { getEnsAvatar } from '@wagmi/core' +import { normalize } from 'viem/ens' +import { config } from './config' + +const ensAvatar = await getEnsAvatar(config, { + blockTag: 'latest', // [!code focus] + name: normalize('wevm.eth'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +--- + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```ts [index.ts] +import { getEnsAvatar } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { normalize } from 'viem/ens' +import { config } from './config' + +const ensAvatar = await getEnsAvatar(config, { + chainId: mainnet.id, // [!code focus] + name: normalize('wevm.eth'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### gatewayUrls + +`string[] | undefined` + +A set of Universal Resolver gateways, used for resolving CCIP-Read requests made through the ENS Universal Resolver Contract. + +::: code-group +```ts [index.ts] +import { getEnsAvatar } from '@wagmi/core' +import { normalize } from 'viem/ens' +import { config } from './config' + +const ensAvatar = await getEnsAvatar(config, { + gatewayUrls: ['https://cloudflare-ipfs.com'] { // [!code focus] + name: normalize('wevm.eth'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### name + +`string` + +Name to get the avatar for. + +::: code-group +```ts [index.ts] +import { getEnsAvatar } from '@wagmi/core' +import { normalize } from 'viem/ens' +import { config } from './config' + +const ensAvatar = await getEnsAvatar(config, { + name: normalize('wevm.eth'), // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### universalResolverAddress + +`Address | undefined` + +- Address of ENS Universal Resolver Contract. +- Defaults to current chain's Universal Resolver Contract address. + +::: code-group +```ts [index.ts] +import { getEnsAvatar } from '@wagmi/core' +import { normalize } from 'viem/ens' +import { config } from './config' + +const ensAvatar = await getEnsAvatar(config, { + name: normalize('wevm.eth'), + universalResolverAddress: '0x74E20Bd2A1fE0cdbe45b9A1d89cb7e0a45b36376', // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type GetEnsAvatarReturnType } from '@wagmi/core' +``` + +`string | null` + +The avatar URI for ENS name. + +## Error + +```ts +import { type getEnsAvatarError } from '@wagmi/core' +``` + + + +## Viem + +- [`getEnsAvatar`](https://viem.sh/docs/ens/actions/getEnsAvatar.html) diff --git a/wagmi-project/site/core/api/actions/getEnsName.md b/wagmi-project/site/core/api/actions/getEnsName.md new file mode 100644 index 000000000..f663923f9 --- /dev/null +++ b/wagmi-project/site/core/api/actions/getEnsName.md @@ -0,0 +1,157 @@ + + +# getEnsName + +Action for fetching primary ENS name for address. + +## Import + +```ts +import { getEnsName } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { getEnsName } from '@wagmi/core' +import { config } from './config' + +const ensName = getEnsName(config, { + address: '0xd2135CfB216b74109775236E36d4b433F1DF507B', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type GetEnsNameParameters } from '@wagmi/core' +``` + +### address + +`Address` + +Address to get the name for. + +::: code-group +```ts [index.ts] +import { getEnsName } from '@wagmi/core' +import { config } from './config' + +const ensName = await getEnsName(config, { + address: '0xd2135CfB216b74109775236E36d4b433F1DF507B', // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +--- + +### blockNumber + +`bigint | undefined` + +Block number to get name at. + +::: code-group +```ts [index.ts] +import { getEnsName } from '@wagmi/core' +import { config } from './config' + +const ensName = getEnsName(config, { + address: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + blockNumber: 17829139n, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Block tag to get name at. + +::: code-group +```ts [index.ts] +import { getEnsName } from '@wagmi/core' +import { config } from './config' + +const ensName = getEnsName(config, { + address: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + blockTag: 'latest', // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +--- + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```ts [index.ts] +import { getEnsName } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { config } from './config' + +const ensName = await getEnsName(config, { + address: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + chainId: mainnet.id, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### universalResolverAddress + +`Address | undefined` + +- Address of ENS Universal Resolver Contract. +- Defaults to current chain's Universal Resolver Contract address. + +::: code-group +```ts [index.ts] +import { getEnsName } from '@wagmi/core' +import { config } from './config' + +const ensName = await getEnsName(config, { + address: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + universalResolverName: '0x74E20Bd2A1fE0cdbe45b9A1d89cb7e0a45b36376', // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type GetEnsNameReturnType } from '@wagmi/core' +``` + +`string | null` + +The primary ENS name for the address. Returns `null` if address does not have primary name assigned. + +## Error + +```ts +import { type GetEnsNameErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`getEnsName`](https://viem.sh/docs/ens/actions/getEnsName.html) diff --git a/wagmi-project/site/core/api/actions/getEnsResolver.md b/wagmi-project/site/core/api/actions/getEnsResolver.md new file mode 100644 index 000000000..c73301e07 --- /dev/null +++ b/wagmi-project/site/core/api/actions/getEnsResolver.md @@ -0,0 +1,167 @@ + + +# getEnsResolver + +Action for fetching ENS resolver for name. + +## Import + +```ts +import { getEnsResolver } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { getEnsResolver } from '@wagmi/core' +import { normalize } from 'viem/ens' +import { config } from './config' + +const ensResolver = getEnsResolver(config, { + name: normalize('wevm.eth'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +::: warning +Since ENS names prohibit certain forbidden characters (e.g. underscore) and have other validation rules, you likely want to [normalize ENS names](https://docs.ens.domains/contract-api-reference/name-processing#normalising-names) with [UTS-46 normalization](https://unicode.org/reports/tr46) before passing them to `getEnsResolver`. You can use Viem's built-in [`normalize`](https://viem.sh/docs/ens/utilities/normalize) function for this. +::: + +## Parameters + +```ts +import { type GetEnsResolverParameters } from '@wagmi/core' +``` + +--- + +### blockNumber + +`bigint | undefined` + +Block number to get resolver at. + +::: code-group +```ts [index.ts] +import { getEnsResolver } from '@wagmi/core' +import { normalize } from 'viem/ens' +import { config } from './config' + +const ensResolver = getEnsResolver(config, { + blockNumber: 17829139n, // [!code focus] + name: normalize('wevm.eth'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Block tag to get resolver at. + +::: code-group +```ts [index.ts] +import { getEnsResolver } from '@wagmi/core' +import { normalize } from 'viem/ens' +import { config } from './config' + +const ensResolver = getEnsResolver(config, { + blockTag: 'latest', // [!code focus] + name: normalize('wevm.eth'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +--- + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```ts [index.ts] +import { getEnsResolver } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { normalize } from 'viem/ens' +import { config } from './config' + +const ensResolver = await getEnsResolver(config, { + chainId: mainnet.id, // [!code focus] + name: normalize('wevm.eth'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### name + +`string` + +Name to get the resolver for. + +::: code-group +```ts [index.ts] +import { getEnsResolver } from '@wagmi/core' +import { normalize } from 'viem/ens' +import { config } from './config' + +const ensResolver = await getEnsResolver(config, { + name: normalize('wevm.eth'), // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### universalResolverAddress + +`Address | undefined` + +- Address of ENS Universal Resolver Contract. +- Defaults to current chain's Universal Resolver Contract address. + +::: code-group +```ts [index.ts] +import { getEnsResolver } from '@wagmi/core' +import { normalize } from 'viem/ens' +import { config } from './config' + +const ensResolver = await getEnsResolver(config, { + name: normalize('wevm.eth'), + universalResolverAddress: '0x74E20Bd2A1fE0cdbe45b9A1d89cb7e0a45b36376', // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type GetEnsResolverReturnType } from '@wagmi/core' +``` + +`Address` + +The address of the resolver. + +## Error + +```ts +import { type getEnsResolverError } from '@wagmi/core' +``` + + + +## Viem + +- [`getEnsResolver`](https://viem.sh/docs/ens/actions/getEnsResolver.html) diff --git a/wagmi-project/site/core/api/actions/getEnsText.md b/wagmi-project/site/core/api/actions/getEnsText.md new file mode 100644 index 000000000..a5ffb8ed5 --- /dev/null +++ b/wagmi-project/site/core/api/actions/getEnsText.md @@ -0,0 +1,195 @@ + + +# getEnsText + +Action for fetching a text record for a specified ENS name and key. + +## Import + +```ts +import { getEnsText } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { getEnsText } from '@wagmi/core' +import { normalize } from 'viem/ens' +import { config } from './config' + +const ensText = getEnsText(config, { + name: normalize('wevm.eth'), + key: 'com.twitter', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +::: warning +Since ENS names prohibit certain forbidden characters (e.g. underscore) and have other validation rules, you likely want to [normalize ENS names](https://docs.ens.domains/contract-api-reference/name-processing#normalising-names) with [UTS-46 normalization](https://unicode.org/reports/tr46) before passing them to `getEnsText`. You can use Viem's built-in [`normalize`](https://viem.sh/docs/ens/utilities/normalize) function for this. +::: + +## Parameters + +```ts +import { type GetEnsTextParameters } from '@wagmi/core' +``` + +--- + +### blockNumber + +`bigint | undefined` + +Block number to get the text at. + +::: code-group +```ts [index.ts] +import { getEnsText } from '@wagmi/core' +import { normalize } from 'viem/ens' +import { config } from './config' + +const ensText = getEnsText(config, { + blockNumber: 17829139n, // [!code focus] + name: normalize('wevm.eth'), + key: 'com.twitter', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Block tag to get the text at. + +::: code-group +```ts [index.ts] +import { getEnsText } from '@wagmi/core' +import { normalize } from 'viem/ens' +import { config } from './config' + +const ensText = getEnsText(config, { + blockTag: 'latest', // [!code focus] + name: normalize('wevm.eth'), + key: 'com.twitter', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +--- + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```ts [index.ts] +import { getEnsText } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { normalize } from 'viem/ens' +import { config } from './config' + +const ensText = await getEnsText(config, { + chainId: mainnet.id, // [!code focus] + name: normalize('wevm.eth'), + key: 'com.twitter', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### key + +`string` + +ENS key to get Text for. + +::: code-group +```ts [index.ts] +import { getEnsText } from '@wagmi/core' +import { normalize } from 'viem/ens' +import { config } from './config' + +const ensText = await getEnsText(config, { + name: normalize('wevm.eth'), + key: 'com.twitter', // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### name + +`string` + +Name to get the text for. + +::: code-group +```ts [index.ts] +import { getEnsText } from '@wagmi/core' +import { normalize } from 'viem/ens' +import { config } from './config' + +const ensText = await getEnsText(config, { + name: normalize('wevm.eth'), // [!code focus] + key: 'com.twitter', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### universalResolverAddress + +`Address | undefined` + +- Address of ENS Universal Resolver Contract. +- Defaults to current chain's Universal Resolver Contract address. + +::: code-group +```ts [index.ts] +import { getEnsText } from '@wagmi/core' +import { normalize } from 'viem/ens' +import { config } from './config' + +const ensText = await getEnsText(config, { + name: normalize('wevm.eth'), + key: 'com.twitter', + universalResolverAddress: '0x74E20Bd2A1fE0cdbe45b9A1d89cb7e0a45b36376', // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type GetEnsTextReturnType } from '@wagmi/core' +``` + +`string | null` + +The text record for ENS name. + +Returns `null` if name does not have text assigned. + +## Error + +```ts +import { type getEnsTextError } from '@wagmi/core' +``` + + + +## Viem + +- [`getEnsText`](https://viem.sh/docs/ens/actions/getEnsText.html) diff --git a/wagmi-project/site/core/api/actions/getFeeHistory.md b/wagmi-project/site/core/api/actions/getFeeHistory.md new file mode 100644 index 000000000..3787d8f66 --- /dev/null +++ b/wagmi-project/site/core/api/actions/getFeeHistory.md @@ -0,0 +1,157 @@ + + +# getFeeHistory + +Action for fetching a collection of historical gas information. + +## Import + +```ts +import { getFeeHistory } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { getFeeHistory } from '@wagmi/core' +import { config } from './config' + +const feeHistory = await getFeeHistory(config, { + blockCount: 4, + rewardPercentiles: [25, 75] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type GetFeeHistoryParameters } from '@wagmi/core' +``` + +### blockCount + +`number` + +Number of blocks in the requested range. Between 1 and 1024 blocks can be requested in a single query. Less than requested may be returned if not all blocks are available. + +::: code-group +```ts [index.ts] +import { getFeeHistory } from '@wagmi/core' +import { config } from './config' + +const feeHistory = await getFeeHistory(config, { + blockCount: 4, // [!code focus] + rewardPercentiles: [25, 75] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### rewardPercentiles + +`number[]` + +A monotonically increasing list of percentile values to sample from each block's effective priority fees per gas in ascending order, weighted by gas used. + +::: code-group +```ts [index.ts] +import { getFeeHistory } from '@wagmi/core' +import { config } from './config' + +const feeHistory = await getFeeHistory(config, { + blockCount: 4, + rewardPercentiles: [25, 75] // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### blockNumber + +`bigint | undefined` + +Highest number block of the requested range. + +::: code-group +```ts [index.ts] +import { getFeeHistory } from '@wagmi/core' +import { config } from './config' + +const feeHistory = await getFeeHistory(config, { + blockCount: 4, + blockNumber: 1551231n, // [!code focus] + rewardPercentiles: [25, 75], +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Block tag of the highest number block of the requested range. + +::: code-group +```ts [index.ts] +import { getFeeHistory } from '@wagmi/core' +import { config } from './config' + +const feeHistory = await getFeeHistory(config, { + blockCount: 4, + blockTag: 'safe', // [!code focus] + rewardPercentiles: [25, 75], +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```ts [index.ts] +import { getFeeHistory } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { config } from './config' + +const feeHistory = await getFeeHistory(config, { + blockCount: 4, + chainId: mainnet.id, // [!code focus] + rewardPercentiles: [25, 75], +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type GetFeeHistoryReturnType } from '@wagmi/core' +``` + +[`FeeHistory`](https://viem.sh/docs/glossary/types.html#feehistory) + +The fee history. + +## Error + +```ts +import { type GetFeeHistoryErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`getFeeHistory`](https://viem.sh/docs/actions/public/getFeeHistory.html) diff --git a/wagmi-project/site/core/api/actions/getGasPrice.md b/wagmi-project/site/core/api/actions/getGasPrice.md new file mode 100644 index 000000000..106829fcf --- /dev/null +++ b/wagmi-project/site/core/api/actions/getGasPrice.md @@ -0,0 +1,74 @@ + + +# getGasPrice + +Action for fetching the current price of gas (in wei). + +## Import + +```ts +import { getGasPrice } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { getGasPrice } from '@wagmi/core' +import { config } from './config' + +const gasPrice = await getGasPrice(config) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type GetGasPriceParameters } from '@wagmi/core' +``` + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```ts [index.ts] +import { getGasPrice } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { config } from './config' + +const gasPrice = await getGasPrice(config, { + chainId: mainnet.id, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type GetGasPriceReturnType } from '@wagmi/core' +``` + +`bigint` + +Current price of gas (in wei). + +## Error + +```ts +import { type GetGasPriceErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`getGasPrice`](https://viem.sh/docs/actions/public/getGasPrice.html) diff --git a/wagmi-project/site/core/api/actions/getProof.md b/wagmi-project/site/core/api/actions/getProof.md new file mode 100644 index 000000000..60cd49326 --- /dev/null +++ b/wagmi-project/site/core/api/actions/getProof.md @@ -0,0 +1,169 @@ + + +# getProof + +Action for return the account and storage values of the specified account including the Merkle-proof. + +## Import + +```ts +import { getProof } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { getProof } from '@wagmi/core' +import { config } from './config' + +await getProof(config, { + address: '0x4200000000000000000000000000000000000016', + storageKeys: [ + '0x4a932049252365b3eedbc5190e18949f2ec11f39d3bef2d259764799a1b27d99', + ], +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type GetProofParameters } from '@wagmi/core' +``` + +### address + +`Address` + +The account address to get the proof for. + +::: code-group +```ts [index.ts] +import { getProof } from '@wagmi/core' +import { config } from './config' + +await getProof(config, { + address: '0x4200000000000000000000000000000000000016', // [!code focus] + storageKeys: [ + '0x4a932049252365b3eedbc5190e18949f2ec11f39d3bef2d259764799a1b27d99', + ], +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### storageKeys + +`` `0x${string}`[] `` + +Array of storage-keys that should be proofed and included. + +::: code-group +```ts [index.ts] +import { getProof } from '@wagmi/core' +import { config } from './config' + +await getProof(config, { + address: '0x4200000000000000000000000000000000000016', + storageKeys: [ // [!code focus:3] + '0x4a932049252365b3eedbc5190e18949f2ec11f39d3bef2d259764799a1b27d99', + ], +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### blockNumber + +`bigint | undefined` + +Proof at a given block number. + +::: code-group +```ts [index.ts] +import { getProof } from '@wagmi/core' +import { config } from './config' + +await getProof(config, { + address: '0x4200000000000000000000000000000000000016', + blockNumber: 42069n, // [!code focus] + storageKeys: [ + '0x4a932049252365b3eedbc5190e18949f2ec11f39d3bef2d259764799a1b27d99', + ], +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Proof at a given block tag. + +::: code-group +```ts [index.ts] +import { getProof } from '@wagmi/core' +import { config } from './config' + +await getProof(config, { + address: '0x4200000000000000000000000000000000000016', + blockTag: 'latest', // [!code focus] + storageKeys: [ + '0x4a932049252365b3eedbc5190e18949f2ec11f39d3bef2d259764799a1b27d99', + ], +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +The ID of chain to get the proof for. + +::: code-group +```ts [index.ts] +import { getProof } from '@wagmi/core' +import { config } from './config' +import { optimism } from '@wagmi/core/chains' + +await getProof(config, { + chainId: optimism.id, // [!code focus] + address: '0x4200000000000000000000000000000000000016', + storageKeys: [ + '0x4a932049252365b3eedbc5190e18949f2ec11f39d3bef2d259764799a1b27d99', + ], +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type GetProofReturnType } from '@wagmi/core' +``` + +`Proof` + +Proof data. + +## Error + +```ts +import { type GetProofErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`getProof`](https://viem.sh/docs/actions/public/getProof.html) diff --git a/wagmi-project/site/core/api/actions/getPublicClient.md b/wagmi-project/site/core/api/actions/getPublicClient.md new file mode 100644 index 000000000..437104aa7 --- /dev/null +++ b/wagmi-project/site/core/api/actions/getPublicClient.md @@ -0,0 +1,60 @@ +# getPublicClient + +Action for getting Viem [`PublicClient`](https://viem.sh/docs/clients/public.html) instance. + +## Import + +```ts +import { getPublicClient } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { getPublicClient } from '@wagmi/core' +import { config } from './config' + +const client = getPublicClient(config) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +::: warning +If you want to optimize bundle size, you should use [`getClient`](/core/api/actions/getClient) along with Viem's [tree-shakable actions](https://viem.sh/docs/clients/custom.html#tree-shaking) instead. Since Public Client has all public actions attached directly to it. +::: + +## Parameters + +```ts +import { type GetClientParameters } from '@wagmi/core' +``` + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when getting Viem Public Client. + +::: code-group +```ts [index.ts] +import { getPublicClient } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { config } from './config' + +const client = getPublicClient(config, { + chainId: mainnet.id, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type GetPublicClientReturnType } from '@wagmi/core' +``` + +`PublicClient | undefined` + +Viem [`PublicClient`](https://viem.sh/docs/clients/public.html) instance. diff --git a/wagmi-project/site/core/api/actions/getStorageAt.md b/wagmi-project/site/core/api/actions/getStorageAt.md new file mode 100644 index 000000000..23a5dc1d2 --- /dev/null +++ b/wagmi-project/site/core/api/actions/getStorageAt.md @@ -0,0 +1,157 @@ + + +# getStorageAt + +Action for returning the value from a storage slot at a given address. + +## Import + +```ts +import { getStorageAt } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { getStorageAt } from '@wagmi/core' +import { config } from './config' + +await getStorageAt(config, { + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + slot: '0x0', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type GetStorageAtParameters } from '@wagmi/core' +``` + +### address + +`Address` + +The contract address. + +::: code-group +```ts [index.ts] +import { getStorageAt } from '@wagmi/core' +import { config } from './config' + +await getStorageAt(config, { + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', // [!code focus] + slot: '0x0', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### slot + +`Hex` + +The storage position (as a hex encoded value). + +::: code-group +```ts [index.ts] +import { getStorageAt } from '@wagmi/core' +import { config } from './config' + +await getStorageAt(config, { + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + slot: '0x0', // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### blockNumber + +`bigint | undefined` + +The block number to check the storage at. + +::: code-group +```ts [index.ts] +import { getStorageAt } from '@wagmi/core' +import { config } from './config' + +await getStorageAt(config, { + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + blockNumber: 16280770n, // [!code focus] + slot: '0x0', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +The block tag to check the storage at. + +::: code-group +```ts [index.ts] +import { getStorageAt } from '@wagmi/core' +import { config } from './config' + +await getStorageAt(config, { + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + blockTag: 'safe', // [!code focus] + slot: '0x0', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +The chain ID to check the storage at. + +::: code-group +```ts [index.ts] +import { getStorageAt } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { config } from './config' + +await getStorageAt(config, { + chainId: mainnet.id, // [!code focus] + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + slot: '0x0', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type GetStorageAtReturnType } from '@wagmi/core' +``` + +`Hex` + +The value of the storage slot. + +## Error + +```ts +import { type GetStorageAtErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`getStorageAt`](https://viem.sh/docs/contract/getStorageAt) diff --git a/wagmi-project/site/core/api/actions/getToken.md b/wagmi-project/site/core/api/actions/getToken.md new file mode 100644 index 000000000..b37805cff --- /dev/null +++ b/wagmi-project/site/core/api/actions/getToken.md @@ -0,0 +1,141 @@ + + +# getToken + +Action for fetching token info. + +## Import + +```ts +import { getToken } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { getToken } from '@wagmi/core' +import { config } from './config' + +const token = getToken(config, { + address: '0x6B175474E89094C44Da98b954EedeAC495271d0F', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type GetTokenParameters } from '@wagmi/core' +``` + +### address + +`Address` + +Address to get token for. + +::: code-group +```ts [index.ts] +import { getToken } from '@wagmi/core' +import { config } from './config' + +const token = getToken(config, { + address: '0x6B175474E89094C44Da98b954EedeAC495271d0F', // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```ts [index.ts] +import { getToken } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { config } from './config' + +const token = await getToken(config, { + address: '0x6B175474E89094C44Da98b954EedeAC495271d0F', + chainId: mainnet.id, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### formatUnits + +`'ether' | 'gwei' | 'wei' | number | undefined` + +- Units to use when formatting result. +- Defaults to `'ether'`. + +::: code-group +```ts [index.ts] +import { getToken } from '@wagmi/core' +import { config } from './config' + +const token = getToken(config, { + address: '0x6B175474E89094C44Da98b954EedeAC495271d0F', + formatUnits: 'ether', // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type GetTokenReturnType } from '@wagmi/core' +``` + +### address + +`Address` + +Address of token. + +### decimals + +`number` + +Number of decimals for token. + +### name + +`string | undefined` + +Name of token. + +### symbol + +`string | undefined` + +Symbol of token. + +### totalSupply + +`{ formatted: string; value: bigint; }` + +Total supply of token. `formatted` is formatted using [`formatUnits`](#formatunits). + +## Error + +```ts +import { type GetTokenErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`multicall`](https://viem.sh/docs/contract/multicall) diff --git a/wagmi-project/site/core/api/actions/getTransaction.md b/wagmi-project/site/core/api/actions/getTransaction.md new file mode 100644 index 000000000..8ebe77099 --- /dev/null +++ b/wagmi-project/site/core/api/actions/getTransaction.md @@ -0,0 +1,173 @@ + + +# getTransaction + +Action for fetching transactions given hashes or block identifiers. + +## Import + +```ts +import { getTransaction } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { getTransaction } from '@wagmi/core' +import { config } from './config' + +const transaction = getTransaction(config, { + hash: '0x0fa64daeae54e207aa98613e308c2ba8abfe274f75507e741508cc4db82c8cb5', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type GetTransactionParameters } from '@wagmi/core' +``` + +--- + +### blockHash + +`bigint | undefined` + +Block hash to get transaction at (with [`index`](#index)). + +::: code-group +```ts [index.ts] +import { getTransaction } from '@wagmi/core' +import { config } from './config' + +const transaction = getTransaction(config, { + blockHash: '0x4ca7ee652d57678f26e887c149ab0735f41de37bcad58c9f6d3ed5824f15b74d', // [!code focus] + index: 0, +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### blockNumber + +`bigint | undefined` + +Block number to get transaction at (with [`index`](#index)). + +::: code-group +```ts [index.ts] +import { getTransaction } from '@wagmi/core' +import { config } from './config' + +const transaction = getTransaction(config, { + blockNumber: 17829139n, // [!code focus] + index: 0, +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Block tag to get transaction at (with [`index`](#index)). + +::: code-group +```ts [index.ts] +import { getTransaction } from '@wagmi/core' +import { config } from './config' + +const transaction = getTransaction(config, { + blockTag: 'safe', // [!code focus] + index: 0, +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +--- + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```ts [index.ts] +import { getTransaction } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { config } from './config' + +const transaction = await getTransaction(config, { + chainId: mainnet.id, // [!code focus] + hash: '0x0fa64daeae54e207aa98613e308c2ba8abfe274f75507e741508cc4db82c8cb5', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### hash + +`` `0x${string}` | undefined `` + +Hash to get transaction. + +::: code-group +```ts [index.ts] +import { getTransaction } from '@wagmi/core' +import { config } from './config' + +const transaction = getTransaction(config, { + hash: '0x0fa64daeae54e207aa98613e308c2ba8abfe274f75507e741508cc4db82c8cb5', // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### index + +`number | undefined` + +An index to be used with a block identifier ([hash](#blockhash), [number](#blocknumber), or [tag](#blocktag)). + +::: code-group +```ts [index.ts] +import { getTransaction } from '@wagmi/core' +import { config } from './config' + +const transaction = getTransaction(config, { + blockTag: 'safe', + index: 0 // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type GetTransactionReturnType } from '@wagmi/core' +``` + +[`Transaction`](https://viem.sh/docs/glossary/types.html#transaction) + +## Error + +```ts +import { type GetTransactionErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`getTransaction`](https://viem.sh/docs/actions/public/getTransaction.html) diff --git a/wagmi-project/site/core/api/actions/getTransactionConfirmations.md b/wagmi-project/site/core/api/actions/getTransactionConfirmations.md new file mode 100644 index 000000000..eb42df19a --- /dev/null +++ b/wagmi-project/site/core/api/actions/getTransactionConfirmations.md @@ -0,0 +1,117 @@ + + +# getTransactionConfirmations + +Action for fetching the number of blocks passed (confirmations) since the transaction was processed on a block. If confirmations is 0, then the Transaction has not been confirmed & processed yet. + +## Import + +```ts +import { getTransactionConfirmations } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { getTransactionConfirmations } from '@wagmi/core' +import { config } from './config' + +const transaction = getTransactionConfirmations(config, { + hash: '0x0fa64daeae54e207aa98613e308c2ba8abfe274f75507e741508cc4db82c8cb5', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type GetTransactionConfirmationsParameters } from '@wagmi/core' +``` + +--- + +### hash + +`` `0x${string}` | undefined `` + +The hash of the transaction. + +::: code-group +```ts [index.ts] +import { getTransactionConfirmations } from '@wagmi/core' +import { config } from './config' + +const transaction = getTransactionConfirmations(config, { + hash: '0x0fa64daeae54e207aa98613e308c2ba8abfe274f75507e741508cc4db82c8cb5', // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### transactionReceipt + +`TransactionReceipt | undefined` + +The transaction receipt. + +::: code-group +```ts [index.ts] +import { getTransactionConfirmations } from '@wagmi/core' +import { config } from './config' + +const transaction = getTransactionConfirmations(config, { + transactionReceipt: { ... }, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +--- + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```ts [index.ts] +import { getTransactionConfirmations } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { config } from './config' + +const transaction = await getTransactionConfirmations(config, { + chainId: mainnet.id, // [!code focus] + hash: '0x0fa64daeae54e207aa98613e308c2ba8abfe274f75507e741508cc4db82c8cb5', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type GetTransactionConfirmationsReturnType } from '@wagmi/core' +``` + +`bigint` + +The number of blocks passed since the transaction was processed. If confirmations is 0, then the Transaction has not been confirmed & processed yet. + +## Error + +```ts +import { type GetTransactionConfirmationsErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`getTransactionConfirmations`](https://viem.sh/docs/actions/public/getTransactionConfirmations.html) diff --git a/wagmi-project/site/core/api/actions/getTransactionCount.md b/wagmi-project/site/core/api/actions/getTransactionCount.md new file mode 100644 index 000000000..d08987c84 --- /dev/null +++ b/wagmi-project/site/core/api/actions/getTransactionCount.md @@ -0,0 +1,139 @@ + + +# getTransactionCount + +Action for fetching the number of transactions an Account has sent. + +## Import + +```ts +import { getTransactionCount } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { getTransactionCount } from '@wagmi/core' +import { config } from './config' + +const transactionCount = getTransactionCount(config, { + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type GetTransactionCountParameters } from '@wagmi/core' +``` + +--- + +### address + +`Address` + +The address of the account. + +::: code-group +```ts [index.ts] +import { getTransactionCount } from '@wagmi/core' +import { config } from './config' + +const transactionCount = getTransactionCount(config, { + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +--- + +### blockNumber + +`bigint | undefined` + +Get the count at a block number. + +::: code-group +```ts [index.ts] +import { getTransactionCount } from '@wagmi/core' +import { config } from './config' + +const transactionCount = getTransactionCount(config, { + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', + blockNumber: 17829139n, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Get the count at a block tag. + +::: code-group +```ts [index.ts] +import { getTransactionCount } from '@wagmi/core' +import { config } from './config' + +const transactionCount = getTransactionCount(config, { + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', + blockTag: 'latest', // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +--- + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```ts [index.ts] +import { getTransactionCount } from '@wagmi/core' +import { config } from './config' + +const transactionCount = getTransactionCount(config, { + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', + chainId: mainnet.id, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + + +## Return Type + +```ts +import { type GetTransactionCountReturnType } from '@wagmi/core' +``` + +`number` + +The number of transactions an account has sent. + +## Error + +```ts +import { type GetTransactionCountErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`getTransactionCount`](https://viem.sh/docs/actions/public/getTransactionCount.html) diff --git a/wagmi-project/site/core/api/actions/getTransactionReceipt.md b/wagmi-project/site/core/api/actions/getTransactionReceipt.md new file mode 100644 index 000000000..d0687ac63 --- /dev/null +++ b/wagmi-project/site/core/api/actions/getTransactionReceipt.md @@ -0,0 +1,95 @@ + + +# getTransactionReceipt + +Action for return the [Transaction Receipt](https://viem.sh/docs/glossary/terms.html#transaction-receipt) given a [Transaction](https://viem.sh/docs/glossary/terms.html#transaction) hash. + +## Import + +```ts +import { getTransactionReceipt } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { getTransactionReceipt } from '@wagmi/core' +import { config } from './config' + +await getTransactionReceipt(config, { + hash: '0x4ca7ee652d57678f26e887c149ab0735f41de37bcad58c9f6d3ed5824f15b74d', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type GetTransactionReceiptParameters } from '@wagmi/core' +``` + +### hash + +`` `0x${string}` `` + +A transaction hash. + +::: code-group +```ts [index.ts] +import { getTransactionReceipt } from '@wagmi/core' +import { config } from './config' + +await getTransactionReceipt(config, { + hash: '0x4ca7ee652d57678f26e887c149ab0735f41de37bcad58c9f6d3ed5824f15b74d', // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +The ID of chain to return the transaction receipt from. + +::: code-group +```ts [index.ts] +import { getTransactionReceipt } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { config } from './config' + +await getTransactionReceipt(config, { + chainId: mainnet.id, // [!code focus] + hash: '0x4ca7ee652d57678f26e887c149ab0735f41de37bcad58c9f6d3ed5824f15b74d', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type GetTransactionReceiptReturnType } from '@wagmi/core' +``` + +[`TransactionReceipt`](https://viem.sh/docs/glossary/types.html#transactionreceipt) + +The transaction receipt. + +## Error + +```ts +import { type GetTransactionReceiptErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`getTransactionReceipt`](https://viem.sh/docs/actions/public/getTransactionReceipt.html) diff --git a/wagmi-project/site/core/api/actions/getWalletClient.md b/wagmi-project/site/core/api/actions/getWalletClient.md new file mode 100644 index 000000000..a321b3637 --- /dev/null +++ b/wagmi-project/site/core/api/actions/getWalletClient.md @@ -0,0 +1,112 @@ + + +# getWalletClient + +Action for getting a Viem [`WalletClient`](https://viem.sh/docs/clients/wallet.html) object for the current or provided connector. + +## Import + +```ts +import { getWalletClient } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { getWalletClient } from '@wagmi/core' +import { config } from './config' + +const client = getWalletClient(config) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +::: warning +If you want to optimize bundle size, you should use [`getConnectorClient`](/core/api/actions/getConnectorClient) along with Viem's [tree-shakable actions](https://viem.sh/docs/clients/custom.html#tree-shaking) instead. Since Wallet Client has all wallet actions attached directly to it. +::: + +## Parameters + +```ts +import { type GetWalletClientParameters } from '@wagmi/core' +``` + +### account + +`Address | Account | undefined` + +Account to use with client. Throws if account is not found on [`connector`](#connector). + +::: code-group +```ts [index.ts] +import { getWalletClient } from '@wagmi/core' +import { config } from './config' + +const client = getWalletClient(config, { + account: '0xd2135CfB216b74109775236E36d4b433F1DF507B', // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use with client. + +::: code-group +```ts [index.ts] +import { getWalletClient } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { config } from './config' + +const client = getWalletClient(config, { + chainId: mainnet.id, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### connector + +`Connector | undefined` + +- Connector to get client for. +- Defaults to current connector. + +::: code-group +```ts [index.ts] +import { getConnections, getWalletClient } from '@wagmi/core' +import { config } from './config' + +const connections = getConnections(config) +const client = getWalletClient(config, { + connector: connections[0]?.connector, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type GetChainIdReturnType } from '@wagmi/core' +``` + +`WalletClient` + +Viem [`WalletClient`](https://viem.sh/docs/clients/wallet.html) object for the current or provided connector. + +## Error + +```ts +import { type GetWalletClientErrorType } from '@wagmi/core' +``` + + \ No newline at end of file diff --git a/wagmi-project/site/core/api/actions/multicall.md b/wagmi-project/site/core/api/actions/multicall.md new file mode 100644 index 000000000..ec46368d1 --- /dev/null +++ b/wagmi-project/site/core/api/actions/multicall.md @@ -0,0 +1,355 @@ +# multicall + +Action for batching up multiple functions on a contract in a single RPC call via the [Multicall3 contract](https://github.com/mds1/multicall). + +## Import + +```ts +import { multicall } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { multicall } from '@wagmi/core' +import { config } from './config' + +const wagmigotchiContract = { + address: '0xecb504d39723b0be0e3a9aa33d646642d1051ee1', + abi: wagmigotchiABI, +} as const +const mlootContract = { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi: mlootABI, +} as const + +const result = await multicall(config, { + contracts: [ + { + ...wagmigotchiContract, + functionName: 'getAlive', + }, + { + ...wagmigotchiContract, + functionName: 'getBoredom', + }, + { + ...mlootContract, + functionName: 'getChest', + args: [69], + }, + { + ...mlootContract, + functionName: 'getWaist', + args: [69], + }, + ], +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type MulticallParameters } from '@wagmi/core' +``` + +### contracts + +`readonly Contract[]` + +Set of contracts to call. + +#### abi + +`Abi | undefined` + +The contract's ABI. Check out the [TypeScript docs](/react/typescript#const-assert-abis-typed-data) for how to set up ABIs for maximum type inference and safety. + +::: code-group +```tsx [index.tsx] +import { multicall } from '@wagmi/core' +import { config } from './config' + +const result = await multicall(config, { + contracts: [ + { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi: mlootABI, // [!code hl] + functionName: 'getChest', + args: [69], + }, + // ... + ], +}) +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +#### address + +`Address | undefined` + +The contract's address. + +::: code-group +```tsx [index.tsx] +import { multicall } from '@wagmi/core' +import { config } from './config' + +const result = await multicall(config, { + contracts: [ + { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', // [!code hl] + abi: mlootABI, + functionName: 'getChest', + args: [69], + }, + // ... + ], +}) +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +#### args + +`readonly unknown[] | undefined` + +- Arguments to pass when calling the contract. +- Inferred from [`abi`](#abi) and [`functionName`](#functionname). + +::: code-group +```tsx [index.tsx] +import { multicall } from '@wagmi/core' +import { config } from './config' + +const result = await multicall(config, { + contracts: [ + { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi: mlootABI, + functionName: 'getChest', + args: [69], // [!code hl] + }, + // ... + ], +}) +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +#### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```tsx [index.tsx] +import { multicall } from '@wagmi/core' +import { config } from './config' + +const result = await multicall(config, { + contracts: [ + { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi: mlootABI, + functionName: 'getChest', + args: [69], + chainId: 1, // [!code hl] + }, + // ... + ], +}) +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + +#### functionName + +`string | undefined` + +- Function to call on the contract. +- Inferred from [`abi`](#abi). + +::: code-group +```tsx [index.tsx] +import { multicall } from '@wagmi/core' +import { config } from './config' + +const result = await multicall(config, { + contracts: [ + { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi: mlootABI, + functionName: 'getChest', // [!code hl] + args: [69], + }, + // ... + ], +}) +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### allowFailure + +`boolean` + +Whether or not the Hook should throw if a call reverts. If set to `true` (default), and a call reverts, then `multicall` will fail silently and its error will be logged in the results array. Defaults to `true`. + +::: code-group +```tsx [index.tsx] +import { multicall } from '@wagmi/core' +import { config } from './config' + +const result = await multicall(config, { + allowFailure: false, // [!code hl] + contracts: [ + { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi: mlootABI, + functionName: 'getChest', + args: [69], + }, + // ... + ], +}) +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### batchSize + +`number` + +The maximum size (in bytes) for each calldata chunk. Set to `0` to disable the size limit. Defaults to `1024`. + +> Note: Some RPC Providers limit the amount of calldata (`data`) that can be sent in a single `eth_call` request. It is best to check with your RPC Provider to see if there are any calldata size limits to `eth_call` requests. + +::: code-group +```tsx [index.tsx] +import { multicall } from '@wagmi/core' +import { config } from './config' + +const result = await multicall(config, { + batchSize: 1_024, // [!code hl] + contracts: [ + { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi: mlootABI, + functionName: 'getChest', + args: [69], + }, + // ... + ], +}) +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### blockNumber + +`number` + +The block number to perform the read against. + +::: code-group +```tsx [index.tsx] +import { multicall } from '@wagmi/core' +import { config } from './config' + +const result = await multicall(config, { + blockNumber: 69420n, // [!code hl] + contracts: [ + { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi: mlootABI, + functionName: 'getChest', + args: [69], + }, + // ... + ], +}) +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Block tag to read against. + +::: code-group +```tsx [index.tsx] +import { multicall } from '@wagmi/core' +import { config } from './config' + +const result = await multicall(config, { + blockTag: 'safe', // [!code hl] + contracts: [ + { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi: mlootABI, + functionName: 'getChest', + args: [69], + }, + // ... + ], +}) +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### multicallAddress + +`Address` + +Address of multicall contract. + +::: code-group +```tsx [index.tsx] +import { multicall } from '@wagmi/core' +import { config } from './config' + +const result = await multicall(config, { + contracts: [ + { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi: mlootABI, + functionName: 'getChest', + args: [69], + }, + // ... + ], + multicallAddress: '0xca11bde05977b3631167028862be2a173976ca11', // [!code hl] +}) +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + +## Return Type + +```ts +import { type MulticallReturnType } from '@wagmi/core' +``` + +## Type Inference + +With [`contracts[number]['abi']`](#abi) setup correctly, TypeScript will infer the correct types for [`functionName`](#functionname), [`args`](#args), and the return type. See the Wagmi [TypeScript docs](/core/typescript) for more information. + +## Error + +```ts +import { type MulticallErrorType } from '@wagmi/core' +``` + +## Viem + +- [`multicall`](https://viem.sh/docs/actions/public/multicall.html) diff --git a/wagmi-project/site/core/api/actions/prepareTransactionRequest.md b/wagmi-project/site/core/api/actions/prepareTransactionRequest.md new file mode 100644 index 000000000..1a1f1fc20 --- /dev/null +++ b/wagmi-project/site/core/api/actions/prepareTransactionRequest.md @@ -0,0 +1,307 @@ + + +# prepareTransactionRequest + +Action for preparing a transaction request for signing by populating a nonce, gas limit, fee values, and a transaction type. + +## Import + +```ts +import { prepareTransactionRequest } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { prepareTransactionRequest } from '@wagmi/core' +import { parseEther } from 'viem' +import { config } from './config' + +await prepareTransactionRequest(config, { + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + value: parseEther('1'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type PrepareTransactionRequestParameters } from '@wagmi/core' +``` + +### account + +`Account | Address | undefined` + +The Account to send the transaction from. + +::: code-group +```ts [index.ts] +import { prepareTransactionRequest } from '@wagmi/core' +import { parseEther } from 'viem' +import { config } from './config' + +await prepareTransactionRequest(config, { + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', // [!code focus] + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + value: parseEther('1'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### to + +`` `0x${string}` | undefined `` + +The transaction recipient or contract address. + +::: code-group +```ts [index.ts] +import { prepareTransactionRequest } from '@wagmi/core' +import { parseEther } from 'viem' +import { config } from './config' + +await prepareTransactionRequest(config, { + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', // [!code focus] + value: parseEther('1'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### accessList + +`AccessList | undefined` + +The access list. + +::: code-group +```ts [index.ts] +import { prepareTransactionRequest } from '@wagmi/core' +import { parseEther } from 'viem' +import { config } from './config' + +await prepareTransactionRequest(config, { + accessList: [ // [!code focus:6] + { + address: '0x1', + storageKeys: ['0x1'], + }, + ], + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + value: parseEther('1'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +Chain ID to prepare the transaction request for. + +::: code-group +```ts [index.ts] +import { prepareTransactionRequest } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { parseEther } from 'viem' +import { config } from './config' + +await prepareTransactionRequest(config, { + chainId: mainnet.id, // [!code focus] + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + value: parseEther('1'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### data + +`` `0x${string}` | undefined `` + +A contract hashed method call with encoded args. + +::: code-group +```ts [index.ts] +import { prepareTransactionRequest } from '@wagmi/core' +import { parseEther } from 'viem' +import { config } from './config' + +await prepareTransactionRequest(config, { + data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', // [!code focus] + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + value: parseEther('1'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### gasPrice + +`bigint | undefined` + +The price (in wei) to pay per gas. Only applies to [Legacy Transactions](https://viem.sh/docs/glossary/terms.html#legacy-transaction). + +::: code-group +```ts [index.ts] +import { prepareTransactionRequest } from '@wagmi/core' +import { parseEther, parseGwei } from 'viem' +import { config } from './config' + +await prepareTransactionRequest(config, { + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + gasPrice: parseGwei('20'), // [!code focus] + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + value: parseEther('1'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### maxFeePerGas + +`bigint | undefined` + +Total fee per gas (in wei), inclusive of `maxPriorityFeePerGas`. Only applies to [EIP-1559 Transactions](https://viem.sh/docs/glossary/terms.html#eip-1559-transaction). + +::: code-group +```ts [index.ts] +import { prepareTransactionRequest } from '@wagmi/core' +import { parseEther, parseGwei } from 'viem' +import { config } from './config' + +await prepareTransactionRequest(config, { + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + maxFeePerGas: parseGwei('20'), // [!code focus] + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + value: parseEther('1'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### maxPriorityFeePerGas + +`bigint | undefined` + +Max priority fee per gas (in wei). Only applies to [EIP-1559 Transactions](https://viem.sh/docs/glossary/terms.html#eip-1559-transaction). + +::: code-group +```ts [index.ts] +import { prepareTransactionRequest } from '@wagmi/core' +import { parseEther, parseGwei } from 'viem' +import { config } from './config' + +await prepareTransactionRequest(config, { + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + maxFeePerGas: parseGwei('20'), + maxPriorityFeePerGas: parseGwei('2'), // [!code focus] + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + value: parseEther('1'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### nonce + +`number | undefined` + +Unique number identifying this transaction. + +::: code-group +```ts [index.ts] +import { prepareTransactionRequest } from '@wagmi/core' +import { parseEther } from 'viem' +import { config } from './config' + +await prepareTransactionRequest(config, { + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + value: parseEther('1'), + nonce: 5, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### parameters + +`("fees" | "gas" | "nonce" | "type")[] | undefined` + +Parameters to prepare. + +For instance, if `["gas", "nonce"]` is provided, then only the `gas` and `nonce` parameters will be prepared. + +::: code-group +```ts [index.ts] +import { prepareTransactionRequest } from '@wagmi/core' +import { parseEther } from 'viem' +import { config } from './config' + +await prepareTransactionRequest(config, { + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + parameters: ['gas', 'nonce'], // [!code focus] + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + value: parseEther('1'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### value + +`bigint | undefined` + +The transaction recipient or contract address. + +::: code-group +```ts [index.ts] +import { prepareTransactionRequest } from '@wagmi/core' +import { parseEther } from 'viem' +import { config } from './config' + +await prepareTransactionRequest(config, { + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + value: parseEther('1'), // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type PrepareTransactionRequestReturnType } from '@wagmi/core' +``` + +[`TransactionRequest`](https://viem.sh/docs/glossary/types.html#transactionrequest) + +The transaction request. + +## Error + +```ts +import { type PrepareTransactionRequestErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`prepareTransactionRequest`](https://viem.sh/docs/actions/wallet/prepareTransactionRequest.html) diff --git a/wagmi-project/site/core/api/actions/readContract.md b/wagmi-project/site/core/api/actions/readContract.md new file mode 100644 index 000000000..80dfbb0b2 --- /dev/null +++ b/wagmi-project/site/core/api/actions/readContract.md @@ -0,0 +1,258 @@ + + +# readContract + +Action for calling a **read-only** function on a contract, and returning the response. + +A **read-only** function (constant function) on a Solidity contract is denoted by a pure or view keyword. They can only read the state of the contract, and cannot make any changes to it. Since read-only methods do not change the state of the contract, they do not require any gas to be executed, and can be called by any user without the need to pay for gas. + +## Import + +```ts +import { readContract } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { readContract } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const result = await readContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'totalSupply', +}) +``` +<<< @/snippets/abi-read.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type ReadContractParameters } from '@wagmi/core' +``` + +### abi + +`Abi` + +The contract's ABI. Check out the [TypeScript docs](/react/typescript#const-assert-abis-typed-data) for how to set up ABIs for maximum type inference and safety. + +::: code-group +```ts [index.ts] +import { readContract } from '@wagmi/core' +import { abi } from './abi' // [!code focus] +import { config } from './config' + +const result = await readContract(config, { + abi, // [!code focus] + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'totalSupply', +}) +``` +<<< @/snippets/abi-read.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### account + +`Account | undefined` + +Account to use when calling the contract (`msg.sender`). + +::: code-group +```ts [index.ts] +import { readContract } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const result = await readContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'balanceOf', + args: ['0xd2135CfB216b74109775236E36d4b433F1DF507B'], + account: '0xd2135CfB216b74109775236E36d4b433F1DF507B', // [!code focus] +}) +``` +<<< @/snippets/abi-read.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### address + +`Address` + +The contract's address. + +::: code-group +```ts [index.ts] +import { readContract } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const result = await readContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', // [!code focus] + functionName: 'totalSupply', +}) +``` +<<< @/snippets/abi-read.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### args + +`readonly unknown[] | undefined` + +- Arguments to pass when calling the contract. +- Inferred from [`abi`](#abi) and [`functionName`](#functionname). + +::: code-group +```ts [index.ts] +import { readContract } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const result = await readContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'balanceOf', + args: ['0xd2135CfB216b74109775236E36d4b433F1DF507B'], // [!code focus] +}) +``` +<<< @/snippets/abi-read.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +--- + +### blockNumber + +`bigint | undefined` + +Block number to call contract at. + +::: code-group +```ts [index.ts] +import { readContract } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const result = await readContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'totalSupply', + blockNumber: 17829139n, // [!code focus] +}) +``` +<<< @/snippets/abi-read.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Block tag to call contract at. + +::: code-group +```ts [index.ts] +import { readContract } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const result = await readContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'totalSupply', + blockTag: 'safe', // [!code focus] +}) +``` +<<< @/snippets/abi-read.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +--- + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```ts [index.ts] +import { readContract } from '@wagmi/core' +import { mainnet } from 'wagmi/chains' // [!code focus] +import { abi } from './abi' +import { config } from './config' + +const result = await readContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'totalSupply', + chainId: mainnet.id, // [!code focus] +}) +``` +<<< @/snippets/abi-read.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### functionName + +`string` + +- Function to call on the contract. +- Inferred from [`abi`](#abi). + +::: code-group +```ts [index.ts] +import { readContract } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const result = await readContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'balanceOf', // [!code focus] + args: ['0xd2135CfB216b74109775236E36d4b433F1DF507B'], +}) +``` +<<< @/snippets/abi-read.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type ReadContractReturnType } from '@wagmi/core' +``` + +`unknown` + +- Result of contract read-only function. +- Inferred from [`abi`](#abi), [`functionName`](#functionname), and [`args`](#args). + +## Type Inference + +With [`abi`](#abi) setup correctly, TypeScript will infer the correct types for [`functionName`](#functionname), [`args`](#args), and the return type. See the Wagmi [TypeScript docs](/core/typescript) for more information. + +## Error + +```ts +import { type ReadContractErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`readContract`](https://viem.sh/docs/contract/readContract.html) diff --git a/wagmi-project/site/core/api/actions/readContracts.md b/wagmi-project/site/core/api/actions/readContracts.md new file mode 100644 index 000000000..67cbdf65a --- /dev/null +++ b/wagmi-project/site/core/api/actions/readContracts.md @@ -0,0 +1,363 @@ + + +# readContracts + +Action for calling multiple read methods on a contract. + +## Import + +```ts +import { readContracts } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { readContracts } from '@wagmi/core' +import { config } from './config' + +const wagmigotchiContract = { + address: '0xecb504d39723b0be0e3a9aa33d646642d1051ee1', + abi: wagmigotchiABI, +} as const +const mlootContract = { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi: mlootABI, +} as const + +const result = await readContracts(config, { + contracts: [ + { + ...wagmigotchiContract, + functionName: 'getAlive', + }, + { + ...wagmigotchiContract, + functionName: 'getBoredom', + }, + { + ...mlootContract, + functionName: 'getChest', + args: [69], + }, + { + ...mlootContract, + functionName: 'getWaist', + args: [69], + }, + ], +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type ReadContractsParameters } from '@wagmi/core' +``` + +### contracts + +`readonly Contract[]` + +Set of contracts to call. + +#### abi + +`Abi | undefined` + +The contract's ABI. Check out the [TypeScript docs](/react/typescript#const-assert-abis-typed-data) for how to set up ABIs for maximum type inference and safety. + +::: code-group +```tsx [index.tsx] +import { readContracts } from '@wagmi/core' +import { config } from './config' + +const result = await readContracts(config, { + contracts: [ + { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi: mlootABI, // [!code hl] + functionName: 'getChest', + args: [69], + }, + // ... + ], +}) +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +#### address + +`Address | undefined` + +The contract's address. + +::: code-group +```tsx [index.tsx] +import { readContracts } from '@wagmi/core' +import { config } from './config' + +const result = await readContracts(config, { + contracts: [ + { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', // [!code hl] + abi: mlootABI, + functionName: 'getChest', + args: [69], + }, + // ... + ], +}) +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +#### args + +`readonly unknown[] | undefined` + +- Arguments to pass when calling the contract. +- Inferred from [`abi`](#abi) and [`functionName`](#functionname). + +::: code-group +```tsx [index.tsx] +import { readContracts } from '@wagmi/core' +import { config } from './config' + +const result = await readContracts(config, { + contracts: [ + { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi: mlootABI, + functionName: 'getChest', + args: [69], // [!code hl] + }, + // ... + ], +}) +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +#### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```tsx [index.tsx] +import { readContracts } from '@wagmi/core' +import { config } from './config' + +const result = await readContracts(config, { + contracts: [ + { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi: mlootABI, + functionName: 'getChest', + args: [69], + chainId: 1, // [!code hl] + }, + // ... + ], +}) +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + +#### functionName + +`string | undefined` + +- Function to call on the contract. +- Inferred from [`abi`](#abi). + +::: code-group +```tsx [index.tsx] +import { readContracts } from '@wagmi/core' +import { config } from './config' + +const result = await readContracts(config, { + contracts: [ + { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi: mlootABI, + functionName: 'getChest', // [!code hl] + args: [69], + }, + // ... + ], +}) +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### allowFailure + +`boolean` + +Whether or not the Hook should throw if a call reverts. If set to `true` (default), and a call reverts, then `readContracts` will fail silently and its error will be logged in the results array. Defaults to `true`. + +::: code-group +```tsx [index.tsx] +import { readContracts } from '@wagmi/core' +import { config } from './config' + +const result = await readContracts(config, { + allowFailure: false, // [!code hl] + contracts: [ + { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi: mlootABI, + functionName: 'getChest', + args: [69], + }, + // ... + ], +}) +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### batchSize + +`number` + +The maximum size (in bytes) for each calldata chunk. Set to `0` to disable the size limit. Defaults to `1024`. + +> Note: Some RPC Providers limit the amount of calldata (`data`) that can be sent in a single `eth_call` request. It is best to check with your RPC Provider to see if there are any calldata size limits to `eth_call` requests. + +::: code-group +```tsx [index.tsx] +import { readContracts } from '@wagmi/core' +import { config } from './config' + +const result = await readContracts(config, { + batchSize: 1_024, // [!code hl] + contracts: [ + { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi: mlootABI, + functionName: 'getChest', + args: [69], + }, + // ... + ], +}) +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### blockNumber + +`number` + +The block number to perform the read against. + +::: code-group +```tsx [index.tsx] +import { readContracts } from '@wagmi/core' +import { config } from './config' + +const result = await readContracts(config, { + blockNumber: 69420n, // [!code hl] + contracts: [ + { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi: mlootABI, + functionName: 'getChest', + args: [69], + }, + // ... + ], +}) +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Block tag to read against. + +::: code-group +```tsx [index.tsx] +import { readContracts } from '@wagmi/core' +import { config } from './config' + +const result = await readContracts(config, { + blockTag: 'safe', // [!code hl] + contracts: [ + { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi: mlootABI, + functionName: 'getChest', + args: [69], + }, + // ... + ], +}) +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### multicallAddress + +`Address` + +Address of multicall contract. + +::: code-group +```tsx [index.tsx] +import { readContracts } from '@wagmi/core' +import { config } from './config' + +const result = await readContracts(config, { + contracts: [ + { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi: mlootABI, + functionName: 'getChest', + args: [69], + }, + // ... + ], + multicallAddress: '0xca11bde05977b3631167028862be2a173976ca11', // [!code hl] +}) +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type ReadContractsReturnType } from '@wagmi/core' +``` + +## Type Inference + +With [`contracts[number]['abi']`](#abi) setup correctly, TypeScript will infer the correct types for [`functionName`](#functionname), [`args`](#args), and the return type. See the Wagmi [TypeScript docs](/core/typescript) for more information. + +## Error + +```ts +import { type ReadContractsErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`multicall`](https://viem.sh/docs/actions/public/multicall.html) when supported by current chain. +- [`readContract`](https://viem.sh/docs/contract/readContract.html) when multicall is not supported. diff --git a/wagmi-project/site/core/api/actions/reconnect.md b/wagmi-project/site/core/api/actions/reconnect.md new file mode 100644 index 000000000..983be9aa7 --- /dev/null +++ b/wagmi-project/site/core/api/actions/reconnect.md @@ -0,0 +1,72 @@ + + +# reconnect + +Action for reconnecting [connectors](/core/api/connectors). + +## Import + +```ts +import { reconnect } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { reconnect } from '@wagmi/core' +import { injected } from '@wagmi/connectors' +import { config } from './config' + +const result = await reconnect(config, { connectors: [injected()] }) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type ReconnectParameters } from '@wagmi/core' +``` + +### connectors + +`(CreateConnectorFn | Connector)[] | undefined` + +- [Connectors](/core/api/connectors) to reconnect to. +- Defaults to [`Config['connectors']`](/core/api/createConfig#connectors). + +::: code-group +```ts [index.ts] +import { reconnect } from '@wagmi/core' +import { injected } from '@wagmi/connectors' +import { config } from './config' + +const result = await reconnect(config, { + connectors: [injected()], // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type ReconnectReturnType } from '@wagmi/core' +``` + +`Connection[]` + +[Connections](/core/api/createConfig#connection) that were successfully reconnected. + +## Error + +```ts +import { type ReconnectErrorType } from '@wagmi/core' +``` + + diff --git a/wagmi-project/site/core/api/actions/sendCalls.md b/wagmi-project/site/core/api/actions/sendCalls.md new file mode 100644 index 000000000..8e65890e5 --- /dev/null +++ b/wagmi-project/site/core/api/actions/sendCalls.md @@ -0,0 +1,223 @@ + + +# sendCalls + +Action that requests for the wallet to sign and broadcast a batch of calls (transactions) to the network. + +[Read more.](https://github.com/ethereum/EIPs/blob/815028dc634463e1716fc5ce44c019a6040f0bef/EIPS/eip-5792.md#wallet_sendcalls) + + + +## Import + +```ts +import { sendCalls } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { parseEther } from 'viem' +import { sendCalls } from '@wagmi/core' +import { config } from './config' + +const id = await sendCalls(config, { + calls: [ + { + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + value: parseEther('1') + }, + { + data: '0xdeadbeef', + to: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC', + }, + ] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type SendCallsParameters } from '@wagmi/core' +``` + +### account + +`Account | Address | null | undefined` + +Account to execute the calls. + +If set to `null`, it is assumed that the wallet will handle filling the sender of the calls. + +::: code-group +```ts [index.ts] +import { parseEther } from 'viem' +import { sendCalls } from '@wagmi/core' +import { config } from './config' + +const id = await sendCalls(config, { + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', // [!code focus] + calls: [ + { + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + value: parseEther('1') + }, + { + data: '0xdeadbeef', + to: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC', + }, + ], +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### calls + +`{ to: Hex, data?: Hex, value?: bigint }[]` + +Calls to execute. + +::: code-group +```ts [index.ts] +import { parseEther } from 'viem' +import { sendCalls } from '@wagmi/core' +import { config } from './config' + +const id = await sendCalls(config, { + calls: [ // [!code focus] + { // [!code focus] + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', // [!code focus] + value: parseEther('1') // [!code focus] + }, // [!code focus] + { // [!code focus] + data: '0xdeadbeef', // [!code focus] + to: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC', // [!code focus] + }, // [!code focus] + ], // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### capabilities + +`WalletCapabilities | undefined` + +Capability metadata for the calls (e.g. specifying a paymaster). + +::: code-group +```ts [index.ts] +import { parseEther } from 'viem' +import { sendCalls } from '@wagmi/core' +import { config } from './config' + +const id = await sendCalls(config, { + calls: [ + { + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + value: parseEther('1') + }, + { + data: '0xdeadbeef', + to: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC', + }, + ], + capabilities: { // [!code focus] + paymasterService: { // [!code focus] + url: 'https://...' // [!code focus] + } // [!code focus] + } // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### chainId + +`number | undefined` + +The target chain ID to broadcast the calls. + +::: code-group +```ts [index.ts] +import { parseEther } from 'viem' +import { sendCalls } from '@wagmi/core' +import { config } from './config' + +const id = await sendCalls(config, { + calls: [ + { + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + value: parseEther('1') + }, + { + data: '0xdeadbeef', + to: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC', + }, + ], + chainId: 10, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### connector + +`Connector | undefined` + +Connector to get send the calls with. + +::: code-group +```ts [index.ts] +import { parseEther } from 'viem' +import { getConnections } from '@wagmi/core' +import { sendCalls } from '@wagmi/core' +import { config } from './config' + +const connections = getConnections(config) +const id = await sendCalls(config, { + calls: [ + { + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + value: parseEther('1') + }, + { + data: '0xdeadbeef', + to: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC', + }, + ], + connector: connections[0]?.connector, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type SendCallsReturnType } from '@wagmi/core' +``` + +`bigint` + +Most recent block number seen. + +## Error + +```ts +import { type SendCallsErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`sendCalls`](https://viem.sh/experimental/eip5792/sendCalls) diff --git a/wagmi-project/site/core/api/actions/sendTransaction.md b/wagmi-project/site/core/api/actions/sendTransaction.md new file mode 100644 index 000000000..e02e1908d --- /dev/null +++ b/wagmi-project/site/core/api/actions/sendTransaction.md @@ -0,0 +1,341 @@ + + +# sendTransaction + +Action for creating, signing, and sending transactions to networks. + +## Import + +```ts +import { sendTransaction } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { sendTransaction } from '@wagmi/core' +import { parseEther } from 'viem' +import { config } from './config' + +const result = await sendTransaction(config, { + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type SendTransactionParameters } from '@wagmi/core' +``` + +### accessList + +`AccessList | undefined` + +The access list. + +::: code-group +```ts [index.ts] +import { sendTransaction } from '@wagmi/core' +import { parseEther } from 'viem' +import { config } from './config' + +const result = await sendTransaction(config, { + accessList: [{ // [!code focus] + address: '0x1', // [!code focus] + storageKeys: ['0x1'], // [!code focus] + }], // [!code focus] + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### account + +`Address | Account | undefined` + +Account to use when sending transaction. Throws if account is not found on [`connector`](#connector). + +::: code-group +```ts [index.ts] +import { sendTransaction } from '@wagmi/core' +import { parseEther } from 'viem' +import { config } from './config' + +const result = await sendTransaction(config, { + account: '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', // [!code focus] + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +Chain ID to validate against before sending transaction. + +::: code-group +```ts [index.ts] +import { sendTransaction } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { parseEther } from 'viem' +import { config } from './config' + +const result = await sendTransaction(config, { + chainId: mainnet.id, // [!code focus] + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### connector + +`Connector | undefined` + +- Connector to send transaction with. +- Defaults to current connector. + +::: code-group +```ts [index.ts] +import { getConnections, sendTransaction } from '@wagmi/core' +import { parseEther } from 'viem' +import { config } from './config' + +const connections = getConnections(config) +const result = await sendTransaction(config, { + connector: connections[0]?.connector, // [!code focus] + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### data + +`` `0x${string}` | undefined `` + +A contract hashed method call with encoded args. + +::: code-group +```ts [index.ts] +import { sendTransaction } from '@wagmi/core' +import { parseEther } from 'viem' +import { config } from './config' + +const result = await sendTransaction(config, { + data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', // [!code focus] + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### gas + +`bigint | undefined | null` + +Gas provided for transaction execution. + +::: code-group +```ts [index.ts] +import { sendTransaction } from '@wagmi/core' +import { parseEther, parseGwei } from 'viem' +import { config } from './config' + +const result = await sendTransaction(config, { + gas: parseGwei('20'), // [!code focus] + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +--- + +### gasPrice + +`bigint | undefined` + +The price in wei to pay per gas. Only applies to [Legacy Transactions](https://viem.sh/docs/glossary/terms.html#legacy-transaction). + +::: code-group +```ts [index.ts] +import { sendTransaction } from '@wagmi/core' +import { parseEther, parseGwei } from 'viem' +import { config } from './config' + +const result = await sendTransaction(config, { + gasPrice: parseGwei('20'), // [!code focus] + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### maxFeePerGas + +`bigint | undefined` + +Total fee per gas in wei, inclusive of [`maxPriorityFeePerGas`](#maxPriorityFeePerGas). Only applies to [EIP-1559 Transactions](https://viem.sh/docs/glossary/terms.html#eip-1559-transaction). + +::: code-group +```ts [index.ts] +import { sendTransaction } from '@wagmi/core' +import { parseEther, parseGwei } from 'viem' +import { config } from './config' + +const result = await sendTransaction(config, { + maxFeePerGas: parseGwei('20'), // [!code focus] + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### maxPriorityFeePerGas + +`bigint | undefined` + +Max priority fee per gas in wei. Only applies to [EIP-1559 Transactions](https://viem.sh/docs/glossary/terms.html#eip-1559-transaction). + +::: code-group +```ts [index.ts] +import { sendTransaction } from '@wagmi/core' +import { parseEther, parseGwei } from 'viem' +import { config } from './config' + +const result = await sendTransaction(config, { + maxFeePerGas: parseGwei('20'), + maxPriorityFeePerGas: parseGwei('2'), // [!code focus] + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +--- + +### nonce + +`number` + +Unique number identifying this transaction. + +::: code-group +```ts [index.ts] +import { sendTransaction } from '@wagmi/core' +import { parseEther } from 'viem' +import { config } from './config' + +const result = await sendTransaction(config, { + nonce: 123, // [!code focus] + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### to + +`Address` + +The transaction recipient or contract address. + +::: code-group +```ts [index.ts] +import { sendTransaction } from '@wagmi/core' +import { parseEther } from 'viem' +import { config } from './config' + +const result = await sendTransaction(config, { + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', // [!code focus] + value: parseEther('0.01'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### type + +`'legacy' | 'eip1559' | 'eip2930' | undefined` + +Optional transaction request type to narrow parameters. + +::: code-group +```ts [index.ts] +import { sendTransaction } from '@wagmi/core' +import { parseEther } from 'viem' +import { config } from './config' + +const result = await sendTransaction(config, { + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + type: 'eip1559', // [!code focus] + value: parseEther('0.01'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### value + +`bigint | undefined` + +Value in wei sent with this transaction. + +::: code-group +```ts [index.ts] +import { sendTransaction } from '@wagmi/core' +import { parseEther } from 'viem' +import { config } from './config' + +const result = await sendTransaction(config, { + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type SendTransactionReturnType } from '@wagmi/core' +``` + +[`Hash`](https://viem.sh/docs/glossary/types.html#hash) + +Transaction hash. + +## Error + +```ts +import { type SendTransactionErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`sendTransaction`](https://viem.sh/docs/actions/wallet/sendTransaction.html) diff --git a/wagmi-project/site/core/api/actions/showCallsStatus.md b/wagmi-project/site/core/api/actions/showCallsStatus.md new file mode 100644 index 000000000..c47d1fb88 --- /dev/null +++ b/wagmi-project/site/core/api/actions/showCallsStatus.md @@ -0,0 +1,99 @@ + + +# showCallsStatus + +Action to request for the wallet to show information about a call batch that was sent via `showCalls`. + +[Read more.](https://github.com/ethereum/EIPs/blob/1663ea2e7a683285f977eda51c32cec86553f585/EIPS/eip-5792.md#wallet_showcallsstatus) + + + +## Import + +```ts +import { showCallsStatus } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { showCallsStatus } from '@wagmi/core' +import { config } from './config' + +await showCallsStatus(config, { + id: '0x1234567890abcdef', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type ShowCallsStatusParameters } from '@wagmi/core' +``` + +### connector + +`Connector | undefined` + +Connector to show call statuses with. + +::: code-group +```ts [index.ts] +import { getConnections, showCallsStatus } from '@wagmi/core' +import { config } from './config' + +const connections = getConnections(config) +await showCallsStatus(config, { + connector: connections[0]?.connector, // [!code focus] + id: '0x1234567890abcdef', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### id + +`string` + +Identifier of the call batch. + +::: code-group +```ts [index.ts] +import { showCallsStatus } from '@wagmi/core' +import { config } from './config' + +await showCallsStatus(config, { + id: '0x1234567890abcdef', // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type ShowCallsStatusReturnType } from '@wagmi/core' +``` + +`bigint` + +Most recent block number seen. + +## Error + +```ts +import { type ShowCallsStatusErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`showCallsStatus`](https://viem.sh/experimental/eip5792/showCallsStatus) diff --git a/wagmi-project/site/core/api/actions/signMessage.md b/wagmi-project/site/core/api/actions/signMessage.md new file mode 100644 index 000000000..23569146a --- /dev/null +++ b/wagmi-project/site/core/api/actions/signMessage.md @@ -0,0 +1,125 @@ + + +# signMessage + +Action for signing messages. + +## Import + +```ts +import { signMessage } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { signMessage } from '@wagmi/core' +import { config } from './config' + +await signMessage(config, { message: 'hello world' }) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type SignMessageParameters } from '@wagmi/core' +``` + +### account + +`Address | Account | undefined` + +Account to use when signing message. Throws if account is not found on [`connector`](#connector). + +::: code-group +```ts [index.ts] +import { signMessage } from '@wagmi/core' +import { config } from './config' + +const result = await signMessage(config, { + account: '0xd2135CfB216b74109775236E36d4b433F1DF507B', // [!code focus] + message: 'hello world', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### connector + +`Connector | undefined` + +[Connector](/core/api/connectors) to sign message with. + +::: code-group +```ts [index.ts] +import { getAccount, signMessage } from '@wagmi/core' +import { config } from './config' + +const { connector } = getAccount(config) +const result = await signMessage(config, { + connector, // [!code focus] + message: 'hello world', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### message + +`string | { raw: Hex | ByteArray }` + +Message to sign. + +::: code-group +```ts [index.ts] +import { signMessage } from '@wagmi/core' +import { config } from './config' + +const result = await signMessage(config, { + message: 'hello world', // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +::: tip +By default, viem signs the UTF-8 representation of the message. To sign the data representation of the message, you can use the `raw` attribute. + +```ts +import { signMessage } from '@wagmi/core' +import { config } from './config' + +const result = await signMessage(config, { + message: { raw: '0x68656c6c6f20776f726c64' }, // [!code focus] +}) +``` +::: + +## Return Type + +```ts +import { type SignMessageReturnType } from '@wagmi/core' +``` + +[`Hex`](https://viem.sh/docs/glossary/types.html#hex) + +The signed message. + +## Error + +```ts +import { type SignMessageErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`signMessage`](https://viem.sh/docs/actions/wallet/signMessage.html) diff --git a/wagmi-project/site/core/api/actions/signTypedData.md b/wagmi-project/site/core/api/actions/signTypedData.md new file mode 100644 index 000000000..757c87160 --- /dev/null +++ b/wagmi-project/site/core/api/actions/signTypedData.md @@ -0,0 +1,409 @@ + + +# signTypedData + +Action for signing typed data and calculating an Ethereum-specific [EIP-712](https://eips.ethereum.org/EIPS/eip-712) signature. + +## Import + +```ts +import { signTypedData } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { signTypedData } from '@wagmi/core' +import { config } from './config' + +const result = await signTypedData(config, { + types: { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], + }, + primaryType: 'Mail', + message: { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type SignTypedDataParameters } from '@wagmi/core' +``` + +### account + +`Address | Account | undefined` + +Account to use when signing data. Throws if account is not found on [`connector`](#connector). + +::: code-group +```ts [index.ts] +import { signTypedData } from '@wagmi/core' +import { config } from './config' +import { types } from './typedData' + +const result = await signTypedData(config, { + account: '0xd2135CfB216b74109775236E36d4b433F1DF507B', // [!code focus] + types, + primaryType: 'Mail', + message: { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, +}) +``` +<<< @/snippets/typedData.ts[typedData.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### connector + +`Connector | undefined` + +[Connector](/core/api/connectors) to sign data with. + +::: code-group +```ts [index.ts] +import { getAccount, signTypedData } from '@wagmi/core' +import { config } from './config' +import { types } from './typedData' + +const { connector } = getAccount(config) +const result = await signTypedData(config, { + connector, // [!code focus] + types, + primaryType: 'Mail', + message: { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, +}) +``` +<<< @/snippets/typedData.ts[typedData.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### domain + +`TypedDataDomain | undefined` + +- The typed data domain. +- If `EIP712Domain` key exists in [`types`](#types), `domain` schema is inferred from it. + +::: code-group +```ts [index.ts] +import { signTypedData } from '@wagmi/core' +import { config } from './config' +import { types } from './typedData' + +const result = await signTypedData(config, { + domain: { // [!code focus] + name: 'Ether Mail', // [!code focus] + chainId: 1, // [!code focus] + verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC', // [!code focus] + version: '1', // [!code focus] + }, // [!code focus] + types, + primaryType: 'Mail', + message: { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, +}) +``` +<<< @/snippets/typedData.ts[typedData.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### message + +`Record` + +- Data to sign. +- Type inferred from [`types`](#types) and [`primaryType`](#primarytype). + +::: code-group +```ts [index.ts] +import { signTypedData } from '@wagmi/core' +import { config } from './config' +import { types } from './typedData' + +const result = await signTypedData(config, { + types, + primaryType: 'Mail', + message: { // [!code focus] + from: { // [!code focus] + name: 'Cow', // [!code focus] + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', // [!code focus] + }, // [!code focus] + to: { // [!code focus] + name: 'Bob', // [!code focus] + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', // [!code focus] + }, // [!code focus] + contents: 'Hello, Bob!', // [!code focus] + }, // [!code focus] +}) +``` +<<< @/snippets/typedData.ts[typedData.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### primaryType + +`string` + +- The primary type to extract from [`types`](#types) and use in [`message`](#message). +- Type inferred from [`types`](#types). + +::: code-group +```ts [index.ts] +import { signTypedData } from '@wagmi/core' +import { config } from './config' +import { types } from './typedData' + +const result = await signTypedData(config, { + types, + primaryType: 'Mail', // [!code focus] + message: { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, +}) +``` +<<< @/snippets/typedData.ts[typedData.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### types + +`TypedData` + +- The type definitions for the typed data. +- By defining inline or adding a [const assertion](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-4.html#const-assertions) to `types`, TypeScript will infer the correct types for [`message`](#message) and [`primaryType`](#primarytype). See the Wagmi [TypeScript docs](/core/typescript) for more information. + +::: code-group +```ts [index.ts] +import { signTypedData } from '@wagmi/core' +import { config } from './config' + +const result = await signTypedData(config, { + types: { // [!code focus] + Person: [ // [!code focus] + { name: 'name', type: 'string' }, // [!code focus] + { name: 'wallet', type: 'address' }, // [!code focus] + ], // [!code focus] + Mail: [ // [!code focus] + { name: 'from', type: 'Person' }, // [!code focus] + { name: 'to', type: 'Person' }, // [!code focus] + { name: 'contents', type: 'string' }, // [!code focus] + ], // [!code focus] + }, // [!code focus] + primaryType: 'Mail', + message: { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type SignTypedDataReturnType } from '@wagmi/core' +``` + +[`Hex`](https://viem.sh/docs/glossary/types.html#hex) + +The signed data. + +## Type Inference + +With [`types`](#types) setup correctly, TypeScript will infer the correct types for [`domain`](#domain), [`message`](#message), and [`primaryType`](#primarytype). See the Wagmi [TypeScript docs](/core/typescript) for more information. + +::: code-group +```ts twoslash [Inline] +import { createConfig, http, signTypedData } from '@wagmi/core' +import { mainnet, sepolia } from '@wagmi/core/chains' + +const config = createConfig({ + chains: [mainnet, sepolia], + transports: { + [mainnet.id]: http(), + [sepolia.id]: http(), + }, +}) +// ---cut--- +const result = await signTypedData(config, { + types: { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], + }, + primaryType: 'Mail', + // ^? + + + message: { + // ^? + + + + + + + + + + + + + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, +}) +``` +```ts twoslash [Const-Asserted] +import { createConfig, http, signTypedData } from '@wagmi/core' +import { mainnet, sepolia } from '@wagmi/core/chains' + +const config = createConfig({ + chains: [mainnet, sepolia], + transports: { + [mainnet.id]: http(), + [sepolia.id]: http(), + }, +}) +// ---cut--- +const types = { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], +} as const + +const result = await signTypedData(config, { + types, + primaryType: 'Mail', + // ^? + + + message: { + // ^? + + + + + + + + + + + + + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, +}) +``` +::: + +## Error + +```ts +import { type SignTypedDataErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`signTypedData`](https://viem.sh/docs/actions/wallet/signTypedData.html) diff --git a/wagmi-project/site/core/api/actions/simulateContract.md b/wagmi-project/site/core/api/actions/simulateContract.md new file mode 100644 index 000000000..b7884ef71 --- /dev/null +++ b/wagmi-project/site/core/api/actions/simulateContract.md @@ -0,0 +1,598 @@ + + +# simulateContract + +Action for simulating/validating a contract interaction. + +## Import + +```ts +import { simulateContract } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { simulateContract } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const result = await simulateContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], +}) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type SimulateContractParameters } from '@wagmi/core' +``` + +### abi + +`Abi` + +The contract's ABI. Check out the [TypeScript docs](/react/typescript#const-assert-abis-typed-data) for how to set up ABIs for maximum type inference and safety. + +::: code-group +```ts [index.ts] +import { simulateContract } from '@wagmi/core' +import { abi } from './abi' // [!code focus] +import { config } from './config' + +const result = await simulateContract(config, { + abi, // [!code focus] + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], +}) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### accessList + +`AccessList | undefined` + +The access list. + +::: code-group +```ts [index.ts] +import { simulateContract } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const result = await simulateContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + accessList: [{ // [!code focus] + address: '0x1', // [!code focus] + storageKeys: ['0x1'], // [!code focus] + }], // [!code focus] +}) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### account + +`Address | Account | undefined` + +Account to use when signing data. Throws if account is not found on [`connector`](#connector). + +::: code-group +```ts [index.ts] +import { simulateContract } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const result = await simulateContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + account: '0xd2135CfB216b74109775236E36d4b433F1DF507B', // [!code focus] +}) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### address + +`Address` + +The contract's address. + +::: code-group +```ts [index.ts] +import { simulateContract } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const result = await simulateContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', // [!code focus] + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], +}) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + + +### args + +`readonly unknown[] | undefined` + +- Arguments to pass when calling the contract. +- Inferred from [`abi`](#abi) and [`functionName`](#functionname). + +::: code-group +```ts [index.ts] +import { simulateContract } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const result = await simulateContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ // [!code focus] + '0xd2135CfB216b74109775236E36d4b433F1DF507B', // [!code focus] + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', // [!code focus] + 123n, // [!code focus] + ], // [!code focus] +}) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +--- + +### blockNumber + +`bigint | undefined` + +Block number to simulate against. + +::: code-group +```ts [index.ts] +import { simulateContract } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const result = await simulateContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + blockNumber: 17829139n, // [!code focus] +}) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Block tag to simulate against. + +::: code-group +```ts [index.ts] +import { simulateContract } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const result = await simulateContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + blockTag: 'safe', // [!code focus] +}) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +--- + +### chainId + +`config['chains'][number]['id'] | undefined` + +Chain ID to validate against before sending transaction. + +::: code-group +```ts [index.ts] +import { simulateContract } from '@wagmi/core' +import { mainnet } from 'wagmi/chains' // [!code focus] +import { abi } from './abi' +import { config } from './config' + +const result = await simulateContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + chainId: mainnet.id, // [!code focus] +}) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### connector + +`Connector | undefined` + +[Connector](/core/api/connectors) to simulate transaction with. + +::: code-group +```ts [index.ts] +import { getAccount, simulateContract } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const { connector } = getAccount(config) +const result = await simulateContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + connector, // [!code focus] +}) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### dataSuffix + +`` `0x${string}` | undefined `` + +Data to append to the end of the calldata. Useful for adding a ["domain" tag](https://opensea.notion.site/opensea/Seaport-Order-Attributions-ec2d69bf455041a5baa490941aad307f). + +::: code-group +```ts [index.ts] +import { simulateContract } from '@wagmi/core' +import { parseGwei } from 'viem' +import { abi } from './abi' +import { config } from './config' + +const result = await simulateContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + dataSuffix: '0xdeadbeef', // [!code focus] +}) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### functionName + +`string` + +- Function to call on the contract. +- Inferred from [`abi`](#abi). + +::: code-group +```ts [index.ts] +import { simulateContract } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const result = await simulateContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'approve', // [!code focus] + args: ['0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', 123n] +}) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### gas + +`bigint | undefined` + +Gas provided for transaction execution. + +::: code-group +```ts [index.ts] +import { simulateContract } from '@wagmi/core' +import { parseGwei } from 'viem' +import { abi } from './abi' +import { config } from './config' + +const result = await simulateContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + gas: parseGwei('20'), // [!code focus] +}) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +--- + +### gasPrice + +`bigint | undefined` + +The price in wei to pay per gas. Only applies to [Legacy Transactions](https://viem.sh/docs/glossary/terms.html#legacy-transaction). + +::: code-group +```ts [index.ts] +import { simulateContract } from '@wagmi/core' +import { parseGwei } from 'viem' +import { abi } from './abi' +import { config } from './config' + +const result = await simulateContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + gasPrice: parseGwei('20'), // [!code focus] +}) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### maxFeePerGas + +`bigint | undefined` + +Total fee per gas in wei, inclusive of [`maxPriorityFeePerGas`](#maxPriorityFeePerGas). Only applies to [EIP-1559 Transactions](https://viem.sh/docs/glossary/terms.html#eip-1559-transaction). + +::: code-group +```ts [index.ts] +import { simulateContract } from '@wagmi/core' +import { parseGwei } from 'viem' +import { abi } from './abi' +import { config } from './config' + +const result = await simulateContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + maxFeePerGas: parseGwei('20'), // [!code focus] +}) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### maxPriorityFeePerGas + +`bigint | undefined` + +Max priority fee per gas in wei. Only applies to [EIP-1559 Transactions](https://viem.sh/docs/glossary/terms.html#eip-1559-transaction). + +::: code-group +```ts [index.ts] +import { simulateContract } from '@wagmi/core' +import { parseGwei } from 'viem' +import { abi } from './abi' +import { config } from './config' + +const result = await simulateContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + maxFeePerGas: parseGwei('20'), + maxPriorityFeePerGas: parseGwei('2'), // [!code focus] +}) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +--- + +### nonce + +`number` + +Unique number identifying this transaction. + +::: code-group +```ts [index.ts] +import { simulateContract } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const result = await simulateContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + nonce: 123, // [!code focus] +}) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### type + +`'legacy' | 'eip1559' | 'eip2930' | undefined` + +Optional transaction request type to narrow parameters. + +::: code-group +```ts [index.ts] +import { simulateContract } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const result = await simulateContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + type: 'eip1559', // [!code focus] +}) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### value + +`bigint | undefined` + +Value in wei sent with this transaction. + +::: code-group +```ts [index.ts] +import { simulateContract } from '@wagmi/core' +import { parseEther } from 'viem' +import { abi } from './abi' +import { config } from './config' + +const result = await simulateContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + value: parseEther('0.01'), // [!code focus] +}) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type SimulateContractReturnType } from '@wagmi/core' +``` + +The simulation result and write request. + +### request + +Write request that includes [parameters](#parameters). + +### response + +`unknown` + +- Result of contract simulation. +- Inferred from [`abi`](#abi), [`functionName`](#functionname), and [`args`](#args). + +## Type Inference + +With [`abi`](#abi) setup correctly, TypeScript will infer the correct types for [`functionName`](#functionname), [`args`](#args), and [`value`](#value). See the Wagmi [TypeScript docs](/core/typescript) for more information. + +## Error + +```ts +import { type SimulateContractErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`simulateContract`](https://viem.sh/docs/contract/simulateContract.html) diff --git a/wagmi-project/site/core/api/actions/switchAccount.md b/wagmi-project/site/core/api/actions/switchAccount.md new file mode 100644 index 000000000..8d0f629c1 --- /dev/null +++ b/wagmi-project/site/core/api/actions/switchAccount.md @@ -0,0 +1,81 @@ + + +# switchAccount + +Action for switching the current account. + +## Import + +```ts +import { switchAccount } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { getConnections, switchAccount } from '@wagmi/core' +import { config } from './config' + +const connections = getConnections(config) +const result = await switchAccount(config, { + connector: connections[0]?.connector, +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type SwitchAccountParameters } from '@wagmi/core' +``` + +### connector + +`Connector` + +[Connector](/core/api/connectors) to switch to. + +::: code-group +```ts [index.ts] +import { getConnections, switchAccount } from '@wagmi/core' +import { config } from './config' + +const connections = getConnections(config) +const result = await switchAccount(config, { + connector: connections[0]?.connector, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type SwitchAccountReturnType } from '@wagmi/core' +``` + +### accounts + +`readonly [Address, ...Address[]]` + +Connected accounts from connector. + +### chainId + +`number` + +Connected chain ID from connector. + +## Error + +```ts +import { type SwitchAccountErrorType } from '@wagmi/core' +``` + + diff --git a/wagmi-project/site/core/api/actions/switchChain.md b/wagmi-project/site/core/api/actions/switchChain.md new file mode 100644 index 000000000..c741e801c --- /dev/null +++ b/wagmi-project/site/core/api/actions/switchChain.md @@ -0,0 +1,122 @@ + + +# switchChain + +Action for switching the target chain for a connector or the Wagmi [`Config`](/core/api/createConfig#config). + +## Import + +```ts +import { switchChain } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { switchChain } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { config } from './config' + +await switchChain(config, { chainId: mainnet.id }) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +::: tip +When connected, `switchChain` will switch the target chain for the connector. When not connected, `switchChain` will switch the target chain for the Wagmi [`Config`](/core/api/createConfig#config). +::: + +## Parameters + +```ts +import { type SwitchChainParameters } from '@wagmi/core' +``` + +### addEthereumChainParameter + +`{ chainName: string; nativeCurrency?: { name: string; symbol: string; decimals: number } | undefined; rpcUrls: readonly string[]; blockExplorerUrls?: string[] | undefined; iconUrls?: string[] | undefined } | undefined` + +[EIP-3085 parameters](https://eips.ethereum.org/EIPS/eip-3085) to use when adding chain to connector (when supported). + +::: code-group +```ts [index.ts] +import { switchChain } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { config } from './config' + +const result = await switchChain(config, { + addEthereumChainParameter: { // [!code focus] + iconUrls: ['https://example.com/icon.png'], // [!code focus] + }, // [!code focus] + chainId: mainnet.id, +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to switch to. + +::: code-group +```ts [index.ts] +import { switchChain } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { config } from './config' + +const result = await switchChain(config, { + chainId: mainnet.id, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### connector + +`Connector` + +[Connector](/core/api/connectors) to switch chain with. + +::: code-group +```ts [index.ts] +import { getConnections, switchAccount } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { config } from './config' + +const connections = getConnections(config) +const result = await switchChain(config, { + chainId: mainnet.id, + connector: connections[0]?.connector, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type SwitchChainReturnType } from '@wagmi/core' +``` + +`Chain` + +Chain that was switched to. + +## Error + +```ts +import { type SwitchChainErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`switchChain`](https://viem.sh/docs/actions/wallet/switchChain.html) when connected. diff --git a/wagmi-project/site/core/api/actions/verifyMessage.md b/wagmi-project/site/core/api/actions/verifyMessage.md new file mode 100644 index 000000000..93d46992b --- /dev/null +++ b/wagmi-project/site/core/api/actions/verifyMessage.md @@ -0,0 +1,200 @@ + + +# verifyMessage + +Action for verify that a message was signed by the provided address. It supports verifying messages that were signed by either a Smart Contract Account or Externally Owned Account. + +## Import + +```ts +import { verifyMessage } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { verifyMessage } from '@wagmi/core' +import { config } from './config' + +await verifyMessage(config, { + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + message: 'hello world', + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type VerifyMessageParameters } from '@wagmi/core' +``` + +### address + +`Address` + +The Ethereum address that signed the original message. + +::: code-group +```ts [index.ts] +import { verifyMessage } from '@wagmi/core' +import { config } from './config' + +await verifyMessage(config, { + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', // [!code focus] + message: 'hello world', + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### message + +`string | { raw: Hex | ByteArray }` + +The message to be verified. + +By default, wagmi verifies the UTF-8 representation of the message. + +::: code-group +```ts [index.ts] +import { getAccount, verifyMessage } from '@wagmi/core' +import { config } from './config' + +await verifyMessage(config, { + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + message: 'hello world', // [!code focus] + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +::: tip +By default, viem signs the UTF-8 representation of the message. To sign the data representation of the message, you can use the `raw` attribute. + +```ts +import { verifyMessage } from '@wagmi/core' +import { config } from './config' + +await verifyMessage(config, { + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + message: { raw: '0x68656c6c6f20776f726c64' } // [!code focus] + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', +}) +``` +::: + +### signature + +`Hex | ByteArray ` + +The signature that was generated by signing the message with the address's signer. + +::: code-group +```ts [index.ts] +import { verifyMessage } from '@wagmi/core' +import { config } from './config' + +await verifyMessage(config, { + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + message: 'hello world', + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +Only used when verifying a message that was signed by a Smart Contract Account. The ID of chain to check if the contract was already deployed. + +::: code-group +```ts [index.ts] +import { verifyMessage } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { config } from './config' + +await verifyMessage(config, { + chainId: mainnet.id, // [!code focus] + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + message: 'hello world', + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### blockNumber + +`bigint | undefined` + +Only used when verifying a message that was signed by a Smart Contract Account. The block number to check if the contract was already deployed. + +::: code-group +```ts [index.ts] +import { verifyMessage } from '@wagmi/core' +import { config } from './config' + +await verifyMessage(config, { + blockNumber: 12345678n, // [!code focus] + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + message: 'hello world', + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Only used when verifying a message that was signed by a Smart Contract Account. The block tag to check if the contract was already deployed. + +::: code-group +```ts [index.ts] +import { verifyMessage } from '@wagmi/core' +import { config } from './config' + +await verifyMessage(config, { + blockTag: 'latest', // [!code focus] + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + message: 'hello world', + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type VerifyMessageReturnType } from '@wagmi/core' +``` + +`boolean` + +Whether the signed message is valid for the given address. + +## Error + +```ts +import { type VerifyMessageErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`verifyMessage`](https://viem.sh/docs/actions/public/verifyMessage.html) diff --git a/wagmi-project/site/core/api/actions/verifyTypedData.md b/wagmi-project/site/core/api/actions/verifyTypedData.md new file mode 100644 index 000000000..e9afa17ad --- /dev/null +++ b/wagmi-project/site/core/api/actions/verifyTypedData.md @@ -0,0 +1,595 @@ + + +# verifyTypedData + +Action for verify that a typed data was signed by the provided address. It supports verifying typed data that were signed by either a Smart Contract Account or Externally Owned Account. + +## Import + +```ts +import { verifyTypedData } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { verifyTypedData } from '@wagmi/core' +import { domain, types } from './data' +import { config } from './config' + +const valid = await verifyTypedData(config, { + domain, + types, + message: { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, + primaryType: 'Mail', + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', +}) +// true +``` +```ts [data.ts] +// All properties on a domain are optional +export const domain = { + name: 'Ether Mail', + version: '1', + chainId: 1, + verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC', +} as const + +// The named list of all type definitions +export const types = { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], +} as const +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type VerifyTypedDataParameters } from '@wagmi/core' +``` + +### address + +`Address` + +The Ethereum address that signed the original typed data. + +::: code-group +```ts [index.ts] +import { verifyTypedData } from '@wagmi/core' +import { domain, types } from './data' +import { config } from './config' + +const valid = await verifyTypedData(config, { + domain, + types, + message: { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, + primaryType: 'Mail', + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', // [!code focus] + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', +}) +// true +``` +```ts [data.ts] +// All properties on a domain are optional +export const domain = { + name: 'Ether Mail', + version: '1', + chainId: 1, + verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC', +} as const + +// The named list of all type definitions +export const types = { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], +} as const +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### domain + +`TypedDataDomain` + +The typed data domain. + +::: code-group +```ts [index.ts] +import { verifyTypedData } from '@wagmi/core' +import { types } from './data' +import { config } from './config' + +const valid = await verifyTypedData(config, { + domain: { // [!code focus:6] + name: 'Ether Mail', + version: '1', + chainId: 1, + verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC', + }, + types, + message: { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, + primaryType: 'Mail', + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', +}) +// true +``` +```ts [data.ts] +// The named list of all type definitions +export const types = { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], +} as const +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### types + +The type definitions for the typed data. + +::: code-group +```ts [index.ts] +import { verifyTypedData } from '@wagmi/core' +import { domain } from './data' +import { config } from './config' + +const valid = await verifyTypedData(config, { + domain, + types: { // [!code focus:11] + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], + }, + primaryType: 'Mail', + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', +}) +// true +``` +```ts [data.ts] +// All properties on a domain are optional +export const domain = { + name: 'Ether Mail', + version: '1', + chainId: 1, + verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC', +} as const +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### primaryType + +`string` + +The primary `type` to extract from types and use in `value`. + +::: code-group +```ts [index.ts] +import { verifyTypedData } from '@wagmi/core' +import { domain } from './data' +import { config } from './config' + +const valid = await verifyTypedData(config, { + domain, + types: { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ // [!code focus:5] + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], + }, + message: { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, + primaryType: 'Mail', // [!code focus] + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', +}) +// true +``` +```ts [data.ts] +// All properties on a domain are optional +export const domain = { + name: 'Ether Mail', + version: '1', + chainId: 1, + verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC', +} as const +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### message + +Type inferred from `types` & `primaryType`. + +The message to be verified. + +::: code-group +```ts [index.ts] +import { verifyTypedData } from '@wagmi/core' +import { domain, types } from './data' +import { config } from './config' + +const valid = await verifyTypedData(config, { + domain, + types, + message: { // [!code focus:11] + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, + primaryType: 'Mail', + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', +}) +// true +``` +```ts [data.ts] +// All properties on a domain are optional +export const domain = { + name: 'Ether Mail', + version: '1', + chainId: 1, + verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC', +} as const + +// The named list of all type definitions +export const types = { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], +} as const +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### signature + +`Hex | ByteArray` + +The signature that was generated by signing the typed data with the address's signer. + +::: code-group +```ts [index.ts] +import { verifyTypedData } from '@wagmi/core' +import { domain, types } from './data' +import { config } from './config' + +const valid = await verifyTypedData(config, { + domain, + types, + message: { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, + primaryType: 'Mail', + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', // [!code focus] +}) +// true +``` +```ts [data.ts] +// All properties on a domain are optional +export const domain = { + name: 'Ether Mail', + version: '1', + chainId: 1, + verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC', +} as const + +// The named list of all type definitions +export const types = { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], +} as const +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +Only used when verifying a typed data that was signed by a Smart Contract Account. The ID of chain to check if the contract was already deployed. + +::: code-group +```ts [index.ts] +import { verifyTypedData } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { domain, types } from './data' +import { config } from './config' + +const valid = await verifyTypedData(config, { + chainId: mainnet.id, // [!code focus] + domain, + types, + message: { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, + primaryType: 'Mail', + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', +}) +// true +``` +```ts [data.ts] +// All properties on a domain are optional +export const domain = { + name: 'Ether Mail', + version: '1', + chainId: 1, + verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC', +} as const + +// The named list of all type definitions +export const types = { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], +} as const +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### blockNumber + +`bigint | undefined` + +Only used when verifying a typed data that was signed by a Smart Contract Account. The block number to check if the contract was already deployed. + +::: code-group +```ts [index.ts] +import { verifyTypedData } from '@wagmi/core' +import { domain, types } from './data' +import { config } from './config' + +const valid = await verifyTypedData(config, { + blockNumber: 12345678n, // [!code focus] + domain, + types, + message: { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, + primaryType: 'Mail', + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', +}) +// true +``` +```ts [data.ts] +// All properties on a domain are optional +export const domain = { + name: 'Ether Mail', + version: '1', + chainId: 1, + verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC', +} as const + +// The named list of all type definitions +export const types = { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], +} as const +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Only used when verifying a typed data that was signed by a Smart Contract Account. The block number to check if the contract was already deployed. + +::: code-group +```ts [index.ts] +import { verifyTypedData } from '@wagmi/core' +import { domain, types } from './data' +import { config } from './config' + +const valid = await verifyTypedData(config, { + blockTag: 'latest', // [!code focus] + domain, + types, + message: { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, + primaryType: 'Mail', + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', +}) +// true +``` +```ts [data.ts] +// All properties on a domain are optional +export const domain = { + name: 'Ether Mail', + version: '1', + chainId: 1, + verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC', +} as const + +// The named list of all type definitions +export const types = { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], +} as const +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type VerifyTypedDataReturnType } from '@wagmi/core' +``` + +`boolean` + +Whether the signed message is valid for the given address. + +## Type Inference + +With [`types`](#types) setup correctly, TypeScript will infer the correct types for [`domain`](#domain), [`message`](#message), and [`primaryType`](#primarytype). See the Wagmi [TypeScript docs](/core/typescript) for more information. + +## Error + +```ts +import { type VerifyTypedDataErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`verifyTypedData`](https://viem.sh/docs/actions/public/verifyTypedData.html) diff --git a/wagmi-project/site/core/api/actions/waitForCallsStatus.md b/wagmi-project/site/core/api/actions/waitForCallsStatus.md new file mode 100644 index 000000000..826180104 --- /dev/null +++ b/wagmi-project/site/core/api/actions/waitForCallsStatus.md @@ -0,0 +1,143 @@ + + +# waitForCallsStatus + +Waits for a call bundle to be confirmed & included on a block before returning the status & receipts. + + + +## Import + +```ts +import { waitForCallsStatus } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { parseEther } from 'viem' +import { sendCalls, waitForCallsStatus } from '@wagmi/core' +import { config } from './config' + +const id = await sendCalls(config, { + calls: [{ + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + value: parseEther('1') + }] +}) + +const { status, receipts } = await waitForCallsStatus(config, { // [!code focus] + id, // [!code focus] +}) // [!code focus] +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type WaitForCallsStatusParameters } from '@wagmi/core' +``` + +### connector + +`Connector | undefined` + +Connector to get call statuses with. + +::: code-group +```ts [index.ts] +import { getConnections, waitForCallsStatus } from '@wagmi/core' +import { config } from './config' + +const connections = getConnections(config) +const status = await waitForCallsStatus(config, { + connector: connections[0]?.connector, // [!code focus] + id: '0x1234567890abcdef', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### id + +`string` + +Identifier of the call batch. + +::: code-group +```ts [index.ts] +import { waitForCallsStatus } from '@wagmi/core' +import { config } from './config' + +const status = await waitForCallsStatus(config, { + id: '0x1234567890abcdef', // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### pollingInterval + +`number` + +Polling interval in milliseconds. + +::: code-group +```ts [index.ts] +import { waitForCallsStatus } from '@wagmi/core' +import { config } from './config' + +const status = await waitForCallsStatus(config, { + id: '0x1234567890abcdef', + pollingInterval: 1_000, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### timeout + +`number` + +Timeout in milliseconds before `waitForCallsStatus` stops polling. + +::: code-group +```ts [index.ts] +import { waitForCallsStatus } from '@wagmi/core' +import { config } from './config' + +const status = await waitForCallsStatus(config, { + id: '0x1234567890abcdef', + timeout: 10_000, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type WaitForCallsStatusReturnType } from '@wagmi/core' +``` + +`{ status: 'PENDING' | 'CONFIRMED', receipts: TransactionReceipt[] }` + +The status and receipts of the call batch. + +## Error + +```ts +import { type WaitForCallsStatusErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`waitForCallsStatus`](https://viem.sh/experimental/eip5792/waitForCallsStatus) diff --git a/wagmi-project/site/core/api/actions/waitForTransactionReceipt.md b/wagmi-project/site/core/api/actions/waitForTransactionReceipt.md new file mode 100644 index 000000000..853189055 --- /dev/null +++ b/wagmi-project/site/core/api/actions/waitForTransactionReceipt.md @@ -0,0 +1,155 @@ + + +# waitForTransactionReceipt + +Action that waits for the transaction to be included on a block, and then returns the transaction receipt. If the transaction reverts, then the action will throw an error. Replacement detection (e.g. sped up transactions) is also supported. + +## Import + +```ts +import { waitForTransactionReceipt } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { waitForTransactionReceipt } from '@wagmi/core' +import { config } from './config' + +const transactionReceipt = waitForTransactionReceipt(config, { + hash: '0x4ca7ee652d57678f26e887c149ab0735f41de37bcad58c9f6d3ed5824f15b74d', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type WaitForTransactionReceiptParameters } from '@wagmi/core' +``` + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```ts [index.ts] +import { waitForTransactionReceipt } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { config } from './config' + +const transactionReceipt = await waitForTransactionReceipt(config, { + chainId: mainnet.id, // [!code focus] + hash: '0x4ca7ee652d57678f26e887c149ab0735f41de37bcad58c9f6d3ed5824f15b74d', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### confirmations + +`number | undefined` + +The number of confirmations (blocks that have passed) to wait before resolving. + +::: code-group +```ts [index.ts] +import { waitForTransactionReceipt } from '@wagmi/core' +import { config } from './config' + +const transactionReceipt = await waitForTransactionReceipt(config, { + confirmations: 2, // [!code focus] + hash: '0x4ca7ee652d57678f26e887c149ab0735f41de37bcad58c9f6d3ed5824f15b74d', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### onReplaced + +` +(({ reason: 'replaced' | 'repriced' | 'cancelled'; replacedTransaction: Transaction; transaction: Transaction; transactionReceipt: TransactionReceipt }) => void) | undefined +` + +Optional callback to emit if the transaction has been replaced. + +::: code-group +```ts [index.ts] +import { waitForTransactionReceipt } from '@wagmi/core' +import { config } from './config' + +const transactionReceipt = await waitForTransactionReceipt(config, { + hash: '0x4ca7ee652d57678f26e887c149ab0735f41de37bcad58c9f6d3ed5824f15b74d', + onReplaced: replacement => console.log(replacement), // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### hash + +`` `0x${string}` `` + +The transaction hash to wait for. + +::: code-group +```ts [index.ts] +import { waitForTransactionReceipt } from '@wagmi/core' +import { config } from './config' + +const transactionReceipt = await waitForTransactionReceipt(config, { + hash: '0x4ca7ee652d57678f26e887c149ab0735f41de37bcad58c9f6d3ed5824f15b74d', // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### pollingInterval + +`number | undefined` + +- Polling frequency (in milliseconds). +- Defaults to the [Config's `pollingInterval` config](/core/api/createConfig#pollinginterval). + +::: code-group +```ts [index.ts] +import { waitForTransactionReceipt } from '@wagmi/core' +import { config } from './config' + +const transactionReceipt = await waitForTransactionReceipt(config, { + hash: '0x4ca7ee652d57678f26e887c149ab0735f41de37bcad58c9f6d3ed5824f15b74d', + pollingInterval: 1_000, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type WaitForTransactionReceiptReturnType } from '@wagmi/core' +``` + +[`TransactionReceipt`](https://viem.sh/docs/glossary/types.html#transactionreceipt) + +The transaction receipt. + +## Error + +```ts +import { type WaitForTransactionReceiptErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`waitForTransactionReceipt`](https://viem.sh/docs/actions/public/waitForTransactionReceipt.html) diff --git a/wagmi-project/site/core/api/actions/watchAccount.md b/wagmi-project/site/core/api/actions/watchAccount.md new file mode 100644 index 000000000..a71ca4d16 --- /dev/null +++ b/wagmi-project/site/core/api/actions/watchAccount.md @@ -0,0 +1,61 @@ +# watchAccount + +Subscribe to account changes. + +## Import + +```ts +import { watchAccount } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { watchAccount } from '@wagmi/core' +import { config } from './config' + +const unwatch = watchAccount(config, { + onChange(data) { + console.log('Account changed!', data) + }, +}) +unwatch() +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type WatchAccountParameters } from '@wagmi/core' +``` + +### onChange + +`onChange(account: GetAccountReturnType, prevAccount: GetAccountReturnType): void` + +Callback function called when account changes. + +::: code-group +```ts [index.ts] +import { watchAccount } from '@wagmi/core' +import { config } from './config' + +const unwatch = watchAccount(config, { + onChange(account) { // [!code focus:3] + console.log('Account changed!', account) + }, +}) +unwatch() +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type WatchAccountReturnType } from '@wagmi/core' +``` + +Function for cleaning up watcher. \ No newline at end of file diff --git a/wagmi-project/site/core/api/actions/watchAsset.md b/wagmi-project/site/core/api/actions/watchAsset.md new file mode 100644 index 000000000..394dadd7a --- /dev/null +++ b/wagmi-project/site/core/api/actions/watchAsset.md @@ -0,0 +1,134 @@ + + +# watchAsset + +Action for requesting user tracks the token in their wallet. Returns a boolean indicating if the token was successfully added. + +## Import + +```ts +import { watchAsset } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { watchAsset } from '@wagmi/core' +import { config } from './config' + +await watchAsset(config, { + type: 'ERC20', + options: { + address: '0x0000000000000000000000000000000000000000', + symbol: 'WAGMI', + decimals: 18, + }, +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type WatchAssetParameters } from '@wagmi/core' +``` + +### connector + +`Connector | undefined` + +[Connector](/core/api/connectors) to sign message with. + +::: code-group +```ts [index.ts] +import { getAccount, watchAsset } from '@wagmi/core' +import { config } from './config' + +const { connector } = getAccount(config) +const result = await watchAsset(config, { + connector, // [!code focus] + options: { + address: '0x0000000000000000000000000000000000000000', + symbol: 'WAGMI', + decimals: 18, + }, + type: 'ERC20', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### options + +`{ address: string; symbol: string; decimals: number; image?: string | undefined; }` + +Asset options. + +::: code-group +```ts [index.ts] +import { watchAsset } from '@wagmi/core' +import { config } from './config' + +const result = await watchAsset(config, { + options: { // [!code focus] + address: '0x0000000000000000000000000000000000000000', // [!code focus] + symbol: 'WAGMI', // [!code focus] + decimals: 18, // [!code focus] + }, // [!code focus] + type: 'ERC20', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### type + +`'ERC20'` + +Type of asset. + +::: code-group +```ts [index.ts] +import { watchAsset } from '@wagmi/core' +import { config } from './config' + +const result = await watchAsset(config, { + options: { + address: '0x0000000000000000000000000000000000000000', + symbol: 'WAGMI', + decimals: 18, + }, + type: 'ERC20', // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type WatchAssetReturnType } from '@wagmi/core' +``` + +`boolean` + +Returns a boolean indicating if the token was successfully added. + +## Error + +```ts +import { type WatchAssetErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`watchAsset`](https://viem.sh/docs/actions/wallet/watchAsset.html) + diff --git a/wagmi-project/site/core/api/actions/watchBlockNumber.md b/wagmi-project/site/core/api/actions/watchBlockNumber.md new file mode 100644 index 000000000..098fd6613 --- /dev/null +++ b/wagmi-project/site/core/api/actions/watchBlockNumber.md @@ -0,0 +1,226 @@ +# watchBlockNumber + +Action that watches for block number changes. + +## Import + +```ts +import { watchBlockNumber } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { watchBlockNumber } from '@wagmi/core' +import { config } from './config' + +const unwatch = watchBlockNumber(config, { + onBlockNumber(blockNumber) { + console.log('Block number changed!', blockNumber) + }, +}) +unwatch() +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type WatchBlockNumberParameters } from '@wagmi/core' +``` + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```ts [index.ts] +import { watchBlockNumber } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { config } from './config' + +const unwatch = watchBlockNumber(config, { + chainId: mainnet.id, // [!code focus] + onBlockNumber(blockNumber) { + console.log('Block number changed!', blockNumber) + }, +}) +unwatch() +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### emitOnBegin + +`boolean | undefined` + +Whether or not to emit the latest block number to the callback when the subscription opens. + +::: code-group +```ts [index.ts] +import { watchBlockNumber } from '@wagmi/core' +import { config } from './config' + +const unwatch = watchBlockNumber(config, { + emitOnBegin: true, // [!code focus] + onBlockNumber(blockNumber) { + console.log('Block number changed!', blockNumber) + }, +}) +unwatch() +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### emitMissed + +`boolean | undefined` + +Whether or not to emit the missed block numbers to the callback. + +::: code-group +```ts [index.ts] +import { watchBlockNumber } from '@wagmi/core' +import { config } from './config' + +const unwatch = watchBlockNumber(config, { + emitMissed: true, // [!code focus] + onBlockNumber(blockNumber) { + console.log('Block number changed!', blockNumber) + }, +}) +unwatch() +``` +<<< @/snippets/core/config.ts[config.ts] +::: + + +### onBlockNumber + +`(blockNumber: bigint, prevBlockNumber: bigint | undefined) => void` + +Callback for when block number changes. + +::: code-group +```ts [index.ts] +import { watchBlockNumber } from '@wagmi/core' +import { config } from './config' + +const unwatch = watchBlockNumber(config, { + onBlockNumber(blockNumber) { // [!code focus] + console.log('Block number changed!', blockNumber) // [!code focus] + }, // [!code focus] +}) +unwatch() +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### onError + +`((error: Error) => void) | undefined` + +Error thrown from getting the block number. + +::: code-group +```ts [index.ts] +import { watchBlockNumber } from '@wagmi/core' +import { config } from './config' + +const unwatch = watchBlockNumber(config, { + onBlockNumber(blockNumber) { + console.log('Block number changed!', blockNumber) + }, + onError(error) { // [!code focus] + console.error('Block number error', error) // [!code focus] + }, // [!code focus] +}) +unwatch() +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### poll + +`boolean | undefined` + +- Whether or not to use a polling mechanism to check for new blocks instead of a WebSocket subscription. +- Defaults to `false` for WebSocket Clients, and `true` for non-WebSocket Clients. + +::: code-group +```ts [index.ts] +import { watchBlockNumber } from '@wagmi/core' +import { config } from './config' + +const unwatch = watchBlockNumber(config, { + onBlockNumber(blockNumber) { + console.log('Block number changed!', blockNumber) + }, + poll: true, // [!code focus] +}) +unwatch() +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### pollingInterval + +`number | undefined` + +- Polling frequency (in milliseconds). +- Defaults to the [Config's `pollingInterval` config](/core/api/createConfig#pollinginterval). + +::: code-group +```ts [index.ts] +import { watchBlockNumber } from '@wagmi/core' +import { config } from './config' + +const unwatch = watchBlockNumber(config, { + onBlockNumber(blockNumber) { + console.log('Block number changed!', blockNumber) + }, + pollingInterval: 1_000, // [!code focus] +}) +unwatch() +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### syncConnectedChain + +`boolean | undefined` + +- Set up subscriber for connected chain changes. +- Defaults to [`Config['syncConnectedChain']`](/core/api/createConfig#syncconnectedchain). + +::: code-group +```ts [index.ts] +import { watchBlockNumber } from '@wagmi/core' +import { config } from './config' + +const unwatch = watchBlockNumber(config, { + onBlockNumber(blockNumber) { + console.log('Block number changed!', blockNumber) + }, + syncConnectedChain: false, // [!code focus] +}) +unwatch() +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type WatchBlockNumberReturnType } from '@wagmi/core' +``` + +Function for cleaning up watcher. + +## Viem + +- [`watchBlockNumber`](https://viem.sh/docs/actions/public/watchBlockNumber.html) diff --git a/wagmi-project/site/core/api/actions/watchBlocks.md b/wagmi-project/site/core/api/actions/watchBlocks.md new file mode 100644 index 000000000..892ef0005 --- /dev/null +++ b/wagmi-project/site/core/api/actions/watchBlocks.md @@ -0,0 +1,249 @@ +# watchBlocks + +Action that watches for block changes. + +## Import + +```ts +import { watchBlocks } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { watchBlocks } from '@wagmi/core' +import { config } from './config' + +const unwatch = watchBlocks(config, { + onBlock(block) { + console.log('Block changed!', block) + }, +}) +unwatch() +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type WatchBlocksParameters } from '@wagmi/core' +``` + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized'` + +Watch for new blocks on a given tag. Defaults to `'latest'`. + +::: code-group +```ts [index.ts] +import { watchBlocks } from '@wagmi/core' +import { config } from './config' + +const unwatch = watchBlocks(config, { + blockTag: 'pending', // [!code focus] + onBlock(block) { + console.log('Block changed!', block) + }, +}) +unwatch() +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```ts [index.ts] +import { watchBlocks } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { config } from './config' + +const unwatch = watchBlocks(config, { + chainId: mainnet.id, // [!code focus] + onBlock(block) { + console.log('Block changed!', block) + }, +}) +unwatch() +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### emitMissed + +`boolean` + +Whether or not to emit missed blocks to the callback. Defaults to `false`. + +Missed blocks may occur in instances where internet connection is lost, or the block time is lesser than the polling interval of the client. + +::: code-group +```ts [index.ts] +import { watchBlocks } from '@wagmi/core' +import { config } from './config' + +const unwatch = watchBlocks(config, { + emitMissed: true, // [!code focus] + onBlock(block) { + console.log('Block changed!', block) + }, +}) +unwatch() +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### emitOnBegin + +`boolean` + +Whether or not to emit the block to the callback when the subscription opens. Defaults to `false`. + +::: code-group +```ts [index.ts] +import { watchBlocks } from '@wagmi/core' +import { config } from './config' + +const unwatch = watchBlocks(config, { + emitOnBegin: true, // [!code focus] + onBlock(block) { + console.log('Block changed!', block) + }, +}) +unwatch() +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### onBlock + +`(block: Block, prevblock: Block | undefined) => void` + +Callback for when block changes. + +::: code-group +```ts [index.ts] +import { watchBlocks } from '@wagmi/core' +import { config } from './config' + +const unwatch = watchBlocks(config, { + onBlock(block) { // [!code focus] + console.log('Block changed!', block) // [!code focus] + }, // [!code focus] +}) +unwatch() +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### onError + +`((error: Error) => void) | undefined` + +Error thrown from getting the block. + +::: code-group +```ts [index.ts] +import { watchBlocks } from '@wagmi/core' +import { config } from './config' + +const unwatch = watchBlocks(config, { + onBlock(block) { + console.log('Block changed!', block) + }, + onError(error) { // [!code focus] + console.error('Block error', error) // [!code focus] + }, // [!code focus] +}) +unwatch() +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### poll + +`boolean | undefined` + +- Whether or not to use a polling mechanism to check for new blocks instead of a WebSocket subscription. +- Defaults to `false` for WebSocket Clients, and `true` for non-WebSocket Clients. + +::: code-group +```ts [index.ts] +import { watchBlocks } from '@wagmi/core' +import { config } from './config' + +const unwatch = watchBlocks(config, { + poll: true, // [!code focus] + onBlock(block) { + console.log('Block changed!', block) + }, +}) +unwatch() +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### pollingInterval + +`number | undefined` + +- Polling frequency (in milliseconds). +- Defaults to the [Config's `pollingInterval` config](/core/api/createConfig#pollinginterval). + +::: code-group +```ts [index.ts] +import { watchBlocks } from '@wagmi/core' +import { config } from './config' + +const unwatch = watchBlocks(config, { + pollingInterval: 1_000, // [!code focus] + onBlock(block) { + console.log('Block changed!', block) + }, +}) +unwatch() +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### syncConnectedChain + +`boolean | undefined` + +- Set up subscriber for connected chain changes. +- Defaults to [`Config['syncConnectedChain']`](/core/api/createConfig#syncconnectedchain). + +::: code-group +```ts [index.ts] +import { watchBlocks } from '@wagmi/core' +import { config } from './config' + +const unwatch = watchBlocks(config, { + onBlock(block) { + console.log('Block changed!', block) + }, + syncConnectedChain: false, // [!code focus] +}) +unwatch() +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type WatchBlocksReturnType } from '@wagmi/core' +``` + +Function for cleaning up watcher. + +## Viem + +- [`watchBlocks`](https://viem.sh/docs/actions/public/watchBlocks.html) diff --git a/wagmi-project/site/core/api/actions/watchChainId.md b/wagmi-project/site/core/api/actions/watchChainId.md new file mode 100644 index 000000000..a003fd16d --- /dev/null +++ b/wagmi-project/site/core/api/actions/watchChainId.md @@ -0,0 +1,61 @@ +# watchChainId + +Subscribe to chain ID changes. + +## Import + +```ts +import { watchChainId } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { watchChainId } from '@wagmi/core' +import { config } from './config' + +const unwatch = watchChainId(config, { + onChange(chainId) { + console.log('Chain ID changed!', chainId) + }, +}) +unwatch() +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type WatchChainIdParameters } from '@wagmi/core' +``` + +### onChange + +`onChange(chainId: GetChainIdReturnType, prevChainId: GetChainIdReturnType): void` + +Callback function called when chain ID changes. + +::: code-group +```ts [index.ts] +import { watchChainId } from '@wagmi/core' +import { config } from './config' + +const unwatch = watchChainId(config, { + onChange(chainId) { // [!code focus:3] + console.log('Chain ID changed!', chainId) + }, +}) +unwatch() +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type WatchChainIdReturnType } from '@wagmi/core' +``` + +Function for cleaning up watcher. \ No newline at end of file diff --git a/wagmi-project/site/core/api/actions/watchClient.md b/wagmi-project/site/core/api/actions/watchClient.md new file mode 100644 index 000000000..aa3087c0d --- /dev/null +++ b/wagmi-project/site/core/api/actions/watchClient.md @@ -0,0 +1,61 @@ +# watchClient + +Subscribe to Client changes. + +## Import + +```ts +import { watchClient } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { watchClient } from '@wagmi/core' +import { config } from './config' + +const unwatch = watchClient(config, { + onChange(client) { + console.log('Client changed!', client) + }, +}) +unwatch() +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type WatchClientParameters } from '@wagmi/core' +``` + +### onChange + +`onChange(client: GetClientReturnType, prevClient: GetClientReturnType): void` + +Callback function called when Client changes. + +::: code-group +```ts [index.ts] +import { watchClient } from '@wagmi/core' +import { config } from './config' + +const unwatch = watchClient(config, { + onChange(client) { // [!code focus:3] + console.log('Client changed!', client) + }, +}) +unwatch() +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type WatchClientReturnType } from '@wagmi/core' +``` + +Function for cleaning up watcher. \ No newline at end of file diff --git a/wagmi-project/site/core/api/actions/watchConnections.md b/wagmi-project/site/core/api/actions/watchConnections.md new file mode 100644 index 000000000..11cb0a617 --- /dev/null +++ b/wagmi-project/site/core/api/actions/watchConnections.md @@ -0,0 +1,61 @@ +# watchConnections + +Subscribe to connections changes. + +## Import + +```ts +import { watchConnections } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { watchConnections } from '@wagmi/core' +import { config } from './config' + +const unwatch = watchConnections(config, { + onChange(data) { + console.log('Connections changed!', data) + }, +}) +unwatch() +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type WatchConnectionsParameters } from '@wagmi/core' +``` + +### onChange + +`onChange(connections: GetConnectionsReturnType, prevConnections: GetConnectionsReturnType): void` + +Callback function called when connections changes. + +::: code-group +```ts [index.ts] +import { watchConnections } from '@wagmi/core' +import { config } from './config' + +const unwatch = watchConnections(config, { + onChange(data) { // [!code focus:3] + console.log('Connections changed!', data) + }, +}) +unwatch() +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type WatchConnectionsReturnType } from '@wagmi/core' +``` + +Function for cleaning up watcher. \ No newline at end of file diff --git a/wagmi-project/site/core/api/actions/watchConnectors.md b/wagmi-project/site/core/api/actions/watchConnectors.md new file mode 100644 index 000000000..0b951a458 --- /dev/null +++ b/wagmi-project/site/core/api/actions/watchConnectors.md @@ -0,0 +1,61 @@ +# watchConnectors + +Subscribe to connectors changes. + +## Import + +```ts +import { watchConnectors } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { watchConnectors } from '@wagmi/core' +import { config } from './config' + +const unwatch = watchConnectors(config, { + onChange(connectors) { + console.log('Connectors changed!', connectors) + }, +}) +unwatch() +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type WatchConnectorsParameters } from '@wagmi/core' +``` + +### onChange + +`onChange(connectors: GetConnectorsReturnType, prevConnectors: GetConnectorsReturnType): void` + +Callback function called when connectors changes. + +::: code-group +```ts [index.ts] +import { watchConnectors } from '@wagmi/core' +import { config } from './config' + +const unwatch = watchConnectors(config, { + onChange(connectors) { // [!code focus:3] + console.log('Connectors changed!', connectors) + }, +}) +unwatch() +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type WatchConnectorsReturnType } from '@wagmi/core' +``` + +Function for cleaning up watcher. \ No newline at end of file diff --git a/wagmi-project/site/core/api/actions/watchContractEvent.md b/wagmi-project/site/core/api/actions/watchContractEvent.md new file mode 100644 index 000000000..91498f178 --- /dev/null +++ b/wagmi-project/site/core/api/actions/watchContractEvent.md @@ -0,0 +1,376 @@ + + +# watchContractEvent + +Action that watches and returns emitted contract event logs. + +## Import + +```ts +import { watchContractEvent } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { watchContractEvent } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const unwatch = watchContractEvent(config, { + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + abi, + eventName: 'Transfer', + onLogs(logs) { + console.log('New logs!', logs) + }, +}) +unwatch() +``` +<<< @/snippets/abi-event.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type WatchContractEventParameters } from '@wagmi/core' +``` + +### abi + +`Abi` + +The contract's ABI. Check out the [TypeScript docs](/react/typescript#const-assert-abis-typed-data) for how to set up ABIs for maximum type inference and safety. + +::: code-group +```ts [index.ts] +import { watchContractEvent } from '@wagmi/core' +import { abi } from './abi' // [!code focus] +import { config } from './config' + +const unwatch = watchContractEvent(config, { + abi, // [!code focus] + onLogs(logs) { + console.log('Logs changed!', logs) + }, +}) +unwatch() +``` +<<< @/snippets/abi-event.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### address + +`Address | undefined` + +The contract's address. + +::: code-group +```ts [index.ts] +import { watchContractEvent } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const unwatch = watchContractEvent(config, { + address: '0x6b175474e89094c44da98b954eedeac495271d0f', // [!code focus] + abi, + onLogs(logs) { + console.log('Logs changed!', logs) + }, +}) +unwatch() +``` +<<< @/snippets/abi-event.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### args + +`object | readonly unknown[] | undefined` + +- Arguments to pass when calling the contract. +- Inferred from [`abi`](#abi) and [`eventName`](#eventname). + +::: code-group +```ts [index.ts] +import { watchContractEvent } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const unwatch = watchContractEvent(config, { + abi, + args: { // [!code focus] + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', // [!code focus] + }, // [!code focus] + onLogs(logs) { + console.log('Logs changed!', logs) + }, +}) +unwatch() +``` +<<< @/snippets/abi-event.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### batch + +`boolean | undefined` + +- Whether or not the events should be batched on each invocation. +- Defaults to `true`. + +::: code-group +```ts [index.ts] +import { watchContractEvent } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const unwatch = watchContractEvent(config, { + abi, + batch: false, // [!code focus] + onLogs(logs) { + console.log('Logs changed!', logs) + }, +}) +unwatch() +``` +<<< @/snippets/abi-event.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```ts [index.ts] +import { watchContractEvent } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { abi } from './abi' +import { config } from './config' + +const unwatch = watchContractEvent(config, { + abi, + chainId: mainnet.id, // [!code focus] + onLogs(logs) { + console.log('Logs changed!', logs) + }, +}) +unwatch() +``` +<<< @/snippets/abi-event.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### eventName + +`string` + +- Event to listen for the contract. +- Inferred from [`abi`](#abi). + +::: code-group +```ts [index.ts] +import { watchContractEvent } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const unwatch = watchContractEvent(config, { + abi, + eventName: 'Approval', // [!code focus] + onLogs(logs) { + console.log('Logs changed!', logs) + }, +}) +unwatch() +``` +<<< @/snippets/abi-event.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### onError + +`((error: Error) => void) | undefined` + +Error thrown from getting the block number. + +::: code-group +```ts [index.ts] +import { watchContractEvent } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const unwatch = watchContractEvent(config, { + abi, + onLogs(logs) { + console.log('Logs changed!', logs) + }, + onError(error) { // [!code focus] + console.error('Logs error', error) // [!code focus] + }, // [!code focus] +}) +unwatch() +``` +<<< @/snippets/abi-event.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### onLogs + +`(logs: Log[], prevLogs: Log[] | undefined) => void` + +Callback for when logs changes. + +::: code-group +```ts [index.ts] +import { watchContractEvent } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const unwatch = watchContractEvent(config, { + abi, + onLogs(logs) { // [!code focus] + console.log('Logs changed!', logs) // [!code focus] + }, // [!code focus] +}) +unwatch() +``` +<<< @/snippets/abi-event.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### poll + +`boolean | undefined` + +- Whether or not to use a polling mechanism to check for new blocks instead of a WebSocket subscription. +- Defaults to `false` for WebSocket Clients, and `true` for non-WebSocket Clients. + +::: code-group +```ts [index.ts] +import { watchContractEvent } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const unwatch = watchContractEvent(config, { + abi, + onLogs(logs) { + console.log('Logs changed!', logs) + }, + poll: true, // [!code focus] +}) +unwatch() +``` +<<< @/snippets/abi-event.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### pollingInterval + +`number | undefined` + +- Polling frequency (in milliseconds). +- Defaults to the [Config's `pollingInterval` config](/core/api/createConfig#pollinginterval). + +::: code-group +```ts [index.ts] +import { watchContractEvent } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const unwatch = watchContractEvent(config, { + abi, + onLogs(logs) { + console.log('Logs changed!', logs) + }, + pollingInterval: 1_000, // [!code focus] +}) +unwatch() +``` +<<< @/snippets/abi-event.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### strict + +`boolean | undefined` + +- Defaults to `false`. + +::: code-group +```ts [index.ts] +import { watchContractEvent } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const unwatch = watchContractEvent(config, { + abi, + onLogs(logs) { + console.log('Logs changed!', logs) + }, + strict: true, // [!code focus] +}) +unwatch() +``` +<<< @/snippets/abi-event.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### syncConnectedChain + +`boolean | undefined` + +- Set up subscriber for connected chain changes. +- Defaults to [`Config['syncConnectedChain']`](/core/api/createConfig#syncconnectedchain). + +::: code-group +```ts [index.ts] +import { watchContractEvent } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const unwatch = watchContractEvent(config, { + abi, + onLogs(logs) { + console.log('Logs changed!', logs) + }, + syncConnectedChain: false, // [!code focus] +}) +unwatch() +``` +<<< @/snippets/abi-event.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type WatchContractEventReturnType } from '@wagmi/core' +``` + +Function for cleaning up watcher. + +## Type Inference + +With [`abi`](#abi) setup correctly, TypeScript will infer the correct types for [`eventName`](#eventname), [`args`](#args), and [`onLogs`](#onlogs) parameters. See the Wagmi [TypeScript docs](/core/typescript) for more information. + +## Error + +```ts +import { type WatchContractEventError } from '@wagmi/core' +``` + + + +## Viem + +- [`watchContractEvent`](https://viem.sh/docs/contract/watchContractEvent.html) diff --git a/wagmi-project/site/core/api/actions/watchPendingTransactions.md b/wagmi-project/site/core/api/actions/watchPendingTransactions.md new file mode 100644 index 000000000..fe0e5c388 --- /dev/null +++ b/wagmi-project/site/core/api/actions/watchPendingTransactions.md @@ -0,0 +1,207 @@ + + +# watchPendingTransactions + +Action that watches and returns pending transaction hashes. + +## Import + +```ts +import { watchPendingTransactions } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { watchPendingTransactions } from '@wagmi/core' +import { config } from './config' + +const unwatch = watchPendingTransactions(config, { + onTransactions(transactions) { + console.log('New transactions!', transactions) + }, +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type WatchPendingTransactionsParameters } from '@wagmi/core' +``` + +### batch + +`boolean | undefined` + +- Whether or not the transactions should be batched on each invocation. +- Defaults to `true`. + +::: code-group +```ts [index.ts] +import { watchPendingTransactions } from '@wagmi/core' + +const unwatch = watchPendingTransactions(config, { + batch: false, // [!code focus] + onTransactions(transactions) { + console.log('New transactions!', transactions) + }, +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```ts [index.ts] +import { watchPendingTransactions } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { config } from './config' + +const unwatch = watchPendingTransactions(config, { + chainId: mainnet.id, // [!code focus] + onTransactions(transactions) { + console.log('New transactions!', transactions) + }, +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### onError + +`((error: Error) => void) | undefined` + +Error thrown from watching pending transactions. + +::: code-group +```ts [index.ts] +import { watchPendingTransactions } from '@wagmi/core' +import { config } from './config' + +const unwatch = watchPendingTransactions(config, { + onError(error) { // [!code focus] + console.log('Error', error) // [!code focus] + }, // [!code focus] + onTransactions(transactions) { + console.log('New transactions!', transactions) + }, +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### onTransactions + +`(transactions: Hash[], prevTransactions: Hash[] | undefined) => void` + +Callback when new incoming pending transactions are detected. + +::: code-group +```ts [index.ts] +import { watchPendingTransactions } from '@wagmi/core' +import { config } from './config' + +const unwatch = watchPendingTransactions(config, { + onTransactions(transactions) { // [!code focus] + console.log('New transactions!', transactions) // [!code focus] + }, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### poll + +`boolean | undefined` + +- Whether or not to use a polling mechanism to check for new pending transactions instead of a WebSocket subscription. +- Defaults to `false` for WebSocket Clients, and `true` for non-WebSocket Clients. + +::: code-group +```ts [index.ts] +import { watchPendingTransactions } from '@wagmi/core' +import { config } from './config' + +const unwatch = watchPendingTransactions(config, { + onTransactions(transactions) { + console.log('New transactions!', transactions) + }, + poll: false, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### pollingInterval + +`number | undefined` + +- Polling frequency (in milliseconds). +- Defaults to the [Config's `pollingInterval` config](/core/api/createConfig#pollinginterval). + +::: code-group +```ts [index.ts] +import { watchPendingTransactions } from '@wagmi/core' +import { config } from './config' + +const unwatch = watchPendingTransactions(config, { + onTransactions(transactions) { + console.log('New transactions!', transactions) + }, + pollingInterval: 1_000, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### syncConnectedChain + +`boolean | undefined` + +- Set up subscriber for connected chain changes. +- Defaults to [`Config['syncConnectedChain']`](/core/api/createConfig#syncconnectedchain). + +::: code-group +```ts [index.ts] +import { watchPendingTransactions } from '@wagmi/core' +import { config } from './config' + +const unwatch = watchPendingTransactions(config, { + onTransactions(transactions) { + console.log('New transactions!', transactions) + }, + syncConnectedChain: false, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type WatchPendingTransactionsReturnType } from '@wagmi/core' +``` + +Function to unsubscribe from pending transaction listener. + +## Error + +```ts +import { type WatchPendingTransactionsError } from '@wagmi/core' +``` + +## Viem + +- [`watchPendingTransactions`](https://viem.sh/docs/actions/public/watchPendingTransactions.html) diff --git a/wagmi-project/site/core/api/actions/watchPublicClient.md b/wagmi-project/site/core/api/actions/watchPublicClient.md new file mode 100644 index 000000000..7363fc3de --- /dev/null +++ b/wagmi-project/site/core/api/actions/watchPublicClient.md @@ -0,0 +1,61 @@ +# watchPublicClient + +Subscribe to Public Client changes. + +## Import + +```ts +import { watchPublicClient } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { watchPublicClient } from '@wagmi/core' +import { config } from './config' + +const unwatch = watchPublicClient(config, { + onChange(client) { + console.log('Public Client changed!', client) + }, +}) +unwatch() +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type WatchPublicClientParameters } from '@wagmi/core' +``` + +### onChange + +`onChange(client: GetPublicClientReturnType, prevClient: GetPublicClientReturnType): void` + +Callback function called when Public Client changes. + +::: code-group +```ts [index.ts] +import { watchPublicClient } from '@wagmi/core' +import { config } from './config' + +const unwatch = watchPublicClient(config, { + onChange(client) { // [!code focus:3] + console.log('Public Client changed!', client) + }, +}) +unwatch() +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type WatchPublicClientReturnType } from '@wagmi/core' +``` + +Function for cleaning up watcher. \ No newline at end of file diff --git a/wagmi-project/site/core/api/actions/writeContract.md b/wagmi-project/site/core/api/actions/writeContract.md new file mode 100644 index 000000000..34000d9d3 --- /dev/null +++ b/wagmi-project/site/core/api/actions/writeContract.md @@ -0,0 +1,560 @@ + + +# writeContract + +Action for executing a write function on a contract. + +A "write" function on a Solidity contract modifies the state of the blockchain. These types of functions require gas to be executed, hence a transaction is broadcasted in order to change the state. + +## Import + +```ts +import { writeContract } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { writeContract } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const result = await writeContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], +}) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +::::tip Pairing with `simulateContract` + +Pairing [`simulateContract`](/core/api/actions/simulateContract) with `writeContract` allows you to validate if the transaction will succeed ahead of time. If the simulate succeeds, `writeContract` can execute the transaction. + +::: code-group +```ts [index.ts] +import { simulateContract, writeContract } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const { request } = await simulateContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], +}) +const hash = await writeContract(config, request) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: +:::: + + +## Parameters + +```ts +import { type WriteContractParameters } from '@wagmi/core' +``` + +### abi + +`Abi` + +The contract's ABI. Check out the [TypeScript docs](/react/typescript#const-assert-abis-typed-data) for how to set up ABIs for maximum type inference and safety. + +::: code-group +```ts [index.ts] +import { writeContract } from '@wagmi/core' +import { abi } from './abi' // [!code focus] +import { config } from './config' + +const result = await writeContract(config, { + abi, // [!code focus] + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], +}) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### accessList + +`AccessList | undefined` + +The access list. + +::: code-group +```ts [index.ts] +import { writeContract } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const result = await writeContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + accessList: [{ // [!code focus] + address: '0x1', // [!code focus] + storageKeys: ['0x1'], // [!code focus] + }], // [!code focus] +}) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### account + +`Address | Account | undefined` + +Account to use when signing data. Throws if account is not found on [`connector`](#connector). + +::: code-group +```ts [index.ts] +import { writeContract } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const result = await writeContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + account: '0xd2135CfB216b74109775236E36d4b433F1DF507B', // [!code focus] +}) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### address + +`Address` + +The contract's address. + +::: code-group +```ts [index.ts] +import { writeContract } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const result = await writeContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', // [!code focus] + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], +}) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + + +### args + +`readonly unknown[] | undefined` + +- Arguments to pass when calling the contract. +- Inferred from [`abi`](#abi) and [`functionName`](#functionname). + +::: code-group +```ts [index.ts] +import { writeContract } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const result = await writeContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ // [!code focus] + '0xd2135CfB216b74109775236E36d4b433F1DF507B', // [!code focus] + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', // [!code focus] + 123n, // [!code focus] + ] // [!code focus] +}) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +Chain ID to validate against before sending transaction. + +::: code-group +```ts [index.ts] +import { writeContract } from '@wagmi/core' +import { mainnet } from 'wagmi/chains' // [!code focus] +import { abi } from './abi' +import { config } from './config' + +const result = await writeContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + chainId: mainnet.id, // [!code focus] +}) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### connector + +`Connector | undefined` + +[Connector](/core/api/connectors) to sign data with. + +::: code-group +```ts [index.ts] +import { getAccount, writeContract } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const { connector } = getAccount(config) +const result = await writeContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + connector, // [!code focus] +}) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### dataSuffix + +`` `0x${string}` | undefined `` + +Data to append to the end of the calldata. Useful for adding a ["domain" tag](https://opensea.notion.site/opensea/Seaport-Order-Attributions-ec2d69bf455041a5baa490941aad307f). + +::: code-group +```ts [index.ts] +import { writeContract } from '@wagmi/core' +import { parseGwei } from 'viem' +import { abi } from './abi' +import { config } from './config' + +const result = await writeContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + dataSuffix: '0xdeadbeef', // [!code focus] +}) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### functionName + +`string` + +- Function to call on the contract. +- Inferred from [`abi`](#abi). + +::: code-group +```ts [index.ts] +import { writeContract } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const result = await writeContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'approve', // [!code focus] + args: ['0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', 123n] +}) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + + +### gas + +`bigint | undefined` + +Gas provided for transaction execution. + +::: code-group +```ts [index.ts] +import { writeContract } from '@wagmi/core' +import { parseGwei } from 'viem' +import { abi } from './abi' +import { config } from './config' + +const result = await writeContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + gas: parseGwei('20'), // [!code focus] +}) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +--- + +### gasPrice + +`bigint | undefined` + +The price in wei to pay per gas. Only applies to [Legacy Transactions](https://viem.sh/docs/glossary/terms.html#legacy-transaction). + +::: code-group +```ts [index.ts] +import { writeContract } from '@wagmi/core' +import { parseGwei } from 'viem' +import { abi } from './abi' +import { config } from './config' + +const result = await writeContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + gasPrice: parseGwei('20'), // [!code focus] +}) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### maxFeePerGas + +`bigint | undefined` + +Total fee per gas in wei, inclusive of [`maxPriorityFeePerGas`](#maxPriorityFeePerGas). Only applies to [EIP-1559 Transactions](https://viem.sh/docs/glossary/terms.html#eip-1559-transaction). + +::: code-group +```ts [index.ts] +import { writeContract } from '@wagmi/core' +import { parseGwei } from 'viem' +import { abi } from './abi' +import { config } from './config' + +const result = await writeContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + maxFeePerGas: parseGwei('20'), // [!code focus] +}) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### maxPriorityFeePerGas + +`bigint | undefined` + +Max priority fee per gas in wei. Only applies to [EIP-1559 Transactions](https://viem.sh/docs/glossary/terms.html#eip-1559-transaction). + +::: code-group +```ts [index.ts] +import { writeContract } from '@wagmi/core' +import { parseGwei } from 'viem' +import { abi } from './abi' +import { config } from './config' + +const result = await writeContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + maxFeePerGas: parseGwei('20'), + maxPriorityFeePerGas: parseGwei('2'), // [!code focus] +}) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +--- + +### nonce + +`number` + +Unique number identifying this transaction. + +::: code-group +```ts [index.ts] +import { writeContract } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const result = await writeContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + nonce: 123, // [!code focus] +}) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### type + +`'legacy' | 'eip1559' | 'eip2930' | undefined` + +Optional transaction request type to narrow parameters. + +::: code-group +```ts [index.ts] +import { writeContract } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const result = await writeContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + type: 'eip1559', // [!code focus] +}) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### value + +`bigint | undefined` + +Value in wei sent with this transaction. + +::: code-group +```ts [index.ts] +import { writeContract } from '@wagmi/core' +import { parseEther } from 'viem' +import { abi } from './abi' +import { config } from './config' + +const result = await writeContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + value: parseEther('0.01'), // [!code focus] +}) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type WriteContractReturnType } from '@wagmi/core' +``` + +[`Hash`](https://viem.sh/docs/glossary/types.html#hash) + +The transaction hash. + +## Type Inference + +With [`abi`](#abi) setup correctly, TypeScript will infer the correct types for [`functionName`](#functionname), [`args`](#args), and [`value`](#value). See the Wagmi [TypeScript docs](/core/typescript) for more information. + +## Error + +```ts +import { type WriteContractErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`writeContract`](https://viem.sh/docs/contract/writeContract.html) diff --git a/wagmi-project/site/core/api/actions/writeContracts.md b/wagmi-project/site/core/api/actions/writeContracts.md new file mode 100644 index 000000000..a6afe42ff --- /dev/null +++ b/wagmi-project/site/core/api/actions/writeContracts.md @@ -0,0 +1,317 @@ + + +# writeContracts + +Action that requests for the wallet to sign and broadcast a batch of write contract calls (transactions) to the network. + +[Read more.](https://github.com/ethereum/EIPs/blob/815028dc634463e1716fc5ce44c019a6040f0bef/EIPS/eip-5792.md#wallet_sendcalls) + + + +## Import + +```ts +import { writeContracts } from '@wagmi/core/experimental' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { parseAbi } from 'viem' +import { writeContracts } from '@wagmi/core/experimental' +import { config } from './config' + +const abi = parseAbi([ + 'function approve(address, uint256) returns (bool)', + 'function transferFrom(address, address, uint256) returns (bool)', +]) + +const id = await writeContracts(config, { + contracts: [ + { + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + abi, + functionName: 'approve', + args: [ + '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC', + 100n + ], + }, + { + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + abi, + functionName: 'transferFrom', + args: [ + '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC', + '0x0000000000000000000000000000000000000000', + 100n + ], + }, + ], +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type WriteContractsParameters } from '@wagmi/core/experimental' +``` + +### account + +`Account | Address | undefined` + +Account to execute the calls. + +::: code-group +```ts [index.ts] +import { parseAbi } from 'viem' +import { writeContracts } from '@wagmi/core/experimental' +import { config } from './config' + +const abi = parseAbi([ + 'function approve(address, uint256) returns (bool)', + 'function transferFrom(address, address, uint256) returns (bool)', +]) + +const id = await writeContracts(config, { + account: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC', // [!code focus] + contracts: [ + { + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + abi, + functionName: 'approve', + args: [ + '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC', + 100n + ], + }, + { + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + abi, + functionName: 'transferFrom', + args: [ + '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC', + '0x0000000000000000000000000000000000000000', + 100n + ], + }, + ], +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### contracts + +`{ to: Hex, data?: Hex, value?: bigint }[]` + +Calls to execute. + +::: code-group +```ts [index.ts] +import { parseAbi } from 'viem' +import { writeContracts } from '@wagmi/core/experimental' +import { config } from './config' + +const abi = parseAbi([ + 'function approve(address, uint256) returns (bool)', + 'function transferFrom(address, address, uint256) returns (bool)', +]) + +const id = await writeContracts(config, { + contracts: [ // [!code focus] + { // [!code focus] + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', // [!code focus] + abi, // [!code focus] + functionName: 'approve', // [!code focus] + args: [ // [!code focus] + '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC', // [!code focus] + 100n // [!code focus] + ], // [!code focus] + }, // [!code focus] + { // [!code focus] + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', // [!code focus] + abi, // [!code focus] + functionName: 'transferFrom', // [!code focus] + args: [ // [!code focus] + '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC', // [!code focus] + '0x0000000000000000000000000000000000000000', // [!code focus] + 100n // [!code focus] + ], // [!code focus] + }, // [!code focus] + ], // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### capabilities + +`WalletCapabilities | undefined` + +Capability metadata for the calls (e.g. specifying a paymaster). + +::: code-group +```ts [index.ts] +import { parseAbi } from 'viem' +import { writeContracts } from '@wagmi/core/experimental' +import { config } from './config' + +const abi = parseAbi([ + 'function approve(address, uint256) returns (bool)', + 'function transferFrom(address, address, uint256) returns (bool)', +]) + +const id = await writeContracts(config, { + contracts: [ + { + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + abi, + functionName: 'approve', + args: [ + '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC', + 100n + ], + }, + { + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + abi, + functionName: 'transferFrom', + args: [ + '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC', + '0x0000000000000000000000000000000000000000', + 100n + ], + }, + ], + capabilities: { // [!code focus] + paymasterService: { // [!code focus] + url: 'https://...' // [!code focus] + } // [!code focus] + } // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### chainId + +`number | undefined` + +The target chain ID to broadcast the calls. + +::: code-group +```ts [index.ts] +import { parseAbi } from 'viem' +import { writeContracts } from '@wagmi/core/experimental' +import { config } from './config' + +const abi = parseAbi([ + 'function approve(address, uint256) returns (bool)', + 'function transferFrom(address, address, uint256) returns (bool)', +]) + +const id = await writeContracts(config, { + contracts: [ + { + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + abi, + functionName: 'approve', + args: [ + '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC', + 100n + ], + }, + { + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + abi, + functionName: 'transferFrom', + args: [ + '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC', + '0x0000000000000000000000000000000000000000', + 100n + ], + }, + ], + chainId: 10, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### connector + +`Connector | undefined` + +Connector to get send the calls with. + +::: code-group +```ts [index.ts] +import { parseAbi } from 'viem' +import { getConnections } from '@wagmi/core' +import { writeContracts } from '@wagmi/core/experimental' +import { config } from './config' + +const abi = parseAbi([ + 'function approve(address, uint256) returns (bool)', + 'function transferFrom(address, address, uint256) returns (bool)', +]) + +const connections = getConnections(config) +const id = await writeContracts(config, { + contracts: [ + { + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + abi, + functionName: 'approve', + args: [ + '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC', + 100n + ], + }, + { + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + abi, + functionName: 'transferFrom', + args: [ + '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC', + '0x0000000000000000000000000000000000000000', + 100n + ], + }, + ], + connector: connections[0]?.connector, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type WriteContractsReturnType } from '@wagmi/core/experimental' +``` + +`bigint` + +Most recent block number seen. + +## Error + +```ts +import { type WriteContractsErrorType } from '@wagmi/core/experimental' +``` + + + +## Viem + +- [`writeContracts`](https://viem.sh/experimental/eip5792/writeContracts) diff --git a/wagmi-project/site/core/api/chains.md b/wagmi-project/site/core/api/chains.md new file mode 100644 index 000000000..6bdd81de6 --- /dev/null +++ b/wagmi-project/site/core/api/chains.md @@ -0,0 +1,24 @@ + + +# Chains + +## Import + +Import via the `'@wagmi/core/chains'` entrypoint (proxies all chains from `'viem/chains'`). + +```ts +import { mainnet } from '@wagmi/core/chains' +``` + +## Available Chains + +Chain definitions as of `viem@{{viemVersion}}`. For `viem@latest`, visit the [Viem repo](https://github.com/wevm/viem/blob/main/src/chains/index.ts). + + + + diff --git a/wagmi-project/site/core/api/connectors.md b/wagmi-project/site/core/api/connectors.md new file mode 100644 index 000000000..d68718b25 --- /dev/null +++ b/wagmi-project/site/core/api/connectors.md @@ -0,0 +1,28 @@ + + +# Connectors + +Connectors for popular wallet providers and protocols. + +## Import + +```ts +import { injected } from 'wagmi/connectors' +``` + +## Built-In Connectors + +Available via the `'wagmi/connectors'` entrypoint. + + diff --git a/wagmi-project/site/core/api/connectors/coinbaseWallet.md b/wagmi-project/site/core/api/connectors/coinbaseWallet.md new file mode 100644 index 000000000..d8968eac7 --- /dev/null +++ b/wagmi-project/site/core/api/connectors/coinbaseWallet.md @@ -0,0 +1,6 @@ + + + \ No newline at end of file diff --git a/wagmi-project/site/core/api/connectors/injected.md b/wagmi-project/site/core/api/connectors/injected.md new file mode 100644 index 000000000..6e874baef --- /dev/null +++ b/wagmi-project/site/core/api/connectors/injected.md @@ -0,0 +1,7 @@ + + + diff --git a/wagmi-project/site/core/api/connectors/metaMask.md b/wagmi-project/site/core/api/connectors/metaMask.md new file mode 100644 index 000000000..5553c2b34 --- /dev/null +++ b/wagmi-project/site/core/api/connectors/metaMask.md @@ -0,0 +1,7 @@ + + + diff --git a/wagmi-project/site/core/api/connectors/mock.md b/wagmi-project/site/core/api/connectors/mock.md new file mode 100644 index 000000000..d085d93cb --- /dev/null +++ b/wagmi-project/site/core/api/connectors/mock.md @@ -0,0 +1,6 @@ + + + diff --git a/wagmi-project/site/core/api/connectors/safe.md b/wagmi-project/site/core/api/connectors/safe.md new file mode 100644 index 000000000..cc800dcc9 --- /dev/null +++ b/wagmi-project/site/core/api/connectors/safe.md @@ -0,0 +1,6 @@ + + + diff --git a/wagmi-project/site/core/api/connectors/walletConnect.md b/wagmi-project/site/core/api/connectors/walletConnect.md new file mode 100644 index 000000000..ba65cbda9 --- /dev/null +++ b/wagmi-project/site/core/api/connectors/walletConnect.md @@ -0,0 +1,6 @@ + + + diff --git a/wagmi-project/site/core/api/createConfig.md b/wagmi-project/site/core/api/createConfig.md new file mode 100644 index 000000000..26df85016 --- /dev/null +++ b/wagmi-project/site/core/api/createConfig.md @@ -0,0 +1,7 @@ + + + diff --git a/wagmi-project/site/core/api/createConnector.md b/wagmi-project/site/core/api/createConnector.md new file mode 100644 index 000000000..7cdbd00bd --- /dev/null +++ b/wagmi-project/site/core/api/createConnector.md @@ -0,0 +1,31 @@ +# createConnector + +Creates new [`CreateConnectorFn`](#parameters). + +## Import + +```ts +import { createConnector } from '@wagmi/core' +``` + +## Usage + +```ts +import { createConnector } from '@wagmi/core' + +export type InjectedParameters = {} + +export function injected(parameters: InjectedParameters = {}) { + return createConnector((config) => ({ + // ... + })) +} +``` + +## Parameters + +```ts +import { type CreateConnectorFn } from '@wagmi/core' +``` + +Read [Creating Connectors](/dev/creating-connectors) for more info on the `CreateConnectorFn` type. \ No newline at end of file diff --git a/wagmi-project/site/core/api/createStorage.md b/wagmi-project/site/core/api/createStorage.md new file mode 100644 index 000000000..f547a9a60 --- /dev/null +++ b/wagmi-project/site/core/api/createStorage.md @@ -0,0 +1,6 @@ + + + diff --git a/wagmi-project/site/core/api/errors.md b/wagmi-project/site/core/api/errors.md new file mode 100644 index 000000000..4a29a1c30 --- /dev/null +++ b/wagmi-project/site/core/api/errors.md @@ -0,0 +1,11 @@ + + +# Errors + +Error classes used by Wagmi. + + + diff --git a/wagmi-project/site/core/api/transports.md b/wagmi-project/site/core/api/transports.md new file mode 100644 index 000000000..cfaa9a602 --- /dev/null +++ b/wagmi-project/site/core/api/transports.md @@ -0,0 +1,28 @@ + + +# Transports + +[`createConfig`](/core/api/createConfig) can be instantiated with a set of Transports for each chain. A Transport is the intermediary layer that is responsible for executing outgoing JSON-RPC requests to the RPC Provider (e.g. Alchemy, Infura, etc). + +## Import + +```ts +import { http } from '@wagmi/core' +``` + +## Built-In Transports + +Available via the `'@wagmi/core'` entrypoint. + + diff --git a/wagmi-project/site/core/api/transports/custom.md b/wagmi-project/site/core/api/transports/custom.md new file mode 100644 index 000000000..487c3ae93 --- /dev/null +++ b/wagmi-project/site/core/api/transports/custom.md @@ -0,0 +1,5 @@ + + + diff --git a/wagmi-project/site/core/api/transports/fallback.md b/wagmi-project/site/core/api/transports/fallback.md new file mode 100644 index 000000000..cefffa734 --- /dev/null +++ b/wagmi-project/site/core/api/transports/fallback.md @@ -0,0 +1,5 @@ + + + diff --git a/wagmi-project/site/core/api/transports/http.md b/wagmi-project/site/core/api/transports/http.md new file mode 100644 index 000000000..7fed8c6d7 --- /dev/null +++ b/wagmi-project/site/core/api/transports/http.md @@ -0,0 +1,5 @@ + + + diff --git a/wagmi-project/site/core/api/transports/unstable_connector.md b/wagmi-project/site/core/api/transports/unstable_connector.md new file mode 100644 index 000000000..19a9b4357 --- /dev/null +++ b/wagmi-project/site/core/api/transports/unstable_connector.md @@ -0,0 +1,6 @@ + + + diff --git a/wagmi-project/site/core/api/transports/webSocket.md b/wagmi-project/site/core/api/transports/webSocket.md new file mode 100644 index 000000000..4ed1ae327 --- /dev/null +++ b/wagmi-project/site/core/api/transports/webSocket.md @@ -0,0 +1,5 @@ + + + diff --git a/wagmi-project/site/core/api/utilities/cookieToInitialState.md b/wagmi-project/site/core/api/utilities/cookieToInitialState.md new file mode 100644 index 000000000..c0470295c --- /dev/null +++ b/wagmi-project/site/core/api/utilities/cookieToInitialState.md @@ -0,0 +1,5 @@ + + + diff --git a/wagmi-project/site/core/api/utilities/deserialize.md b/wagmi-project/site/core/api/utilities/deserialize.md new file mode 100644 index 000000000..4f051cdc5 --- /dev/null +++ b/wagmi-project/site/core/api/utilities/deserialize.md @@ -0,0 +1,5 @@ + + + diff --git a/wagmi-project/site/core/api/utilities/normalizeChainId.md b/wagmi-project/site/core/api/utilities/normalizeChainId.md new file mode 100644 index 000000000..9dd43935b --- /dev/null +++ b/wagmi-project/site/core/api/utilities/normalizeChainId.md @@ -0,0 +1,5 @@ + + + diff --git a/wagmi-project/site/core/api/utilities/serialize.md b/wagmi-project/site/core/api/utilities/serialize.md new file mode 100644 index 000000000..3672a67c1 --- /dev/null +++ b/wagmi-project/site/core/api/utilities/serialize.md @@ -0,0 +1,5 @@ + + + diff --git a/wagmi-project/site/core/getting-started.md b/wagmi-project/site/core/getting-started.md new file mode 100644 index 000000000..f5759957a --- /dev/null +++ b/wagmi-project/site/core/getting-started.md @@ -0,0 +1,71 @@ + + +# Getting Started + +## Overview + +Wagmi Core is a VanillaJS library for Ethereum. You can learn more about the rationale behind the project in the [Why Wagmi](/core/why) section. + +## Manual Installation + +To manually add Wagmi to your project, install the required packages. + +::: code-group +```bash-vue [pnpm] +pnpm add @wagmi/core @wagmi/connectors viem@{{viemVersion}} +``` + +```bash-vue [npm] +npm install @wagmi/core @wagmi/connectors viem@{{viemVersion}} +``` + +```bash-vue [yarn] +yarn add @wagmi/core @wagmi/connectors viem@{{viemVersion}} +``` + +```bash-vue [bun] +bun add @wagmi/core @wagmi/connectors viem@{{viemVersion}} +``` +::: + +- [Wagmi Connectors](/core/api/connectors) is a collection of interfaces for linking accounts/wallets to Wagmi. +- [Viem](https://viem.sh) is a TypeScript interface for Ethereum that performs blockchain operations. +- [TypeScript](/react/typescript) is optional, but highly recommended. Learn more about [TypeScript support](/core/typescript). + +### Create Config + +Create and export a new Wagmi config using `createConfig`. + +::: code-group +<<< @/snippets/core/config.ts[config.ts] +::: + +In this example, Wagmi is configured to use the Mainnet and Sepolia chains. Check out the [`createConfig` docs](/core/api/createConfig) for more configuration options. + +### Use Wagmi + +Now that everything is set up, you can pass the `config` to use actions. + +::: code-group +```tsx [index.ts] +import { getAccount, getEnsName } from '@wagmi/core' +import { config } from './config' + +const { address } = getAccount(config) +const ensName = await getEnsName(config, { address }) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Next Steps + +For more information on what to do next, check out the following topics. + +- [**TypeScript**](/core/typescript) Learn how to get the most out of Wagmi's type-safety and inference for an enlightened developer experience. +- [**Actions**](/core/api/actions) Browse the collection of actions and learn how to use them. +- [**Framework Adapters**](/core/guides/framework-adapters) Learn how to create a Wagmi-like adapter for your favorite framework. +- [**Viem docs**](https://viem.sh) Wagmi Core is a wrapper around Viem that manages account and client reactivity. Learn more about Viem and how to use it. diff --git a/wagmi-project/site/core/guides/chain-properties.md b/wagmi-project/site/core/guides/chain-properties.md new file mode 100644 index 000000000..4f0b480fe --- /dev/null +++ b/wagmi-project/site/core/guides/chain-properties.md @@ -0,0 +1,91 @@ +# Chain Properties + +Some chains support additional properties related to blocks and transactions. This is powered by Viem's [formatters](https://viem.sh/docs/chains/formatters) and [serializers](https://viem.sh/docs/chains/serializers). For example, Celo, ZkSync, OP Stack chains support all additional properties. In order to use these properties in a type-safe way, there are a few things you should be aware of. + +## Narrowing Parameters + +When you pass your `config` to an action, you are ready to access chain-specific properties! For example, Celo's `feeCurrency` is available. + +::: code-group +```ts [index.ts] +import { parseEther } from 'viem' +import { simulateContract } from '@wagmi/core' +import { config } from './config' + +const result = await simulateContract(config, { + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), + feeCurrency: '0x…', // [!code focus] +}) +``` +<<< @/snippets/core/config-chain-properties.ts[config.ts] +::: + +This is great, but if you have multiple chains that support additional properties, your autocomplete could be overwhelmed with all of them. By setting the `chainId` property to a specific value (e.g. `celo.id`), you can narrow parameters to a single chain. + +::: code-group +```ts [index.ts] +import { parseEther } from 'viem' +import { simulateContract } from '@wagmi/core' +import { celo } from 'wagmi/chains' + +const result = await simulateContract({ + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), + chainId: celo.id, // [!code focus] + feeCurrency: '0x…', // [!code focus] + // ^? (property) feeCurrency?: `0x${string}` | undefined // [!code focus] +}) +``` +<<< @/snippets/core/config-chain-properties.ts[config.ts] +::: + +## Narrowing Return Types + +Return types can also have chain-specific properties attached to them. There are a couple approaches for extracting these properties. + +### `chainId` Parameter + +Not only can you use the `chainId` parameter to [narrow parameters](#narrowing-parameters), you can also use it to narrow the return type. + +::: code-group +```ts [index.tsx] +import { waitForTransactionReceipt } from '@wagmi/core' +import { zkSync } from '@wagmi/core/chains' + +const result = await waitForTransactionReceipt({ + chainId: zkSync.id, + hash: '0x16854fcdd0219cacf5aec5e4eb2154dac9e406578a1510a6fc48bd0b67e69ea9', +}) + +result.logs +// ^? (property) logs: ZkSyncLog[] | undefined +``` +<<< @/snippets/core/config-chain-properties.ts[config.ts] +::: + +### `chainId` Data Property + +Wagmi internally will set a `chainId` property on return types that you can use to narrow results. The `chainId` is determined from the `chainId` parameter or global state (e.g. connector). You can use this property to help TypeScript narrow the type. + +::: code-group +```ts [index.tsx] +import { waitForTransactionReceipt } from '@wagmi/core' +import { zkSync } from '@wagmi/core/chains' + +const result = await waitForTransactionReceipt({ + hash: '0x16854fcdd0219cacf5aec5e4eb2154dac9e406578a1510a6fc48bd0b67e69ea9', +}) + +if (result.chainId === zkSync.id) { + result.logs + // ^? (property) logs: ZkSyncLog[] | undefined +} +``` +<<< @/snippets/core/config-chain-properties.ts[config.ts] +::: + +## Troubleshooting + +If chain properties aren't working, make sure [TypeScript](/core/guides/faq#type-inference-doesn-t-work) is configured correctly. Not all chains have additional properties, to check which ones do, see the [Viem repo](https://github.com/wevm/viem/tree/main/src/chains) (chains that have a top-level directory under [`src/chains`](https://github.com/wevm/viem/tree/main/src/chains) support additional properties). + diff --git a/wagmi-project/site/core/guides/error-handling.md b/wagmi-project/site/core/guides/error-handling.md new file mode 100644 index 000000000..bac34a1d2 --- /dev/null +++ b/wagmi-project/site/core/guides/error-handling.md @@ -0,0 +1,37 @@ +# Error Handling + +Every module in Wagmi Core exports an accompanying error type which you can use to strongly type your `catch` statements. + +These types come in the form of `ErrorType`. For example, the `getBlockNumber` action exports a `GetBlockNumberErrorType` type. + +Unfortunately, [TypeScript doesn't have an abstraction for typed exceptions](https://github.com/microsoft/TypeScript/issues/13219), so the most pragmatic & vanilla approach would be to explicitly cast error types in the `catch` statement. + +::: code-group +```tsx [index.tsx] +import { type GetBlockNumberErrorType, getBlockNumber } from '@wagmi/core' +import { config } from './config' + +try { + const blockNumber = await getBlockNumber(config) +} catch (e) { + const error = e as GetBlockNumberErrorType + error.name + // ^? (property) name: "Error" | "ChainDisconnectedError" | "HttpRequestError" | "InternalRpcError" | "InvalidInputRpcError" | "InvalidParamsRpcError" | "InvalidRequestRpcError" | "JsonRpcVersionUnsupportedError" | ... 16 more ... | "WebSocketRequestError" + + if (error.name === 'InternalRpcError') + error.code + // ^? (property) code: -32603 + + if (error.name === 'HttpRequestError') + error.headers + // ^? (property) headers: Headers + error.status + // ^? (property) status: number +} +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +::: tip +If you are using [Wagmi Hooks](/react/api/hooks), errors are [already strongly typed](/react/guides/error-handling) via the `error` property. +::: \ No newline at end of file diff --git a/wagmi-project/site/core/guides/ethers.md b/wagmi-project/site/core/guides/ethers.md new file mode 100644 index 000000000..c99598a36 --- /dev/null +++ b/wagmi-project/site/core/guides/ethers.md @@ -0,0 +1,306 @@ +# Ethers.js Adapters + +It is recommended for projects to migrate to [Viem](https://viem.sh) when using Wagmi, but there are some cases where you might still need to use [Ethers.js](https://ethers.org) in your project: + +- You may want to **incrementally migrate** Ethers.js usage to Viem +- Some **third-party libraries & SDKs** may only support Ethers.js +- Personal preference + +We have provided reference implementations for Viem → Ethers.js adapters that you can copy + paste in your project. + +## Client → Provider + +### Reference Implementation + +Copy the following reference implementation into a file of your choice: + +::: code-group + +```ts [Ethers v5] +import { type Config, getClient } from '@wagmi/core' +import { providers } from 'ethers' +import type { Client, Chain, Transport } from 'viem' + +export function clientToProvider(client: Client) { + const { chain, transport } = client + const network = { + chainId: chain.id, + name: chain.name, + ensAddress: chain.contracts?.ensRegistry?.address, + } + if (transport.type === 'fallback') + return new providers.FallbackProvider( + (transport.transports as ReturnType[]).map( + ({ value }) => new providers.JsonRpcProvider(value?.url, network), + ), + ) + return new providers.JsonRpcProvider(transport.url, network) +} + +/** Action to convert a viem Public Client to an ethers.js Provider. */ +export function getEthersProvider( + config: Config, + { chainId }: { chainId?: number } = {}, +) { + const client = getClient(config, { chainId }) + if (!client) return + return clientToProvider(client) +} +``` + +```ts [Ethers v6] +import { type Config, getClient } from '@wagmi/core' +import { FallbackProvider, JsonRpcProvider } from 'ethers' +import type { Client, Chain, Transport } from 'viem' + +export function clientToProvider(client: Client) { + const { chain, transport } = client + const network = { + chainId: chain.id, + name: chain.name, + ensAddress: chain.contracts?.ensRegistry?.address, + } + if (transport.type === 'fallback') { + const providers = (transport.transports as ReturnType[]).map( + ({ value }) => new JsonRpcProvider(value?.url, network), + ) + if (providers.length === 1) return providers[0] + return new FallbackProvider(providers) + } + return new JsonRpcProvider(transport.url, network) +} + +/** Action to convert a viem Client to an ethers.js Provider. */ +export function getEthersProvider( + config: Config, + { chainId }: { chainId?: number } = {}, +) { + const client = getClient(config, { chainId }) + if (!client) return + return clientToProvider(client) +} +``` + +::: + +### Usage + +Now you can use the `getEthersProvider` function in your components: + +::: code-group + +```ts [example.ts] +import { getEthersProvider } from './ethers' +import { config } from './config' + +function example() { + const provider = getEthersProvider(config) + ... +} +``` + +```ts [ethers.ts (Ethers v5)] +import { type Config, getClient } from '@wagmi/core' +import { providers } from 'ethers' +import type { Client, Chain, Transport } from 'viem' + +export function clientToProvider(client: Client) { + const { chain, transport } = client + const network = { + chainId: chain.id, + name: chain.name, + ensAddress: chain.contracts?.ensRegistry?.address, + } + if (transport.type === 'fallback') + return new providers.FallbackProvider( + (transport.transports as ReturnType[]).map( + ({ value }) => new providers.JsonRpcProvider(value?.url, network), + ), + ) + return new providers.JsonRpcProvider(transport.url, network) +} + +/** Action to convert a viem Public Client to an ethers.js Provider. */ +export function getEthersProvider( + config: Config, + { chainId }: { chainId?: number } = {}, +) { + const client = getClient(config, { chainId }) + if (!client) return + return clientToProvider(client) +} + +``` + +```ts [ethers.ts (Ethers v6)] +import { type Config, getClient } from '@wagmi/core' +import { FallbackProvider, JsonRpcProvider } from 'ethers' +import type { Client, Chain, Transport } from 'viem' + +export function clientToProvider(client: Client) { + const { chain, transport } = client + const network = { + chainId: chain.id, + name: chain.name, + ensAddress: chain.contracts?.ensRegistry?.address, + } + if (transport.type === 'fallback') { + const providers = (transport.transports as ReturnType[]).map( + ({ value }) => new JsonRpcProvider(value?.url, network), + ) + if (providers.length === 1) return providers[0] + return new FallbackProvider(providers) + } + return new JsonRpcProvider(transport.url, network) +} + +/** Action to convert a viem Client to an ethers.js Provider. */ +export function getEthersProvider( + config: Config, + { chainId }: { chainId?: number } = {}, +) { + const client = getClient(config, { chainId }) + if (!client) return + return clientToProvider(client) +} +``` + +::: + +## Connector Client → Signer + +### Reference Implementation + +Copy the following reference implementation into a file of your choice: + +::: code-group + +```ts [Ethers v5] +import { Config, getConnectorClient } from '@wagmi/core' +import { providers } from 'ethers' +import type { Account, Chain, Client, Transport } from 'viem' + +export function clientToSigner(client: Client) { + const { account, chain, transport } = client + const network = { + chainId: chain.id, + name: chain.name, + ensAddress: chain.contracts?.ensRegistry?.address, + } + const provider = new providers.Web3Provider(transport, network) + const signer = provider.getSigner(account.address) + return signer +} + +/** Action to convert a Viem Client to an ethers.js Signer. */ +export async function getEthersSigner( + config: Config, + { chainId }: { chainId?: number } = {}, +) { + const client = await getConnectorClient(config, { chainId }) + return clientToSigner(client) +} +``` + +```ts [Ethers v6] +import { Config, getConnectorClient } from '@wagmi/core' +import { BrowserProvider, JsonRpcSigner } from 'ethers' +import type { Account, Chain, Client, Transport } from 'viem' + +export function clientToSigner(client: Client) { + const { account, chain, transport } = client + const network = { + chainId: chain.id, + name: chain.name, + ensAddress: chain.contracts?.ensRegistry?.address, + } + const provider = new BrowserProvider(transport, network) + const signer = new JsonRpcSigner(provider, account.address) + return signer +} + +/** Action to convert a viem Wallet Client to an ethers.js Signer. */ +export async function getEthersSigner( + config: Config, + { chainId }: { chainId?: number } = {}, +) { + const client = await getConnectorClient(config, { chainId }) + return clientToSigner(client) +} + +``` + +::: + +### Usage + +Now you can use the `getEthersSigner` function in your components: + +::: code-group + +```ts [example.ts] +import { getEthersSigner } from './ethers' +import { config } from './config' + +function example() { + const provider = getEthersSigner(config) + ... +} +``` + +```ts [ethers.ts (Ethers v5)] +import { Config, getConnectorClient } from '@wagmi/core' +import { providers } from 'ethers' +import type { Account, Chain, Client, Transport } from 'viem' + +export function clientToSigner(client: Client) { + const { account, chain, transport } = client + const network = { + chainId: chain.id, + name: chain.name, + ensAddress: chain.contracts?.ensRegistry?.address, + } + const provider = new providers.Web3Provider(transport, network) + const signer = provider.getSigner(account.address) + return signer +} + +/** Action to convert a Viem Client to an ethers.js Signer. */ +export async function getEthersSigner( + config: Config, + { chainId }: { chainId?: number } = {}, +) { + const client = await getConnectorClient(config, { chainId }) + return clientToSigner(client) +} +``` + +```ts [ethers.ts (Ethers v6)] +import { Config, getConnectorClient } from '@wagmi/core' +import { BrowserProvider, JsonRpcSigner } from 'ethers' +import type { Account, Chain, Client, Transport } from 'viem' + +export function clientToSigner(client: Client) { + const { account, chain, transport } = client + const network = { + chainId: chain.id, + name: chain.name, + ensAddress: chain.contracts?.ensRegistry?.address, + } + const provider = new BrowserProvider(transport, network) + const signer = new JsonRpcSigner(provider, account.address) + return signer +} + +/** Action to convert a viem Wallet Client to an ethers.js Signer. */ +export async function getEthersSigner( + config: Config, + { chainId }: { chainId?: number } = {}, +) { + const client = await getConnectorClient(config, { chainId }) + return clientToSigner(client) +} + +``` + +::: diff --git a/wagmi-project/site/core/guides/faq.md b/wagmi-project/site/core/guides/faq.md new file mode 100644 index 000000000..7e3ca47e1 --- /dev/null +++ b/wagmi-project/site/core/guides/faq.md @@ -0,0 +1,9 @@ + + +# FAQ / Troubleshooting + +Collection of frequently asked questions with ideas on how to troubleshoot and resolve them. + + diff --git a/wagmi-project/site/core/guides/framework-adapters.md b/wagmi-project/site/core/guides/framework-adapters.md new file mode 100644 index 000000000..1e45ba63e --- /dev/null +++ b/wagmi-project/site/core/guides/framework-adapters.md @@ -0,0 +1,35 @@ +# Framework Adapters + +Folks often ask if they can use Wagmi with other frameworks, like Svelte, Solid.js, and more. + +The short answer is — you already can! Wagmi Core is pure VanillaJS that you can use with any framework. For some, this answer is (understandably) unsatisfying as they want a tight integration between Wagmi Core and their favorite framework's reactivity system, e.g. what Wagmi is for React and Vue. + +Someday, we would love to support additional frameworks, but unfortunately the core team doesn't have time to build and support them in a high-quality way at the moment. This could change in the future with additional [sponsors](https://github.com/sponsors/wevm), reshuffling of the roadmap, or if someone from the community wants to lead the effort. + +In the meantime, here are some tips on how to create tighter bonds between Wagmi Core and other frameworks. + +## Dependency Injection + +Once you create a Wagmi Config, you'll need to make sure your framework has access to it inside your higher-level functions (e.g. hooks for React, composables for Vue). For example, Wagmi uses [React Context](https://react.dev/learn/passing-data-deeply-with-context) to inject the Config into React Hooks and update it if it changes. This makes it so your users don't need to pass a Config object every time they use a hook. + +## Reactivity Layer + +All frameworks approach reactivity in a different way. To hook into your favorite frameworks, reactivity system, it's often helpful to see what other popular libraries for your framework are doing. + +The most important thing to hook up Wagmi Core with your framework is to make sure changes to the Wagmi Config are tracked. This enables behavior, like switching chains or connecting accounts, to propagate throughout your app and update state. Check out [`useAccount`](https://github.com/wevm/wagmi/blob/main/packages/react/src/hooks/useAccount.ts), [`useChainId`](https://github.com/wevm/wagmi/blob/main/packages/react/src/hooks/useChainId.ts), [`useClient`](https://github.com/wevm/wagmi/blob/main/packages/react/src/hooks/useClient.ts), and [`useConnectorClient`](https://github.com/wevm/wagmi/blob/main/packages/react/src/hooks/useConnectorClient.ts) — versions of these for your framework are important to get right as they power a lot of internals. + +## TanStack Query + +Wagmi uses [TanStack Query](https://tanstack.com/query) to enable caching, deduplication, persistence, and more in React and Vue applications. Normally, you would need to find a similar library for your framework, but the good news is TanStack Query supports other frameworks! (Svelte, Solid, and Angular at the time of writing.) + +To get started with your framework, install and set up the related TanStack Query adapter. Next, import query keys/functions and mutation functions from the `'@wagmi/core/query'` entrypoint. You can plug these directly into your framework's TanStack Query adapter functions. + +If you are building a library, you'll also want to make sure that you wire up generics correctly so type-inference and safety work correctly. The best way to make sure you are doing this correctly, is to see how we do this for React with Wagmi by checking out the [source code](https://github.com/wevm/wagmi/tree/main/packages/react/src/hooks). + +## Testing + +If you are building a library, you'll want to write tests. Wagmi uses [React Testing Library](https://testing-library.com/docs/react-testing-library/intro) to test hooks. [Testing Library](https://testing-library.com) also supports other frameworks, like Svelte, Solid, and more. You can take a look at how the React tests work and do something similar for your code. + +## Proxy Exports + +Wagmi proxies exports directly from Wagmi Core and [Viem](https://viem.sh) to make importing easier. You'll likely want to imitate this behavior for your framework. diff --git a/wagmi-project/site/core/guides/migrate-from-v1-to-v2.md b/wagmi-project/site/core/guides/migrate-from-v1-to-v2.md new file mode 100644 index 000000000..6807ebafc --- /dev/null +++ b/wagmi-project/site/core/guides/migrate-from-v1-to-v2.md @@ -0,0 +1,585 @@ +--- +title: Migrate from v1 to v2 +titleTemplate: Wagmi Core +description: Guide for migrating from Wagmi Core v1 to v2. +--- + + + +# Migrate from v1 to v2 + +Wagmi Core v2 redesigns the core APIs to mesh better with [Viem](https://viem.sh). This major version transforms Wagmi into a light wrapper around Viem, sprinkling in multichain support and account management. As such, there are some breaking changes and deprecations to be aware of outlined in this guide. + +To get started, install the latest version of Wagmi and it's required peer dependencies. + +::: code-group +```bash-vue [pnpm] +pnpm add @wagmi/core viem@{{viemVersion}} @wagmi/connectors +``` + +```bash-vue [npm] +npm install @wagmi/core viem@{{viemVersion}} @wagmi/connectors +``` + +```bash-vue [yarn] +yarn add @wagmi/core viem@{{viemVersion}} @wagmi/connectors +``` + +```bash-vue [bun] +bun add @wagmi/core viem@{{viemVersion}} @wagmi/connectors +``` +::: + +::: info Wagmi Core v2 should be the last major version that will have this many actionable breaking changes. +Moving forward, new functionality will be opt-in with old functionality being deprecated alongside the new features. This means upgrading to the latest major versions will not require immediate changes. +::: + +::: info Not ready to migrate yet? +The Wagmi Core v1 docs are still available at [1.x.wagmi.sh/core](https://1.x.wagmi.sh/core). +::: + +## Dependencies + +### Dropped CommonJS support + +Wagmi v2 no longer publishes a separate `cjs` tag since very few people use this tag and ESM is the future. See [Sindre Sorhus' guide](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c) for more info about switching to ESM. + +## Actions + +### Removed `config` singleton + +Before v2, when you called [`createConfig`](/core/api/createConfig), it set a global `config` singleton that was used internally by actions. For v2, `config` is now a required first parameter for actions. + +::: code-group +```ts [index.ts] +import { getAccount, readContract } from '@wagmi/core' +import { parseAbi } from 'viem' +import { config } from './config' // [!code ++] + +const account = getAccount() // [!code --] +const account = getAccount(config) // [!code ++] + +const balanceOf = readContract({ // [!code --] +const balanceOf = readContract(config, { // [!code ++] + address: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', + abi: parseAbi(['function balanceOf(address) view returns (uint256)']), + functionName: 'balanceOf', + args: ['0xd2135CfB216b74109775236E36d4b433F1DF507B'], +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +The previous global `config` singleton made it so you couldn't use multiple `Config` objects in the same project. In addition, we think passing `config` is more explicit and makes it easier to understand what's going on. Finally, types can be inferred directly from the `config`, like [chain properties](/core/guides/chain-properties) and more. + +### Removed `getContract` + +Removed `getContract` export. Use Viem's [`getContract`](https://viem.sh/docs/contract/getContract.html) instead. + +```ts +import { getContract } from '@wagmi/core' // [!code --] +import { getContract } from 'viem' // [!code ++] + +const contract = getContract() // [!code --] +const contract = getContract() // [!code ++] +``` + +### Removed `getNetwork` and `watchNetwork` + +The `getNetwork` and `watchNetwork` actions were removed since the connected chain is typically based on the connected account. + +- Use [`config.chains`](/core/api/createConfig#chains-1) instead to get `chains`. + + ::: code-group + ```ts [index.ts] + import { getNetwork } from '@wagmi/core' // [!code --] + + const { chains } = getNetwork() // [!code --] + const chains = config.chains // [!code ++] + ``` + <<< @/snippets/core/config.ts[config.ts] + ::: + +- Use [`getAccount`](/core/api/actions/getAccount) and `config.chains` instead to get `chain`. + + ::: code-group + ```ts [index.ts] + import { getNetwork } from '@wagmi/core' // [!code --] + import { getAccount } from '@wagmi/core' // [!code ++] + import { config } from './config' // [!code ++] + + const { chain } = getNetwork() // [!code --] + const { chainId } = getAccount(config) // [!code ++] + const chain = chains.find(chain => chain.id === chainId) // [!code ++] + ``` + <<< @/snippets/core/config.ts[config.ts] + ::: + + Before v2, `getNetwork().chain` could result in an invalid chain if the active connector's `chainId` was not configured in the list of `config.chains`. Using `getAccount` and `config.chains` is more work, but ensures that chain is either valid or not defined. You can also use `getAccount(config).chain` if you don't care about the chain being `undefined` when not configured. + +- Use `watchAccount` instead of `watchNetwork`. + + ::: code-group + ```ts [index.ts] + import { watchNetwork } from '@wagmi/core' // [!code --] + import { watchAccount } from '@wagmi/core' // [!code ++] + import { config } from './config' // [!code ++] + + const unwatch = watchNetwork((data) => console.log('Changed!', data)) // [!code --] + const unwatch = watchAccount(config, { // [!code ++] + onChange(data) { // [!code ++] + const chains = config.chains // [!code ++] + const chain = chains.find(chain => chain.id === data.chainId) // [!code ++] + }, // [!code ++] + }) // [!code ++] + ``` + <<< @/snippets/core/config.ts[config.ts] + ::: + +### Removed `getWebSocketPublicClient` and `watchWebSocketPublicClient` + +Viem [Transports](https://viem.sh/docs/clients/intro.html#transports) now determine the type of client that is returned. You can use [`getPublicClient`](/core/api/actions/getPublicClient) and [`watchPublicClient`](/core/api/actions/watchPublicClient) to retrieve Viem [`PublicClient`](https://viem.sh/docs/clients/public.html) instances. + +Alternatively, you can use [`getClient`](/core/api/actions/getClient) and [`watchClient`](/core/api/actions/watchClient) to retrieve plain Viem [`Client`](https://viem.sh/docs/clients/custom.html) instances. This is a better option for users that care about optimizing bundle size to be as small as possible. + +### Removed `watchReadContract`, `watchReadContracts`, and `watchReadMulticall` + +Use [`watchBlockNumber`](/core/api/actions/watchBlockNumber) along with [`readContract`](/core/api/actions/readContract), [`readContracts`](/core/api/actions/readContracts), and [`multicall`](/core/api/actions/multicall) actions instead. Before v2, `watchReadContract`, `watchReadContracts`, and `watchReadMulticall` were all wrappers around `watchBlockNumber` and this simplifies the API. + +::: code-group +```ts [index.ts] +import { watchReadContract } from '@wagmi/core' // [!code --] +import { watchBlockNumber, readContract } from '@wagmi/core' // [!code ++] +import { config } from './config' // [!code ++] + +const unwatch = watchReadContract( // [!code --] + { // [!code --] + address: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', // [!code --] + abi: parseAbi(['function balanceOf(address) view returns (uint256)']), // [!code --] + functionName: 'balanceOf', // [!code --] + args: ['0xd2135CfB216b74109775236E36d4b433F1DF507B'], // [!code --] + }, // [!code --] + (result) => console.log('Changed!', result), // [!code --] +) // [!code --] +const unwatch = watchBlockNumber(config, { // [!code ++] + onBlockNumber() { // [!code ++] + const balanceOf = readContract(config, { // [!code ++] + address: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', // [!code ++] + abi: parseAbi(['function balanceOf(address) view returns (uint256)']), // [!code ++] + functionName: 'balanceOf', // [!code ++] + args: ['0xd2135CfB216b74109775236E36d4b433F1DF507B'], // [!code ++] + }) // [!code ++] + console.log('Changed!', balanceOf)// [!code ++] + }, // [!code ++] +}) // [!code ++] +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### Removed `fetchFeeData` + +Removed `fetchFeeData`. Use [`estimateFeesPerGas`](/core/api/actions/estimateFeesPerGas) instead. + +::: code-group +```ts [index.ts] +import { fetchFeeData } from '@wagmi/core' // [!code --] +import { estimateFeesPerGas } from '@wagmi/core' // [!code ++] +import { config } from './config' // [!code ++] + +const result = await fetchFeeData() // [!code --] +const result = await estimateFeesPerGas(config) // [!code ++] +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### Removed `prepareWriteContract` + +Removed `prepareWriteContract`. Use [`simulateContract`](/core/api/actions/simulateContract) instead. + +::: code-group +```ts [index.ts] +import { prepareWriteContract } from '@wagmi/core' // [!code --] +import { simulateContract } from '@wagmi/core' // [!code ++] +import { config } from './config' // [!code ++] + +const result = await prepareWriteContract({ ... }) // [!code --] +const result = await simulateContract(config, { ... }) // [!code ++] +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### Removed `prepareSendTransaction` + +Removed `prepareSendTransaction`. Use [`estimateGas`](/core/api/actions/estimateGas) instead. + +::: code-group +```ts [index.ts] +import { prepareSendTransaction } from '@wagmi/core' // [!code --] +import { estimateGas } from '@wagmi/core' // [!code ++] +import { config } from './config' // [!code ++] + +const result = await prepareSendTransaction({ ... }) // [!code --] +const result = await estimateGas(config, { ... }) // [!code ++] +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### Updated `sendTransaction` and `writeContract` return type + +Updated [`sendTransaction`](/core/api/actions/sendTransaction) and [`writeContract`](/core/api/actions/writeContract) return type from `` { hash: `0x${string}` } `` to `` `0x${string}` ``. + +```ts +const result = await sendTransaction({ hash: '0x...' }) +result.hash // [!code --] +result // [!code ++] +``` + +### Updated `connect` return type + +Updated [`connect`](/core/api/actions/connect) return type from `` { account: Address; chain: { id: number; unsupported?: boolean }; connector: Connector } `` to `` { accounts: readonly Address[]; chainId: number } ``. This better reflects the ability to have multiple accounts per connector. + +### Renamed parameters and return types + +All hook parameters and return types follow the naming pattern of `[PascalCaseActionName]Parameters` and `[PascalCaseActionName]ReturnType`. For example, `GetAccountParameters` and `GetAccountReturnType`. + +```ts +import { GetAccountConfig, GetAccountResult } from '@wagmi/core' // [!code --] +import { GetAccountParameters, GetAccountReturnType } from '@wagmi/core' // [!code ++] +``` + +## Connectors + +### Moved Wagmi Connectors to peer dependencies + +Wagmi Core v2 no longer exports connectors via the `'@wagmi/core/connectors/*'` entrypoints. Instead, you should install the `@wagmi/connectors` package. + +::: code-group +```bash-vue [pnpm] +pnpm add @wagmi/connectors +``` + +```bash-vue [npm] +npm install @wagmi/connectors +``` + +```bash-vue [yarn] +yarn add @wagmi/connectors +``` + +```bash-vue [bun] +bun add @wagmi/connectors +``` +::: + +And import connectors from there. + +```ts +import { injected } from '@wagmi/connectors' +``` + +See the [connectors documentation](/core/api/connectors) for more information. + +### Updated connector API + +In order to maximize type-safety and ease of creating connectors, the connector API changed. Follow the [Creating Connectors guide](/dev/creating-connectors) for more info on creating new connectors and converting Wagmi v1 connectors. + +### Removed individual entrypoints + +Previously, each connector had its own entrypoint to optimize tree-shaking. Since all connectors now have [`package.json#sideEffects`](https://webpack.js.org/guides/tree-shaking/#mark-the-file-as-side-effect-free) enabled, this is no longer necessary and the entrypoint is unified. Use the `'@wagmi/connectors'` package instead. + +```ts +import { InjectedConnector } from '@wagmi/core/connectors/injected' // [!code --] +import { CoinbaseWalletConnector } from '@wagmi/core/connectors/coinbaseWallet' // [!code --] +import { coinbaseWallet, injected } from '@wagmi/connectors' // [!code ++] +``` + +### Removed `MetaMaskConnector` + +The `MetaMaskConnector` was removed since it was nearly the same thing as the `InjectedConnector`. Use the [`injected`](/core/api/connectors/injected) connector instead, along with the [`target`](/core/api/connectors/injected#target) parameter set to `'metaMask'`, for the same behavior. + +```ts +import { MetaMaskConnector } from '@wagmi/core/connectors/metaMask' // [!code --] +import { injected } from '@wagmi/connectors' // [!code ++] + +const connector = new MetaMaskConnector() // [!code --] +const connector = injected({ target: 'metaMask' }) // [!code ++] +``` + +### Renamed connectors + +In Wagmi v1, connectors were classes you needed to instantiate. In Wagmi v2, connectors are functions. As a result, the API has changed. Connectors have the following new names: + +- `CoinbaseWalletConnector` is now [`coinbaseWallet`](/core/api/connectors/coinbaseWallet). +- `InjectedConnector` is now [`injected`](/core/api/connectors/injected). +- `SafeConnector` is now [`safe`](/core/api/connectors/safe). +- `WalletConnectConnector` is now [`walletConnect`](/core/api/connectors/walletConnect). + +To create a connector, you now call the connector function with parameters. + +```ts +import { WalletConnectConnector } from '@wagmi/core/connectors/walletConnect' // [!code --] +import { walletConnect } from '@wagmi/connectors' // [!code ++] + +const connector = new WalletConnectConnector({ // [!code --] +const connector = walletConnect({ // [!code ++] + projectId: '3fcc6bba6f1de962d911bb5b5c3dba68', +}) +``` + +### Removed `WalletConnectLegacyConnector` + +WalletConnect v1 was sunset June 28, 2023. Use the [`walletConnect`](/core/api/connectors/walletConnect) connector instead. + +```ts +import { WalletConnectLegacyConnector } from '@wagmi/core/connectors/walletConnectLegacy' // [!code --] +import { walletConnect } from '@wagmi/connectors' // [!code ++] + +const connector = new WalletConnectLegacyConnector({ // [!code --] +const connector = walletConnect({ // [!code ++] + projectId: '3fcc6bba6f1de962d911bb5b5c3dba68', +}) +``` + +## Chains + +### Updated `'@wagmi/core/chains'` entrypoint + +Chains now live in the [Viem repository](https://github.com/wevm/viem). As a result, the `'@wagmi/core/chains'` entrypoint now proxies all chains from `'viem/chains'` directly. + +### Removed `mainnet` and `sepolia` from main entrypoint + +Since the `'@wagmi/core/chains'` entrypoint now proxies `'viem/chains'`, `mainnet` and `sepolia` were removed from the main entrypoint. Use the `'@wagmi/core/chains'` entrypoint instead. + +```ts +import { mainnet, sepolia } from '@wagmi/core' // [!code --] +import { mainnet, sepolia } from '@wagmi/core/chains' // [!code ++] +``` + +## Errors + +A number of errors were renamed to better reflect their functionality or replaced by Viem errors. + +## Miscellaneous + +### Removed internal ENS normalization + +Before v2, Wagmi handled ENS name normalization internally for `getEnsAddress`, `getEnsAvatar`, and `getEnsResolver`, using Viem's [`normalize`](https://viem.sh/docs/ens/utilities/normalize.html) function. This added extra bundle size as full normalization is quite heavy. For v2, you must normalize ENS names yourself before passing them to these actions. You can use Viem's `normalize` function or any other function that performs [UTS-46 normalization](https://unicode.org/reports/tr46). + + +::: code-group +```ts [index.ts] +import { getEnsAddress } from '@wagmi/core' +import { normalize } from 'viem' // [!code ++] +import { config } from './config' + +const result = await getEnsAddress(config, { + name: 'wevm.eth', // [!code --] + name: normalize('wevm.eth'), // [!code ++] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +By inverting control, Wagmi lets you choose how much normalization to do. For example, maybe your project only allows ENS names that are numeric so no normalization is not needed. Check out the [ENS documentation](https://docs.ens.domains/contract-api-reference/name-processing#normalising-names) for more information on normalizing names. + +### Removed `configureChains` + +The Wagmi v2 `Config` now has native multichain support using the [`chains`](/core/api/createConfig) parameter so the `configureChains` function is no longer required. + +```ts +import { configureChains, createConfig } from '@wagmi/core' // [!code --] +import { http, createConfig } from '@wagmi/core' // [!code ++] +import { mainnet, sepolia } from '@wagmi/core/chains' + +const { chains, publicClient } = configureChains( // [!code --] + [mainnet, sepolia], // [!code --] + [publicProvider(), publicProvider()], // [!code --] +) // [!code --] + +export const config = createConfig({ + publicClient, // [!code --] + chains: [mainnet, sepolia], // [!code ++] + transports: { // [!code ++] + [mainnet.id]: http(), // [!code ++] + [sepolia.id]: http(), // [!code ++] + }, // [!code ++] +}) +``` + +### Removed ABI exports + +Import from Viem instead. + +```ts +import { erc20ABI } from '@wagmi/core' // [!code --] +import { erc20Abi } from 'viem' // [!code ++] +``` + +### Removed `'@wagmi/core/providers/*` entrypoints + +It never made sense that we would have provider URLs hardcoded in the Wagmi codebase. Use [Viem transports](https://viem.sh/docs/clients/intro.html#transports) along with RPC provider URLs instead. + +```ts +import { alchemyProvider } from '@wagmi/core/providers/alchemy' // [!code --] +import { http } from 'viem' // [!code ++] + +const transport = http('https://mainnet.example.com') +``` + +### Updated `createConfig` parameters + +- Removed `autoConnect`. The reconnecting behavior must be managed manually and is not related to the Wagmi `Config`. Use the [`reconnect`](/core/api/actions/reconnect) action instead. +- Removed `publicClient` and `webSocketPublicClient`. Use [`transports`](/core/api/createConfig#transports) or [`client`](/core/api/createConfig#client) instead. +- Removed `logger`. Wagmi no longer logs debug information to console. + +### Updated `Config` object + +- Removed `config.connector`. Use `config.state.connections.get(config.state.current)?.connector` instead. +- Removed `config.data`. Use `config.state.connections.get(config.state.current)` instead. +- Removed `config.error`. Was unused and not needed. +- Removed `config.lastUsedChainId`. Use `config.state.connections.get(config.state.current)?.chainId` instead. +- Removed `config.publicClient`. Use [`config.getClient()`](/core/api/createConfig#getclient) or [`getPublicClient`](/core/api/actions/getPublicClient) instead. +- Removed `config.status`. Use [`config.state.status`](/core/api/createConfig#status) instead. +- Removed `config.webSocketClient`. Use [`config.getClient()`](/core/api/createConfig#getclient) or [`getPublicClient`](/core/api/actions/getPublicClient) instead. +- Removed `config.clearState`. Was unused and not needed. +- Removed `config.autoConnect()`. Use [`reconnect`](/core/api/actions/reconnect) action instead. +- Renamed `config.setConnectors`. Use `config._internal.setConnectors` instead. +- Removed `config.setLastUsedConnector`. Use `config.storage?.setItem('recentConnectorId', connectorId)` instead. +- Removed `getConfig`. `config` should be passed explicitly to actions instead of using global `config`. + +## Deprecations + +### Deprecated `getBalance` `token` parameter + +Moving forward, `getBalance` will only work for native currencies, thus the `token` parameter is no longer supported. Use [`readContracts`](/core/api/actions/readContracts) instead. + +```ts +import { getBalance } from '@wagmi/core' // [!code --] +import { readContracts } from '@wagmi/core' // [!code ++] +import { erc20Abi } from 'viem' // [!code ++] +import { config } from './config' // [!code ++] + +const result = await getBalance(config, { // [!code --] + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', // [!code --] + token: '0x6B175474E89094C44Da98b954EedeAC495271d0F', // [!code --] +}) // [!code --] +const result = await readContracts(config, { // [!code ++] + allowFailure: false, // [!code ++] + contracts: [ // [!code ++] + { // [!code ++] + address: '0x6B175474E89094C44Da98b954EedeAC495271d0F', // [!code ++] + abi: erc20Abi, // [!code ++] + functionName: 'balanceOf', // [!code ++] + args: ['0x4557B18E779944BFE9d78A672452331C186a9f48'], // [!code ++] + }, // [!code ++] + { // [!code ++] + address: '0x6B175474E89094C44Da98b954EedeAC495271d0F', // [!code ++] + abi: erc20Abi, // [!code ++] + functionName: 'decimals', // [!code ++] + }, // [!code ++] + { // [!code ++] + address: '0x6B175474E89094C44Da98b954EedeAC495271d0F', // [!code ++] + abi: erc20Abi, // [!code ++] + functionName: 'symbol', // [!code ++] + }, // [!code ++] + ] // [!code ++] +}) // [!code ++] +``` + +### Deprecated `getBalance` `unit` parameter and `formatted` return value + +Moving forward, `getBalance` will not accept the `unit` parameter or return a `formatted` value. Instead you can call `formatUnits` from Viem directly or use another number formatting library, like [dnum](https://github.com/bpierre/dnum) instead. + +```ts +import { formatUnits } from 'viem' // [!code ++] +import { getBalance } from '@wagmi/core' + +const result = await getBalance({ + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', + unit: 'ether', // [!code --] +}) +result.formatted // [!code --] +formatUnits(result.value, result.decimals) // [!code ++] +``` + +### Deprecated `getToken` + +Moving forward, `getToken` is no longer supported. Use [`readContracts`](/core/api/actions/readContracts) instead. + +```ts +import { getToken } from '@wagmi/core' // [!code --] +import { readContracts } from '@wagmi/core' // [!code ++] +import { erc20Abi } from 'viem' // [!code ++] +import { config } from './config' // [!code ++] + +const result = await getToken(config, { // [!code --] + address: '0x6B175474E89094C44Da98b954EedeAC495271d0F', // [!code --] +}) // [!code --] +const result = await readContracts(config, { // [!code ++] + allowFailure: false, // [!code ++] + contracts: [ // [!code ++] + { // [!code ++] + address: '0x6B175474E89094C44Da98b954EedeAC495271d0F', // [!code ++] + abi: erc20Abi, // [!code ++] + functionName: 'decimals', // [!code ++] + }, // [!code ++] + { // [!code ++] + address: '0x6B175474E89094C44Da98b954EedeAC495271d0F', // [!code ++] + abi: erc20Abi, // [!code ++] + functionName: 'name', // [!code ++] + }, // [!code ++] + { // [!code ++] + address: '0x6B175474E89094C44Da98b954EedeAC495271d0F', // [!code ++] + abi: erc20Abi, // [!code ++] + functionName: 'symbol', // [!code ++] + }, // [!code ++] + { // [!code ++] + address: '0x6B175474E89094C44Da98b954EedeAC495271d0F', // [!code ++] + abi: erc20Abi, // [!code ++] + functionName: 'totalSupply', // [!code ++] + }, // [!code ++] + ] // [!code ++] +}) // [!code ++] +``` + +### Deprecated `formatUnits` parameters and return values + +The `formatUnits` parameter and related return values (e.g. `result.formatted`) are deprecated for the following actions: + +- [`estimateFeesPerGas`](/core/api/actions/estimateFeesPerGas) +- [`getToken`](/core/api/actions/getToken) + +Instead you can call `formatUnits` from Viem directly or use another number formatting library, like [dnum](https://github.com/bpierre/dnum) instead. + +```ts +import { formatUnits } from 'viem' // [!code ++] +import { getToken } from '@wagmi/core' + +const result = await getToken({ + address: '0x6B175474E89094C44Da98b954EedeAC495271d0F', + formatUnits: 'ether', +}) +result.totalSupply.formatted // [!code --] +formatUnits(result.totalSupply.value, 18) // [!code ++] +``` + +This allows us to invert control to users so they can handle number formatting however they want, taking into account precision, localization, and more. + +### Renamed actions + +The following actions were renamed to better reflect their functionality and underlying [Viem](https://viem.sh) actions: + +- `fetchBalance` is now [`getBalance`](/core/api/actions/getBalance) +- `fetchBlockNumber` is now [`getBlockNumber`](/core/api/actions/getBlockNumber) +- `fetchEnsAddress` is now [`getEnsAddress`](/core/api/actions/getEnsAddress) +- `fetchEnsAvatar` is now [`getEnsAvatar`](/core/api/actions/getEnsAvatar) +- `fetchEnsName` is now [`getEnsName`](/core/api/actions/getEnsName) +- `fetchEnsResolver` is now [`getEnsResolver`](/core/api/actions/getEnsResolver) +- `fetchToken` is now [`getToken`](/core/api/actions/getToken) +- `fetchTransaction` is now [`getTransaction`](/core/api/actions/getTransaction) +- `switchNetwork` is now [`switchChain`](/core/api/actions/switchChain) +- `waitForTransaction` is now [`waitForTransactionReceipt`](/core/api/actions/waitForTransactionReceipt) diff --git a/wagmi-project/site/core/guides/testing.md b/wagmi-project/site/core/guides/testing.md new file mode 100644 index 000000000..383062dbe --- /dev/null +++ b/wagmi-project/site/core/guides/testing.md @@ -0,0 +1,3 @@ +# Testing + + diff --git a/wagmi-project/site/core/guides/viem.md b/wagmi-project/site/core/guides/viem.md new file mode 100644 index 000000000..275ed8694 --- /dev/null +++ b/wagmi-project/site/core/guides/viem.md @@ -0,0 +1,197 @@ +# Viem + +[Viem](https://viem.sh) is a low-level TypeScript Interface for Ethereum that enables developers to interact with the Ethereum blockchain, including: JSON-RPC API abstractions, Smart Contract interaction, wallet & signing implementations, coding/parsing utilities and more. + +**Wagmi Core** is essentially a wrapper over **Viem** that provides multi-chain functionality via [Wagmi Config](/core/api/createConfig) and automatic account management via [Connectors](/core/api/connectors). + +## Leveraging Viem Actions + +All of the core [Wagmi Actions](/core/api/actions) are friendly wrappers around [Viem Actions](https://viem.sh/docs/actions/public/introduction.html) that inject a multi-chain and connector aware [Wagmi Config](/core/api/createConfig). + +There may be cases where you might want to dig deeper and utilize Viem Actions directly (maybe an Action doesn't exist in Wagmi yet). In these cases, you can import Viem Actions directly via `viem/actions` and plug in a Viem Client returned by the [`getClient` Action](/core/api/actions/getClient). + +The example below demonstrates two different ways to utilize Viem Actions: + +1. **Tree-shakable Actions (recommended):** Uses `getClient` (for public actions) and `getConnectorClient` (for wallet actions). +2. **Client Actions:** Uses `getPublicClient` (for public actions) and `getWalletClient` (for wallet actions). + +::: tip + +It is highly recommended to use the **tree-shakable** method to ensure that you are only pulling modules you use, and keep your bundle size low. + +::: + +::: code-group + +```tsx [Tree-shakable Actions] +// 1. Import modules. +import { http, createConfig, getClient, getConnectorClient } from '@wagmi/core' +import { base, mainnet, optimism, zora } from '@wagmi/core/chains' +import { getLogs, watchAsset } from 'viem/actions' // [!code hl] + +// 2. Set up a Wagmi Config +export const config = createConfig({ + chains: [base, mainnet, optimism, zora], + transports: { + [base.id]: http(), + [mainnet.id]: http(), + [optimism.id]: http(), + [zora.id]: http(), + }, +}) + +// 3. Extract a Viem Client for the current active chain. +const publicClient = getClient(config) +const logs = await getLogs(publicClient, /* ... */) // [!code hl] + +// 4. Extract a Viem Client for the current active chain & account. +const walletClient = getConnectorClient(config) +const success = await watchAsset(walletClient, /* ... */) // [!code hl] +``` + +```tsx [Client Actions] +// 1. Import modules. +import { http, createConfig, getPublicClient, getWalletClient } from '@wagmi/core' +import { base, mainnet, optimism, zora } from '@wagmi/core/chains' + +// 2. Set up a Wagmi Config +export const config = createConfig({ + chains: [base, mainnet, optimism, zora], + transports: { + [base.id]: http(), + [mainnet.id]: http(), + [optimism.id]: http(), + [zora.id]: http(), + }, +}) + +// 3. Extract a Viem Public Client for the current active chain. +const publicClient = getPublicClient(config) +const logs = await publicClient.getLogs(publicClient, /* ... */) // [!code hl] + +// 4. Extract a Viem Wallet Client for the current active chain & account. +const walletClient = getWalletClient(config) +const success = await walletClient.watchAsset(walletClient, /* ... */) // [!code hl] +``` + +::: + +## Multi-chain Viem Client + +The [Viem Client](https://viem.sh/docs/client) provides an interface to interact with an JSON-RPC Provider. By nature, JSON-RPC Providers are single-chain, so the Viem Client is designed to be instantiated with a single `chain`. As a result, setting up Viem to be multi-chain aware can get a bit verbose. + +The good news is that you can create a **"multi-chain Viem Client"** with **Wagmi** by utilizing [`createConfig`](/core/api/createConfig) and [`getClient`](/core/api/actions/getClient). + +::: code-group + +```tsx [Wagmi Usage] +// 1. Import modules. +import { http, createConfig, getClient, getConnectorClient } from '@wagmi/core' +import { base, mainnet, optimism, zora } from '@wagmi/core/chains' +import { getBlockNumber, sendTransaction } from 'viem/actions' // [!code hl] + +// 2. Set up a Wagmi Config +export const config = createConfig({ + chains: [base, mainnet, optimism, zora], + transports: { + [base.id]: http(), + [mainnet.id]: http(), + [optimism.id]: http(), + [zora.id]: http(), + }, +}) + +// 3. Extract a Viem Client for the current active chain. +const publicClient = getClient(config) +const blockNumber = await getBlockNumber(publicClient) // [!code hl] + +// 4. Extract a Viem Client for the current active chain & account. +const walletClient = getConnectorClient(config) +const hash = await sendTransaction(walletClient, /* ... */) // [!code hl] +``` + +```tsx [Viem Usage] +// Manually set up Viem Clients without wagmi. Don't do this, it's only here +// to demonstrate the amount of boilerplate required. + +import { createPublicClient, createWalletClient, http } from 'viem' +import { base, mainnet, optimism, zora } from 'viem/chains' + +const publicClient = { + base: createPublicClient({ + chain: base, + transport: http() + }), + mainnet: createPublicClient({ + chain: mainnet, + transport: http() + }), + optimism: createPublicClient({ + chain: optimism, + transport: http() + }), + zora: createPublicClient({ + chain: zora, + transport: http() + }) +} as const + +const walletClient = { + base: createWalletClient({ + chain: base, + transport: custom(window.ethereum) + }), + mainnet: createWalletClient({ + chain: mainnet, + transport: custom(window.ethereum) + }), + optimism: createWalletClient({ + chain: optimism, + transport: custom(window.ethereum) + }), + zora: createWalletClient({ + chain: zora, + transport: custom(window.ethereum) + }) +} as const + +const blockNumber = await publicClient.mainnet.getBlockNumber() +const hash = await walletClient.mainnet.sendTransaction(/* ... */) +``` + +::: + +## Private Key & Mnemonic Accounts + +It is possible to utilize Viem's [Private Key & Mnemonic Accounts](https://viem.sh/docs/accounts/local.html) with Wagmi by explicitly passing through the account via the `account` argument on Wagmi Actions. + +```tsx +import { http, createConfig, sendTransaction } from '@wagmi/core' +import { base, mainnet, optimism, zora } from '@wagmi/core/chains' +import { parseEther } from 'viem' +import { privateKeyToAccount } from 'viem/accounts' + +export const config = createConfig({ + chains: [base, mainnet, optimism, zora], + transports: { + [base.id]: http(), + [mainnet.id]: http(), + [optimism.id]: http(), + [zora.id]: http(), + }, +}) + +const account = privateKeyToAccount('0x...') // [!code hl] + +const hash = await sendTransaction({ + account, // [!code hl] + to: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC', + value: parseEther('0.001') +}) +``` + +::: info + +Wagmi currently does not support hoisting Private Key & Mnemonic Accounts to the top-level Wagmi Config – meaning you have to explicitly pass through the account to every Action. If you feel like this is a feature that should be added, please [open a discussion](https://github.com/wevm/wagmi/discussions/new?category=ideas). + +::: diff --git a/wagmi-project/site/core/installation.md b/wagmi-project/site/core/installation.md new file mode 100644 index 000000000..858ebc687 --- /dev/null +++ b/wagmi-project/site/core/installation.md @@ -0,0 +1,52 @@ + + +# Installation + +Install Wagmi Core via your package manager, a ` +``` + + diff --git a/wagmi-project/site/core/typescript.md b/wagmi-project/site/core/typescript.md new file mode 100644 index 000000000..e41d94282 --- /dev/null +++ b/wagmi-project/site/core/typescript.md @@ -0,0 +1,241 @@ + + +# TypeScript + +## Requirements + +Wagmi Core is designed to be as type-safe as possible! Things to keep in mind: + +- Types currently require using TypeScript {{typescriptVersion}}. +- [TypeScript doesn't follow semver](https://www.learningtypescript.com/articles/why-typescript-doesnt-follow-strict-semantic-versioning) and often introduces breaking changes in minor releases. +- Changes to types in this repository are considered non-breaking and are usually released as patch changes (otherwise every type enhancement would be a major version!). +- It is highly recommended that you lock your `@wagmi/core` and `typescript` versions to specific patch releases and upgrade with the expectation that types may be fixed or upgraded between any release. +- The non-type-related public API of Wagmi Core still follows semver very strictly. + +To ensure everything works correctly, make sure your `tsconfig.json` has [`strict`](https://www.typescriptlang.org/tsconfig#strict) mode set to `true`. + +::: code-group +```json [tsconfig.json] +{ + "compilerOptions": { + "strict": true + } +} +``` +::: + +## Const-Assert ABIs & Typed Data + +Wagmi Core can infer types based on [ABIs](https://docs.soliditylang.org/en/latest/abi-spec.html#json) and [EIP-712](https://eips.ethereum.org/EIPS/eip-712) Typed Data definitions, powered by [Viem](https://viem.sh) and [ABIType](https://github.com/wevm/abitype). This achieves full end-to-end type-safety from your contracts to your frontend and enlightened developer experience by autocompleting ABI item names, catching misspellings, inferring argument and return types (including overloads), and more. + +For this to work, you must either [const-assert](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-4.html#const-assertions) ABIs and Typed Data (more info below) or define them inline. For example, `useReadContract`'s `abi` configuration parameter: + +```ts +const result = await readContract({ + abi: […], // <--- defined inline // [!code focus] +}) +``` + +```ts +const abi = […] as const // <--- const assertion // [!code focus] +const result = readContract({ abi }) +``` + +If type inference isn't working, it's likely you forgot to add a `const` assertion or define the configuration parameter inline. Also, make sure your ABIs, Typed Data definitions, and [TypeScript configuration](#requirements) are valid and set up correctly. + +::: tip +Unfortunately [TypeScript doesn't support importing JSON `as const` yet](https://github.com/microsoft/TypeScript/issues/32063). Check out the [Wagmi CLI](/cli/getting-started) to help with this! It can automatically fetch ABIs from Etherscan and other block explorers, resolve ABIs from your Foundry/Hardhat projects, and more. +::: + +Anywhere you see the `abi` or `types` configuration property, you can likely use const-asserted or inline ABIs and Typed Data to get type-safety and inference. These properties are also called out in the docs. + +Here's what [`readContract`](/core/api/actions/readContract) looks like with and without a const-asserted `abi` property. + +::: code-group +```ts twoslash [Const-Asserted] +import { createConfig, http } from '@wagmi/core' +import { mainnet, sepolia } from '@wagmi/core/chains' + +const config = createConfig({ + chains: [mainnet, sepolia], + transports: { + [mainnet.id]: http(), + [sepolia.id]: http(), + }, +}) + +const erc721Abi = [ + { + name: 'balanceOf', + type: 'function', + stateMutability: 'view', + inputs: [{ type: 'address', name: 'owner' }], + outputs: [{ type: 'uint256' }], + }, + { + name: 'isApprovedForAll', + type: 'function', + stateMutability: 'view', + inputs: [ + { type: 'address', name: 'owner' }, + { type: 'address', name: 'operator' }, + ], + outputs: [{ type: 'bool' }], + }, + { + name: 'getApproved', + type: 'function', + stateMutability: 'view', + inputs: [{ type: 'uint256', name: 'tokenId' }], + outputs: [{ type: 'address' }], + }, + { + name: 'ownerOf', + type: 'function', + stateMutability: 'view', + inputs: [{ type: 'uint256', name: 'tokenId' }], + outputs: [{ type: 'address' }], + }, + { + name: 'tokenURI', + type: 'function', + stateMutability: 'pure', + inputs: [{ type: 'uint256', name: 'tokenId' }], + outputs: [{ type: 'string' }], + }, +] as const +// ---cut--- +import { readContract } from '@wagmi/core' + +const result = await readContract(config, { + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + abi: erc721Abi, + functionName: 'balanceOf', + // ^? + + + + args: ['0xA0Cf798816D4b9b9866b5330EEa46a18382f251e'], + // ^? +}) + +result +// ^? +``` +```ts twoslash [Not Const-Asserted] +import { createConfig, http } from '@wagmi/core' +import { mainnet, sepolia } from '@wagmi/core/chains' + +const config = createConfig({ + chains: [mainnet, sepolia], + transports: { + [mainnet.id]: http(), + [sepolia.id]: http(), + }, +}) + +declare const erc721Abi: { + name: string; + type: string; + stateMutability: string; + inputs: { + type: string; + name: string; + }[]; + outputs: { + type: string; + }[]; +}[] +// ---cut--- +import { readContract } from '@wagmi/core' + +const result = await readContract(config, { + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + abi: erc721Abi, + functionName: 'balanceOf', + // ^? + + + + args: ['0xA0Cf798816D4b9b9866b5330EEa46a18382f251e'], + // ^? +}) + +result +// ^? +``` +::: + +You can prevent runtime errors and be more productive by making sure your ABIs and Typed Data definitions are set up appropriately. 🎉 + +```ts twoslash +// @errors: 2820 +import { createConfig, http } from '@wagmi/core' +import { mainnet, sepolia } from '@wagmi/core/chains' + +const config = createConfig({ + chains: [mainnet, sepolia], + transports: { + [mainnet.id]: http(), + [sepolia.id]: http(), + }, +}) + +const erc721Abi = [ + { + name: 'balanceOf', + type: 'function', + stateMutability: 'view', + inputs: [{ type: 'address', name: 'owner' }], + outputs: [{ type: 'uint256' }], + }, + { + name: 'isApprovedForAll', + type: 'function', + stateMutability: 'view', + inputs: [ + { type: 'address', name: 'owner' }, + { type: 'address', name: 'operator' }, + ], + outputs: [{ type: 'bool' }], + }, + { + name: 'getApproved', + type: 'function', + stateMutability: 'view', + inputs: [{ type: 'uint256', name: 'tokenId' }], + outputs: [{ type: 'address' }], + }, + { + name: 'ownerOf', + type: 'function', + stateMutability: 'view', + inputs: [{ type: 'uint256', name: 'tokenId' }], + outputs: [{ type: 'address' }], + }, + { + name: 'tokenURI', + type: 'function', + stateMutability: 'pure', + inputs: [{ type: 'uint256', name: 'tokenId' }], + outputs: [{ type: 'string' }], + }, +] as const +// ---cut--- +import { readContract } from '@wagmi/core' + +readContract(config, { + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + abi: erc721Abi, + functionName: 'balanecOf', + args: ['0xA0Cf798816D4b9b9866b5330EEa46a18382f251e'], +}) +``` + +## Configure Internal Types + +For advanced use-cases, you may want to configure wagmi's internal types. Most of wagmi's types relating to ABIs and EIP-712 Typed Data are powered by [ABIType](https://github.com/wevm/abitype). See the [ABIType docs](https://abitype.dev) for more info on how to configure types. diff --git a/wagmi-project/site/core/why.md b/wagmi-project/site/core/why.md new file mode 100644 index 000000000..d7ed951f0 --- /dev/null +++ b/wagmi-project/site/core/why.md @@ -0,0 +1,46 @@ +# Why Wagmi Core + +## The Problems + +Building Ethereum applications is hard. Apps need to support connecting wallets, multiple chains, signing messages and data, sending transactions, listening for events and state changes, refreshing stale blockchain data, and much more. This is all on top of solving for app-specific use-cases and providing polished user experiences. + +The ecosystem is also continuously evolving, meaning you need to adapt to new improvements or get left behind. App developers should not need to worry about connecting tens of different wallets, the intricacies of multi-chain support, typos accidentally sending an order of magnitude more ETH or calling a misspelled contract function, or accidentally spamming their RPC provider, costing thousands in compute units. + +Wagmi Core solves all these problems and more — allowing app developers to focus on building high-quality and performant experiences for Ethereum — by focusing on **developer experience**, **performance**, **feature coverage**, and **stability.** + +## Developer Experience + +Wagmi Core delivers a great developer experience through modular and composable APIs, automatic type safety and inference, and comprehensive documentation. + +It provides developers with intuitive building blocks to build their Ethereum apps. While Wagmi Core's APIs might seem more verbose at first, it makes Wagmi Core's modular building blocks extremely flexible. Easy to move around, change, and remove. It also allows developers to better understand Ethereum concepts as well as understand _what_ and _why_ certain properties are being passed through. Learning how to use Wagmi Core is a great way to learn how to interact with Ethereum in general. + +Wagmi Core also provides [strongly typed APIs](/core/typescript), allowing consumers to get the best possible experience through [autocomplete](https://twitter.com/awkweb/status/1555678944770367493), [type inference](https://twitter.com/jakemoxey/status/1570244174502588417?s=20), as well as static validation. You often just need to provide an ABI and Wagmi Core can help you autocomplete your way to success, identify type errors before your users do, drill into blockchain errors [at compile and runtimes](/core/guides/error-handling) with surgical precision, and much more. + +The API documentation is comprehensive and contains usage info for _every_ module in Wagmi Core. The core team uses a [documentation](https://gist.github.com/zsup/9434452) and [test driven](https://en.wikipedia.org/wiki/Test-driven_development#:~:text=Test%2Ddriven%20development%20(TDD),software%20against%20all%20test%20cases.) development approach to building modules, which leads to predictable and stable APIs. + +## Performance + +Performance is critical for applications on all sizes. Slow page load and interactions can cause users to stop using applications. Wagmi Core uses and is built by the same team behind [Viem](https://viem.sh), the most performant production-ready Ethereum library. + +End users should not be required to download a module of over 100kB in order to interact with Ethereum. Wagmi Core is optimized for tree-shaking and dead-code elimination, allowing apps to minimize bundle size for fast page load times. + +Data layer performance is also critical. Slow, unnecessary, and manual data fetching can make apps unusable and cost thousands in RPC compute units. Wagmi Core supports caching, deduplication, persistence, and much more through [TanStack Query](/react/guides/tanstack-query) via the `'@wagmi/core/query'` entrypoint so you can [plug it into your framework](/core/guides/framework-adapters) of choice, like Vue, Svelte, and more. + +## Feature Coverage + +Wagmi Core supports the most popular and commonly-used Ethereum features out of the box with 40+ VanillaJS Actions for accounts, wallets, contracts, transactions, signing, ENS, and more. Wagmi Core also supports just about any wallet out there through its official [connectors](/core/api/connectors), [EIP-6963 support](/core/api/createConfig#multiinjectedproviderdiscovery), and [extensible API](/dev/creating-connectors). + +If you need lower-level control, you can always drop down to [Viem](https://viem.sh), which Wagmi Core uses internally to perform blockchain operations. Wagmi Core also manages multi-chain support automatically so developers can focus on their applications instead of adding custom code. + +Finally, Wagmi Core has a [CLI](/cli/getting-started) to manage ABIs as well as a robust ecosystem of third-party libraries, like [ConnectKit](https://docs.family.co/connectkit), [RainbowKit](https://www.rainbowkit.com), [AppKit](https://walletconnect.com/appkit), [Dynamic](https://www.dynamic.xyz), [Privy](https://privy.io), and many more, so you can get started quickly without needing to build everything from scratch. + +## Stability + +Stability is a fundamental principle for Wagmi Core. Many organizations, large and small, rely heavily on Wagmi Core and expect it to be entirely stable for their users and applications. + +Wagmi Core's test suite runs against forked Ethereum nodes to make sure functions work across chains. The test suite also runs type tests against many different versions of peer dependencies, like TypeScript, to ensure compatibility with the latest releases of other popular software. + +Wagmi Core follows semver so developers can upgrade between versions with confidence. Starting with Wagmi Core v2, new functionality will be opt-in with old functionality being deprecated alongside the new features. This means upgrading to the latest major versions will not require immediate changes. + +Lastly, the core team works full-time on Wagmi Core and [related projects](https://github.com/wevm), and is constantly improving Wagmi Core and keeping it up-to-date with industry trends and changes. + diff --git a/wagmi-project/site/dev/contributing.md b/wagmi-project/site/dev/contributing.md new file mode 100644 index 000000000..f5c0d8335 --- /dev/null +++ b/wagmi-project/site/dev/contributing.md @@ -0,0 +1,171 @@ + + +# Contributing + +Thanks for your interest in contributing to Wagmi! Please take a moment to review this document **before submitting a pull request.** + +## Overview + +This guide is intended to help you get started with contributing. By following these steps, you will understand the development process and workflow. If you want to contribute, but aren't sure where to start, you can create a [new discussion](https://github.com/wevm/wagmi/discussions/new/choose). + +:::warning +**Please ask first before starting work on any significant new features. This includes things like adding new hooks, actions, connectors, etc.** + +It's never a fun experience to have your pull request declined after investing time and effort into a new feature. To avoid this from happening, we request that contributors first create a [feature request](https://github.com/wevm/wagmi/discussions/new?category=ideas) to discuss any API changes or significant new ideas. +::: + +## 1. Cloning the repository + +To start contributing to the project, clone it to your local machine using git: + +```bash +git clone https://github.com/wevm/wagmi.git +``` + +Or the [GitHub CLI](https://cli.github.com): + +```bash +gh repo clone wevm/wagmi +``` + +## 2. Installing Node.js and pnpm + +Wagmi uses Node.js with [pnpm workspaces](https://pnpm.io/workspaces) to manage multiple projects. You can run the following command in your terminal to check your local Node.js version. + +```bash +node -v +``` + +If **`node@{{nodeVersion}}`** is not installed, you can install via [fnm](https://github.com/Schniz/fnm) or from the [official website](https://nodejs.org). + +Once Node.js is installed, run the following to install [Corepack](https://nodejs.org/api/corepack.html). Corepack automatically installs and manages **`{{packageManager}}`**. + +```bash +corepack enable +``` + +## 3. Installing dependencies + +Once in the project's root directory, run the following command to install pnpm (via Corepack) and the project's dependencies: + +```bash +pnpm install +``` + +After the install completes, pnpm links packages across the project for development and [git hooks](https://github.com/toplenboren/simple-git-hooks) are set up. + +## 4. Adding the env variables + +The [dev playgrounds](#_5-running-the-dev-playgrounds) and [test suite](#_6-running-the-test-suite) require environment variables to be set. Copy over the following environment variables to `.env`, and fill them out. + +```bash +VITE_MAINNET_FORK_URL=https://eth.merkle.io +VITE_OPTIMISM_FORK_URL=https://mainnet.optimism.io + +NEXT_PUBLIC_WC_PROJECT_ID=3fbb6bba6f1de962d911bb5b5c9dba88 +NUXT_PUBLIC_WC_PROJECT_ID=3fbb6bba6f1de962d911bb5b5c9dba88 +VITE_WC_PROJECT_ID=3fbb6bba6f1de962d911bb5b5c9dba88 + +NEXT_TELEMETRY_DISABLED=1 +NUXT_TELEMETRY_DISABLED=1 +``` + +You might want to change `*_FORK_URL` to a paid RPC provider for better performance. + +## 5. Running the dev playgrounds + +To start the local development playgrounds, run one of the following commands. These commands run playground apps, located at `./playgrounds`, that are set up for trying out code while making changes. + +```bash +pnpm dev # `wagmi` playground +pnpm dev:core # `@wagmi/core` playground +pnpm dev:create-wagmi # `create-wagmi` cli tool +pnpm dev:cli # `@wagmi/cli` tool +pnpm dev:next # `wagmi` playground with Next.js +pnpm dev:nuxt # `@wagmi/vue` playground with Nuxt.js +pnpm dev:react # `wagmi` playground (same as `pnpm dev`) +pnpm dev:vue # `@wagmi/vue` playground +``` + +Once a playground dev server is running, you can make changes to any of the package source files (e.g. `packages/react`) and it will automatically update the playground. + +## 6. Running the test suite + +Wagmi uses [Vitest](https://vitest.dev) to run tests and [Prool](https://github.com/wevm/prool) to execute tests against locally running chain forks. First, install [Anvil](https://github.com/foundry-rs/foundry/tree/master/crates/anvil) via [Foundryup](https://book.getfoundry.sh/getting-started/installation). + +```bash +curl -L https://foundry.paradigm.xyz | bash +foundryup +``` + +Next, make sure you have set up your [env variables](#_4-adding-the-env-variables). Now you are ready to run the tests! You have the following options for running tests: + +- `pnpm test [package?]` — runs tests in watch mode +- `pnpm test:cov` — runs tests and reports coverage +- `pnpm test:core` — runs `@wagmi/core` tests +- `pnpm test:react` — runs `wagmi` tests +- `pnpm test:vue` — runs `@wagmi/vue` tests + +When adding new features or fixing bugs, it's important to add test cases to cover the new or updated behavior. If snapshot tests fail, you can run the `test:update` command to update the snapshots. + +## 7. Writing documentation + +Documentation is crucial to helping developers of all experience levels use Wagmi. Wagmi uses [VitePress](https://vitepress.dev) for the documentation site (located at `./site`). To start the site in dev mode, run: + +```bash +pnpm docs:dev +``` + +Try to keep documentation brief and use plain language so folks of all experience levels can understand. If you think something is unclear or could be explained better, you are welcome to open a pull request. + +## 8. Submitting a pull request + +When you're ready to submit a pull request, you can follow these naming conventions: + +- Pull request titles use the [Imperative Mood](https://en.wikipedia.org/wiki/Imperative_mood) (e.g., `Add something`, `Fix something`). +- [Changesets](#versioning) use past tense verbs (e.g., `Added something`, `Fixed something`). + +When you submit a pull request, GitHub will automatically lint, build, and test your changes. If you see an ❌, it's most likely a bug in your code. Please, inspect the logs through the GitHub UI to find the cause. + +**Please make sure that "Allow edits from maintainers" is enabled so the core team can make updates to your pull request if necessary.** + +## 9. Versioning + +When adding new features or fixing bugs, we'll need to bump the package versions. We use [Changesets](https://github.com/changesets/changesets) to do this. + +::: tip +Only changes to the codebase that affect the public API or existing behavior (e.g. bugs) need changesets. +::: + +Each changeset defines which packages should be published and whether the change should be a major/minor/patch release, as well as providing release notes that will be added to the changelog upon release. + +To create a new changeset, run `pnpm changeset`. This will run the Changesets CLI, prompting you for details about the change. You’ll be able to edit the file after it’s created — don’t worry about getting everything perfect up front. + +Even though you can technically use any markdown formatting you like, headings should be avoided since each changeset will ultimately be nested within a bullet list. Instead, bold text should be used as section headings. + +If your PR is making changes to an area that already has a changeset (e.g. there’s an existing changeset covering theme API changes but you’re making further changes to the same API), you should update the existing changeset in your PR rather than creating a new one. + +### Releasing to npm + +The first time a PR with a changeset is merged after a release, a new PR will automatically be created called `chore: version packages`. Any subsequent PRs with changesets will automatically update this existing version packages PR. Merging this PR triggers the release process by publishing to npm and cleaning up the changeset files. + +### Creating a snapshot release + +If a PR has changesets, you can create a [snapshot release](https://github.com/changesets/changesets/blob/main/docs/snapshot-releases.md) by [manually dispatching](https://github.com/wevm/wagmi/actions/workflows/canary.yml) the Canary workflow. This publishes a tagged version to npm with the PR branch name and timestamp. + +## 10. Updating dependencies + +Use [Taze](https://github.com/antfu/taze) by running: + +```bash +pnpm deps # prints outdated deps +pnpm deps patch # print outdated deps with new patch versions +pnpm deps -w # updates deps (best done with clean working tree) +``` + +[Socket](https://socket.dev) checks pull requests for vulnerabilities when new dependencies and versions are added, but you should also be vigilant! When updating dependencies, you should check release notes and source code as well as lock versions when possible. diff --git a/wagmi-project/site/dev/creating-connectors.md b/wagmi-project/site/dev/creating-connectors.md new file mode 100644 index 000000000..c9e82b04b --- /dev/null +++ b/wagmi-project/site/dev/creating-connectors.md @@ -0,0 +1,155 @@ +# Creating Connectors + +Thanks for your interest in adding a new connector to Wagmi! Please take a moment to review this document **before starting work on a new connector.** + +## Overview + +This guide details how to create new connectors and upstream them back into Wagmi. By following these steps, you will understand the development process, workflow, and requirements for new connectors. **Not all connectors will be accepted into Wagmi** for a variety of reasons outlined in this document. + +In addition, for connector requests to be accepted, the team creating the connector must [sponsor Wagmi](https://github.com/sponsors/wevm). It takes time and effort to maintain third-party connectors. Wagmi is an OSS project that depends on sponsors and grants to continue our work. Please get in touch via [dev@wevm.dev](mailto:dev@wevm.dev) if you have questions about sponsoring. + +::: warning **Please ask first before starting work on a new connector.** +To avoid having your pull request declined after investing time and effort into a new connector, we ask that contributors create a [Connector Request](https://github.com/wevm/wagmi/discussions/new?category=connector-request) before starting work. This ensures the connector solves for an important or general use-case of interest to Wagmi users and is well supported by the Wagmi and connector teams. +::: + +## 1. Follow the contributing guide + +Check out the [Contributing Guide](/dev/contributing) to get your local development environment set up and learn more about the contributing workflow. + +## 2. Create a new file for the connector + +Create a new file in `packages/connector/src` named after the connector you want to add. + +For example, if you want to add Foo, you would create a file named `foo.ts`. File names should be camel-cased and as short as possible. + +## 3. Create the connector object. + +Import `createConnector` from `@wagmi/core` and export a new function that accepts a parameters object and returns the `createConnector` result. This is the base of all connectors. The name of the connector name should be the same as the file name. + +```ts +import { createConnector } from '@wagmi/core' + +export type FooBarBazParameters = {} + +export function fooBarBaz(parameters: FooBarBazParameters = {}) { + return createConnector((config) => ({})) +} +``` + +## 4. Add the missing properties to the object + +Now that the base of the connector is set up, you should see a type error that looks something like this: + +```ts twoslash +// @errors: 2740 +import { createConnector } from '@wagmi/core' +// ---cut--- +createConnector((config) => ({})) +``` + +The type error tells you what properties are missing from `createConnector`'s return type. Add them all in! + +#### Properties + +- `icon`: Optional icon URL for the connector. +- `id`: The ID for the connector. This should be camel-cased and as short as possible. Example: `fooBarBaz`. +- `name`: Human-readable name for the connector. Example: `'Foo Bar Baz'`. +- `rdns`: Optional reverse DNS for the connector. This is used to filter out duplicate [EIP-6963](https://eips.ethereum.org/EIPS/eip-6963) injected providers when `createConfig#multiInjectedProviderDiscovery` is enabled. + +#### Methods + +- `connect`: Function for connecting the connector. +- `disconnect`: Function for disconnecting the connector. +- `getAccounts`: Function that returns the connected accounts for the connector. +- `getChainId`: Function that returns the connected chain ID for the connector. +- `getProvider`: Function that returns the underlying provider interface for internal use throughout the connector. +- `isAuthorized`: Function that returns whether the connector has connected previously and is still authorized. +- `setup`: Optional function for running when the connector is first created. +- `switchChain`: Optional function for switching the connector's active chain. + +#### Events + +- `onAccountsChanged`: Function for subscribing to account changes internally in the connector. +- `onChainChanged`: Function for subscribing to chain changes internally in the connector. +- `onConnect`: Function for subscribing to connection events internally in the connector. +- `onDisconnect`: Function for subscribing to disconnection events internally in the connector. +- `onMessage`: Optional function for subscribing to messages internally in the connector. + +#### Parameters + +`createConnector` also has the following config properties you can use within the connector: + +- `chains`: List of chains configured by the user. +- `emitter`: Emitter for emitting events. Used to sync connector state with Wagmi `Config`. The following events are available: + - `change`: Emitted when the connected accounts or chain changes. + - `connect`: Emitted when the connector connects. + - `disconnect`: Emitted when the connector disconnects. + - `error`: Emitted when the connector receives an error. + - `message`: Emitted when the connector receives a message. +- `storage`: Optional storage configured by the user. Defaults to wrapper around localStorage. + +::: tip +If you plan to use a third-party SDK, it should have minimal dependencies (limit bundle size, supply chain attacks, etc.) and use the most permissive license possible (ideally MIT). Any third-party packages, should also have [`"sideEffects": false`](https://webpack.js.org/guides/tree-shaking/#mark-the-file-as-side-effect-free) in their `package.json` file for maximum tree-shakability support. +::: + +::: tip +All address values returned and emitted by the connector should be checksummed using Viem's [`getAddress`](https://viem.sh/docs/utilities/getAddress). +::: + +## 5. Export the connector + +Export the connector from `packages/connector/src/exports/index.ts` in alphabetic order. + +```ts +export { fooBarBaz } from './fooBarBaz.js' +``` + +## 6. Try out the connector and add tests + +While building a connector, it can be useful to try it out with Wagmi. You can use the [development playgrounds](/dev/contributing#_5-running-the-dev-playgrounds) for testing your changes. + +Ideally, you should also be able to add tests for the connector in a `connectorName.test.ts` file. This isn't always easy so at a minimum please create a test file with instructions for how to test the connector manually. The test file should include actual tests or "instruction tests" for the following: + +- How to connect the connector. +- How to disconnect the connector. +- How to switch the connector's active chain (if applicable). + +Remember to include all info required to test the connector, like software to install (browser extension, mobile app, etc.), smart contracts to interact with/deploy, etc. + +Finally, you should also update the test file in `packages/connectors/src/exports/index.test.ts` to include the new connector. You can do this manually or by running: + +```bash +pnpm test:update packages/connectors/src/exports/index.test.ts +``` + +## 7. Add your team to CODEOWNERS + +It is critical that connectors are updated in a timely manner and actively maintained so that users of Wagmi can rely on them in production settings. + +The Wagmi core team will provide as much assistance as possible to keep connectors up-to-date with breaking changes from Wagmi, but it is your responsibility to ensure that any dependencies and issues/discussions related to the connector are handled in a timely manner. If issues are not resolved in a timely manner, the connector may be removed from Wagmi. + +In support of this goal, add at least one member of your team to the [CODEOWNERS](https://github.com/wevm/wagmi/blob/main/.github/CODEOWNERS) file so that you get notified of pull requests, issues, etc. related to the connector. You can add your team like this: + +``` +/packages/connectors/src/fooBarBaz @tmm @jxom +``` + +For more info about GitHub code owners, check out the [GitHub Documentation](https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners). + +## 8. Document the connector + +The connector should be documented. Follow the step on [writing documentation](/dev/contributing#_7-writing-documentation) to get set up with running the docs site locally and add the required pages. + +## 9. Create a changeset + +Now that the connector works and has tests, it's time to create a changeset to prepare for release. Run the following to create a changeset: + +```bash +pnpm changeset +``` + +The changeset should be a `patch` applied to the `@wagmi/connectors` repository with the description `Added [ConnectorName]`, For example, `Added Foo Bar Baz`. + +## 10. Create a pull request + +The connector is ready to go! Create a [pull request](/dev/contributing#_8-submitting-a-pull-request) and the connector should make it into a future release of Wagmi after some review. diff --git a/wagmi-project/site/index.md b/wagmi-project/site/index.md new file mode 100644 index 000000000..23b40a7f1 --- /dev/null +++ b/wagmi-project/site/index.md @@ -0,0 +1,58 @@ +--- +# https://vitepress.dev/reference/default-theme-home-page +layout: home + +description: Type Safe, Extensible, and Modular by design. Build high-performance blockchain frontends. +title: 'Wagmi | Reactivity for Ethereum apps' +titleTemplate: false + +hero: + name: Wagmi + text: Reactivity for Ethereum apps + tagline: Type Safe, Extensible, and Modular by design. Build high-performance blockchain frontends. + actions: + - theme: brand + text: Get Started + link: /react/getting-started + - theme: alt + text: Why Wagmi + link: /react/why + - theme: alt + text: View on GitHub + link: https://github.com/wevm/wagmi + image: + src: /logo-dark.svg + alt: Wagmi Logo + +features: + - icon: 🚀 + title: 20+ React Hooks + details: React Hooks for accounts, wallets, contracts, transactions, signing, ENS, and more. + link: /react/api/hooks + linkText: See all hooks + - icon: 🦄 + title: TypeScript Ready + details: Infer types from ABIs and EIP-712 Typed Data and autocomplete your way to productivity. + link: /react/typescript + linkText: Learn about TypeScript support + - icon: 💼 + title: Connect Wallet + details: Official connectors for MetaMask, EIP-6963, WalletConnect, Coinbase Wallet, and more. + link: /react/api/connectors + linkText: See all connectors + - icon: 👟 + title: Caching. Deduplication. Persistence. + details: Built-in caching, deduplication, persistence powered by TanStack Query. + link: /react/guides/tanstack-query + linkText: How to use TanStack Query + - icon: 🌳 + title: Modular By Design + details: Don't use React or Vue? Use VanillaJS or build an adapter for your favorite framework. + link: /core/getting-started + linkText: Learn about Wagmi Core + - icon: ✌️ + title: Built on Viem + details: The modern, low-level TypeScript interface for Ethereum that performs blockchain operations. + link: https://viem.sh + linkText: Check out Viem +--- diff --git a/wagmi-project/site/package.json b/wagmi-project/site/package.json new file mode 100644 index 000000000..3bdbb9ba8 --- /dev/null +++ b/wagmi-project/site/package.json @@ -0,0 +1,28 @@ +{ + "name": "site", + "private": true, + "type": "module", + "scripts": { + "dev": "vitepress dev", + "build": "vitepress build", + "preview": "vitepress preview" + }, + "devDependencies": { + "@shikijs/vitepress-twoslash": "1.22.2", + "@tanstack/query-core": "catalog:", + "@tanstack/react-query": "catalog:", + "@tanstack/vue-query": "catalog:", + "@types/react": "catalog:", + "@wagmi/connectors": "workspace:*", + "@wagmi/core": "workspace:*", + "@wagmi/vue": "workspace:*", + "abitype": "*", + "nuxt": "^3.16.0", + "react": "catalog:", + "unocss": "^0.59.4", + "viem": "2.*", + "vitepress": "1.5.0", + "vue": "catalog:", + "wagmi": "workspace:*" + } +} diff --git a/wagmi-project/site/public/browsers/chrome.png b/wagmi-project/site/public/browsers/chrome.png new file mode 100644 index 0000000000000000000000000000000000000000..3024356395b717fe191f1110247c05cf06625927 GIT binary patch literal 12226 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 literal 0 HcmV?d00001 diff --git a/wagmi-project/site/public/browsers/edge.png b/wagmi-project/site/public/browsers/edge.png new file mode 100644 index 0000000000000000000000000000000000000000..931cb1c1bf7ffb570c33c03853f0ba9432d86eb0 GIT binary patch literal 11311 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 literal 0 HcmV?d00001 diff --git a/wagmi-project/site/public/favicon.svg b/wagmi-project/site/public/favicon.svg new file mode 100644 index 000000000..48c440d66 --- /dev/null +++ b/wagmi-project/site/public/favicon.svg @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/wagmi-project/site/public/logo-dark.svg b/wagmi-project/site/public/logo-dark.svg new file mode 100644 index 000000000..df0c2945c --- /dev/null +++ b/wagmi-project/site/public/logo-dark.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/wagmi-project/site/public/logo-light.svg b/wagmi-project/site/public/logo-light.svg new file mode 100644 index 000000000..cc571bc09 --- /dev/null +++ b/wagmi-project/site/public/logo-light.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/wagmi-project/site/public/og.png b/wagmi-project/site/public/og.png new file mode 100644 index 0000000000000000000000000000000000000000..8b3a05f55661601dcfe2a02f694c9f2ff66a23d9 GIT binary patch literal 12491 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 RWjyv_Zf5;Qm8tvf{|80@3k3iG literal 0 HcmV?d00001 diff --git a/wagmi-project/site/react/api/WagmiProvider.md b/wagmi-project/site/react/api/WagmiProvider.md new file mode 100644 index 000000000..7330f4569 --- /dev/null +++ b/wagmi-project/site/react/api/WagmiProvider.md @@ -0,0 +1,112 @@ +# WagmiProvider + +React Context Provider for Wagmi. + +## Import + +```ts +import { WagmiProvider } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [app.tsx] +import { WagmiProvider } from 'wagmi' +import { config } from './config' + +function App() { + return ( + + {/** ... */} + + ) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type WagmiProviderProps } from 'wagmi' +``` + +### config + +[`Config`](/react/api/createConfig#config) object to inject with context. + +::: code-group +```tsx [app.tsx] +import { WagmiProvider } from 'wagmi' +import { config } from './config' + +function App() { + return ( + + {/** ... */} + + ) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### initialState + +`State | undefined` + +- Initial state to hydrate into the [Wagmi Config](/react/api/createConfig). Useful for SSR. + +::: code-group +```tsx [app.tsx] +import { WagmiProvider } from 'wagmi' +import { config } from './config' + +function App() { + return ( + + {/** ... */} + + ) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### reconnectOnMount + +`boolean | undefined` + +- Whether or not to reconnect previously connected [connectors](/react/api/createConfig#connectors) on mount. +- Defaults to `true`. + +::: code-group +```tsx [app.tsx] +import { WagmiProvider } from 'wagmi' +import { config } from './config' + +function App() { + return ( + + {/** ... */} + + ) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Context + +```ts +import { type WagmiContext } from 'wagmi' +``` diff --git a/wagmi-project/site/react/api/actions.md b/wagmi-project/site/react/api/actions.md new file mode 100644 index 000000000..af367bb02 --- /dev/null +++ b/wagmi-project/site/react/api/actions.md @@ -0,0 +1,28 @@ +# Actions + +Sometimes the declarative nature of React Hooks doesn't work for parts of your app. For those cases, you can use Wagmi Core Actions directly! + +All the Wagmi Core Actions are importable using the `wagmi/actions` entrypoint. For example, you can use the `watchBlockNumber` action to watch for block number changes. + +::: code-group +```ts [index.tsx] +import { useConfig } from 'wagmi' +import { watchBlockNumber } from 'wagmi/actions' +import { useEffect } from 'react' + +function App() { + const config = useConfig() + + useEffect(() => { + return watchBlockNumber(config, { + onBlockNumber(blockNumber) { + console.log('Block number changed!', blockNumber) + }, + }) + }, []) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +See the [Wagmi Core docs](/core/api/actions) for more info on what actions are available. diff --git a/wagmi-project/site/react/api/chains.md b/wagmi-project/site/react/api/chains.md new file mode 100644 index 000000000..4a7e60044 --- /dev/null +++ b/wagmi-project/site/react/api/chains.md @@ -0,0 +1,26 @@ + + +# Chains + +Viem `Chain` objects. More info at the [Viem docs](https://viem.sh/docs/chains/introduction). + +## Import + +Import via the `'wagmi/chains'` entrypoint (proxies all chains from `'viem/chains'`). + +```ts +import { mainnet } from 'wagmi/chains' +``` + +## Available Chains + +Chain definitions as of `viem@{{viemVersion}}`. For `viem@latest`, visit the [Viem repo](https://github.com/wevm/viem/blob/main/src/chains/index.ts). + + + + diff --git a/wagmi-project/site/react/api/connectors.md b/wagmi-project/site/react/api/connectors.md new file mode 100644 index 000000000..49096a164 --- /dev/null +++ b/wagmi-project/site/react/api/connectors.md @@ -0,0 +1,28 @@ + + +# Connectors + +Connectors for popular wallet providers and protocols. + +## Import + +Import via the `'wagmi/connectors'` entrypoint. + +```ts +import { injected } from 'wagmi/connectors' +``` + +## Available Connectors + + diff --git a/wagmi-project/site/react/api/connectors/coinbaseWallet.md b/wagmi-project/site/react/api/connectors/coinbaseWallet.md new file mode 100644 index 000000000..b8597b11a --- /dev/null +++ b/wagmi-project/site/react/api/connectors/coinbaseWallet.md @@ -0,0 +1,6 @@ + + + \ No newline at end of file diff --git a/wagmi-project/site/react/api/connectors/injected.md b/wagmi-project/site/react/api/connectors/injected.md new file mode 100644 index 000000000..56573881f --- /dev/null +++ b/wagmi-project/site/react/api/connectors/injected.md @@ -0,0 +1,7 @@ + + + diff --git a/wagmi-project/site/react/api/connectors/metaMask.md b/wagmi-project/site/react/api/connectors/metaMask.md new file mode 100644 index 000000000..e16d84903 --- /dev/null +++ b/wagmi-project/site/react/api/connectors/metaMask.md @@ -0,0 +1,7 @@ + + + diff --git a/wagmi-project/site/react/api/connectors/mock.md b/wagmi-project/site/react/api/connectors/mock.md new file mode 100644 index 000000000..3a111297a --- /dev/null +++ b/wagmi-project/site/react/api/connectors/mock.md @@ -0,0 +1,6 @@ + + + diff --git a/wagmi-project/site/react/api/connectors/safe.md b/wagmi-project/site/react/api/connectors/safe.md new file mode 100644 index 000000000..375ddb7b2 --- /dev/null +++ b/wagmi-project/site/react/api/connectors/safe.md @@ -0,0 +1,6 @@ + + + diff --git a/wagmi-project/site/react/api/connectors/walletConnect.md b/wagmi-project/site/react/api/connectors/walletConnect.md new file mode 100644 index 000000000..3e1a4a5c2 --- /dev/null +++ b/wagmi-project/site/react/api/connectors/walletConnect.md @@ -0,0 +1,6 @@ + + + diff --git a/wagmi-project/site/react/api/createConfig.md b/wagmi-project/site/react/api/createConfig.md new file mode 100644 index 000000000..f42bec253 --- /dev/null +++ b/wagmi-project/site/react/api/createConfig.md @@ -0,0 +1,7 @@ + + + diff --git a/wagmi-project/site/react/api/createStorage.md b/wagmi-project/site/react/api/createStorage.md new file mode 100644 index 000000000..738e998f0 --- /dev/null +++ b/wagmi-project/site/react/api/createStorage.md @@ -0,0 +1,6 @@ + + + diff --git a/wagmi-project/site/react/api/errors.md b/wagmi-project/site/react/api/errors.md new file mode 100644 index 000000000..d431a6c4f --- /dev/null +++ b/wagmi-project/site/react/api/errors.md @@ -0,0 +1,20 @@ + + +# Errors + +Error classes used by Wagmi. + + + +## React + +### WagmiProviderNotFoundError + +When a Wagmi hook is used outside of a [`WagmiProvider`](/react/api/WagmiProvider). + +```ts +import { WagmiProviderNotFoundError } from 'wagmi' +``` \ No newline at end of file diff --git a/wagmi-project/site/react/api/hooks.md b/wagmi-project/site/react/api/hooks.md new file mode 100644 index 000000000..9d8a65c71 --- /dev/null +++ b/wagmi-project/site/react/api/hooks.md @@ -0,0 +1,25 @@ + + +# Hooks + +React Hooks for accounts, wallets, contracts, transactions, signing, ENS, and more. + +## Import + +```ts +import { useAccount } from 'wagmi' +``` + +## Available Hooks + + diff --git a/wagmi-project/site/react/api/hooks/useAccount.md b/wagmi-project/site/react/api/hooks/useAccount.md new file mode 100644 index 000000000..d5b9e2964 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useAccount.md @@ -0,0 +1,65 @@ +--- +title: useAccount +description: Hook for getting current account. +--- + +# useAccount + +Hook for getting current account. + +## Import + +```ts +import { useAccount } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useAccount } from 'wagmi' + +function App() { + const account = useAccount() +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseAccountParameters } from 'wagmi' +``` + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useAccount } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const account = useAccount({ + config, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type UseAccountReturnType } from 'wagmi' +``` + + + +## Action + +- [`getAccount`](/core/api/actions/getAccount) diff --git a/wagmi-project/site/react/api/hooks/useAccountEffect.md b/wagmi-project/site/react/api/hooks/useAccountEffect.md new file mode 100644 index 000000000..6636f4bba --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useAccountEffect.md @@ -0,0 +1,113 @@ +--- +title: useAccountEffect +description: Hook for listening to account lifecycle events. +--- + +# useAccountEffect + +Hook for listening to account lifecycle events. + +## Import + +```ts +import { useAccountEffect } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useAccountEffect } from 'wagmi' + +function App() { + useAccountEffect({ + onConnect(data) { + console.log('Connected!', data) + }, + onDisconnect() { + console.log('Disconnected!') + }, + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseAccountEffectParameters } from 'wagmi' +``` + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useAccountEffect } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + useAccountEffect({ + config, // [!code focus] + onConnect(data) { + console.log('Connected!', data) + }, + onDisconnect() { + console.log('Disconnected!') + }, + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### onConnect + +`` ((data: { address: `0x${string}`; addresses: readonly [`0x${string}`, ...`0x${string}`[]]; chain: Chain | undefined chainId: number; connector: Connector; isReconnected: boolean }) => void) | undefined `` + +Callback that is called when accounts are connected. + +::: code-group +```tsx [index.tsx] +import { useAccountEffect } from 'wagmi' + +function App() { + useAccountEffect({ + onConnect(data) { // [!code focus] + console.log('Connected!', data) // [!code focus] + }, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### onDisconnect + +`(() => void) | undefined` + +Callback that is called when no more accounts are connected. + +::: code-group +```tsx [index.tsx] +import { useAccountEffect } from 'wagmi' + +function App() { + useAccountEffect({ + onDisconnect() { // [!code focus] + console.log('Disconnected!') // [!code focus] + }, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Action + +- [`getAccount`](/core/api/actions/getAccount) +- [`watchAccount`](/core/api/actions/watchAccount) diff --git a/wagmi-project/site/react/api/hooks/useBalance.md b/wagmi-project/site/react/api/hooks/useBalance.md new file mode 100644 index 000000000..deddbb720 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useBalance.md @@ -0,0 +1,226 @@ +--- +title: useBalance +description: Hook for fetching native currency or token balance. +--- + + + +# useBalance + +Hook for fetching native currency or token balance. + +## Import + +```ts +import { useBalance } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useBalance } from 'wagmi' + +function App() { + const result = useBalance({ + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseBalanceParameters } from 'wagmi' +``` + +### address + +`Address | undefined` + +Address to get balance for. [`enabled`](#enabled) set to `false` if `address` is `undefined`. + +::: code-group +```tsx [index.tsx] +import { useBalance } from 'wagmi' +import { mainnet } from 'wagmi/chains' + +function App() { + const result = useBalance({ + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +--- + +### blockNumber + +`bigint | undefined` + +Block number to get balance at. + +::: code-group +```ts [index.ts] +import { useBalance } from 'wagmi' + +function App() { + const result = useBalance({ + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', + blockNumber: 17829139n, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Block tag to get balance at. + +::: code-group +```ts [index.ts] +import { useBalance } from 'wagmi' + +function App() { + const result = useBalance({ + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', + blockTag: 'latest', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +--- + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```tsx [index.tsx] +import { useBalance } from 'wagmi' +import { mainnet } from 'wagmi/chains' // [!code focus] + +function App() { + const result = useBalance({ + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', + chainId: mainnet.id, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useBalance } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useBalance({ + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', + config, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Hooks that have identical context will share the same cache. + +::: code-group +```tsx [index.tsx] +import { useBalance } from 'wagmi' + +function App() { + const result = useBalance({ + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', + scopeKey: 'foo', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### token [deprecated](/react/guides/migrate-from-v1-to-v2#deprecated-usebalance-token-parameter) + +`Address | undefined` + +ERC-20 token address to get balance for. + +::: code-group +```ts [index.ts] +import { useBalance } from 'wagmi' + +function App() { + const result = useBalance({ + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', + token: '0x6B175474E89094C44Da98b954EedeAC495271d0F', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### unit [deprecated](/react/guides/migrate-from-v1-to-v2#deprecated-usebalance-unit-parameter-and-formatted-return-value) + +`'ether' | 'gwei' | 'wei' | number | undefined` + +- Units to use when formatting result. +- Defaults to `'ether'`. + +::: code-group +```ts [index.ts] +import { useBalance } from 'wagmi' + +function App() { + const result = useBalance({ + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', + unit: 'ether', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseBalanceReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`getBalance`](/core/api/actions/getBalance) diff --git a/wagmi-project/site/react/api/hooks/useBlock.md b/wagmi-project/site/react/api/hooks/useBlock.md new file mode 100644 index 000000000..f0962ee4c --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useBlock.md @@ -0,0 +1,227 @@ +--- +title: useBlock +description: Hook for fetching information about a block at a block number, hash or tag. +--- + + + +# useBlock + +Hook for fetching information about a block at a block number, hash or tag. + +## Import + +```ts +import { useBlock } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useBlock } from 'wagmi' + +function App() { + const result = useBlock() +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseBlockParameters } from 'wagmi' +``` + +### blockHash + +`` `0x${string}` `` + +Information at a given block hash. + +::: code-group +```tsx [index.tsx] +import { useBlock } from 'wagmi' + +function App() { + const result = useBlock({ + blockHash: '0x89644bbd5c8d682a2e9611170e6c1f02573d866d286f006cbf517eec7254ec2d' // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### blockNumber + +`` bigint `` + +Information at a given block number. + +::: code-group +```tsx [index.tsx] +import { useBlock } from 'wagmi' + +function App() { + const result = useBlock({ + blockNumber: 42069n // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### blockTag + +`` 'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' `` + +Information at a given block tag. Defaults to `'latest'`. + +::: code-group +```tsx [index.tsx] +import { useBlock } from 'wagmi' + +function App() { + const result = useBlock({ + blockTag: 'pending' // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```tsx [index.tsx] +import { useBlock } from 'wagmi' +import { mainnet } from 'wagmi/chains' // [!code focus] + +function App() { + const result = useBlock({ + chainId: mainnet.id, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useBlock } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useBlock({ + config, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### includeTransactions + +`boolean` + +Whether or not to include transactions as objects. + +::: code-group +```tsx [index.tsx] +import { useBlock } from 'wagmi' +import { config } from './config' + +function App() { + const result = useBlock({ + includeTransactions: true // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Hooks that have identical context will share the same cache. + +::: code-group +```tsx [index.tsx] +import { useBlock } from 'wagmi' +import { config } from './config' + +function App() { + const result = useBlock({ + scopeKey: 'foo' // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### watch + +`boolean | UseWatchBlockParameters | undefined` + +- Enables/disables listening for block changes. +- Can pass a subset of [`UseWatchBlocksParameters`](/react/api/hooks/useWatchBlocks#parameters) directly to [`useWatchBlocks`](/react/api/hooks/useWatchBlocks). + +::: code-group +```tsx [index.tsx] +import { useBlock } from 'wagmi' + +function App() { + const result = useBlock({ + watch: true, // [!code focus] + }) +} +``` + +```tsx [index-2.tsx] +import { useBlock } from 'wagmi' + +function App() { + const result = useBlock({ + watch: { // [!code focus] + pollingInterval: 4_000, // [!code focus] + }, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseBlockReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`getBlock`](/core/api/actions/getBlock) +- [`watchBlockNumber`](/core/api/actions/watchBlockNumber) diff --git a/wagmi-project/site/react/api/hooks/useBlockNumber.md b/wagmi-project/site/react/api/hooks/useBlockNumber.md new file mode 100644 index 000000000..e0c6ff724 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useBlockNumber.md @@ -0,0 +1,169 @@ +--- +title: useBlockNumber +description: Hook for fetching the number of the most recent block seen. +--- + + + +# useBlockNumber + +Hook for fetching the number of the most recent block seen. + +## Import + +```ts +import { useBlockNumber } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useBlockNumber } from 'wagmi' + +function App() { + const result = useBlockNumber() +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseBlockNumberParameters } from 'wagmi' +``` + +### cacheTime + +`number | undefined` + +Time in milliseconds that cached block number will remain in memory. + +::: code-group +```tsx [index.tsx] +import { useBlockNumber } from 'wagmi' + +function App() { + const result = useBlockNumber({ + cacheTime: 4_000, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```tsx [index.tsx] +import { useBlockNumber } from 'wagmi' +import { mainnet } from 'wagmi/chains' // [!code focus] + +function App() { + const result = useBlockNumber({ + chainId: mainnet.id, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useBlockNumber } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useBlockNumber({ + config, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Hooks that have identical context will share the same cache. + +::: code-group +```tsx [index.tsx] +import { useBlockNumber } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useBlockNumber({ + scopeKey: 'foo', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### watch + +`boolean | UseWatchBlockNumberParameters | undefined` + +- Enables/disables listening for block number changes. +- Can pass a subset of [`UseWatchBlockNumberParameters`](/react/api/hooks/useWatchBlockNumber#parameters)directly to [`useWatchBlockNumber`](/react/api/hooks/useWatchBlockNumber). + +::: code-group +```tsx [index.tsx] +import { useBlockNumber } from 'wagmi' + +function App() { + const result = useBlockNumber({ + watch: true, // [!code focus] + }) +} +``` + +```tsx [index-2.tsx] +import { useBlockNumber } from 'wagmi' + +function App() { + const result = useBlockNumber({ + watch: { // [!code focus] + pollingInterval: 4_000, // [!code focus] + }, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseBlockNumberReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`getBlockNumber`](/core/api/actions/getBlockNumber) +- [`watchBlockNumber`](/core/api/actions/watchBlockNumber) diff --git a/wagmi-project/site/react/api/hooks/useBlockTransactionCount.md b/wagmi-project/site/react/api/hooks/useBlockTransactionCount.md new file mode 100644 index 000000000..80cb99de3 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useBlockTransactionCount.md @@ -0,0 +1,175 @@ +--- +title: useBlockTransactionCount +description: Hook for fetching the number of Transactions at a block number, hash or tag. +--- + + + +# useBlockTransactionCount + +Hook for fetching the number of Transactions at a block number, hash or tag. + +## Import + +```ts +import { useBlockTransactionCount } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useBlockTransactionCount } from 'wagmi' + +function App() { + const result = useBlockTransactionCount() +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseBlockTransactionCountParameters } from 'wagmi' +``` + +### blockHash + +`` `0x${string}` `` + +Transaction count at a given block hash. + +::: code-group +```tsx [index.tsx] +import { useBlock } from 'wagmi' + +function App() { + const result = useBlock({ + blockHash: '0x89644bbd5c8d682a2e9611170e6c1f02573d866d286f006cbf517eec7254ec2d' // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### blockNumber + +`` bigint `` + +Transaction count at a given block number. + +::: code-group +```tsx [index.tsx] +import { useBlock } from 'wagmi' + +function App() { + const result = useBlock({ + blockNumber: 42069n // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### blockTag + +`` 'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' `` + +Transaction count at a given block tag. Defaults to `'latest'`. + +::: code-group +```tsx [index.tsx] +import { useBlock } from 'wagmi' + +function App() { + const result = useBlock({ + blockTag: 'pending' // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```tsx [index.tsx] +import { useBlock } from 'wagmi' +import { mainnet } from 'wagmi/chains' // [!code focus] + +function App() { + const result = useBlock({ + chainId: mainnet.id, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useBlockTransactionCount } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useBlockTransactionCount({ + config, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Hooks that have identical context will share the same cache. + +::: code-group +```tsx [index.tsx] +import { useBlockTransactionCount } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useBlockTransactionCount({ + scopeKey: 'foo', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + + +## Return Type + +```ts +import { type UseBlockTransactionCountReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`getBlockTransactionCount`](/core/api/actions/getBlockTransactionCount) diff --git a/wagmi-project/site/react/api/hooks/useBytecode.md b/wagmi-project/site/react/api/hooks/useBytecode.md new file mode 100644 index 000000000..573cee32c --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useBytecode.md @@ -0,0 +1,181 @@ +--- +title: useBytecode +description: Hook for retrieving the bytecode at an address. +--- + + + +# useBytecode + +Hook for retrieving the bytecode at an address. + +## Import + +```ts +import { useBytecode } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useBytecode } from 'wagmi' + +function App() { + const result = useBytecode({ + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseBytecodeParameters } from 'wagmi' +``` + +### address + +`Address | undefined` + +The contract address. + +::: code-group +```tsx [index.tsx] +import { useBytecode } from 'wagmi' + +function App() { + const result = useBytecode({ + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### blockNumber + +`bigint | undefined` + +The block number to check the bytecode at. + +::: code-group +```tsx [index.tsx] +import { useBytecode } from 'wagmi' + +function App() { + const result = useBytecode({ + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + blockNumber: 16280770n, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +The block tag to check the bytecode at. + +::: code-group +```tsx [index.tsx] +import { useBytecode } from 'wagmi' + +function App() { + const result = useBytecode({ + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + blockTag: 'safe', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +The chain ID to check the bytecode at. + +::: code-group +```tsx [index.tsx] +import { useBytecode } from 'wagmi' +import { mainnet } from 'wagmi/chains' + +function App() { + const result = useBytecode({ + chainId: mainnet.id, // [!code focus] + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useBytecode } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useBytecode({ + config, // [!code focus] + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Hooks that have identical context will share the same cache. + +::: code-group +```tsx [index.tsx] +import { useBytecode } from 'wagmi' +import { config } from './config' + +function App() { + const result = useBytecode({ + scopeKey: 'foo' // [!code focus] + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseBytecodeReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`getBytecode`](/core/api/actions/getBytecode) diff --git a/wagmi-project/site/react/api/hooks/useCall.md b/wagmi-project/site/react/api/hooks/useCall.md new file mode 100644 index 000000000..9bc2250cf --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useCall.md @@ -0,0 +1,397 @@ +--- +title: useCall +description: Hook for executing a new message call immediately without submitting a transaction to the network. +--- + + + +# useCall + +Hook for executing a new message call immediately without submitting a transaction to the network. + +## Import + +```ts +import { useCall } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useCall } from 'wagmi' + +function App() { + const result = useCall({ + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseCallParameters } from 'wagmi' +``` + +### account + +`Account | Address | undefined` + +The Account to call from. + +::: code-group +```tsx [index.tsx] +import { useCall } from 'wagmi' + +function App() { + const result = useCall({ + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', // [!code focus] + data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### data + +`0x${string} | undefined` + +A contract hashed method call with encoded args. + +::: code-group +```tsx [index.tsx] +import { useCall } from 'wagmi' + +function App() { + const result = useCall({ + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', // [!code focus] + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### to + +`Address | undefined` + +The contract address or recipient. + +::: code-group +```tsx [index.tsx] +import { useCall } from 'wagmi' + +function App() { + const result = useCall({ + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### accessList + +`AccessList | undefined` + +The access list. + +::: code-group +```tsx [index.tsx] +import { useCall } from 'wagmi' + +function App() { + const result = useCall({ + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + accessList: [ // [!code focus:6] + { + address: '0x1', + storageKeys: ['0x1'], + }, + ], + data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### gas + +`bigint | undefined` + +The gas provided for transaction execution. + +::: code-group +```tsx [index.tsx] +import { useCall } from 'wagmi' + +function App() { + const result = useCall({ + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + gas: 1_000_000n, // [!code focus] + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### gasPrice + +`bigint | undefined` + +The price (in wei) to pay per gas. Only applies to [Legacy Transactions](https://viem.sh/docs/glossary/terms.html#legacy-transaction). + +::: code-group +```tsx [index.tsx] +import { useCall } from 'wagmi' + +function App() { + const result = useCall({ + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + gasPrice: parseGwei('20'), // [!code focus] + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### maxFeePerGas + +`bigint | undefined` + +Total fee per gas (in wei), inclusive of `maxPriorityFeePerGas`. Only applies to [EIP-1559 Transactions](https://viem.sh/docs/glossary/terms.html#eip-1559-transaction). + +::: code-group +```tsx [index.tsx] +import { useCall } from 'wagmi' + +function App() { + const result = useCall({ + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + maxFeePerGas: parseGwei('20'), // [!code focus] + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### maxPriorityFeePerGas + +`bigint | undefined` + +Max priority fee per gas (in wei). Only applies to [EIP-1559 Transactions](https://viem.sh/docs/glossary/terms.html#eip-1559-transaction). + +::: code-group +```tsx [index.tsx] +import { useCall } from 'wagmi' + +function App() { + const result = useCall({ + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + maxFeePerGas: parseGwei('20'), + maxPriorityFeePerGas: parseGwei('2'), // [!code focus] + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### nonce + +`number | undefined` + +Unique number identifying this transaction. + +::: code-group +```tsx [index.tsx] +import { useCall } from 'wagmi' + +function App() { + const result = useCall({ + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + nonce: 420, // [!code focus] + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### value + +`bigint | undefined` + +Value (in wei) sent with this transaction. + +::: code-group +```tsx [index.tsx] +import { useCall } from 'wagmi' + +function App() { + const result = useCall({ + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + value: parseEther('1'), // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### blockNumber + +`number | undefined` + +The block number to perform the call against. + +::: code-group +```tsx [index.tsx] +import { useCall } from 'wagmi' + +function App() { + const result = useCall({ + blockNumber: 15121123n, // [!code focus] + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +The block tag to perform the call against. + +::: code-group +```tsx [index.tsx] +import { useCall } from 'wagmi' + +function App() { + const result = useCall({ + blockTag: 'safe', // [!code focus] + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +The block tag to perform the call against. + +::: code-group +```tsx [index.tsx] +import { useCall } from 'wagmi' +import { mainnet } from '@wagmi/core/chains' + +function App() { + const result = useCall({ + chainId: mainnet.id, // [!code focus] + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useCall } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useCall({ + config, // [!code focus] + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Hooks that have identical context will share the same cache. + +::: code-group +```tsx [index.tsx] +import { useCall } from 'wagmi' +import { config } from './config' + +function App() { + const result = useCall({ + scopeKey: 'foo' // [!code focus] + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseCallReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`call`](/core/api/actions/call) diff --git a/wagmi-project/site/react/api/hooks/useCallsStatus.md b/wagmi-project/site/react/api/hooks/useCallsStatus.md new file mode 100644 index 000000000..48135c53e --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useCallsStatus.md @@ -0,0 +1,143 @@ +--- +title: useCallsStatus +description: Hook for fetching the number of the most recent block seen. +--- + + + +# useCallsStatus + +Hook to fetch the status and receipts of a call batch that was sent via [`useSendCalls`](/react/api/hooks/useSendCalls). + + + +## Import + +```ts +import { useCallsStatus } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useCallsStatus } from 'wagmi' + +function App() { + const result = useCallsStatus({ + id: '0x...', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseCallsStatusParameters } from 'wagmi' +``` + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useCallsStatus } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useCallsStatus({ + config, // [!code focus] + id: '0x...', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### connector + +`Connector | undefined` + +Connector to get call statuses with. + +::: code-group +```tsx [index.tsx] +import { useCallsStatus, useConnections } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const connections = useConnections() + const result = useCallsStatus({ + connector: connections[0]?.connector, // [!code focus] + id: '0x...', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### id + +`string` + +Identifier of the call batch. + +::: code-group +```ts [index.ts] +import { useCallsStatus } from '@wagmi/core' +import { config } from './config' + +const status = await useCallsStatus({ + id: '0x1234567890abcdef', // [!code focus] +}) +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Hooks that have identical context will share the same cache. + +::: code-group +```tsx [index.tsx] +import { useCallsStatus } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useCallsStatus({ + id: '0x...', + scopeKey: 'foo', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseCallsStatusReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`getCallsStatus`](https://viem.sh/experimental/eip5792/getCallsStatus) \ No newline at end of file diff --git a/wagmi-project/site/react/api/hooks/useCapabilities.md b/wagmi-project/site/react/api/hooks/useCapabilities.md new file mode 100644 index 000000000..d9d6fc74a --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useCapabilities.md @@ -0,0 +1,138 @@ +--- +title: useCapabilities +description: Hook for fetching the number of the most recent block seen. +--- + + + +# useCapabilities + +Hook to extract capabilities (grouped by chain ID) that a connected wallet supports (e.g. paymasters, session keys, etc). + +[Read more.](https://github.com/ethereum/EIPs/blob/815028dc634463e1716fc5ce44c019a6040f0bef/EIPS/eip-5792.md#wallet_getcapabilities) + +## Import + +```ts +import { useCapabilities } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useCapabilities } from 'wagmi' + +function App() { + const result = useCapabilities() +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseCapabilitiesParameters } from 'wagmi' +``` + +### account + +`Account | Address | undefined` + +Fetch capabilities for the provided account. + +::: code-group +```ts [index.ts] +import { useCapabilities } from '@wagmi/core' +import { config } from './config' + +const status = await useCapabilities({ + account: '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', // [!code focus] +}) +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useCapabilities } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useCapabilities({ + config, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### connector + +`Connector | undefined` + +Connector to get call statuses with. + +::: code-group +```tsx [index.tsx] +import { useCapabilities, useConnections } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const connections = useConnections() + const result = useCapabilities({ + connector: connections[0]?.connector, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Hooks that have identical context will share the same cache. + +::: code-group +```tsx [index.tsx] +import { useCapabilities } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useCapabilities({ + scopeKey: 'foo', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseCapabilitiesReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`getCapabilities`](https://viem.sh/experimental/eip5792/getCapabilities) \ No newline at end of file diff --git a/wagmi-project/site/react/api/hooks/useChainId.md b/wagmi-project/site/react/api/hooks/useChainId.md new file mode 100644 index 000000000..509f5a1e4 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useChainId.md @@ -0,0 +1,74 @@ +--- +title: useChainId +description: Hook for getting current chain ID. +--- + +# useChainId + +Hook for getting current chain ID. + +## Import + +```ts +import { useChainId } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useChainId } from 'wagmi' + +function App() { + const chainId = useChainId() +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseChainIdParameters } from 'wagmi' +``` + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useChainId } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const chainId = useChainId({ + config, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type UseChainIdReturnType } from 'wagmi' +``` + +`number` + +Current chain ID from [`config.state.chainId`](/react/api/createConfig#chainid). + +::: info +Only returns chain IDs for chains configured via `createConfig`'s [`chains`](/react/api/createConfig#chains) parameter. + +If the active [connection](/react/api/createConfig#connection) [`chainId`](/react/api/createConfig#chainid-1) is not from a chain included in your Wagmi `Config`, `useChainId` will return the last configured chain ID. +::: + +## Action + +- [`getChainId`](/core/api/actions/getChainId) +- [`watchChainId`](/core/api/actions/watchChainId) diff --git a/wagmi-project/site/react/api/hooks/useChains.md b/wagmi-project/site/react/api/hooks/useChains.md new file mode 100644 index 000000000..286f79427 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useChains.md @@ -0,0 +1,67 @@ +--- +title: useChains +description: Hook for getting configured chains +--- + +# useChains + +Hook for getting configured chains + +## Import + +```ts +import { useChains } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useChains } from 'wagmi' + +function App() { + const chains = useChains() +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseChainsParameters } from 'wagmi' +``` + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useChains } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const chains = useChains({ + config, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type UseChainsReturnType } from 'wagmi' +``` + +`readonly [Chain, ...Chain[]]` + +Chains from [`config.chains`](/react/api/createConfig#chains). + +## Action + +- [`getChains`](/core/api/actions/getChains) diff --git a/wagmi-project/site/react/api/hooks/useClient.md b/wagmi-project/site/react/api/hooks/useClient.md new file mode 100644 index 000000000..fc87a15e4 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useClient.md @@ -0,0 +1,89 @@ +--- +title: useClient +description: Hook for getting Viem `Client` instance. +--- + +# useClient + +Hook for getting Viem [`Client`](https://viem.sh/docs/clients/custom.html) instance. + +## Import + +```ts +import { useClient } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useClient } from 'wagmi' + +function App() { + const client = useClient() +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseClientParameters } from 'wagmi' +``` + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when getting Viem Client. + +::: code-group +```ts [index.ts] +import { useClient } from 'wagmi' +import { mainnet } from 'wagmi/chains' // [!code focus] +import { config } from './config' + +function App() { + const client = useClient({ + chainId: mainnet.id, // [!code focus] + }) +} +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useClient } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const client = useClient({ + config, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type UseClientReturnType } from 'wagmi' +``` + +`Client | undefined` + +Viem [`Client`](https://viem.sh/docs/clients/custom.html) instance. + +## Action + +- [`getClient`](/core/api/actions/getClient) +- [`watchClient`](/core/api/actions/watchClient) diff --git a/wagmi-project/site/react/api/hooks/useConfig.md b/wagmi-project/site/react/api/hooks/useConfig.md new file mode 100644 index 000000000..6f70b6e82 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useConfig.md @@ -0,0 +1,75 @@ +--- +title: useConfig +description: Hook for getting `Config` from nearest `WagmiProvider`. +--- + +# useConfig + +Hook for getting [`Config`](/react/api/createConfig#config) from nearest [`WagmiProvider`](/react/api/WagmiProvider). + +## Import + +```ts +import { useConfig } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useConfig } from 'wagmi' + +function App() { + const config = useConfig() +} +``` + +::: + +## Return Type + +```ts +import { type UseConfigReturnType } from 'wagmi' +``` + +If you use TypeScript and [register your `Config`](/react/typescript#register-config), the return type will be inferred. + +::: code-group +```ts twoslash [index.tsx] +import { type Config } from 'wagmi' +import { mainnet, sepolia } from 'wagmi/chains' + +declare module 'wagmi' { + interface Register { + config: Config + } +} +// ---cut--- +import { useConfig } from 'wagmi' + +function App() { + const config = useConfig() + // ^? +} +``` + +```ts [config.ts] +import { createConfig, http } from 'wagmi' +import { mainnet, sepolia } from 'wagmi/chains' + +declare module 'wagmi' { + interface Register { + config: typeof config + } +} + +export const config = createConfig({ + chains: [mainnet, sepolia], + transports: { + [mainnet.id]: http(), + [sepolia.id]: http(), + }, +}) +``` + +::: diff --git a/wagmi-project/site/react/api/hooks/useConnect.md b/wagmi-project/site/react/api/hooks/useConnect.md new file mode 100644 index 000000000..ba52ee2aa --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useConnect.md @@ -0,0 +1,117 @@ +--- +title: useConnect +description: Hook for connecting accounts with connectors. +--- + + + +# useConnect + +Hook for connecting accounts with [connectors](/react/api/connectors). + +## Import + +```ts +import { useConnect } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useConnect } from 'wagmi' +import { injected } from 'wagmi/connectors' + +function App() { + const { connect } = useConnect() + + return ( + + ) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseConnectParameters } from 'wagmi' +``` + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useConnect } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useConnect({ + config, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseConnectReturnType } from 'wagmi' +``` + +### connectors + +`readonly Connector[]` + +Globally configured connectors via [`createConfig`](/react/api/createConfig#connectors). Useful for rendering a list of available connectors. + +::: code-group +```tsx [index.tsx] +import { useConnect } from 'wagmi' + +function App() { + const { connect, connectors } = useConnect() + + return ( +
+ {connectors.map((connector) => ( + + ))} +
+ ) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +::: tip +Not all connectors support connecting directly to a `chainId` (e.g. they don't support programmatic chain switching). In those cases, the connector will connect to whatever chain the connector's provider (e.g. wallet) is connected to. +::: + + + +## Action + +- [`connect`](/core/api/actions/connect) diff --git a/wagmi-project/site/react/api/hooks/useConnections.md b/wagmi-project/site/react/api/hooks/useConnections.md new file mode 100644 index 000000000..f6f18b14f --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useConnections.md @@ -0,0 +1,64 @@ +--- +title: useConnections +description: Hook for getting active connections. +--- + +# useConnections + +Hook for getting active connections. + +## Import + +```ts +import { useConnections } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useConnections } from 'wagmi' + +function App() { + const connections = useConnections() +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseConnectionsParameters } from 'wagmi' +``` + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useConnections } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const connections = useConnections({ + config, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type UseConnectionsReturnType } from 'wagmi' +``` + +## Action + +- [`getConnections`](/core/api/actions/getConnections) +- [`watchConnections`](/core/api/actions/watchConnections) diff --git a/wagmi-project/site/react/api/hooks/useConnectorClient.md b/wagmi-project/site/react/api/hooks/useConnectorClient.md new file mode 100644 index 000000000..60aa74b77 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useConnectorClient.md @@ -0,0 +1,128 @@ +--- +title: useConnectorClient +description: Hook for getting a Viem `Client` object for the current or provided connector. +--- + + + +# useConnectorClient + +Hook for getting a Viem [`Client`](https://viem.sh/docs/clients/custom.html) object for the current or provided connector. + +## Import + +```ts +import { useConnectorClient } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useConnectorClient } from 'wagmi' + +function App() { + const result = useConnectorClient() +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseConnectorClientParameters } from 'wagmi' +``` + +### account + +`Address | Account | undefined` + +Account to use with client. Throws if account is not found on [`connector`](#connector). + +```ts +import { useConnectorClient } from 'wagmi' + +function App() { + const result = useConnectorClient({ + account: '0xd2135CfB216b74109775236E36d4b433F1DF507B', // [!code focus] + }) +} +``` + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use with client. + +```ts +import { useConnectorClient } from 'wagmi' + +function App() { + const result = useConnectorClient({ + chainId: mainnet.id, // [!code focus] + }) +} +``` + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useConnectorClient } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useConnectorClient({ + config, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### connector + +`Connector | undefined` + +- Connector to get client for. +- Defaults to current connector. + +```ts +import { useConnections, useConnectorClient } from 'wagmi' + +function App() { + const connections = useConnections(config) + const result = useConnectorClient({ + connector: connections[0]?.connector, // [!code focus] + }) +} +``` + + + +## Return Type + +```ts +import { type UseConnectorClientReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`getConnectorClient`](/core/api/actions/getConnectorClient) diff --git a/wagmi-project/site/react/api/hooks/useConnectors.md b/wagmi-project/site/react/api/hooks/useConnectors.md new file mode 100644 index 000000000..f02e2dfd2 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useConnectors.md @@ -0,0 +1,41 @@ +--- +title: useConnectors +description: Hook for getting configured connectors. +--- + +# useConnectors + +Hook for getting configured connectors. + +## Import + +```ts +import { useConnectors } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useConnectors } from 'wagmi' + +function App() { + const connectors = useConnectors() +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type UseConnectorsReturnType } from 'wagmi' +``` + +`readonly Connector[]` + +Connectors from [`config.connectors`](/react/api/createConfig#connectors-1). + +## Action + +- [`getConnectors`](/core/api/actions/getConnectors) diff --git a/wagmi-project/site/react/api/hooks/useDeployContract.md b/wagmi-project/site/react/api/hooks/useDeployContract.md new file mode 100644 index 000000000..42b2e9ffe --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useDeployContract.md @@ -0,0 +1,145 @@ +--- +title: useDeployContract +description: Hook for deploying a contract to the network, given bytecode & constructor arguments. +--- + + + +# useDeployContract + +Hook for deploying a contract to the network, given bytecode, and constructor arguments. + +## Import + +```ts +import { useDeployContract } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useDeployContract } from 'wagmi' +import { parseEther } from 'viem' +import { wagmiAbi } from './abi' + +function App() { + const { deployContract } = useDeployContract() + + return ( + + ) +} +``` +```ts [abi.ts] +export const wagmiAbi = [ + ... + { + inputs: [], + stateMutability: "nonpayable", + type: "constructor", + }, + ... +] as const +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Deploying with Constructor Args + +::: code-group +```tsx [index.tsx] +import { useDeployContract } from 'wagmi' +import { parseEther } from 'viem' +import { wagmiAbi } from './abi' + +function App() { + const { deployContract } = useDeployContract() + + return ( + + ) +} +``` +```ts [abi.ts] +export const wagmiAbi = [ + ... + { + inputs: [{ name: "x", type: "uint32" }], + stateMutability: "nonpayable", + type: "constructor", + }, + ... +] as const; +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type useDeployContractParameters } from 'wagmi' +``` + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useDeployContract } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useDeployContract({ + config, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type useDeployContractReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`deployContract`](/core/api/actions/deployContract) diff --git a/wagmi-project/site/react/api/hooks/useDisconnect.md b/wagmi-project/site/react/api/hooks/useDisconnect.md new file mode 100644 index 000000000..5e537a846 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useDisconnect.md @@ -0,0 +1,113 @@ +--- +title: useDisconnect +description: Hook for disconnecting connections. +--- + + + +# useDisconnect + +Hook for disconnecting connections. + +## Import + +```ts +import { useDisconnect } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useDisconnect } from 'wagmi' + +function App() { + const { disconnect } = useDisconnect() + + return ( + + ) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseDisconnectParameters } from 'wagmi' +``` + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useDisconnect } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useDisconnect({ + config, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseDisconnectReturnType } from 'wagmi' +``` + +### connectors + +`readonly Connector[]` + +Connectors that are currently connected. Useful for rendering a list of connectors to disconnect. + +::: code-group +```tsx [index.tsx] +import { useDisconnect } from 'wagmi' +import { mainnet } from 'wagmi/chains' + +function App() { + const { connectors, disconnect } = useDisconnect() + + return ( +
+ {connectors.map((connector) => ( + + ))} +
+ ) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + + + +## Action + +- [`disconnect`](/core/api/actions/disconnect) diff --git a/wagmi-project/site/react/api/hooks/useEnsAddress.md b/wagmi-project/site/react/api/hooks/useEnsAddress.md new file mode 100644 index 000000000..b4807384f --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useEnsAddress.md @@ -0,0 +1,238 @@ +--- +title: useEnsAddress +description: Hook for fetching ENS address for name. +--- + + + +# useEnsAddress + +Hook for fetching ENS address for name. + +## Import + +```ts +import { useEnsAddress } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useEnsAddress } from 'wagmi' +import { normalize } from 'viem/ens' + +function App() { + const result = useEnsAddress({ + name: normalize('wevm.eth'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +::: warning +Since ENS names prohibit certain forbidden characters (e.g. underscore) and have other validation rules, you likely want to [normalize ENS names](https://docs.ens.domains/contract-api-reference/name-processing#normalising-names) with [UTS-46 normalization](https://unicode.org/reports/tr46) before passing them to `useEnsAddress`. You can use Viem's built-in [`normalize`](https://viem.sh/docs/ens/utilities/normalize) function for this. +::: + +## Parameters + +```ts +import { type UseEnsAddressParameters } from 'wagmi' +``` + +--- + +### blockNumber + +`bigint | undefined` + +Block number to get ENS address at. + +::: code-group +```ts [index.ts] +import { useEnsAddress } from 'wagmi' +import { normalize } from 'viem/ens' + +function App() { + const result = useEnsAddress({ + blockNumber: 17829139n, // [!code focus] + name: normalize('wevm.eth'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Block tag to get ENS address at. + +::: code-group +```ts [index.ts] +import { useEnsAddress } from 'wagmi' +import { normalize } from 'viem/ens' + +function App() { + const result = useEnsAddress({ + name: normalize('wevm.eth'), + blockTag: 'latest', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +--- + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```tsx [index.tsx] +import { useEnsAddress } from 'wagmi' +import { mainnet } from 'wagmi/chains' // [!code focus] +import { normalize } from 'viem/ens' + +function App() { + const result = useEnsAddress({ + chainId: mainnet.id, // [!code focus] + name: normalize('wevm.eth'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### coinType + +`number | undefined` + +The [ENSIP-9](https://docs.ens.domains/ens-improvement-proposals/ensip-9-multichain-address-resolution) coin type to fetch the address for. + +::: code-group +```ts [index.ts] +import { useEnsAddress } from 'wagmi' +import { normalize } from 'viem/ens' + +function App() { + const result = useEnsAddress({ + coinType: 60, // [!code focus] + name: normalize('wevm.eth'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useEnsAddress } from 'wagmi' +import { normalize } from 'viem/ens' +import { config } from './config' // [!code focus] + +function App() { + const result = useEnsAddress({ + config, // [!code focus] + name: normalize('wevm.eth'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### name + +`string | undefined` + +Name to get the address for. [`enabled`](#enabled) set to `false` if `name` is `undefined`. + +::: code-group +```ts [index.ts] +import { useEnsAddress } from 'wagmi' +import { normalize } from 'viem/ens' + +function App() { + const result = useEnsAddress({ + name: normalize('wevm.eth'), // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Hooks that have identical context will share the same cache. + +::: code-group +```ts [index.ts] +import { useEnsAddress } from 'wagmi' +import { normalize } from 'viem/ens' + +function App() { + const result = useEnsAddress({ + name: normalize('wevm.eth'), + scopeKey: 'foo', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### universalResolverAddress + +`Address | undefined` + +- Address of ENS Universal Resolver Contract. +- Defaults to current chain's Universal Resolver Contract address. + +::: code-group +```ts [index.ts] +import { useEnsAddress } from 'wagmi' +import { normalize } from 'viem/ens' + +function App() { + const result = useEnsAddress({ + name: normalize('wevm.eth'), + universalResolverAddress: '0x74E20Bd2A1fE0cdbe45b9A1d89cb7e0a45b36376', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseEnsAddressReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`getEnsAddress`](/core/api/actions/getEnsAddress) diff --git a/wagmi-project/site/react/api/hooks/useEnsAvatar.md b/wagmi-project/site/react/api/hooks/useEnsAvatar.md new file mode 100644 index 000000000..ec09af5e3 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useEnsAvatar.md @@ -0,0 +1,262 @@ +--- +title: useEnsAvatar +description: Hook for fetching ENS avatar for name. +--- + + + +# useEnsAvatar + +Hook for fetching ENS avatar for name. + +## Import + +```ts +import { useEnsAvatar } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useEnsAvatar } from 'wagmi' +import { normalize } from 'viem/ens' + +function App() { + const result = useEnsAvatar({ + name: normalize('wevm.eth'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +::: warning +Since ENS names prohibit certain forbidden characters (e.g. underscore) and have other validation rules, you likely want to [normalize ENS names](https://docs.ens.domains/contract-api-reference/name-processing#normalising-names) with [UTS-46 normalization](https://unicode.org/reports/tr46) before passing them to `useEnsAvatar`. You can use Viem's built-in [`normalize`](https://viem.sh/docs/ens/utilities/normalize) function for this. +::: + +## Parameters + +```ts +import { type UseEnsAvatarParameters } from 'wagmi' +``` + +--- + +### assetGatewayUrls + +`{ ipfs?: string | undefined; arweave?: string | undefined } | undefined` + +Gateway urls to resolve IPFS and/or Arweave assets. + +::: code-group +```ts [index.ts] +import { getEnsAvatar } from '@wagmi/core' +import { normalize } from 'viem/ens' +import { config } from './config' + +function App() { + const result = useEnsAvatar({ + assetGatewayUrls: { // [!code focus] + ipfs: 'https://cloudflare-ipfs.com', // [!code focus] + }, // [!code focus] + name: normalize('wevm.eth'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### blockNumber + +`bigint | undefined` + +Block number to get ENS avatar at. + +::: code-group +```ts [index.ts] +import { useEnsAvatar } from 'wagmi' +import { normalize } from 'viem/ens' + +function App() { + const result = useEnsAvatar({ + blockNumber: 17829139n, // [!code focus] + name: normalize('wevm.eth'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Block tag to get ENS avatar at. + +::: code-group +```ts [index.ts] +import { useEnsAvatar } from 'wagmi' +import { normalize } from 'viem/ens' + +function App() { + const result = useEnsAvatar({ + name: normalize('wevm.eth'), + blockTag: 'latest', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +--- + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```tsx [index.tsx] +import { useEnsAvatar } from 'wagmi' +import { mainnet } from 'wagmi/chains' // [!code focus] +import { normalize } from 'viem/ens' + +function App() { + const result = useEnsAvatar({ + chainId: mainnet.id, // [!code focus], + name: normalize('wevm.eth'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useEnsAvatar } from 'wagmi' +import { normalize } from 'viem/ens' +import { config } from './config' // [!code focus] + +function App() { + const result = useEnsAvatar({ + config, // [!code focus] + name: normalize('wevm.eth'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### gatewayUrls + +`string[] | undefined` + +A set of Universal Resolver gateways, used for resolving CCIP-Read requests made through the ENS Universal Resolver Contract. + +::: code-group +```ts [index.ts] +import { useEnsAvatar } from 'wagmi' +import { normalize } from 'viem/ens' + +function App() { + const result = useEnsAvatar({ + gatewayUrls: ['https://cloudflare-ipfs.com'] { // [!code focus] + name: normalize('wevm.eth'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### name + +`string | undefined` + +Name to get the avatar for. [`enabled`](#enabled) set to `false` if `name` is `undefined`. + +::: code-group +```ts [index.ts] +import { useEnsAvatar } from 'wagmi' +import { normalize } from 'viem/ens' + +function App() { + const result = useEnsAvatar({ + name: normalize('wevm.eth'), // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Hooks that have identical context will share the same cache. + +::: code-group +```ts [index.ts] +import { useEnsAvatar } from 'wagmi' +import { normalize } from 'viem/ens' + +function App() { + const result = useEnsAvatar({ + name: normalize('wevm.eth'), + scopeKey: 'foo', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### universalResolverAddress + +`Address | undefined` + +- Address of ENS Universal Resolver Contract. +- Defaults to current chain's Universal Resolver Contract address. + +::: code-group +```ts [index.ts] +import { useEnsAvatar } from 'wagmi' +import { normalize } from 'viem/ens' + +function App() { + const result = useEnsAvatar({ + name: normalize('wevm.eth'), + universalResolverAddress: '0x74E20Bd2A1fE0cdbe45b9A1d89cb7e0a45b36376', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseEnsAvatarReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`getEnsAvatar`](/core/api/actions/getEnsAvatar) diff --git a/wagmi-project/site/react/api/hooks/useEnsName.md b/wagmi-project/site/react/api/hooks/useEnsName.md new file mode 100644 index 000000000..71d128b1b --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useEnsName.md @@ -0,0 +1,206 @@ +--- +title: useEnsName +description: Hook for fetching primary ENS name for address. +--- + + + +# useEnsName + +Hook for fetching primary ENS name for address. + +## Import + +```ts +import { useEnsName } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useEnsName } from 'wagmi' + +function App() { + const result = useEnsName({ + address: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseEnsNameParameters } from 'wagmi' +``` + +### address + +`Address | undefined` + +Name to get the resolver for. [`enabled`](#enabled) set to `false` if `address` is `undefined`. + +::: code-group +```ts [index.ts] +import { useEnsName } from 'wagmi' + +function App() { + const result = useEnsName({ + address: '0xd2135CfB216b74109775236E36d4b433F1DF507B', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +--- + +### blockNumber + +`bigint | undefined` + +Block number to get ENS name at. + +::: code-group +```ts [index.ts] +import { useEnsName } from 'wagmi' + +function App() { + const result = useEnsName({ + address: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + blockNumber: 17829139n, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Block tag to get ENS name at. + +::: code-group +```ts [index.ts] +import { useEnsName } from 'wagmi' + +function App() { + const result = useEnsName({ + address: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + blockTag: 'latest', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +--- + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```tsx [index.tsx] +import { useEnsName } from 'wagmi' +import { mainnet } from 'wagmi/chains' // [!code focus] + +function App() { + const result = useEnsName({ + address: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + chainId: mainnet.id, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useEnsName } from 'wagmi' +import { normalize } from 'viem/ens' +import { config } from './config' // [!code focus] + +function App() { + const result = useEnsName({ + address: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + config, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Hooks that have identical context will share the same cache. + +::: code-group +```ts [index.ts] +import { useEnsName } from 'wagmi' + +function App() { + const result = useEnsName({ + address: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + scopeKey: 'foo', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### universalResolverAddress + +`Address | undefined` + +- Address of ENS Universal Resolver Contract. +- Defaults to current chain's Universal Resolver Contract address. + +::: code-group +```ts [index.ts] +import { useEnsName } from 'wagmi' + +function App() { + const result = useEnsName({ + address: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + universalResolverAddress: '0x74E20Bd2A1fE0cdbe45b9A1d89cb7e0a45b36376', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseEnsNameReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`getEnsName`](/core/api/actions/getEnsName) diff --git a/wagmi-project/site/react/api/hooks/useEnsResolver.md b/wagmi-project/site/react/api/hooks/useEnsResolver.md new file mode 100644 index 000000000..b66e17fa0 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useEnsResolver.md @@ -0,0 +1,217 @@ +--- +title: useEnsResolver +description: Hook for fetching ENS resolver for name. +--- + + + +# useEnsResolver + +Hook for fetching ENS resolver for name. + +## Import + +```ts +import { useEnsResolver } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useEnsResolver } from 'wagmi' +import { normalize } from 'viem/ens' + +function App() { + const result = useEnsResolver({ + name: normalize('wevm.eth'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +::: warning +Since ENS names prohibit certain forbidden characters (e.g. underscore) and have other validation rules, you likely want to [normalize ENS names](https://docs.ens.domains/contract-api-reference/name-processing#normalising-names) with [UTS-46 normalization](https://unicode.org/reports/tr46) before passing them to `useEnsResolver`. You can use Viem's built-in [`normalize`](https://viem.sh/docs/ens/utilities/normalize) function for this. +::: + +## Parameters + +```ts +import { type UseEnsResolverParameters } from 'wagmi' +``` + +--- + +### blockNumber + +`bigint | undefined` + +Block number to get ENS resolver at. + +::: code-group +```ts [index.ts] +import { useEnsResolver } from 'wagmi' +import { normalize } from 'viem/ens' + +function App() { + const result = useEnsResolver({ + blockNumber: 17829139n, // [!code focus] + name: normalize('wevm.eth'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Block tag to get ENS resolver at. + +::: code-group +```ts [index.ts] +import { useEnsResolver } from 'wagmi' +import { normalize } from 'viem/ens' + +function App() { + const result = useEnsResolver({ + name: normalize('wevm.eth'), + blockTag: 'latest', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +--- + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```tsx [index.tsx] +import { useEnsResolver } from 'wagmi' +import { mainnet } from 'wagmi/chains' // [!code focus] +import { normalize } from 'viem/ens' + +function App() { + const result = useEnsResolver({ + chainId: mainnet.id, // [!code focus] + name: normalize('wevm.eth'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useEnsResolver } from 'wagmi' +import { normalize } from 'viem/ens' +import { config } from './config' // [!code focus] + +function App() { + const result = useEnsResolver({ + config, // [!code focus] + name: normalize('wevm.eth'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### name + +`string | undefined` + +Name to get the resolver for. [`enabled`](#enabled) set to `false` if `name` is `undefined`. + +::: code-group +```ts [index.ts] +import { useEnsResolver } from 'wagmi' +import { normalize } from 'viem/ens' + +function App() { + const result = useEnsResolver({ + name: normalize('wevm.eth'), // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Hooks that have identical context will share the same cache. + +::: code-group +```ts [index.ts] +import { useEnsResolver } from 'wagmi' +import { normalize } from 'viem/ens' + +function App() { + const result = useEnsResolver({ + name: normalize('wevm.eth'), + scopeKey: 'foo', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### universalResolverAddress + +`Address | undefined` + +- Resolver of ENS Universal Resolver Contract. +- Defaults to current chain's Universal Resolver Contract address. + +::: code-group +```ts [index.ts] +import { useEnsResolver } from 'wagmi' +import { normalize } from 'viem/ens' + +function App() { + const result = useEnsResolver({ + name: normalize('wevm.eth'), + universalResolverAddress: '0x74E20Bd2A1fE0cdbe45b9A1d89cb7e0a45b36376', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseEnsResolverReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`getEnsResolver`](/core/api/actions/getEnsResolver) diff --git a/wagmi-project/site/react/api/hooks/useEnsText.md b/wagmi-project/site/react/api/hooks/useEnsText.md new file mode 100644 index 000000000..769bae66c --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useEnsText.md @@ -0,0 +1,247 @@ +--- +title: useEnsText +description: Hook for fetching a text record for a specified ENS name and key. +--- + + + +# useEnsText + +Hook for fetching a text record for a specified ENS name and key. + +## Import + +```ts +import { useEnsText } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useEnsText } from 'wagmi' +import { normalize } from 'viem/ens' + +function App() { + const result = useEnsText({ + name: normalize('wevm.eth'), + key: 'com.twitter', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +::: warning +Since ENS names prohibit certain forbidden characters (e.g. underscore) and have other validation rules, you likely want to [normalize ENS names](https://docs.ens.domains/contract-api-reference/name-processing#normalising-names) with [UTS-46 normalization](https://unicode.org/reports/tr46) before passing them to `useEnsText`. You can use Viem's built-in [`normalize`](https://viem.sh/docs/ens/utilities/normalize) function for this. +::: + +## Parameters + +```ts +import { type UseEnsTextParameters } from 'wagmi' +``` + +--- + +### blockNumber + +`bigint | undefined` + +Block number to get the text at. + +::: code-group +```ts [index.ts] +import { useEnsText } from 'wagmi' +import { normalize } from 'viem/ens' + +function App() { + const result = useEnsText({ + blockNumber: 17829139n, // [!code focus] + name: normalize('wevm.eth'), + key: 'com.twitter', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Block tag to get the text at. + +::: code-group +```ts [index.ts] +import { useEnsText } from 'wagmi' +import { normalize } from 'viem/ens' + +function App() { + const result = useEnsText({ + blockTag: 'latest', // [!code focus] + name: normalize('wevm.eth'), + key: 'com.twitter', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +--- + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```tsx [index.tsx] +import { useEnsText } from 'wagmi' +import { mainnet } from 'wagmi/chains' // [!code focus] +import { normalize } from 'viem/ens' + +function App() { + const result = useEnsText({ + chainId: mainnet.id, // [!code focus] + name: normalize('wevm.eth'), + key: 'com.twitter', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### key + +`string | undefined` + +ENS key to get Text for. + +::: code-group +```ts [index.ts] +import { useEnsText } from 'wagmi' +import { normalize } from 'viem/ens' + +function App() { + const result = useEnsText({ + name: normalize('wevm.eth'), + key: 'com.twitter', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + +### name + +`string | undefined` + +Name to get the text for. [`enabled`](#enabled) set to `false` if `name` is `undefined`. + +::: code-group +```ts [index.ts] +import { useEnsText } from 'wagmi' +import { normalize } from 'viem/ens' + +function App() { + const result = useEnsText({ + name: normalize('wevm.eth'), // [!code focus] + key: 'com.twitter', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useEnsText } from 'wagmi' +import { normalize } from 'viem/ens' +import { config } from './config' // [!code focus] + +function App() { + const result = useEnsText({ + config, // [!code focus] + name: normalize('wevm.eth'), + key: 'com.twitter', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Hooks that have identical context will share the same cache. + +::: code-group +```ts [index.ts] +import { useEnsText } from 'wagmi' +import { normalize } from 'viem/ens' + +function App() { + const result = useEnsText({ + scopeKey: 'foo', // [!code focus] + name: normalize('wevm.eth'), + key: 'com.twitter', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### universalResolverAddress + +`Address | undefined` + +- Resolver of ENS Universal Resolver Contract. +- Defaults to current chain's Universal Resolver Contract address. + +::: code-group +```ts [index.ts] +import { useEnsText } from 'wagmi' +import { normalize } from 'viem/ens' + +function App() { + const result = useEnsText({ + name: normalize('wevm.eth'), + key: 'com.twitter', + universalResolverAddress: '0x74E20Bd2A1fE0cdbe45b9A1d89cb7e0a45b36376', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseEnsTextReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`getEnsText`](/core/api/actions/getEnsText) diff --git a/wagmi-project/site/react/api/hooks/useEstimateFeesPerGas.md b/wagmi-project/site/react/api/hooks/useEstimateFeesPerGas.md new file mode 100644 index 000000000..29b871167 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useEstimateFeesPerGas.md @@ -0,0 +1,155 @@ +--- +title: useEstimateFeesPerGas +description: Hook for fetching an estimate for the fees per gas (in wei) for a transaction to be likely included in the next block. +--- + + + +# useEstimateFeesPerGas + +Hook for fetching an estimate for the fees per gas (in wei) for a transaction to be likely included in the next block. + +## Import + +```ts +import { useEstimateFeesPerGas } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useEstimateFeesPerGas } from 'wagmi' + +function App() { + const result = useEstimateFeesPerGas() +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseEstimateFeesPerGas } from 'wagmi' +``` + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```tsx [index.tsx] +import { useEstimateFeesPerGas } from 'wagmi' +import { mainnet } from 'wagmi/chains' // [!code focus] + +function App() { + const result = useEstimateFeesPerGas({ + chainId: mainnet.id, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useEstimateFeesPerGas } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useEstimateFeesPerGas({ + config, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### formatUnits + +`'ether' | 'gwei' | 'wei' | number | undefined` + +- Units to use when formatting result. +- Defaults to `'ether'`. + +::: code-group +```ts [index.ts] +import { useEstimateFeesPerGas } from 'wagmi' + +function App() { + const result = useEstimateFeesPerGas({ + formatUnits: 'ether', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Hooks that have identical context will share the same cache. + +::: code-group +```ts [index.ts] +import { useEstimateFeesPerGas } from 'wagmi' + +function App() { + const result = useEstimateFeesPerGas({ + scopeKey: 'foo', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### type + +`'legacy' | 'eip1559'` + +- Defaults to `'eip1559'` + +::: code-group +```ts [index.ts] +import { useEstimateFeesPerGas } from 'wagmi' + +function App() { + const result = useEstimateFeesPerGas({ + type: 'legacy', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseEstimateFeesPerGasReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`estimateFeesPerGas`](/core/api/actions/estimateFeesPerGas) diff --git a/wagmi-project/site/react/api/hooks/useEstimateGas.md b/wagmi-project/site/react/api/hooks/useEstimateGas.md new file mode 100644 index 000000000..db0707ca1 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useEstimateGas.md @@ -0,0 +1,387 @@ +--- +title: useEstimateGas +description: Hook for estimating the gas necessary to complete a transaction without submitting it to the network. +--- + + + +# useEstimateGas + +Hook for estimating the gas necessary to complete a transaction without submitting it to the network. + +## Import + +```ts +import { useEstimateGas } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useEstimateGas } from 'wagmi' + +function App() { + const result = useEstimateGas() +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseEstimateGasParameters } from 'wagmi' +``` + +### accessList + +`AccessList | undefined` + +The access list. + +::: code-group +```ts [index.ts] +import { useEstimateGas } from 'wagmi' +import { parseEther } from 'viem' +import { config } from './config' + +function App() { + const result = useEstimateGas({ + accessList: [{ // [!code focus] + address: '0x1', // [!code focus] + storageKeys: ['0x1'], // [!code focus] + }], // [!code focus] + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### account + +`Address | Account | undefined` + +Account to use when estimating gas. + +::: code-group +```ts [index.ts] +import { useEstimateGas } from 'wagmi' +import { parseEther } from 'viem' +import { config } from './config' + +function App() { + const result = useEstimateGas({ + account: '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', // [!code focus] + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +Chain ID to target when estimating gas. + +::: code-group +```ts [index.ts] +import { useEstimateGas } from 'wagmi' +import { mainnet } from '@wagmi/core/chains' +import { parseEther } from 'viem' +import { config } from './config' + +function App() { + const result = useEstimateGas({ + chainId: mainnet.id, // [!code focus] + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### connector + +`Connector | undefined` + +Connector to estimate with. If no [`account`](#account) is provided, will use default account from connector. + +::: code-group +```ts [index.ts] +import { getConnections, estimateGas } from '@wagmi/core' +import { parseEther } from 'viem' +import { config } from './config' + +function App() { + const connections = getConnections(config) + const result = useEstimateGas({ + connector: connections[0]?.connector, // [!code focus] + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### data + +`` `0x${string}` | undefined `` + +A contract hashed method call with encoded function data. + +::: code-group +```ts [index.ts] +import { useEstimateGas } from 'wagmi' +import { parseEther } from 'viem' +import { config } from './config' + +function App() { + const result = useEstimateGas({ + data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', // [!code focus] + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### gas + +`bigint | undefined` + +Gas provided for transaction execution. + +::: code-group +```ts [index.ts] +import { useEstimateGas } from 'wagmi' +import { parseEther, parseGwei } from 'viem' +import { config } from './config' + +function App() { + const result = useEstimateGas({ + gas: parseGwei('20'), // [!code focus] + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +--- + +### gasPrice + +`bigint | undefined` + +The price in wei to pay per gas. Only applies to [Legacy Transactions](https://viem.sh/docs/glossary/terms.html#legacy-transaction). + +::: code-group +```ts [index.ts] +import { useEstimateGas } from 'wagmi' +import { parseEther, parseGwei } from 'viem' +import { config } from './config' + +function App() { + const result = useEstimateGas({ + gasPrice: parseGwei('20'), // [!code focus] + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### maxFeePerGas + +`bigint | undefined` + +Total fee per gas in wei, inclusive of [`maxPriorityFeePerGas`](#maxPriorityFeePerGas). Only applies to [EIP-1559 Transactions](https://viem.sh/docs/glossary/terms.html#eip-1559-transaction). + +::: code-group +```ts [index.ts] +import { useEstimateGas } from 'wagmi' +import { parseEther, parseGwei } from 'viem' +import { config } from './config' + +function App() { + const result = useEstimateGas({ + maxFeePerGas: parseGwei('20'), // [!code focus] + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### maxPriorityFeePerGas + +`bigint | undefined` + +Max priority fee per gas in wei. Only applies to [EIP-1559 Transactions](https://viem.sh/docs/glossary/terms.html#eip-1559-transaction). + +::: code-group +```ts [index.ts] +import { useEstimateGas } from 'wagmi' +import { parseEther, parseGwei } from 'viem' +import { config } from './config' + +function App() { + const result = useEstimateGas({ + maxFeePerGas: parseGwei('20'), + maxPriorityFeePerGas: parseGwei('2'), // [!code focus] + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +--- + +### nonce + +`number` + +Unique number identifying this transaction. + +::: code-group +```ts [index.ts] +import { useEstimateGas } from 'wagmi' +import { parseEther } from 'viem' +import { config } from './config' + +function App() { + const result = useEstimateGas({ + nonce: 123, // [!code focus] + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Hooks that have identical context will share the same cache. + +::: code-group +```ts [index.ts] +import { useEstimateGas } from 'wagmi' +import { parseEther } from 'viem' +import { config } from './config' + +function App() { + const result = useEstimateGas({ + scopeKey: 'foo', // [!code focus] + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### to + +`Address | undefined` + +The transaction recipient or contract address. + +::: code-group +```ts [index.ts] +import { useEstimateGas } from 'wagmi' +import { parseEther } from 'viem' +import { config } from './config' + +function App() { + const result = useEstimateGas({ + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', // [!code focus] + value: parseEther('0.01'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### type + +`'legacy' | 'eip1559' | 'eip2930' | undefined` + +Optional transaction request type to narrow parameters. + +::: code-group +```ts [index.ts] +import { useEstimateGas } from 'wagmi' +import { parseEther } from 'viem' +import { config } from './config' + +function App() { + const result = useEstimateGas({ + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + type: 'eip1559', // [!code focus] + value: parseEther('0.01'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### value + +`bigint | undefined` + +Value in wei sent with this transaction. + +::: code-group +```ts [index.ts] +import { useEstimateGas } from 'wagmi' +import { parseEther } from 'viem' +import { config } from './config' + +function App() { + const result = useEstimateGas({ + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseEstimateGasReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`estimateGas`](/core/api/actions/estimateGas) diff --git a/wagmi-project/site/react/api/hooks/useEstimateMaxPriorityFeePerGas.md b/wagmi-project/site/react/api/hooks/useEstimateMaxPriorityFeePerGas.md new file mode 100644 index 000000000..affb16571 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useEstimateMaxPriorityFeePerGas.md @@ -0,0 +1,116 @@ +--- +title: useEstimateMaxPriorityFeePerGas +description: Hook for fetching an estimate for the max priority fee per gas (in wei) for a transaction to be likely included in the next block. +--- + + + +# useEstimateMaxPriorityFeePerGas + +Hook for fetching an estimate for the fees per gas (in wei) for a transaction to be likely included in the next block. + +## Import + +```ts +import { useEstimateMaxPriorityFeePerGas } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useEstimateMaxPriorityFeePerGas } from 'wagmi' + +function App() { + const result = useEstimateMaxPriorityFeePerGas() +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseEstimateMaxPriorityFeePerGas } from 'wagmi' +``` + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```tsx [index.tsx] +import { useEstimateMaxPriorityFeePerGas } from 'wagmi' +import { mainnet } from 'wagmi/chains' // [!code focus] + +function App() { + const result = useEstimateMaxPriorityFeePerGas({ + chainId: mainnet.id, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useEstimateMaxPriorityFeePerGas } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useEstimateMaxPriorityFeePerGas({ + config, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Hooks that have identical context will share the same cache. + +::: code-group +```ts [index.ts] +import { useEstimateMaxPriorityFeePerGas } from 'wagmi' + +function App() { + const result = useEstimateMaxPriorityFeePerGas({ + scopeKey: 'foo', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseEstimateMaxPriorityFeePerGasReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`estimateMaxPriorityFeePerGas`](/core/api/actions/estimateMaxPriorityFeePerGas) diff --git a/wagmi-project/site/react/api/hooks/useFeeHistory.md b/wagmi-project/site/react/api/hooks/useFeeHistory.md new file mode 100644 index 000000000..42bf60d89 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useFeeHistory.md @@ -0,0 +1,210 @@ +--- +title: useFeeHistory +description: Hook for fetching a collection of historical gas information. +--- + + + +# useFeeHistory + +Hook for fetching a collection of historical gas information. + +## Import + +```ts +import { useFeeHistory } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useFeeHistory } from 'wagmi' + +function App() { + const result = useFeeHistory({ + blockCount: 4, + rewardPercentiles: [25, 75] +}) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseFeeHistoryParameters } from 'wagmi' +``` + +### blockCount + +`number | undefined` + +Number of blocks in the requested range. Between 1 and 1024 blocks can be requested in a single query. Less than requested may be returned if not all blocks are available. + +::: code-group +```tsx [index.tsx] +import { useFeeHistory } from 'wagmi' + +function App() { + const result = useFeeHistory({ + blockCount: 4, // [!code focus] + rewardPercentiles: [25, 75] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### rewardPercentiles + +`number[] | undefined` + +A monotonically increasing list of percentile values to sample from each block's effective priority fees per gas in ascending order, weighted by gas used. + +::: code-group +```tsx [index.tsx] +import { useFeeHistory } from 'wagmi' + +function App() { + const result = useFeeHistory({ + blockCount: 4, + rewardPercentiles: [25, 75] // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### blockNumber + +`bigint | undefined` + +Highest number block of the requested range. + + +::: code-group +```tsx [index.tsx] +import { useFeeHistory } from 'wagmi' + +function App() { + const result = useFeeHistory({ + blockCount: 4, + blockNumber: 1551231n, // [!code focus] + rewardPercentiles: [25, 75] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Block tag of the highest number block of the requested range. + +::: code-group +```tsx [index.tsx] +import { useFeeHistory } from 'wagmi' + +function App() { + const result = useFeeHistory({ + blockCount: 4, + blockTag: 'safe', // [!code focus] + rewardPercentiles: [25, 75] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + + +::: code-group +```tsx [index.tsx] +import { useFeeHistory } from 'wagmi' +import { mainnet } from '@wagmi/core/chains' + +function App() { + const result = useFeeHistory({ + blockCount: 4, + chainId: mainnet.id, // [!code focus] + rewardPercentiles: [25, 75] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useFeeHistory } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useFeeHistory({ + blockCount: 4, + rewardPercentiles: [25, 75] + config, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Hooks that have identical context will share the same cache. + +::: code-group +```tsx [index.tsx] +import { useFeeHistory } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useFeeHistory({ + blockCount: 4, + rewardPercentiles: [25, 75] + scopeKey: 'foo', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseFeeHistoryReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`getFeeHistory`](/core/api/actions/getFeeHistory) diff --git a/wagmi-project/site/react/api/hooks/useGasPrice.md b/wagmi-project/site/react/api/hooks/useGasPrice.md new file mode 100644 index 000000000..2dfa13aa1 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useGasPrice.md @@ -0,0 +1,117 @@ +--- +title: useGasPrice +description: Hook for fetching the current price of gas (in wei). +--- + + + +# useGasPrice + +Hook for fetching the current price of gas (in wei). + +## Import + +```ts +import { useGasPrice } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useGasPrice } from 'wagmi' + +function App() { + const result = useGasPrice() +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseGasPriceParameters } from 'wagmi' +``` + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```tsx [index.tsx] +import { useGasPrice } from 'wagmi' +import { mainnet } from 'wagmi/chains' // [!code focus] + +function App() { + const result = useGasPrice({ + chainId: mainnet.id, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useGasPrice } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useGasPrice({ + config, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Hooks that have identical context will share the same cache. + +::: code-group +```tsx [index.tsx] +import { useGasPrice } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useGasPrice({ + scopeKey: 'foo', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseGasPriceReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`getGasPrice`](/core/api/actions/getGasPrice) diff --git a/wagmi-project/site/react/api/hooks/useInfiniteReadContracts.md b/wagmi-project/site/react/api/hooks/useInfiniteReadContracts.md new file mode 100644 index 000000000..bc25df59f --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useInfiniteReadContracts.md @@ -0,0 +1,358 @@ +--- +title: useInfiniteReadContracts +description: Hook for calling multiple read methods on a contract with "infinite scroll"/"fetch more" support. +--- + + + +# useInfiniteReadContracts + +Hook for calling multiple contract read-only methods with "infinite scrolling"/"fetch more" support. + +## Import + +```ts +import { useInfiniteReadContracts } from 'wagmi' +``` + +## Usage + +The example below shows how to demonstrate how to fetch a set of [mloot](https://etherscan.io/address/0x1dfe7ca09e99d10835bf73044a23b73fc20623df) attributes (chestwear, footwear, and handwear) with "fetch more" support. + +::: code-group +```tsx [index.tsx] +import { useInfiniteReadContracts } from 'wagmi' +import { abi } from './abi' + +const mlootContractConfig = { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi, +} as const + +function App() { + const result = useInfiniteReadContracts({ + cacheKey: 'mlootAttributes', + contracts(pageParam) { + const args = [pageParam] as const + return [ + { ...mlootContractConfig, functionName: 'getChest', args }, + { ...mlootContractConfig, functionName: 'getFoot', args }, + { ...mlootContractConfig, functionName: 'getHand', args }, + ] + } + query: { + initialPageParam: 0, + getNextPageParam: (_lastPage, _allPages, lastPageParam) => { + return lastPageParam + 1 + } + } + }) +} +``` +<<< @/snippets/abi-infinite-read.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +In the above example, we are setting a few things: + +- [`cacheKey`](#cachekey): A unique key to store the data in the cache. +- [`query.initialPageParam`](#initialpageparam): An initial page parameter to use when fetching the first set of contracts. +- [`query.getNextPageParam`](#getnextpageparam): A function that returns the next page parameter to use when fetching the next set of contracts. +- [`contracts`](#contracts): A function that provides `pageParam` (derived from the above) as an argument and expects to return an array of contracts. + +### Paginated Parameters + +We can also leverage properties like `getNextPageParam` with a custom `limit` variable to achieve "pagination" of parameters. For example, we can fetch the first 10 contract functions, then fetch the next 10 contract functions, and so on. + +::: code-group +```tsx [index.tsx] +import { useInfiniteReadContracts } from 'wagmi' +import { abi } from './abi' + +function Example({ limit = 10 }: { limit?: number } = {}) { + const result = useInfiniteReadContracts({ + cacheKey: 'mlootAttributes', + contracts(pageParam) { + return [...new Array(limit)].map( + (_, i) => + ({ + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi, + functionName: 'getHand', + args: [BigInt(pageParam + i)], + }) as const, + ) + }, + query: { + initialPageParam: 1, + getNextPageParam(_lastPage, _allPages, lastPageParam) { + return lastPageParam + limit + }, + } + }) +} +``` +<<< @/snippets/abi-infinite-read.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + + +## Parameters + +```ts +import { type UseInfiniteReadContractsParameters } from 'wagmi' +``` + +### cacheKey + +`string` + +A unique key to store the data in the cache. + +::: code-group +```tsx [index.tsx] +import { useInfiniteReadContracts } from 'wagmi' +import { abi } from './abi' + +function App() { + const result = useInfiniteReadContracts({ + cacheKey: 'mlootAttributes', // [!code hl] + contracts(pageParam) { + // ... + } + query: { + initialPageParam: 0, + getNextPageParam: (_lastPage, _allPages, lastPageParam) => { + return lastPageParam + 1 + } + } + }) +} +``` +<<< @/snippets/abi-infinite-read.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +### contracts + +`(pageParam: {{TPageParam}}) => Contract[]` + +A function that provides `pageParam` (derived from the above) as an argument and expects to return an array of contracts. + +#### abi + +`Abi | undefined` + +The contract's ABI. Check out the [TypeScript docs](/react/typescript#const-assert-abis-typed-data) for how to set up ABIs for maximum type inference and safety. + +::: code-group +```tsx [index.tsx] +import { useInfiniteReadContracts } from 'wagmi' +import { abi } from './abi' + +function App() { + const result = useInfiniteReadContracts({ + cacheKey: 'mlootAttributes', + contracts(pageParam) { + const args = [pageParam] as const + return [ + // ... + { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi, // [!code hl] + functionName: 'getChest', + args + }, + // ... + ] + } + query: { + initialPageParam: 0, + getNextPageParam: (_lastPage, _allPages, lastPageParam) => { + return lastPageParam + 1 + } + } + }) +} +``` +<<< @/snippets/abi-infinite-read.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +#### address + +`Address | undefined` + +The contract's address. + +::: code-group +```tsx [index.tsx] +import { useInfiniteReadContracts } from 'wagmi' +import { abi } from './abi' + +function App() { + const result = useInfiniteReadContracts({ + cacheKey: 'mlootAttributes', + contracts(pageParam) { + const args = [pageParam] as const + return [ + // ... + { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', // [!code hl] + abi, + functionName: 'getChest', + args + }, + // ... + ] + } + query: { + initialPageParam: 0, + getNextPageParam: (_lastPage, _allPages, lastPageParam) => { + return lastPageParam + 1 + } + } + }) +} +``` +<<< @/snippets/abi-infinite-read.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +#### functionName + +`string | undefined` + +- Function to call on the contract. +- Inferred from [`abi`](#abi). + +::: code-group +```tsx [index.tsx] +import { useInfiniteReadContracts } from 'wagmi' +import { abi } from './abi' + +function App() { + const result = useInfiniteReadContracts({ + cacheKey: 'mlootAttributes', + contracts(pageParam) { + const args = [pageParam] as const + return [ + // ... + { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi, + functionName: 'getChest', // [!code hl] + args + }, + // ... + ] + } + query: { + initialPageParam: 0, + getNextPageParam: (_lastPage, _allPages, lastPageParam) => { + return lastPageParam + 1 + } + } + }) +} +``` +<<< @/snippets/abi-infinite-read.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +#### args + +`readonly unknown[] | undefined` + +- Arguments to pass when calling the contract. +- Inferred from [`abi`](#abi) and [`functionName`](#functionname). + +::: code-group +```tsx [index.tsx] +import { useInfiniteReadContracts } from 'wagmi' +import { abi } from './abi' + +function App() { + const result = useInfiniteReadContracts({ + cacheKey: 'mlootAttributes', + contracts(pageParam) { + return [ + // ... + { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi, + functionName: 'getChest', + args: [pageParam] // [!code hl] + }, + // ... + ] + } + query: { + initialPageParam: 0, + getNextPageParam: (_lastPage, _allPages, lastPageParam) => { + return lastPageParam + 1 + } + } + }) +} +``` +<<< @/snippets/abi-infinite-read.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +#### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```tsx [index.tsx] +import { useInfiniteReadContracts } from 'wagmi' +import { abi } from './abi' + +function App() { + const result = useInfiniteReadContracts({ + cacheKey: 'mlootAttributes', + contracts(pageParam) { + const args = [pageParam] as const + return [ + // ... + { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi, + functionName: 'getChest', + args, + chainId: 1 // [!code hl] + }, + // ... + ] + } + query: { + initialPageParam: 0, + getNextPageParam: (_lastPage, _allPages, lastPageParam) => { + return lastPageParam + 1 + } + } + }) +} +``` +<<< @/snippets/abi-infinite-read.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseInfiniteReadContractsReturnType } from 'wagmi' +``` + + \ No newline at end of file diff --git a/wagmi-project/site/react/api/hooks/usePrepareTransactionRequest.md b/wagmi-project/site/react/api/hooks/usePrepareTransactionRequest.md new file mode 100644 index 000000000..431fdda48 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/usePrepareTransactionRequest.md @@ -0,0 +1,368 @@ +--- +title: usePrepareTransactionRequest +description: Hook for preparing a transaction request for signing by populating a nonce, gas limit, fee values, and a transaction type. +--- + + + +# usePrepareTransactionRequest + +Hook for preparing a transaction request for signing by populating a nonce, gas limit, fee values, and a transaction type. + +## Import + +```ts +import { usePrepareTransactionRequest } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { usePrepareTransactionRequest } from 'wagmi' +import { parseEther } from 'viem' + +function App() { + const result = usePrepareTransactionRequest({ + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + value: parseEther('1'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UsePrepareTransactionRequestParameters } from 'wagmi' +``` + +### account + +`Account | Address | undefined` + +The Account to send the transaction from. + +::: code-group +```tsx [index.tsx] +import { usePrepareTransactionRequest } from 'wagmi' +import { parseEther } from 'viem' + +function App() { + const result = usePrepareTransactionRequest({ + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', // [!code focus] + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + value: parseEther('1'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### to + +`` `0x${string}` | undefined `` + +The transaction recipient or contract address. + +::: code-group +```tsx [index.tsx] +import { usePrepareTransactionRequest } from 'wagmi' +import { parseEther } from 'viem' + +function App() { + const result = usePrepareTransactionRequest({ + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', // [!code focus] + value: parseEther('1'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### accessList + +`AccessList | undefined` + +The access list. + +::: code-group +```tsx [index.tsx] +import { usePrepareTransactionRequest } from 'wagmi' +import { parseEther } from 'viem' + +function App() { + const result = usePrepareTransactionRequest({ + accessList: [ // [!code focus:6] + { + address: '0x1', + storageKeys: ['0x1'], + }, + ], + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + value: parseEther('1'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +Chain ID to prepare the transaction request for. + +::: code-group +```tsx [index.tsx] +import { usePrepareTransactionRequest } from 'wagmi' +import { parseEther } from 'viem' + +function App() { + const result = usePrepareTransactionRequest({ + chainId: mainnet.id, // [!code focus] + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + value: parseEther('1'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### data + +`` `0x${string}` | undefined `` + +A contract hashed method call with encoded args. + +::: code-group +```tsx [index.tsx] +import { usePrepareTransactionRequest } from 'wagmi' +import { parseEther } from 'viem' + +function App() { + const result = usePrepareTransactionRequest({ + data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', // [!code focus] + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + value: parseEther('1'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### gasPrice + +`bigint | undefined` + +The price (in wei) to pay per gas. Only applies to [Legacy Transactions](https://viem.sh/docs/glossary/terms.html#legacy-transaction). + +::: code-group +```tsx [index.tsx] +import { usePrepareTransactionRequest } from 'wagmi' +import { parseEther, parseGwei } from 'viem' + +function App() { + const result = usePrepareTransactionRequest({ + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + gasPrice: parseGwei('20'), // [!code focus] + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + value: parseEther('1'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### maxFeePerGas + +`bigint | undefined` + +Total fee per gas (in wei), inclusive of `maxPriorityFeePerGas`. Only applies to [EIP-1559 Transactions](https://viem.sh/docs/glossary/terms.html#eip-1559-transaction). + +::: code-group +```tsx [index.tsx] +import { usePrepareTransactionRequest } from 'wagmi' +import { parseEther, parseGwei } from 'viem' + +function App() { + const result = usePrepareTransactionRequest({ + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + maxFeePerGas: parseGwei('20'), // [!code focus] + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + value: parseEther('1'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### maxPriorityFeePerGas + +`bigint | undefined` + +Max priority fee per gas (in wei). Only applies to [EIP-1559 Transactions](https://viem.sh/docs/glossary/terms.html#eip-1559-transaction). + +::: code-group +```tsx [index.tsx] +import { usePrepareTransactionRequest } from 'wagmi' +import { parseEther, parseGwei } from 'viem' + +function App() { + const result = usePrepareTransactionRequest({ + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + maxFeePerGas: parseGwei('20'), + maxPriorityFeePerGas: parseGwei('2'), // [!code focus] + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + value: parseEther('1'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### nonce + +`number | undefined` + +Unique number identifying this transaction. + +::: code-group +```tsx [index.tsx] +import { usePrepareTransactionRequest } from 'wagmi' +import { parseEther } from 'viem' + +function App() { + const result = usePrepareTransactionRequest({ + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + value: parseEther('1'), + nonce: 5, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### parameters + +`("fees" | "gas" | "nonce" | "type")[] | undefined` + +Parameters to prepare. + +For instance, if `["gas", "nonce"]` is provided, then only the `gas` and `nonce` parameters will be prepared. + +::: code-group +```tsx [index.tsx] +import { usePrepareTransactionRequest } from 'wagmi' +import { parseEther } from 'viem' + +function App() { + const result = usePrepareTransactionRequest({ + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + parameters: ['gas', 'nonce'], // [!code focus] + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + value: parseEther('1'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### value + +`bigint | undefined` + +Value in wei sent with this transaction. + +::: code-group +```tsx [index.tsx] +import { usePrepareTransactionRequest } from 'wagmi' +import { parseEther } from 'viem' + +function App() { + const result = usePrepareTransactionRequest({ + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + value: parseEther('1'), // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { usePrepareTransactionRequest } from 'wagmi' +import { parseEther } from 'viem' +import { config } from './config' // [!code focus] + +function App() { + const result = usePrepareTransactionRequest({ + config, // [!code focus] + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + value: parseEther('1'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Hooks that have identical context will share the same cache. + +::: code-group +```tsx [index.tsx] +import { usePrepareTransactionRequest } from 'wagmi' +import { parseEther } from 'viem' +import { config } from './config' + +function App() { + const result = usePrepareTransactionRequest({ + scopeKey: 'foo' // [!code focus] + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + value: parseEther('1'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UsePrepareTransactionRequestReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`prepareTransactionRequest`](/core/api/actions/prepareTransactionRequest) diff --git a/wagmi-project/site/react/api/hooks/useProof.md b/wagmi-project/site/react/api/hooks/useProof.md new file mode 100644 index 000000000..76adcdca4 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useProof.md @@ -0,0 +1,224 @@ +--- +title: useProof +description: Hook for return the account and storage values of the specified account including the Merkle-proof. +--- + + + +# useProof + +Hook for return the account and storage values of the specified account including the Merkle-proof. + +## Import + +```ts +import { useProof } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useProof } from 'wagmi' + +function App() { + const result = useProof({ + address: '0x4200000000000000000000000000000000000016', + storageKeys: [ + '0x4a932049252365b3eedbc5190e18949f2ec11f39d3bef2d259764799a1b27d99', + ], + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseProofParameters } from 'wagmi' +``` + +### address + +`Address | undefined` + +The account address to get the proof for. + +::: code-group +```tsx [index.tsx] +import { useProof } from 'wagmi' + +function App() { + const result = useProof({ + address: '0x4200000000000000000000000000000000000016', // [!code focus] + storageKeys: [ + '0x4a932049252365b3eedbc5190e18949f2ec11f39d3bef2d259764799a1b27d99', + ], + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### storageKeys + +`` `0x${string}`[] | undefined `` + +Array of storage-keys that should be proofed and included. + +::: code-group +```tsx [index.tsx] +import { useProof } from 'wagmi' + +function App() { + const result = useProof({ + address: '0x4200000000000000000000000000000000000016', + storageKeys: [ // [!code focus:3] + '0x4a932049252365b3eedbc5190e18949f2ec11f39d3bef2d259764799a1b27d99', + ], + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### blockNumber + +`bigint | undefined` + +Proof at a given block number. + +::: code-group +```tsx [index.tsx] +import { useProof } from 'wagmi' + +function App() { + const result = useProof({ + address: '0x4200000000000000000000000000000000000016', + blockNumber: 42069n, // [!code focus] + storageKeys: [ + '0x4a932049252365b3eedbc5190e18949f2ec11f39d3bef2d259764799a1b27d99', + ], + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Proof at a given block tag. + +::: code-group +```tsx [index.tsx] +import { useProof } from 'wagmi' + +function App() { + const result = useProof({ + address: '0x4200000000000000000000000000000000000016', + blockTag: 'latest', // [!code focus] + storageKeys: [ + '0x4a932049252365b3eedbc5190e18949f2ec11f39d3bef2d259764799a1b27d99', + ], + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +The ID of chain to get the proof for. + +::: code-group +```tsx [index.tsx] +import { useProof } from 'wagmi' +import { optimism } from 'wagmi/chains' + +function App() { + const result = useProof({ + chainId: optimism.id, // [!code focus] + address: '0x4200000000000000000000000000000000000016', + storageKeys: [ + '0x4a932049252365b3eedbc5190e18949f2ec11f39d3bef2d259764799a1b27d99', + ], + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useProof } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useProof({ + config, // [!code focus] + address: '0x4200000000000000000000000000000000000016', + storageKeys: [ + '0x4a932049252365b3eedbc5190e18949f2ec11f39d3bef2d259764799a1b27d99', + ], + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Hooks that have identical context will share the same cache. + +::: code-group +```tsx [index.tsx] +import { useProof } from 'wagmi' +import { config } from './config' + +function App() { + const result = useProof({ + scopeKey: 'foo' // [!code focus] + address: '0x4200000000000000000000000000000000000016', + storageKeys: [ + '0x4a932049252365b3eedbc5190e18949f2ec11f39d3bef2d259764799a1b27d99', + ], + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseProofReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`getProof`](/core/api/actions/getProof) diff --git a/wagmi-project/site/react/api/hooks/usePublicClient.md b/wagmi-project/site/react/api/hooks/usePublicClient.md new file mode 100644 index 000000000..9f0411055 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/usePublicClient.md @@ -0,0 +1,93 @@ +--- +title: usePublicClient +description: Hook for getting Viem `PublicClient` instance. +--- + +# usePublicClient + +Hook for getting Viem [`PublicClient`](https://viem.sh/docs/clients/public.html) instance. + +## Import + +```ts +import { usePublicClient } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { usePublicClient } from 'wagmi' + +function App() { + const client = usePublicClient() +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +::: warning +If you want to optimize bundle size, you should use [`useClient`](/react/api/hooks/useClient) along with Viem's [tree-shakable actions](https://viem.sh/docs/clients/custom.html#tree-shaking) instead. Since Public Client has all public actions attached directly to it. +::: + +## Parameters + +```ts +import { type UsePublicClientParameters } from 'wagmi' +``` + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when getting Viem Public Client. + +::: code-group +```ts [index.ts] +import { usePublicClient } from 'wagmi' +import { mainnet } from 'wagmi/chains' // [!code focus] +import { config } from './config' + +function App() { + const client = usePublicClient({ + chainId: mainnet.id, // [!code focus] + }) +} +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { usePublicClient } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const client = usePublicClient({ + config, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type UsePublicClientReturnType } from 'wagmi' +``` + +`PublicClient | undefined` + +Viem [`PublicClient`](https://viem.sh/docs/clients/public.html) instance. + +## Action + +- [`getPublicClient`](/core/api/actions/getPublicClient) +- [`watchPublicClient`](/core/api/actions/watchPublicClient) diff --git a/wagmi-project/site/react/api/hooks/useReadContract.md b/wagmi-project/site/react/api/hooks/useReadContract.md new file mode 100644 index 000000000..07be91e01 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useReadContract.md @@ -0,0 +1,406 @@ +--- +title: useReadContract +description: Hook for calling a read-only function on a contract, and returning the response. +--- + + + +# useReadContract + +Hook for calling a **read-only** function on a contract, and returning the response. + +A **read-only** function (constant function) on a Solidity contract is denoted by a pure or view keyword. They can only read the state of the contract, and cannot make any changes to it. Since read-only methods do not change the state of the contract, they do not require any gas to be executed, and can be called by any user without the need to pay for gas. + +## Import + +```ts +import { useReadContract } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useReadContract } from 'wagmi' +import { abi } from './abi' + +function App() { + const result = useReadContract({ + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'totalSupply', + }) +} +``` +<<< @/snippets/abi-read.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseReadContractParameters } from 'wagmi' +``` + +### abi + +`Abi | undefined` + +The contract's ABI. Check out the [TypeScript docs](/react/typescript#const-assert-abis-typed-data) for how to set up ABIs for maximum type inference and safety. + +::: code-group +```tsx [index.tsx] +import { useReadContract } from 'wagmi' +import { abi } from './abi' // [!code focus] + +function App() { + const result = useReadContract({ + abi, // [!code focus] + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'totalSupply', + }) +} +``` +<<< @/snippets/abi-read.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +### account + +`Account | undefined` + +Account to use when calling the contract (`msg.sender`). + +::: code-group +```tsx [index.tsx] +import { useReadContract } from 'wagmi' +import { abi } from './abi' + +function App() { + const result = useReadContract({ + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'balanceOf', + args: ['0x6b175474e89094c44da98b954eedeac495271d0f'], + account: '0xd2135CfB216b74109775236E36d4b433F1DF507B', // [!code focus] + }) +} +``` +<<< @/snippets/abi-read.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +### address + +`Address | undefined` + +The contract's address. + +::: code-group +```tsx [index.tsx] +import { useReadContract } from 'wagmi' +import { abi } from './abi' + +function App() { + const result = useReadContract({ + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', // [!code focus] + functionName: 'totalSupply', + }) +} +``` +<<< @/snippets/abi-read.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +### args + +`readonly unknown[] | undefined` + +- Arguments to pass when calling the contract. +- Inferred from [`abi`](#abi) and [`functionName`](#functionname). + +::: code-group +```tsx [index.tsx] +import { useReadContract } from 'wagmi' +import { abi } from './abi' + +function App() { + const result = useReadContract({ + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'balanceOf', + args: ['0x6b175474e89094c44da98b954eedeac495271d0f'], // [!code focus] + }) +} +``` +<<< @/snippets/abi-read.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +--- + +### blockNumber + +`bigint | undefined` + +Block number to call contract at. + +::: code-group +```tsx [index.tsx] +import { useReadContract } from 'wagmi' +import { abi } from './abi' + +function App() { + const result = useReadContract({ + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'totalSupply', + blockNumber: 17829139n, // [!code focus] + }) +} +``` +<<< @/snippets/abi-read.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Block tag to call contract at. + +::: code-group +```tsx [index.tsx] +import { useReadContract } from 'wagmi' +import { abi } from './abi' + +function App() { + const result = useReadContract({ + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'totalSupply', + blockTag: 'safe', // [!code focus] + }) +} +``` +<<< @/snippets/abi-read.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +--- + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```tsx [index.tsx] +import { useReadContract } from 'wagmi' +import { mainnet } from 'wagmi/chains' // [!code focus] +import { abi } from './abi' + +function App() { + const result = useReadContract({ + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'totalSupply', + chainId: mainnet.id, // [!code focus] + }) +} +``` +<<< @/snippets/abi-read.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useReadContract } from 'wagmi' +import { abi } from './abi' +import { config } from './config' // [!code focus] + +function App() { + const result = useReadContract({ + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'totalSupply', + config, // [!code focus] + }) +} +``` +<<< @/snippets/abi-read.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +### functionName + +`string | undefined` + +- Function to call on the contract. +- Inferred from [`abi`](#abi). + +::: code-group +```tsx [index.tsx] +import { useReadContract } from 'wagmi' +import { abi } from './abi' + +function App() { + const result = useReadContract({ + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'balanceOf', // [!code focus] + args: ['0x6b175474e89094c44da98b954eedeac495271d0f'], + }) +} +``` +<<< @/snippets/abi-read.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Hooks that have identical context will share the same cache. + +::: code-group +```tsx [index.tsx] +import { useReadContract } from 'wagmi' +import { abi } from './abi' + +function App() { + const result = useReadContract({ + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'balanceOf', + args: ['0x6b175474e89094c44da98b954eedeac495271d0f'], + scopeKey: 'foo', // [!code focus] + }) +} +``` +<<< @/snippets/abi-read.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseReadContractReturnType } from 'wagmi' +``` + +The return type's [`data`](#data) property is inferrable via the combination of [`abi`](#abi), [`functionName`](#functionname), and [`args`](#args). Check out the [TypeScript docs](/react/typescript#const-assert-abis-typed-data) for more info. + + + +## Type Inference + +With [`abi`](#abi) setup correctly, TypeScript will infer the correct types for [`functionName`](#functionname), [`args`](#args), and the return type. See the Wagmi [TypeScript docs](/react/typescript) for more information. + +::: code-group +```ts twoslash [Inline] +import { createConfig, http, useReadContract } from 'wagmi' +import { mainnet, sepolia } from 'wagmi/chains' + +const config = createConfig({ + chains: [mainnet, sepolia], + transports: { + [mainnet.id]: http(), + [sepolia.id]: http(), + }, +}) +// ---cut--- +const result = useReadContract({ + abi: [ + { + type: 'function', + name: 'balanceOf', + stateMutability: 'view', + inputs: [{ name: 'account', type: 'address' }], + outputs: [{ type: 'uint256' }], + }, + { + type: 'function', + name: 'totalSupply', + stateMutability: 'view', + inputs: [], + outputs: [{ name: 'supply', type: 'uint256' }], + }, + ], + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'balanceOf', + // ^? + + + args: ['0x6b175474e89094c44da98b954eedeac495271d0f'], + // ^? +}) + +result.data +// ^? +``` +```ts twoslash [Const-Asserted] +import { createConfig, http, useReadContract } from 'wagmi' +import { mainnet, sepolia } from 'wagmi/chains' + +const config = createConfig({ + chains: [mainnet, sepolia], + transports: { + [mainnet.id]: http(), + [sepolia.id]: http(), + }, +}) +// ---cut--- +const abi = [ + { + type: 'function', + name: 'balanceOf', + stateMutability: 'view', + inputs: [{ name: 'account', type: 'address' }], + outputs: [{ type: 'uint256' }], + }, + { + type: 'function', + name: 'totalSupply', + stateMutability: 'view', + inputs: [], + outputs: [{ name: 'supply', type: 'uint256' }], + }, +] as const + +const result = useReadContract({ + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'balanceOf', + // ^? + + + args: ['0x6b175474e89094c44da98b954eedeac495271d0f'], + // ^? +}) + +result.data +// ^? +``` +::: + + + +## Action + +- [`readContract`](/core/api/actions/readContract) diff --git a/wagmi-project/site/react/api/hooks/useReadContracts.md b/wagmi-project/site/react/api/hooks/useReadContracts.md new file mode 100644 index 000000000..48436c936 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useReadContracts.md @@ -0,0 +1,394 @@ +--- +title: useReadContracts +description: Hook for calling multiple read methods on a contract. +--- + +# useReadContracts + +Hook for calling multiple read methods on a contract. + +## Import + +```ts +import { useReadContracts } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useReadContracts } from 'wagmi' + +const wagmigotchiContract = { + address: '0xecb504d39723b0be0e3a9aa33d646642d1051ee1', + abi: wagmigotchiABI, +} as const +const mlootContract = { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi: mlootABI, +} as const + +function App() { + const result = useReadContracts({ + contracts: [ + { + ...wagmigotchiContract, + functionName: 'getAlive', + }, + { + ...wagmigotchiContract, + functionName: 'getBoredom', + }, + { + ...mlootContract, + functionName: 'getChest', + args: [69], + }, + { + ...mlootContract, + functionName: 'getWaist', + args: [69], + }, + ], + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseReadContractsParameters } from 'wagmi' +``` + +### contracts + +`readonly Contract[]` + +Set of contracts to call. + +#### abi + +`Abi | undefined` + +The contract's ABI. Check out the [TypeScript docs](/react/typescript#const-assert-abis-typed-data) for how to set up ABIs for maximum type inference and safety. + +::: code-group +```tsx [index.tsx] +import { useReadContracts } from 'wagmi' + +function App() { + const result = useReadContracts({ + contracts: [ + { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi: mlootABI, // [!code hl] + functionName: 'getChest', + args: [69], + }, + // ... + ], + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +#### address + +`Address | undefined` + +The contract's address. + +::: code-group +```tsx [index.tsx] +import { useReadContracts } from 'wagmi' + +function App() { + const result = useReadContracts({ + contracts: [ + { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', // [!code hl] + abi: mlootABI, + functionName: 'getChest', + args: [69], + }, + // ... + ], + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +#### functionName + +`string | undefined` + +- Function to call on the contract. +- Inferred from [`abi`](#abi). + +::: code-group +```tsx [index.tsx] +import { useReadContracts } from 'wagmi' + +function App() { + const result = useReadContracts({ + contracts: [ + { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi: mlootABI, + functionName: 'getChest', // [!code hl] + args: [69], + }, + // ... + ], + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +#### args + +`readonly unknown[] | undefined` + +- Arguments to pass when calling the contract. +- Inferred from [`abi`](#abi) and [`functionName`](#functionname). + +::: code-group +```tsx [index.tsx] +import { useReadContracts } from 'wagmi' + +function App() { + const result = useReadContracts({ + contracts: [ + { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi: mlootABI, + functionName: 'getChest', + args: [69], // [!code hl] + }, + // ... + ], + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +#### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```tsx [index.tsx] +import { useReadContracts } from 'wagmi' + +function App() { + const result = useReadContracts({ + contracts: [ + { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi: mlootABI, + functionName: 'getChest', + args: [69], + chainId: 1 // [!code hl] + }, + // ... + ], + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + +### allowFailure + +`boolean` + +Whether or not the Hook should throw if a call reverts. If set to `true` (default), and a call reverts, then `useReadContracts` will fail silently and its error will be logged in the results array. Defaults to `true`. + +::: code-group +```tsx [index.tsx] +import { useReadContracts } from 'wagmi' + +function App() { + const result = useReadContracts({ + allowFailure: false, // [!code hl] + contracts: [ + { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi: mlootABI, + functionName: 'getChest', + args: [69] + }, + // ... + ], + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + +### batchSize + +`number` + +The maximum size (in bytes) for each calldata chunk. Set to `0` to disable the size limit. Defaults to `1024`. + +> Note: Some RPC Providers limit the amount of calldata (`data`) that can be sent in a single `eth_call` request. It is best to check with your RPC Provider to see if there are any calldata size limits to `eth_call` requests. + +::: code-group +```tsx [index.tsx] +import { useReadContracts } from 'wagmi' + +function App() { + const result = useReadContracts({ + batchSize: 1024, // [!code hl] + contracts: [ + { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi: mlootABI, + functionName: 'getChest', + args: [69] + }, + // ... + ], + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### blockNumber + +`number` + +The block number to perform the read against. + +::: code-group +```tsx [index.tsx] +import { useReadContracts } from 'wagmi' + +function App() { + const result = useReadContracts({ + blockNumber: 69420n, // [!code hl] + contracts: [ + { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi: mlootABI, + functionName: 'getChest', + args: [69] + }, + // ... + ], + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Block tag to read against. + +::: code-group +```tsx [index.tsx] +import { useReadContracts } from 'wagmi' + +function App() { + const result = useReadContracts({ + blockTag: 'safe', // [!code hl] + contracts: [ + { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi: mlootABI, + functionName: 'getChest', + args: [69] + }, + // ... + ], + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useReadContracts } from 'wagmi' +import { config } from './config' + +function App() { + const result = useReadContracts({ + config, // [!code hl] + contracts: [ + { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi: mlootABI, + functionName: 'getChest', + args: [69] + }, + // ... + ], + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### multicallAddress + +`Address` + +Address of multicall contract. + +::: code-group +```tsx [index.tsx] +import { useReadContracts } from 'wagmi' + +function App() { + const result = useReadContracts({ + contracts: [ + { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi: mlootABI, + functionName: 'getChest', + args: [69] + }, + // ... + ], + multicallAddress: '0xca11bde05977b3631167028862be2a173976ca11', // [!code hl] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseReadContractsReturnType } from 'wagmi' +``` + + + +## Action + +- [`readContracts`](/core/api/actions/readContracts) diff --git a/wagmi-project/site/react/api/hooks/useReconnect.md b/wagmi-project/site/react/api/hooks/useReconnect.md new file mode 100644 index 000000000..7aff4945c --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useReconnect.md @@ -0,0 +1,111 @@ +--- +title: useReconnect +description: Hook for reconnecting connectors. +--- + + + +# useReconnect + +Hook for reconnecting [connectors](/core/api/connectors). + +## Import + +```ts +import { useReconnect } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useReconnect } from 'wagmi' +import { useEffect } from 'react' + +function App() { + const { reconnect } = useReconnect() + + useEffect(() => { + reconnect() + }, []) +} +``` + +::: + +::: tip +When [`WagmiProvider['reconnectOnMount']`](/react/api/WagmiProvider#reconnectonmount) is `true`, `reconnect` is called automatically on mount. +::: + +## Parameters + +```ts +import { type UseReconnectParameters } from 'wagmi' +``` + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useReconnect } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useReconnect({ + config, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseReconnectReturnType } from 'wagmi' +``` + +### connectors + +`readonly Connector[]` + +Globally configured connectors via [`createConfig`](/react/api/createConfig#connectors). + +::: code-group +```tsx [index.tsx] +import { useReconnect } from 'wagmi' +import { mainnet } from 'wagmi/chains' +import { useEffect } from 'react' + +function App() { + const { reconnect, connectors } = useReconnect() + + useEffect(() => { + reconnect({ connectors }) + }, []) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + + + +## Action + +- [`reconnect`](/core/api/actions/reconnect) diff --git a/wagmi-project/site/react/api/hooks/useSendCalls.md b/wagmi-project/site/react/api/hooks/useSendCalls.md new file mode 100644 index 000000000..d7020fd8b --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useSendCalls.md @@ -0,0 +1,103 @@ +--- +title: useSendCalls +description: Hook that requests for the wallet to sign and broadcast a batch of calls (transactions) to the network. +--- + + + +# useSendCalls + +Hook that requests for the wallet to sign and broadcast a batch of calls (transactions) to the network. + +[Read more.](https://github.com/ethereum/EIPs/blob/815028dc634463e1716fc5ce44c019a6040f0bef/EIPS/eip-5792.md#wallet_sendcalls) + +## Import + +```ts +import { useSendCalls } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useSendCalls } from 'wagmi' +import { parseEther } from 'viem' + +function App() { + const { sendCalls } = useSendCalls() + + return ( + + ) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseSendCallsParameters } from 'wagmi' +``` + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useSendCalls } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useSendCalls({ + config, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseSendCallsReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`sendCalls`](/core/api/actions/sendCalls) diff --git a/wagmi-project/site/react/api/hooks/useSendTransaction.md b/wagmi-project/site/react/api/hooks/useSendTransaction.md new file mode 100644 index 000000000..c9d4bf441 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useSendTransaction.md @@ -0,0 +1,93 @@ +--- +title: useSendTransaction +description: Hook for creating, signing, and sending transactions to networks. +--- + + + +# useSendTransaction + +Hook for creating, signing, and sending transactions to networks. + +## Import + +```ts +import { useSendTransaction } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useSendTransaction } from 'wagmi' +import { parseEther } from 'viem' + +function App() { + const { sendTransaction } = useSendTransaction() + + return ( + + ) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseSendTransactionParameters } from 'wagmi' +``` + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useSendTransaction } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useSendTransaction({ + config, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseSendTransactionReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`sendTransaction`](/core/api/actions/sendTransaction) diff --git a/wagmi-project/site/react/api/hooks/useShowCallsStatus.md b/wagmi-project/site/react/api/hooks/useShowCallsStatus.md new file mode 100644 index 000000000..6fb26e9f0 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useShowCallsStatus.md @@ -0,0 +1,96 @@ +--- +title: useShowCallsStatus +description: Action to request for the wallet to show information about a call batch +--- + + + +# useShowCallsStatus + +Action to request for the wallet to show information about a call batch that was sent via `useShowCalls`. + +[Read more.](https://github.com/ethereum/EIPs/blob/1663ea2e7a683285f977eda51c32cec86553f585/EIPS/eip-5792.md#wallet_showcallsstatus) + + + +## Import + +```ts +import { useShowCallsStatus } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useShowCallsStatus } from 'wagmi' +import { parseEther } from 'viem' + +function App() { + const { showCallsStatus } = useShowCallsStatus() + + return ( + + ) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseShowCallsStatusParameters } from 'wagmi' +``` + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useShowCallsStatus } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useShowCallsStatus({ + config, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseShowCallsStatusReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`showCallsStatus`](/core/api/actions/showCallsStatus) diff --git a/wagmi-project/site/react/api/hooks/useSignMessage.md b/wagmi-project/site/react/api/hooks/useSignMessage.md new file mode 100644 index 000000000..7b0ffb3a4 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useSignMessage.md @@ -0,0 +1,85 @@ +--- +title: useSignMessage +description: Hook for signing messages. +--- + + + +# useSignMessage + +Hook for signing messages. + +## Import + +```ts +import { useSignMessage } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useSignMessage } from 'wagmi' + +function App() { + const { signMessage } = useSignMessage() + + return ( + + ) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseSignMessageParameters } from 'wagmi' +``` + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useSignMessage } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useSignMessage({ + config, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseSignMessageReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`signMessage`](/core/api/actions/signMessage) diff --git a/wagmi-project/site/react/api/hooks/useSignTypedData.md b/wagmi-project/site/react/api/hooks/useSignTypedData.md new file mode 100644 index 000000000..140b0e86a --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useSignTypedData.md @@ -0,0 +1,217 @@ +--- +title: useSignTypedData +description: Hook for signing typed data and calculating an Ethereum-specific EIP-712 signature. +--- + + + +# useSignTypedData + +Hook for signing typed data and calculating an Ethereum-specific [EIP-712](https://eips.ethereum.org/EIPS/eip-712) signature. + +## Import + +```ts +import { useSignTypedData } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useSignTypedData } from 'wagmi' + + +function App() { + const { signTypedData } = useSignTypedData() + + return ( + + ) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseSignTypedDataParameters } from 'wagmi' +``` + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useSignTypedData } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useSignTypedData({ + config, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseSignTypedDataReturnType } from 'wagmi' +``` + + + +## Type Inference + +With [`types`](/core/api/actions/signTypedData#types) setup correctly, TypeScript will infer the correct types for [`domain`](/core/api/actions/signTypedData#domain), [`message`](/core/api/actions/signTypedData#message), and [`primaryType`](/core/api/actions/signTypedData#primarytype). See the Wagmi [TypeScript docs](/react/typescript) for more information. + +::: code-group +```ts twoslash [Inline] +import { useSignTypedData } from 'wagmi' +// ---cut--- +const { signTypedData } = useSignTypedData() + +signTypedData({ + types: { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], + }, + primaryType: 'Mail', + // ^? + + + message: { + // ^? + + + + + + + + + + + + + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, +}) +``` +```ts twoslash [Const-Asserted] +import { useSignTypedData } from 'wagmi' +// ---cut--- +const types = { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], +} as const + +const { signTypedData } = useSignTypedData() + +signTypedData({ + types, + primaryType: 'Mail', + // ^? + + + message: { + // ^? + + + + + + + + + + + + + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, +}) +``` +::: + + + +## Action + +- [`signTypedData`](/core/api/actions/signTypedData) diff --git a/wagmi-project/site/react/api/hooks/useSimulateContract.md b/wagmi-project/site/react/api/hooks/useSimulateContract.md new file mode 100644 index 000000000..03872f53e --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useSimulateContract.md @@ -0,0 +1,686 @@ +--- +title: useSimulateContract +description: Hook for simulating/validating a contract interaction. +--- + + + +# useSimulateContract + +Hook for simulating/validating a contract interaction. + +## Import + +```ts +import { useSimulateContract } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useSimulateContract } from 'wagmi' +import { abi } from './abi' + +function App() { + const result = useSimulateContract({ + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + }) +} +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Parameters + +```ts +import { type UseSimulateContractParameters } from 'wagmi' +``` + +### abi + +`Abi | undefined` + +The contract's ABI. Check out the [TypeScript docs](/react/typescript#const-assert-abis-typed-data) for how to set up ABIs for maximum type inference and safety. + +::: code-group +```tsx [index.tsx] +import { useSimulateContract } from 'wagmi' +import { abi } from './abi' // [!code focus] + +function App() { + const result = useSimulateContract({ + abi, // [!code focus] + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + }) +} +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +### accessList + +`AccessList | undefined` + +The access list. + +::: code-group +```tsx [index.ts] +import { useSimulateContract } from 'wagmi' +import { abi } from './abi' +import { config } from './config' + +function App() { + const result = useSimulateContract({ + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + accessList: [{ // [!code focus] + address: '0x1', // [!code focus] + storageKeys: ['0x1'], // [!code focus] + }], // [!code focus] + }) +} +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +### account + +`Account | undefined` + +Account to use when calling the contract (`msg.sender`). Throws if account is not found on [`connector`](#connector). + +::: code-group +```tsx [index.tsx] +import { useSimulateContract } from 'wagmi' +import { abi } from './abi' + +function App() { + const result = useSimulateContract({ + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + account: '0xd2135CfB216b74109775236E36d4b433F1DF507B', // [!code focus] + }) +} +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +### address + +`Address | undefined` + +The contract's address. + +::: code-group +```tsx [index.tsx] +import { useSimulateContract } from 'wagmi' +import { abi } from './abi' + +function App() { + const result = useSimulateContract({ + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', // [!code focus] + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + }) +} +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +### args + +`readonly unknown[] | undefined` + +- Arguments to pass when calling the contract. +- Inferred from [`abi`](#abi) and [`functionName`](#functionname). + +::: code-group +```tsx [index.tsx] +import { useSimulateContract } from 'wagmi' +import { abi } from './abi' + +function App() { + const result = useSimulateContract({ + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ // [!code focus] + '0xd2135CfB216b74109775236E36d4b433F1DF507B', // [!code focus] + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', // [!code focus] + 123n, // [!code focus] + ], // [!code focus] + }) +} +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +--- + +### blockNumber + +`bigint | undefined` + +Block number to call contract at. + +::: code-group +```tsx [index.tsx] +import { useSimulateContract } from 'wagmi' +import { abi } from './abi' + +function App() { + const result = useSimulateContract({ + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + blockNumber: 17829139n, // [!code focus] + }) +} +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Block tag to call contract at. + +::: code-group +```tsx [index.tsx] +import { useSimulateContract } from 'wagmi' +import { abi } from './abi' + +function App() { + const result = useSimulateContract({ + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + blockTag: 'safe', // [!code focus] + }) +} +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +--- + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```tsx [index.tsx] +import { useSimulateContract } from 'wagmi' +import { mainnet } from 'wagmi/chains' // [!code focus] +import { abi } from './abi' + +function App() { + const result = useSimulateContract({ + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + chainId: mainnet.id, // [!code focus] + }) +} +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useSimulateContract } from 'wagmi' +import { abi } from './abi' +import { config } from './config' // [!code focus] + +function App() { + const result = useSimulateContract({ + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + config, // [!code focus] + }) +} +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +### connector + +`Connector | undefined` + +[Connector](/react/api/connectors) to simulate transaction with. + +::: code-group +```tsx [index.ts] +import { useConnectorClient, useSimulateContract } from 'wagmi' +import { abi } from './abi' +import { config } from './config' + +function App() { + const { data: connector } = useConnectorClient() + const result = useSimulateContract({ + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + connector, // [!code focus] + }) +} +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +### dataSuffix + +`` `0x${string}` | undefined `` + +Data to append to the end of the calldata. Useful for adding a ["domain" tag](https://opensea.notion.site/opensea/Seaport-Order-Attributions-ec2d69bf455041a5baa490941aad307f). + +::: code-group +```tsx [index.ts] +import { useSimulateContract } from 'wagmi' +import { parseGwei } from 'viem' +import { abi } from './abi' +import { config } from './config' + +function App() { + const result = useSimulateContract({ + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + dataSuffix: '0xdeadbeef', // [!code focus] + }) +} +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +### functionName + +`string | undefined` + +- Function to call on the contract. +- Inferred from [`abi`](#abi). + +::: code-group +```tsx [index.tsx] +import { useSimulateContract } from 'wagmi' +import { abi } from './abi' + +function App() { + const result = useSimulateContract({ + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', // [!code focus] + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + }) +} +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +### gas + +`bigint | undefined` + +Gas provided for transaction execution. + +::: code-group +```tsx [index.ts] +import { useSimulateContract } from 'wagmi' +import { parseGwei } from 'viem' +import { abi } from './abi' +import { config } from './config' + +function App() { + const result = useSimulateContract({ + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + gas: parseGwei('20'), // [!code focus] + }) +} +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +--- + +### gasPrice + +`bigint | undefined` + +The price in wei to pay per gas. Only applies to [Legacy Transactions](https://viem.sh/docs/glossary/terms.html#legacy-transaction). + +::: code-group +```tsx [index.ts] +import { useSimulateContract } from 'wagmi' +import { parseGwei } from 'viem' +import { abi } from './abi' +import { config } from './config' + +function App() { + const result = useSimulateContract({ + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + gasPrice: parseGwei('20'), // [!code focus] + }) +} +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +### maxFeePerGas + +`bigint | undefined` + +Total fee per gas in wei, inclusive of [`maxPriorityFeePerGas`](#maxPriorityFeePerGas). Only applies to [EIP-1559 Transactions](https://viem.sh/docs/glossary/terms.html#eip-1559-transaction). + +::: code-group +```tsx [index.ts] +import { useSimulateContract } from 'wagmi' +import { parseGwei } from 'viem' +import { abi } from './abi' +import { config } from './config' + +function App() { + const result = useSimulateContract({ + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + maxFeePerGas: parseGwei('20'), // [!code focus] + }) +} +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +### maxPriorityFeePerGas + +`bigint | undefined` + +Max priority fee per gas in wei. Only applies to [EIP-1559 Transactions](https://viem.sh/docs/glossary/terms.html#eip-1559-transaction). + +::: code-group +```tsx [index.ts] +import { useSimulateContract } from 'wagmi' +import { parseGwei } from 'viem' +import { abi } from './abi' +import { config } from './config' + +function App() { + const result = useSimulateContract({ + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + maxFeePerGas: parseGwei('20'), + maxPriorityFeePerGas: parseGwei('2'), // [!code focus] + }) +} +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +--- + +### nonce + +`number` + +Unique number identifying this transaction. + +::: code-group +```tsx [index.ts] +import { useSimulateContract } from 'wagmi' +import { abi } from './abi' +import { config } from './config' + +function App() { + const result = useSimulateContract({ + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + nonce: 123, // [!code focus] + }) +} +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +### type + +`'legacy' | 'eip1559' | 'eip2930' | undefined` + +Optional transaction request type to narrow parameters. + +::: code-group +```tsx [index.ts] +import { useSimulateContract } from 'wagmi' +import { abi } from './abi' +import { config } from './config' + +function App() { + const result = useSimulateContract({ + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + type: 'eip1559', // [!code focus] + }) +} +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +### value + +`bigint | undefined` + +Value in wei sent with this transaction. + +::: code-group +```tsx [index.ts] +import { useSimulateContract } from 'wagmi' +import { parseEther } from 'viem' +import { abi } from './abi' +import { config } from './config' + +function App() { + const result = useSimulateContract({ + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + value: parseEther('0.01'), // [!code focus] + }) +} +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Hooks that have identical context will share the same cache. + +::: code-group +```tsx [index.ts] +import { useSimulateContract } from 'wagmi' +import { abi } from './abi' +import { config } from './config' + +function App() { + const result = useSimulateContract({ + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + scopeKey: 'foo', // [!code focus] + }) +} +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseSimulateContractReturnType } from 'wagmi' +``` + +The return type's [`data`](#data) property is inferrable via the combination of [`abi`](#abi), [`functionName`](#functionname), and [`args`](#args). Check out the [TypeScript docs](/react/typescript#const-assert-abis-typed-data) for more info. + + + +## Type Inference + +With [`abi`](#abi) setup correctly, TypeScript will infer the correct types for [`functionName`](#functionname), [`args`](#args), and [`value`](#value). See the Wagmi [TypeScript docs](/react/typescript) for more information. + + + +## Action + +- [`simulateContract`](/core/api/actions/simulateContract) diff --git a/wagmi-project/site/react/api/hooks/useStorageAt.md b/wagmi-project/site/react/api/hooks/useStorageAt.md new file mode 100644 index 000000000..12c524ac1 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useStorageAt.md @@ -0,0 +1,208 @@ +--- +title: useStorageAt +description: Hook for returning the value from a storage slot at a given address. +--- + + + +# useStorageAt + +Hook for for returning the value from a storage slot at a given address. + +## Import + +```ts +import { useStorageAt } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useStorageAt } from 'wagmi' + +function App() { + const result = useStorageAt({ + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + slot: '0x0', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseStorageAtParameters } from 'wagmi' +``` + +### address + +`Address | undefined` + +The contract address. + +::: code-group +```tsx [index.tsx] +import { useStorageAt } from 'wagmi' + +function App() { + const result = useStorageAt({ + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', // [!code focus] + slot: '0x0', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### slot + +`Hex | undefined` + +The storage position (as a hex encoded value). + +::: code-group +```tsx [index.tsx] +import { useStorageAt } from 'wagmi' + +function App() { + const result = useStorageAt({ + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + slot: '0x0', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## blockNumber + +`bigint | undefined` + +The block number to check the storage at. + +::: code-group +```tsx [index.tsx] +import { useStorageAt } from 'wagmi' + +function App() { + const result = useStorageAt({ + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + blockNumber: 16280770n, // [!code focus] + slot: '0x0', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +The block tag to check the storage at. + +::: code-group +```tsx [index.tsx] +import { useStorageAt } from 'wagmi' + +function App() { + const result = useStorageAt({ + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + blockTag: 'safe', // [!code focus] + slot: '0x0', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +The chain ID to check the storage at. + +::: code-group +```tsx [index.tsx] +import { useStorageAt } from 'wagmi' +import { mainnet } from '@wagmi/core/chains' + +function App() { + const result = useStorageAt({ + chainId: mainnet.id, // [!code focus] + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + slot: '0x0', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useStorageAt } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useStorageAt({ + config, // [!code focus] + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + slot: '0x0', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Hooks that have identical context will share the same cache. + +::: code-group +```tsx [index.tsx] +import { useStorageAt } from 'wagmi' +import { config } from './config' + +function App() { + const result = useStorageAt({ + scopeKey: 'foo' // [!code focus] + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + slot: '0x0', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseStorageAtReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`getStorageAt`](/core/api/actions/getStorageAt) diff --git a/wagmi-project/site/react/api/hooks/useSwitchAccount.md b/wagmi-project/site/react/api/hooks/useSwitchAccount.md new file mode 100644 index 000000000..8dc3395a7 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useSwitchAccount.md @@ -0,0 +1,116 @@ +--- +title: useSwitchAccount +description: Hook for switching the current account. +--- + + + +# useSwitchAccount + +Hook for switching the current account. + +## Import + +```ts +import { useSwitchAccount } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useSwitchAccount } from 'wagmi' + +function App() { + const { connectors, switchAccount } = useSwitchAccount() + + return ( +
+ {connectors.map((connector) => ( + + ))} +
+ ) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseSwitchAccountParameters } from 'wagmi' +``` + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useSwitchAccount } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useSwitchAccount({ + config, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseSwitchAccountReturnType } from 'wagmi' +``` + +### connectors + +`readonly Connector[]` + +Globally configured and actively connected connectors. Useful for rendering a list of available connectors to switch to. + +::: code-group +```tsx [index.tsx] +import { useSwitchAccount } from 'wagmi' + +function App() { + const { connectors, switchAccount } = useSwitchAccount() + + return ( +
+ {connectors.map((connector) => ( + + ))} +
+ ) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + + + +## Action + +- [`switchAccount`](/core/api/actions/switchAccount) diff --git a/wagmi-project/site/react/api/hooks/useSwitchChain.md b/wagmi-project/site/react/api/hooks/useSwitchChain.md new file mode 100644 index 000000000..3b139bd70 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useSwitchChain.md @@ -0,0 +1,120 @@ +--- +title: useSwitchChain +description: Hook for switching the target chain for a connector or the Wagmi `Config`. +--- + + + +# useSwitchChain + +Hook for switching the target chain for a connector or the Wagmi [`Config`](/react/api/createConfig#config). + +## Import + +```ts +import { useSwitchChain } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useSwitchChain } from 'wagmi' + +function App() { + const { chains, switchChain } = useSwitchChain() + + return ( +
+ {chains.map((chain) => ( + + ))} +
+ ) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +::: tip +When connected, `switchChain` will switch the target chain for the connector. When not connected, `switchChain` will switch the target chain for the Wagmi [`Config`](/react/api/createConfig#config). +::: + +## Parameters + +```ts +import { type UseSwitchChainParameters } from 'wagmi' +``` + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useSwitchChain } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useSwitchChain({ + config, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseSwitchChainReturnType } from 'wagmi' +``` + +### chains + +`readonly [Chain, ...Chain[]]` + +Globally configured chains. Useful for rendering a list of available chains to switch to. + +::: code-group +```tsx [index.tsx] +import { useSwitchChain } from 'wagmi' + +function App() { + const { chains, switchChain } = useSwitchChain() + + return ( +
+ {chains.map((chain) => ( + + ))} +
+ ) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + + + +## Action + +- [`switchChain`](/core/api/actions/switchChain) diff --git a/wagmi-project/site/react/api/hooks/useToken.md b/wagmi-project/site/react/api/hooks/useToken.md new file mode 100644 index 000000000..cd4c6dbec --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useToken.md @@ -0,0 +1,162 @@ +--- +title: useToken +description: Hook for fetching token info. +--- + + + +# useToken [deprecated](/react/guides/migrate-from-v1-to-v2#deprecated-usetoken) + +Hook for fetching token info. + +## Import + +```ts +import { useToken } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useToken } from 'wagmi' + +function App() { + const result = useToken({ + address: '0x6B175474E89094C44Da98b954EedeAC495271d0F', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseTokenParameters } from 'wagmi' +``` + +### address + +`Address | undefined` + +Address to get token for. [`enabled`](#enabled) set to `false` if `address` is `undefined`. + +::: code-group +```tsx [index.tsx] +import { useToken } from 'wagmi' +import { mainnet } from 'wagmi/chains' + +function App() { + const result = useToken({ + address: '0x6B175474E89094C44Da98b954EedeAC495271d0F', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```tsx [index.tsx] +import { useToken } from 'wagmi' +import { mainnet } from 'wagmi/chains' // [!code focus] + +function App() { + const result = useToken({ + address: '0x6B175474E89094C44Da98b954EedeAC495271d0F', + chainId: mainnet.id, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useToken } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useToken({ + address: '0x6B175474E89094C44Da98b954EedeAC495271d0F', + config, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### formatUnits + +`'ether' | 'gwei' | 'wei' | number | undefined` + +- Units to use when formatting result. +- Defaults to `'ether'`. + +::: code-group +```ts [index.ts] +import { useToken } from 'wagmi' + +function App() { + const result = useToken({ + address: '0x6B175474E89094C44Da98b954EedeAC495271d0F', + formatUnits: 'ether', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Hooks that have identical context will share the same cache. + +::: code-group +```ts [index.ts] +import { useToken } from 'wagmi' + +function App() { + const result = useToken({ + address: '0x6B175474E89094C44Da98b954EedeAC495271d0F', + scopeKey: 'foo', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseTokenReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`getToken`](/core/api/actions/getToken) diff --git a/wagmi-project/site/react/api/hooks/useTransaction.md b/wagmi-project/site/react/api/hooks/useTransaction.md new file mode 100644 index 000000000..391f5bf80 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useTransaction.md @@ -0,0 +1,184 @@ +--- +title: useTransaction +description: Hook for fetching transactions given hashes or block identifiers. +--- + + + +# useTransaction + +Hook for fetching transactions given hashes or block identifiers. + +## Import + +```ts +import { useTransaction } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useTransaction } from 'wagmi' + +function App() { + const result = useTransaction({ + hash: '0x0fa64daeae54e207aa98613e308c2ba8abfe274f75507e741508cc4db82c8cb5', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseTransactionParameters } from 'wagmi' +``` + +--- + +### blockHash + +`bigint | undefined` + +Block hash to get transaction at (with [`index`](#index)). + +```ts +import { useTransaction } from 'wagmi' + +function App() { + const result = useTransaction({ + blockHash: '0x4ca7ee652d57678f26e887c149ab0735f41de37bcad58c9f6d3ed5824f15b74d', // [!code focus] + index: 0, + }) +} +``` + +### blockNumber + +`bigint | undefined` + +Block number to get transaction at (with [`index`](#index)). + +```ts +import { useTransaction } from 'wagmi' + +function App() { + const result = useTransaction({ + blockNumber: 17829139n, // [!code focus] + index: 0, + }) +} +``` + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Block tag to get transaction at (with [`index`](#index)). + +```ts +import { useTransaction } from 'wagmi' + +function App() { + const result = useTransaction({ + blockTag: 'safe', // [!code focus] + index: 0, + }) +} +``` + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +```ts +import { useTransaction } from 'wagmi' +import { mainnet } from 'wagmi/chains' + +function App() { + const result = useTransaction({ + chainId: mainnet.id, // [!code focus] + hash: '0x0fa64daeae54e207aa98613e308c2ba8abfe274f75507e741508cc4db82c8cb5', + }) +} +``` + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useTransaction } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useTransaction({ + hash: '0x0fa64daeae54e207aa98613e308c2ba8abfe274f75507e741508cc4db82c8cb5', + config, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### hash + +`` `0x${string}` | undefined `` + +Hash to get transaction. [`enabled`](#enabled) set to `false` if `hash` and [`index`](#index) are `undefined`. + +```ts +import { useTransaction } from 'wagmi' + +function App() { + const result = useTransaction({ + hash: '0x0fa64daeae54e207aa98613e308c2ba8abfe274f75507e741508cc4db82c8cb5', // [!code focus] + }) +} +``` + +### index + +`number | undefined` + +An index to be used with a block identifier ([hash](#blockhash), [number](#blocknumber), or [tag](#blocktag)). [`enabled`](#enabled) set to `false` if `index` and [`hash`](#hash) are `undefined`. + +```ts +import { useTransaction } from 'wagmi' + +function App() { + const result = useTransaction({ + blockTag: 'safe', + index: 0 // [!code focus] + }) +} +``` + + + +## Return Type + +```ts +import { type UseTransactionReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`getTransaction`](/core/api/actions/getTransaction) diff --git a/wagmi-project/site/react/api/hooks/useTransactionConfirmations.md b/wagmi-project/site/react/api/hooks/useTransactionConfirmations.md new file mode 100644 index 000000000..6dec7c131 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useTransactionConfirmations.md @@ -0,0 +1,153 @@ +--- +title: useTransactionConfirmations +description: Hook for fetching the number of blocks passed (confirmations) since the transaction was processed on a block. +--- + + + +# useTransactionConfirmations + +Hook for fetching the number of blocks passed (confirmations) since the transaction was processed on a block. If confirmations is 0, then the Transaction has not been confirmed & processed yet. + +## Import + +```ts +import { useTransactionConfirmations } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useTransactionConfirmations } from 'wagmi' + +function App() { + const result = useTransactionConfirmations({ + hash: '0x0fa64daeae54e207aa98613e308c2ba8abfe274f75507e741508cc4db82c8cb5', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseTransactionConfirmationsParameters } from 'wagmi' +``` + +--- + +### hash + +`` `0x${string}` | undefined `` + +The hash of the transaction. + +```ts +import { useTransactionConfirmations } from 'wagmi' + +function App() { + const result = useTransactionConfirmations({ + hash: '0x0fa64daeae54e207aa98613e308c2ba8abfe274f75507e741508cc4db82c8cb5', // [!code focus] + }) +} +``` + +### transactionReceipt + +`TransactionReceipt | undefined` + +The transaction receipt. + +```ts +import { useTransactionConfirmations } from 'wagmi' + +function App() { + const result = useTransactionConfirmations({ + transactionReceipt: { ... }, // [!code focus] + }) +} +``` + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +```ts +import { useTransactionConfirmations } from 'wagmi' +import { mainnet } from 'wagmi/chains' + +function App() { + const result = useTransactionConfirmations({ + chainId: mainnet.id, // [!code focus] + hash: '0x0fa64daeae54e207aa98613e308c2ba8abfe274f75507e741508cc4db82c8cb5', + }) +} +``` + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useTransactionConfirmations } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useTransactionConfirmations({ + config, // [!code focus] + hash: '0x0fa64daeae54e207aa98613e308c2ba8abfe274f75507e741508cc4db82c8cb5', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Hooks that have identical context will share the same cache. + +::: code-group +```tsx [index.tsx] +import { useBlock } from 'wagmi' +import { config } from './config' + +function App() { + const result = useTransactionConfirmations({ + scopeKey: 'foo' // [!code focus] + hash: '0x0fa64daeae54e207aa98613e308c2ba8abfe274f75507e741508cc4db82c8cb5', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseTransactionConfirmationsReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`getTransactionConfirmations`](/core/api/actions/getTransactionConfirmations) diff --git a/wagmi-project/site/react/api/hooks/useTransactionCount.md b/wagmi-project/site/react/api/hooks/useTransactionCount.md new file mode 100644 index 000000000..142453af4 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useTransactionCount.md @@ -0,0 +1,185 @@ +--- +title: useTransactionCount +description: Hook for fetching the number of transactions an Account has broadcast / sent. +--- + + + +# useTransactionCount + +Hook for fetching the number of transactions an Account has sent. + +## Import + +```ts +import { useTransactionCount } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useTransactionCount } from 'wagmi' + +function App() { + const result = useTransactionCount({ + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseTransactionCountParameters } from 'wagmi' +``` + +### address + +`Address | undefined` + +Address to get the transaction count for. [`enabled`](#enabled) set to `false` if `address` is `undefined`. + +::: code-group +```tsx [index.tsx] +import { useTransactionCount } from 'wagmi' +import { mainnet } from 'wagmi/chains' + +function App() { + const result = useTransactionCount({ + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +--- + +### blockNumber + +`bigint | undefined` + +Block number to get the transaction count at. + +::: code-group +```ts [index.ts] +import { useTransactionCount } from 'wagmi' + +function App() { + const result = useTransactionCount({ + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', + blockNumber: 17829139n, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Block tag to get the transaction count at. + +::: code-group +```ts [index.ts] +import { useTransactionCount } from 'wagmi' + +function App() { + const result = useTransactionCount({ + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', + blockTag: 'latest', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +--- + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```tsx [index.tsx] +import { useTransactionCount } from 'wagmi' +import { mainnet } from 'wagmi/chains' // [!code focus] + +function App() { + const result = useTransactionCount({ + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', + chainId: mainnet.id, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useTransactionCount } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useTransactionCount({ + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', + config, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Hooks that have identical context will share the same cache. + +::: code-group +```tsx [index.tsx] +import { useTransactionCount } from 'wagmi' + +function App() { + const result = useTransactionCount({ + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', + scopeKey: 'foo', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseTransactionCountReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`getTransactionCount`](/core/api/actions/getTransactionCount) diff --git a/wagmi-project/site/react/api/hooks/useTransactionReceipt.md b/wagmi-project/site/react/api/hooks/useTransactionReceipt.md new file mode 100644 index 000000000..2f909ee89 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useTransactionReceipt.md @@ -0,0 +1,142 @@ +--- +title: useTransactionReceipt +description: Hook for return the Transaction Receipt given a Transaction hash. +--- + + + +# useTransactionReceipt + +Hook for return the [Transaction Receipt](https://viem.sh/docs/glossary/terms.html#transaction-receipt) given a [Transaction](https://viem.sh/docs/glossary/terms.html#transaction) hash. + +## Import + +```ts +import { useTransactionReceipt } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useTransactionReceipt } from 'wagmi' + +function App() { + const result = useTransactionReceipt({ + hash: '0x4ca7ee652d57678f26e887c149ab0735f41de37bcad58c9f6d3ed5824f15b74d', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseTransactionReceiptParameters } from 'wagmi' +``` + +### hash + +`` `0x${string}` | undefined `` + +A transaction hash. + +::: code-group +```tsx [index.tsx] +import { useTransactionReceipt } from 'wagmi' + +function App() { + const result = useTransactionReceipt({ + hash: '0x4ca7ee652d57678f26e887c149ab0735f41de37bcad58c9f6d3ed5824f15b74d', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +The ID of chain to return the transaction receipt from. + +::: code-group +```tsx [index.tsx] +import { useTransactionReceipt } from 'wagmi' +import { mainnet } from 'wagmi/chains' + + +function App() { + const result = useTransactionReceipt({ + chainId: mainnet.id, // [!code focus] + hash: '0x4ca7ee652d57678f26e887c149ab0735f41de37bcad58c9f6d3ed5824f15b74d', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useTransactionReceipt } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useTransactionReceipt({ + config, // [!code focus] + hash: '0x4ca7ee652d57678f26e887c149ab0735f41de37bcad58c9f6d3ed5824f15b74d', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Hooks that have identical context will share the same cache. + +::: code-group +```tsx [index.tsx] +import { useTransactionReceipt } from 'wagmi' +import { config } from './config' + +function App() { + const result = useTransactionReceipt({ + scopeKey: 'foo' // [!code focus] + hash: '0x4ca7ee652d57678f26e887c149ab0735f41de37bcad58c9f6d3ed5824f15b74d', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseTransactionReceiptReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`getTransactionReceipt`](/core/api/actions/getTransactionReceipt) diff --git a/wagmi-project/site/react/api/hooks/useVerifyMessage.md b/wagmi-project/site/react/api/hooks/useVerifyMessage.md new file mode 100644 index 000000000..e7750d79f --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useVerifyMessage.md @@ -0,0 +1,257 @@ +--- +title: useVerifyMessage +description: Hook for verify that a message was signed by the provided address. +--- + + + +# useVerifyMessage + +Hook for verify that a message was signed by the provided address. It supports verifying messages that were signed by either a Smart Contract Account or Externally Owned Account. + +## Import + +```ts +import { useVerifyMessage } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useVerifyMessage } from 'wagmi' + +function App() { + const result = useVerifyMessage({ + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + message: 'hello world', + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseVerifyMessageParameters } from 'wagmi' +``` + +### address + +`Address | undefined` + +The Ethereum address that signed the original message. + +::: code-group +```tsx [index.tsx] +import { useVerifyMessage } from 'wagmi' + +function App() { + const result = useVerifyMessage({ + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', // [!code focus] + message: 'hello world', + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### message + +`string | { raw: Hex | ByteArray } | undefined` + +The message to be verified. + +By default, wagmi verifies the UTF-8 representation of the message. + +::: code-group +```tsx [index.tsx] +import { useVerifyMessage } from 'wagmi' + +function App() { + const result = useVerifyMessage({ + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + message: 'hello world', // [!code focus] + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +::: tip +By default, viem signs the UTF-8 representation of the message. To sign the data representation of the message, you can use the `raw` attribute. + +```ts +import { useVerifyMessage } from 'wagmi' + +function App() { + const result = useVerifyMessage({ + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + message: { raw: '0x68656c6c6f20776f726c64' } // [!code focus] + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', + }) +} +``` +::: + +### signature + +`Hex | ByteArray | undefined` + +The signature that was generated by signing the message with the address's signer. + +::: code-group +```tsx [index.tsx] +import { useVerifyMessage } from 'wagmi' + +function App() { + const result = useVerifyMessage({ + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + message: 'hello world', + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +Only used when verifying a message that was signed by a Smart Contract Account. The ID of chain to check if the contract was already deployed. + +::: code-group +```tsx [index.tsx] +import { useVerifyMessage } from 'wagmi' +import { mainnet } from 'wagmi/chains' + +function App() { + const result = useVerifyMessage({ + chainId: mainnet.id, // [!code focus] + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + message: 'hello world', + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### blockNumber + +`bigint | undefined` + +Only used when verifying a message that was signed by a Smart Contract Account. The block number to check if the contract was already deployed. + +::: code-group +```tsx [index.tsx] +import { useVerifyMessage } from 'wagmi' +import { mainnet } from 'wagmi/chains' + +function App() { + const result = useVerifyMessage({ + blockNumber: 12345678n, // [!code focus] + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + message: 'hello world', + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Only used when verifying a message that was signed by a Smart Contract Account. The block tag to check if the contract was already deployed. + +::: code-group +```tsx [index.tsx] +import { useVerifyMessage } from 'wagmi' +import { mainnet } from 'wagmi/chains' + +function App() { + const result = useVerifyMessage({ + blockTag: 'pending', // [!code focus] + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + message: 'hello world', + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useVerifyMessage } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useVerifyMessage({ + config, // [!code focus] + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + message: 'hello world', + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Hooks that have identical context will share the same cache. + +::: code-group +```tsx [index.tsx] +import { useVerifyMessage } from 'wagmi' +import { config } from './config' + +function App() { + const result = useVerifyMessage({ + scopeKey: 'foo' // [!code focus] + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + message: 'hello world', + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseVerifyMessageReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`verifyMessage`](/core/api/actions/verifyMessage) diff --git a/wagmi-project/site/react/api/hooks/useVerifyTypedData.md b/wagmi-project/site/react/api/hooks/useVerifyTypedData.md new file mode 100644 index 000000000..4d9f8bc24 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useVerifyTypedData.md @@ -0,0 +1,724 @@ +--- +title: useVerifyTypedData +description: Hook for verify that a typed data was signed by the provided address. +--- + + + +# useVerifyTypedData + +Hook for verify that a typed data was signed by the provided address. It supports verifying typed data that were signed by either a Smart Contract Account or Externally Owned Account. + +## Import + +```ts +import { useVerifyTypedData } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { domain, types } from './data' +import { useVerifyTypedData } from 'wagmi' + +function App() { + const result = useVerifyTypedData({ + domain, + types, + message: { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, + primaryType: 'Mail', + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', + }) +} +``` +```ts [data.ts] +// All properties on a domain are optional +export const domain = { + name: 'Ether Mail', + version: '1', + chainId: 1, + verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC', +} as const + +// The named list of all type definitions +export const types = { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], +} as const +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseVerifyTypedDataParameters } from 'wagmi' +``` + +### address + +`Address | undefined` + +The Ethereum address that signed the original typed data. + +::: code-group +```tsx [index.tsx] +import { domain, types } from './data' +import { useVerifyTypedData } from 'wagmi' + +function App() { + const result = useVerifyTypedData({ + domain, + types, + message: { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, + primaryType: 'Mail', + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', // [!code focus] + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', + }) +} +``` +```ts [data.ts] +// All properties on a domain are optional +export const domain = { + name: 'Ether Mail', + version: '1', + chainId: 1, + verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC', +} as const + +// The named list of all type definitions +export const types = { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], +} as const +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### domain + +`TypedDataDomain | undefined` + +The typed data domain. + +::: code-group +```tsx [index.tsx] +import { types } from './data' +import { useVerifyTypedData } from 'wagmi' + +function App() { + const result = useVerifyTypedData({ + domain: { // [!code focus:6] + name: 'Ether Mail', + version: '1', + chainId: 1, + verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC', + }, + types, + message: { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, + primaryType: 'Mail', + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', + }) +} +``` +```ts [data.ts] +// The named list of all type definitions +export const types = { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], +} as const +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### types + +The type definitions for the typed data. + +::: code-group +```tsx [index.tsx] +import { domain } from './data' +import { useVerifyTypedData } from 'wagmi' + +function App() { + const result = useVerifyTypedData({ + domain, + types: { // [!code focus:11] + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], + }, + message: { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, + primaryType: 'Mail', + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', + }) +} +``` +```ts [data.ts] +// All properties on a domain are optional +export const domain = { + name: 'Ether Mail', + version: '1', + chainId: 1, + verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC', +} as const +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### primaryType + +`string | undefined` + +The primary `type` to extract from types and use in `value`. + +::: code-group +```tsx [index.tsx] +import { domain } from './data' +import { useVerifyTypedData } from 'wagmi' + +function App() { + const result = useVerifyTypedData({ + domain, + types: { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ // [!code focus:5] + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], + }, + primaryType: 'Mail', // [!code focus] + message: { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', + }) +} +``` +```ts [data.ts] +// All properties on a domain are optional +export const domain = { + name: 'Ether Mail', + version: '1', + chainId: 1, + verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC', +} as const +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### message + +Type inferred from `types` & `primaryType`. + +The message to be verified. + +::: code-group +```tsx [index.tsx] +import { domain, types } from './data' +import { useVerifyTypedData } from 'wagmi' + +function App() { + const result = useVerifyTypedData({ + domain, + types, + message: { // [!code focus:11] + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, + primaryType: 'Mail', + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', + }) +} +``` +```ts [data.ts] +// All properties on a domain are optional +export const domain = { + name: 'Ether Mail', + version: '1', + chainId: 1, + verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC', +} as const + +// The named list of all type definitions +export const types = { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], +} as const +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### signature + +`Hex | ByteArray | undefined` + +The signature that was generated by signing the typed data with the address's signer. + +::: code-group +```tsx [index.tsx] +import { domain, types } from './data' +import { useVerifyTypedData } from 'wagmi' + +function App() { + const result = useVerifyTypedData({ + domain, + types, + message: { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, + primaryType: 'Mail', + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', // [!code focus] + }) +} +``` +```ts [data.ts] +// All properties on a domain are optional +export const domain = { + name: 'Ether Mail', + version: '1', + chainId: 1, + verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC', +} as const + +// The named list of all type definitions +export const types = { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], +} as const +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +Only used when verifying a typed data that was signed by a Smart Contract Account. The ID of chain to check if the contract was already deployed. + +::: code-group +```tsx [index.tsx] +import { domain, types } from './data' +import { useVerifyTypedData } from 'wagmi' +import { mainnet } from 'wagmi/chains' + +function App() { + const result = useVerifyTypedData({ + chainId: mainnet.id, // [!code focus] + domain, + types, + message: { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, + primaryType: 'Mail', + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', + }) +} +``` +```ts [data.ts] +// All properties on a domain are optional +export const domain = { + name: 'Ether Mail', + version: '1', + chainId: 1, + verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC', +} as const + +// The named list of all type definitions +export const types = { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], +} as const +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### blockNumber + +`bigint | undefined` + +Only used when verifying a typed data that was signed by a Smart Contract Account. The block number to check if the contract was already deployed. + +::: code-group +```tsx [index.tsx] +import { domain, types } from './data' +import { useVerifyTypedData } from 'wagmi' + +function App() { + const result = useVerifyTypedData({ + blockNumber: 12345678n, // [!code focus] + domain, + types, + message: { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, + primaryType: 'Mail', + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', + }) +} +``` +```ts [data.ts] +// All properties on a domain are optional +export const domain = { + name: 'Ether Mail', + version: '1', + chainId: 1, + verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC', +} as const + +// The named list of all type definitions +export const types = { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], +} as const +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Only used when verifying a typed data that was signed by a Smart Contract Account. The block tag to check if the contract was already deployed. + +::: code-group +```tsx [index.tsx] +import { domain, types } from './data' +import { useVerifyTypedData } from 'wagmi' + +function App() { + const result = useVerifyTypedData({ + blockTag: 'latest', // [!code focus] + domain, + types, + message: { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, + primaryType: 'Mail', + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', + }) +} +``` +```ts [data.ts] +// All properties on a domain are optional +export const domain = { + name: 'Ether Mail', + version: '1', + chainId: 1, + verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC', +} as const + +// The named list of all type definitions +export const types = { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], +} as const +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { domain, types } from './data' +import { useVerifyTypedData } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useVerifyTypedData({ + config, // [!code focus] + domain, + types, + message: { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, + primaryType: 'Mail', + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', + }) +} +``` +```ts [data.ts] +// All properties on a domain are optional +export const domain = { + name: 'Ether Mail', + version: '1', + chainId: 1, + verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC', +} as const + +// The named list of all type definitions +export const types = { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], +} as const +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Hooks that have identical context will share the same cache. + +::: code-group +```tsx [index.tsx] +import { domain, types } from './data' +import { useVerifyTypedData } from 'wagmi' + +function App() { + const result = useVerifyTypedData({ + scopeKey: 'foo' // [!code focus] + domain, + types, + message: { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, + primaryType: 'Mail', + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', + }) +} +``` +```ts [data.ts] +// All properties on a domain are optional +export const domain = { + name: 'Ether Mail', + version: '1', + chainId: 1, + verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC', +} as const + +// The named list of all type definitions +export const types = { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], +} as const +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseVerifyTypedDataReturnType } from 'wagmi' +``` + + + +## Type Inference + +With [`types`](#types) setup correctly, TypeScript will infer the correct types for [`domain`](#domain), [`message`](#message), and [`primaryType`](#primarytype). See the Wagmi [TypeScript docs](/react/typescript) for more information. + + + +## Action + +- [`verifyTypedData`](/core/api/actions/verifyTypedData) diff --git a/wagmi-project/site/react/api/hooks/useWaitForCallsStatus.md b/wagmi-project/site/react/api/hooks/useWaitForCallsStatus.md new file mode 100644 index 000000000..39e520de5 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useWaitForCallsStatus.md @@ -0,0 +1,181 @@ +--- +title: useWaitForCallsStatus +description: Waits for a call bundle to be confirmed & included on a block. +--- + + + +# useWaitForCallsStatus + +Waits for a call bundle to be confirmed & included on a block before returning the status & receipts. + + + +## Import + +```ts +import { useWaitForCallsStatus } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useWaitForCallsStatus } from 'wagmi' + +function App() { + const result = useWaitForCallsStatus({ + id: '0x...', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseWaitForCallsStatusParameters } from 'wagmi' +``` + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useWaitForCallsStatus } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useWaitForCallsStatus({ + config, // [!code focus] + id: '0x...', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### connector + +`Connector | undefined` + +Connector to get call statuses with. + +::: code-group +```tsx [index.tsx] +import { useWaitForCallsStatus, useConnections } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const connections = useConnections() + const result = useWaitForCallsStatus({ + connector: connections[0]?.connector, // [!code focus] + id: '0x...', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### id + +`string` + +Identifier of the call batch. + +::: code-group +```ts [index.ts] +import { useWaitForCallsStatus } from '@wagmi/core' +import { config } from './config' + +const status = await useWaitForCallsStatus({ + id: '0x1234567890abcdef', // [!code focus] +}) +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### pollingInterval + +`number | undefined` + +Polling interval in milliseconds. + +::: code-group +```ts [index.ts] +import { useWaitForCallsStatus } from '@wagmi/core' +import { config } from './config' + +const status = await useWaitForCallsStatus({ + id: '0x1234567890abcdef', + pollingInterval: 1_000, // [!code focus] +}) +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Hooks that have identical context will share the same cache. + +::: code-group +```tsx [index.tsx] +import { useWaitForCallsStatus } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useWaitForCallsStatus({ + id: '0x...', + scopeKey: 'foo', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### timeout + +`number | undefined` + +Timeout in milliseconds. + +::: code-group +```ts [index.ts] +import { useWaitForCallsStatus } from '@wagmi/core' +import { config } from './config' + +const status = await useWaitForCallsStatus({ + id: '0x1234567890abcdef', + timeout: 10_000, // [!code focus] +}) +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseWaitForCallsStatusReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`waitForCallsStatus`](https://viem.sh/experimental/eip5792/waitForCallsStatus) \ No newline at end of file diff --git a/wagmi-project/site/react/api/hooks/useWaitForTransactionReceipt.md b/wagmi-project/site/react/api/hooks/useWaitForTransactionReceipt.md new file mode 100644 index 000000000..78dbe7bc5 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useWaitForTransactionReceipt.md @@ -0,0 +1,168 @@ +--- +title: useWaitForTransactionReceipt +description: Hook that waits for the transaction to be included on a block, and then returns the transaction receipt. If the transaction reverts, then the action will throw an error. Replacement detection (e.g. sped up transactions) is also supported. +--- + + + +# useWaitForTransactionReceipt + +Hook that waits for the transaction to be included on a block, and then returns the transaction receipt. If the transaction reverts, then the action will throw an error. Replacement detection (e.g. sped up transactions) is also supported. + +## Import + +```ts +import { useWaitForTransactionReceipt } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useWaitForTransactionReceipt } from 'wagmi' + +function App() { + const result = useWaitForTransactionReceipt({ + hash: '0x4ca7ee652d57678f26e887c149ab0735f41de37bcad58c9f6d3ed5824f15b74d', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseWaitForTransactionReceiptParameters } from 'wagmi' +``` + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +```ts [index.ts] +import { useWaitForTransactionReceipt } from 'wagmi' +import { mainnet } from 'wagmi/chains' + +function App() { + const result = useWaitForTransactionReceipt({ + chainId: mainnet.id, // [!code focus] + hash: '0x4ca7ee652d57678f26e887c149ab0735f41de37bcad58c9f6d3ed5824f15b74d', + }) +} +``` + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useWaitForTransactionReceipt } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useWaitForTransactionReceipt({ + hash: '0x4ca7ee652d57678f26e887c149ab0735f41de37bcad58c9f6d3ed5824f15b74d', + config, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### confirmations + +`number | undefined` + +The number of confirmations (blocks that have passed) to wait before resolving. + +```ts [index.ts] +import { useWaitForTransactionReceipt } from 'wagmi' + +function App() { + const result = useWaitForTransactionReceipt({ + confirmations: 2, // [!code focus] + hash: '0x4ca7ee652d57678f26e887c149ab0735f41de37bcad58c9f6d3ed5824f15b74d', + }) +} +``` + +### onReplaced + +` +(({ reason: 'replaced' | 'repriced' | 'cancelled'; replacedTransaction: Transaction; transaction: Transaction; transactionReceipt: TransactionReceipt }) => void) | undefined +` + +Optional callback to emit if the transaction has been replaced. + +```ts [index.ts] +import { useWaitForTransactionReceipt } from 'wagmi' + +function App() { + const result = useWaitForTransactionReceipt({ + hash: '0x4ca7ee652d57678f26e887c149ab0735f41de37bcad58c9f6d3ed5824f15b74d', + onReplaced: replacement => console.log(replacement), // [!code focus] + }) +} +``` + +### pollingInterval + +`number | undefined` + +- Polling frequency (in milliseconds). +- Defaults to the [Config's `pollingInterval` config](/react/api/createConfig#pollinginterval). + +```ts [index.ts] +import { useWaitForTransactionReceipt } from 'wagmi' + +function App() { + const result = useWaitForTransactionReceipt({ + hash: '0x4ca7ee652d57678f26e887c149ab0735f41de37bcad58c9f6d3ed5824f15b74d', + pollingInterval: 1_000, // [!code focus] + }) +} +``` + +### hash + +`` `0x${string}` | undefined `` + +The transaction hash to wait for. [`enabled`](#enabled) set to `false` if `hash` is `undefined`. + +```ts [index.ts] +import { useWaitForTransactionReceipt } from 'wagmi' + +function App() { + const result = useWaitForTransactionReceipt({ + hash: '0x4ca7ee652d57678f26e887c149ab0735f41de37bcad58c9f6d3ed5824f15b74d', // [!code focus] + }) +} +``` + + + +## Return Type + +```ts +import { type UseWaitForTransactionReceiptReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`waitForTransactionReceipt`](/core/api/actions/waitForTransactionReceipt) diff --git a/wagmi-project/site/react/api/hooks/useWalletClient.md b/wagmi-project/site/react/api/hooks/useWalletClient.md new file mode 100644 index 000000000..e6ee792c2 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useWalletClient.md @@ -0,0 +1,132 @@ +--- +title: useWalletClient +description: Hook for getting a Viem `WalletClient` object for the current or provided connector. +--- + + + +# useWalletClient + +Hook for getting a Viem [`WalletClient`](https://viem.sh/docs/clients/wallet.html) object for the current or provided connector. + +## Import + +```ts +import { useWalletClient } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useWalletClient } from 'wagmi' + +function App() { + const result = useWalletClient() +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +::: warning +If you want to optimize bundle size, you should use [`useConnectorClient`](/react/api/hooks/useConnectorClient) along with Viem's [tree-shakable actions](https://viem.sh/docs/clients/custom.html#tree-shaking) instead. Since Wallet Client has all wallet actions attached directly to it. +::: + +## Parameters + +```ts +import { type UseWalletClientParameters } from 'wagmi' +``` + +### account + +`Address | Account | undefined` + +Account to use with client. Throws if account is not found on [`connector`](#connector). + +```ts +import { useWalletClient } from 'wagmi' + +function App() { + const result = useWalletClient({ + account: '0xd2135CfB216b74109775236E36d4b433F1DF507B', // [!code focus] + }) +} +``` + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use with client. + +```ts +import { useWalletClient } from 'wagmi' + +function App() { + const result = useWalletClient({ + chainId: mainnet.id, // [!code focus] + }) +} +``` + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useWalletClient } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useWalletClient({ + config, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### connector + +`Connector | undefined` + +- Connector to get client for. +- Defaults to current connector. + +```ts +import { useConnections, useWalletClient } from 'wagmi' + +function App() { + const connections = useConnections(config) + const result = useWalletClient({ + connector: connections[0]?.connector, // [!code focus] + }) +} +``` + + + +## Return Type + +```ts +import { type UseWalletClientReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`getWalletClient`](/core/api/actions/getWalletClient) diff --git a/wagmi-project/site/react/api/hooks/useWatchAsset.md b/wagmi-project/site/react/api/hooks/useWatchAsset.md new file mode 100644 index 000000000..03f756d56 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useWatchAsset.md @@ -0,0 +1,94 @@ +--- +title: useWatchAsset +description: Hook for requesting user tracks the token in their wallet. Returns a boolean indicating if the token was successfully added. +--- + + + +# useWatchAsset + +Hook for requesting user tracks the token in their wallet. Returns a boolean indicating if the token was successfully added. + +## Import + +```ts +import { useWatchAsset } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useWatchAsset } from 'wagmi' + +function App() { + const { watchAsset } = useWatchAsset() + + return ( + + ) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseWatchAssetParameters } from 'wagmi' +``` + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useWatchAsset } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useWatchAsset({ + config, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseWatchAssetReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`watchAsset`](/core/api/actions/watchAsset) diff --git a/wagmi-project/site/react/api/hooks/useWatchBlockNumber.md b/wagmi-project/site/react/api/hooks/useWatchBlockNumber.md new file mode 100644 index 000000000..925dddfc1 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useWatchBlockNumber.md @@ -0,0 +1,276 @@ +--- +title: useWatchBlockNumber +description: Hook that watches for block number changes. +--- + +# useWatchBlockNumber + +Hook that watches for block number changes. + +## Import + +```ts +import { useWatchBlockNumber } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useWatchBlockNumber } from 'wagmi' + +function App() { + useWatchBlockNumber({ + onBlockNumber(blockNumber) { + console.log('Block number changed!', blockNumber) + }, + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseWatchBlockNumberParameters } from 'wagmi' +``` + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to watch blocks at. + +::: code-group +```ts [index.ts] +import { useWatchBlockNumber } from 'wagmi' + +function App() { + useWatchBlockNumber({ + chainId: 1, // [!code focus] + onBlockNumber(blockNumber) { + console.log('New block number', blockNumber) + }, + }) +} +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```ts [index.ts] +import { useWatchBlockNumber } from 'wagmi' +import { config } from './config' + +function App() { + useWatchBlockNumber({ + config, // [!code focus] + onBlockNumber(blockNumber) { + console.log('New block number', blockNumber) + }, + }) +} +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### emitMissed + +`boolean` + +Whether or not to emit missed blocks to the callback. Defaults to `false`. + +Missed blocks may occur in instances where internet connection is lost, or the block time is lesser than the polling interval of the client. + +::: code-group +```ts [index.ts] +import { useWatchBlockNumber } from 'wagmi' + +function App() { + useWatchBlockNumber({ + emitMissed: true, // [!code focus] + onBlockNumber(blockNumber) { + console.log('New block number', blockNumber) + }, + }) +} +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### emitOnBegin + +`boolean` + +Whether or not to emit the block to the callback when the subscription opens. Defaults to `false`. + +::: code-group +```ts [index.ts] +import { useWatchBlockNumber } from 'wagmi' + +function App() { + useWatchBlockNumber({ + emitOnBegin: true, // [!code focus] + onBlockNumber(blockNumber) { + console.log('New block number', blockNumber) + }, + }) +} +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### enabled + +`boolean` + +Whether or not to watch for blocks. Defaults to `true`. + +::: code-group +```ts [index.ts] +import { useWatchBlockNumber } from 'wagmi' + +function App() { + useWatchBlockNumber({ + enabled: false, // [!code focus] + onBlockNumber(blockNumber) { + console.log('New block number', blockNumber) + }, + }) +} +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### onBlockNumber + +`(block: Block, prevblock: Block | undefined) => void` + +Callback for when block changes. + +::: code-group +```ts [index.ts] +import { useWatchBlockNumber } from 'wagmi' + +function App() { + useWatchBlockNumber({ + onBlockNumber(blockNumber) { // [!code focus] + console.log('New block number', blockNumber) // [!code focus] + }, // [!code focus] + }) +} +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### onError + +`((error: Error) => void) | undefined` + +Error thrown from getting the block. + +::: code-group +```ts [index.ts] +import { useWatchBlockNumber } from 'wagmi' + +function App() { + useWatchBlockNumber({ + onBlockNumber(blockNumber) { + console.log('New block number', blockNumber) + }, + onError(error) { // [!code focus] + console.error('Block error', error) // [!code focus] + }, // [!code focus] + }) +} +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### poll + +`boolean | undefined` + +- Whether or not to use a polling mechanism to check for new blocks instead of a WebSocket subscription. +- Defaults to `false` for WebSocket Clients, and `true` for non-WebSocket Clients. + +::: code-group +```ts [index.ts] +import { useWatchBlockNumber } from 'wagmi' + +function App() { + useWatchBlockNumber({ + onBlockNumber(blockNumber) { + console.log('New block number', blockNumber) + } + poll: true, // [!code focus] + }) +} +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### pollingInterval + +`number | undefined` + +- Polling frequency (in milliseconds). +- Defaults to the [Config's `pollingInterval` config](/core/api/createConfig#pollinginterval). + +::: code-group +```ts [index.ts] +import { useWatchBlockNumber } from 'wagmi' + +function App() { + useWatchBlockNumber({ + onBlockNumber(blockNumber) { + console.log('New block number', blockNumber) + } + pollingInterval: 1_000, // [!code focus] + }) +} +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### syncConnectedChain + +`boolean | undefined` + +- Set up subscriber for connected chain changes. +- Defaults to [`Config['syncConnectedChain']`](/core/api/createConfig#syncconnectedchain). + +::: code-group +```ts [index.ts] +import { useWatchBlockNumber } from 'wagmi' + +function App() { + useWatchBlockNumber({ + onBlockNumber(blockNumber) { + console.log('New block number', blockNumber) + } + syncConnectedChain: false, // [!code focus] + }) +} +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type UseWatchBlockNumberReturnType } from 'wagmi' +``` + +Function for cleaning up watcher. + +## Action + +- [`watchBlockNumber`](/core/api/actions/watchBlockNumber) diff --git a/wagmi-project/site/react/api/hooks/useWatchBlocks.md b/wagmi-project/site/react/api/hooks/useWatchBlocks.md new file mode 100644 index 000000000..ec2b17326 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useWatchBlocks.md @@ -0,0 +1,318 @@ +--- +title: useWatchBlocks +description: Hook that watches for block changes. +--- + +# useWatchBlocks + +Hook that watches for block changes. + +## Import + +```ts +import { useWatchBlocks } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useWatchBlocks } from 'wagmi' + +function App() { + useWatchBlocks({ + onBlock(block) { + console.log('New block', block.number) + }, + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseWatchBlocksParameters } from 'wagmi' +``` + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Block tag to watch blocks at. + +::: code-group +```ts [index.ts] +import { useWatchBlocks } from 'wagmi' + +function App() { + useWatchBlocks({ + blockTag: 'latest', // [!code focus] + onBlock(block) { + console.log('New block', block.number) + }, + }) +} +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to watch blocks at. + +::: code-group +```ts [index.ts] +import { useWatchBlocks } from 'wagmi' + +function App() { + useWatchBlocks({ + chainId: 1, // [!code focus] + onBlock(block) { + console.log('New block', block.number) + }, + }) +} +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```ts [index.ts] +import { useWatchBlocks } from 'wagmi' +import { config } from './config' + +function App() { + useWatchBlocks({ + config, // [!code focus] + onBlock(block) { + console.log('New block', block.number) + }, + }) +} +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### emitMissed + +`boolean` + +Whether or not to emit missed blocks to the callback. Defaults to `false`. + +Missed blocks may occur in instances where internet connection is lost, or the block time is lesser than the polling interval of the client. + +::: code-group +```ts [index.ts] +import { useWatchBlocks } from 'wagmi' + +function App() { + useWatchBlocks({ + emitMissed: true, // [!code focus] + onBlock(block) { + console.log('New block', block.number) + }, + }) +} +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### emitOnBegin + +`boolean` + +Whether or not to emit the block to the callback when the subscription opens. Defaults to `false`. + +::: code-group +```ts [index.ts] +import { useWatchBlocks } from 'wagmi' + +function App() { + useWatchBlocks({ + emitOnBegin: true, // [!code focus] + onBlock(block) { + console.log('New block', block.number) + }, + }) +} +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### enabled + +`boolean` + +Whether or not to watch for blocks. Defaults to `true`. + +::: code-group +```ts [index.ts] +import { useWatchBlocks } from 'wagmi' + +function App() { + useWatchBlocks({ + enabled: false, // [!code focus] + onBlock(block) { + console.log('New block', block.number) + }, + }) +} +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### includeTransactions + +`boolean` + +Whether or not to unwrap transactions as objects (instead of hashes) in blocks. Defaults to `false`. + +::: code-group +```ts [index.ts] +import { useWatchBlocks } from 'wagmi' + +function App() { + useWatchBlocks({ + includeTransactions: true, // [!code focus] + onBlock(block) { + console.log('New block', block.number) + }, + }) +} +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### onBlock + +`(block: Block, prevblock: Block | undefined) => void` + +Callback for when block changes. + +::: code-group +```ts [index.ts] +import { useWatchBlocks } from 'wagmi' + +function App() { + useWatchBlocks({ + onBlock(block) { // [!code focus] + console.log('New block', block.number) // [!code focus] + }, // [!code focus] + }) +} +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### onError + +`((error: Error) => void) | undefined` + +Error thrown from getting the block. + +::: code-group +```ts [index.ts] +import { useWatchBlocks } from 'wagmi' + +function App() { + useWatchBlocks({ + onBlock(block) { + console.log('New block', block.number) + }, + onError(error) { // [!code focus] + console.error('Block error', error) // [!code focus] + }, // [!code focus] + }) +} +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### poll + +`boolean | undefined` + +- Whether or not to use a polling mechanism to check for new blocks instead of a WebSocket subscription. +- Defaults to `false` for WebSocket Clients, and `true` for non-WebSocket Clients. + +::: code-group +```ts [index.ts] +import { useWatchBlocks } from 'wagmi' + +function App() { + useWatchBlocks({ + onBlock(block) { + console.log('New block', block.number) + } + poll: true, // [!code focus] + }) +} +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### pollingInterval + +`number | undefined` + +- Polling frequency (in milliseconds). +- Defaults to the [Config's `pollingInterval` config](/core/api/createConfig#pollinginterval). + +::: code-group +```ts [index.ts] +import { useWatchBlocks } from 'wagmi' + +function App() { + useWatchBlocks({ + onBlock(block) { + console.log('New block', block.number) + } + pollingInterval: 1_000, // [!code focus] + }) +} +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### syncConnectedChain + +`boolean | undefined` + +- Set up subscriber for connected chain changes. +- Defaults to [`Config['syncConnectedChain']`](/core/api/createConfig#syncconnectedchain). + +::: code-group +```ts [index.ts] +import { useWatchBlocks } from 'wagmi' + +function App() { + useWatchBlocks({ + onBlock(block) { + console.log('New block', block.number) + } + syncConnectedChain: false, // [!code focus] + }) +} +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type UseWatchBlocksReturnType } from 'wagmi' +``` + +## Action + +- [`watchBlocks`](/core/api/actions/watchBlocks) diff --git a/wagmi-project/site/react/api/hooks/useWatchContractEvent.md b/wagmi-project/site/react/api/hooks/useWatchContractEvent.md new file mode 100644 index 000000000..1bdcfb262 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useWatchContractEvent.md @@ -0,0 +1,413 @@ +--- +title: useWatchContractEvent +description: Hook that watches and returns emitted contract event logs. +--- + +# useWatchContractEvent + +Hook that watches and returns emitted contract event logs. + +## Import + +```ts +import { useWatchContractEvent } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useWatchContractEvent } from 'wagmi' +import { abi } from './abi' + +function App() { + useWatchContractEvent({ + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + abi, + eventName: 'Transfer', + onLogs(logs) { + console.log('New logs!', logs) + }, + }) +} +``` +<<< @/snippets/abi-event.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseWatchContractEventParameters } from 'wagmi' +``` + +### abi + +`Abi` + +The contract's ABI. Check out the [TypeScript docs](/react/typescript#const-assert-abis-typed-data) for how to set up ABIs for maximum type inference and safety. + +::: code-group +```tsx [index.tsx] +import { useWatchContractEvent } from 'wagmi' +import { abi } from './abi' + +function App() { + useWatchContractEvent({ + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + abi, // [!code focus] + eventName: 'Transfer', + onLogs(logs) { + console.log('New logs!', logs) + }, + }) +} +``` +<<< @/snippets/abi-event.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +### address + +`Address | undefined` + +The contract's address. + +::: code-group +```tsx [index.tsx] +import { useWatchContractEvent } from 'wagmi' +import { abi } from './abi' + +function App() { + useWatchContractEvent({ + address: '0x6b175474e89094c44da98b954eedeac495271d0f', // [!code focus] + abi, + eventName: 'Transfer', + onLogs(logs) { + console.log('New logs!', logs) + }, + }) +} +``` +<<< @/snippets/abi-event.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +### args + +`object | readonly unknown[] | undefined` + +- Arguments to pass when calling the contract. +- Inferred from [`abi`](#abi) and [`eventName`](#eventname). + +::: code-group +```tsx [index.tsx] +import { useWatchContractEvent } from 'wagmi' +import { abi } from './abi' + +function App() { + useWatchContractEvent({ + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + abi, + args: { // [!code focus] + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B' // [!code focus] + } // [!code focus] + eventName: 'Transfer', + onLogs(logs) { + console.log('New logs!', logs) + }, + }) +} +``` +<<< @/snippets/abi-event.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +### batch + +`boolean | undefined` + +- Whether or not the events should be batched on each invocation. +- Defaults to `true`. + +::: code-group +```tsx [index.tsx] +import { useWatchContractEvent } from 'wagmi' +import { abi } from './abi' + +function App() { + useWatchContractEvent({ + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + abi, + batch: false, // [!code focus] + eventName: 'Transfer', + onLogs(logs) { + console.log('New logs!', logs) + }, + }) +} +``` +<<< @/snippets/abi-event.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```tsx [index.tsx] +import { useWatchContractEvent } from 'wagmi' +import { abi } from './abi' + +function App() { + useWatchContractEvent({ + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + abi, + chainId: 1, // [!code focus] + eventName: 'Transfer', + onLogs(logs) { + console.log('New logs!', logs) + }, + }) +} +``` +<<< @/snippets/abi-event.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useWatchContractEvent } from 'wagmi' +import { abi } from './abi' +import { config } from './config' + +function App() { + useWatchContractEvent({ + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + abi, + config, // [!code focus] + eventName: 'Transfer', + onLogs(logs) { + console.log('New logs!', logs) + }, + }) +} +``` +<<< @/snippets/abi-event.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +### eventName + +`string` + +- Event to listen for the contract. +- Inferred from [`abi`](#abi). + +::: code-group +```tsx [index.tsx] +import { useWatchContractEvent } from 'wagmi' +import { abi } from './abi' +import { config } from './config' + +function App() { + useWatchContractEvent({ + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + abi, + eventName: 'Transfer', // [!code focus] + onLogs(logs) { + console.log('New logs!', logs) + }, + }) +} +``` +<<< @/snippets/abi-event.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +### onError + +`((error: Error) => void) | undefined` + +Error thrown from getting the block number. + +::: code-group +```tsx [index.tsx] +import { useWatchContractEvent } from 'wagmi' +import { abi } from './abi' + +function App() { + useWatchContractEvent({ + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + abi, + eventName: 'Transfer', + onLogs(logs) { + console.log('New logs!', logs) + }, + onError(error) { // [!code focus] + console.log('Error', error) // [!code focus] + } // [!code focus] + }) +} +``` +<<< @/snippets/abi-event.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +### onLogs + +`(logs: Log[], prevLogs: Log[] | undefined) => void` + +Callback for when logs changes. + +::: code-group +```tsx [index.tsx] +import { useWatchContractEvent } from 'wagmi' +import { abi } from './abi' + +function App() { + useWatchContractEvent({ + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + abi, + eventName: 'Transfer', + onLogs(logs) { // [!code focus] + console.log('New logs!', logs) // [!code focus] + } // [!code focus] + }) +} +``` +<<< @/snippets/abi-event.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +### poll + +`boolean | undefined` + +- Whether or not to use a polling mechanism to check for new blocks instead of a WebSocket subscription. +- Defaults to `false` for WebSocket Clients, and `true` for non-WebSocket Clients. + +::: code-group +```tsx [index.tsx] +import { useWatchContractEvent } from 'wagmi' +import { abi } from './abi' + +function App() { + useWatchContractEvent({ + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + abi, + eventName: 'Transfer', + onLogs(logs) { + console.log('New logs!', logs) + }, + poll: true // [!code focus] + }) +} +``` +<<< @/snippets/abi-event.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +### pollingInterval + +`number | undefined` + +- Polling frequency (in milliseconds). +- Defaults to the [Config's `pollingInterval` config](/core/api/createConfig#pollinginterval). + +::: code-group +```tsx [index.tsx] +import { useWatchContractEvent } from 'wagmi' +import { abi } from './abi' + +function App() { + useWatchContractEvent({ + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + abi, + eventName: 'Transfer', + onLogs(logs) { + console.log('New logs!', logs) + }, + pollingInterval: 1_000 // [!code focus] + }) +} +``` +<<< @/snippets/abi-event.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +### strict + +`boolean | undefined` + +- Defaults to `false`. + +::: code-group +```tsx [index.tsx] +import { useWatchContractEvent } from 'wagmi' +import { abi } from './abi' + +function App() { + useWatchContractEvent({ + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + abi, + eventName: 'Transfer', + onLogs(logs) { + console.log('New logs!', logs) + }, + strict: true // [!code focus] + }) +} +``` +<<< @/snippets/abi-event.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +### syncConnectedChain + +`boolean | undefined` + +- Set up subscriber for connected chain changes. +- Defaults to [`Config['syncConnectedChain']`](/core/api/createConfig#syncconnectedchain). + +::: code-group +```tsx [index.tsx] +import { useWatchContractEvent } from 'wagmi' +import { abi } from './abi' + +function App() { + useWatchContractEvent({ + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + abi, + eventName: 'Transfer', + onLogs(logs) { + console.log('New logs!', logs) + }, + syncConnectedChain: true // [!code focus] + }) +} +``` +<<< @/snippets/abi-event.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type UseWatchContractEventReturnType } from 'wagmi' +``` + +Hook returns `void` + +## Action + +- [`watchContractEvent`](/core/api/actions/watchContractEvent) diff --git a/wagmi-project/site/react/api/hooks/useWatchPendingTransactions.md b/wagmi-project/site/react/api/hooks/useWatchPendingTransactions.md new file mode 100644 index 000000000..0bfbb8136 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useWatchPendingTransactions.md @@ -0,0 +1,229 @@ +--- +title: useWatchPendingTransactions +description: Hook that watches and returns pending transaction hashes. +--- + +# useWatchPendingTransactions + +Hook that watches and returns pending transaction hashes. + +## Import + +```ts +import { useWatchPendingTransactions } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useWatchPendingTransactions } from 'wagmi' + +function App() { + useWatchPendingTransactions({ + onTransactions(transactions) { + console.log('New transactions!', transactions) + }, + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseWatchPendingTransactionsParameters } from 'wagmi' +``` + +### batch + +`boolean | undefined` + +- Whether or not the transactions should be batched on each invocation. +- Defaults to `true`. + +::: code-group +```tsx [index.tsx] +import { useWatchPendingTransactions } from 'wagmi' + +function App() { + useWatchPendingTransactions({ + batch: true // [!code focus] + onTransactions(transactions) { + console.log('New transactions!', transactions) + }, + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```tsx [index.tsx] +import { useWatchPendingTransactions } from 'wagmi' + +function App() { + useWatchPendingTransactions({ + chainId: 1 // [!code focus] + onTransactions(transactions) { + console.log('New transactions!', transactions) + }, + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useWatchPendingTransactions } from 'wagmi' +import { config } from './config' + +function App() { + useWatchPendingTransactions({ + config // [!code focus] + onTransactions(transactions) { + console.log('New transactions!', transactions) + }, + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### onError + +`((error: Error) => void) | undefined` + +Error thrown from watching pending transactions. + +::: code-group +```tsx [index.tsx] +import { useWatchPendingTransactions } from 'wagmi' + +function App() { + useWatchPendingTransactions({ + onError(error) { // [!code focus] + console.log('Error', error) // [!code focus] + }, // [!code focus] + onTransactions(transactions) { + console.log('New transactions!', transactions) + }, + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### onTransactions + +`(transactions: Hash[], prevTransactions: Hash[] | undefined) => void` + +Callback when new incoming pending transactions are detected. + +::: code-group +```tsx [index.tsx] +import { useWatchPendingTransactions } from 'wagmi' + +function App() { + useWatchPendingTransactions({ + onTransactions(transactions) { // [!code focus] + console.log('New transactions!', transactions) // [!code focus] + }, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### poll + +`boolean | undefined` + +- Whether or not to use a polling mechanism to check for new pending transactions instead of a WebSocket subscription. +- Defaults to `false` for WebSocket Clients, and `true` for non-WebSocket Clients. + +::: code-group +```tsx [index.tsx] +import { useWatchPendingTransactions } from 'wagmi' + +function App() { + useWatchPendingTransactions({ + onTransactions(transactions) { + console.log('New transactions!', transactions) + }, + poll: true, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### pollingInterval + +`number | undefined` + +- Polling frequency (in milliseconds). +- Defaults to the [Config's `pollingInterval` config](/core/api/createConfig#pollinginterval). + +::: code-group +```tsx [index.tsx] +import { useWatchPendingTransactions } from 'wagmi' + +function App() { + useWatchPendingTransactions({ + onTransactions(transactions) { + console.log('New transactions!', transactions) + }, + pollingInterval: 1_000, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### syncConnectedChain + +`boolean | undefined` + +- Set up subscriber for connected chain changes. +- Defaults to [`Config['syncConnectedChain']`](/core/api/createConfig#syncconnectedchain). + +::: code-group +```tsx [index.tsx] +import { useWatchPendingTransactions } from 'wagmi' + +function App() { + useWatchPendingTransactions({ + onTransactions(transactions) { + console.log('New transactions!', transactions) + }, + syncConnectedChain: false, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type UseWatchPendingTransactionsReturnType } from 'wagmi' +``` + +## Action + +- [`watchPendingTransactions`](/core/api/actions/watchPendingTransactions) diff --git a/wagmi-project/site/react/api/hooks/useWriteContract.md b/wagmi-project/site/react/api/hooks/useWriteContract.md new file mode 100644 index 000000000..bc575ce88 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useWriteContract.md @@ -0,0 +1,116 @@ +--- +title: useWriteContract +description: Action for executing a write function on a contract. +--- + + + +# useWriteContract + +Action for executing a write function on a contract. + +A "write" function on a Solidity contract modifies the state of the blockchain. These types of functions require gas to be executed, hence a transaction is broadcasted in order to change the state. + +## Import + +```ts +import { useWriteContract } from 'wagmi' +``` + +## Usage + +::: code-group + +```tsx [index.tsx] +import { useWriteContract } from 'wagmi' +import { abi } from './abi' + +function App() { + const { writeContract } = useWriteContract() + + return ( + + ) +} +``` + +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + + + + + +## Parameters + +```ts +import { type UseWriteContractParameters } from 'wagmi' +``` + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group + +```tsx [index.tsx] +import { useWriteContract } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useWriteContract({ + config, // [!code focus] + }) +} +``` + +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseWriteContractReturnType } from 'wagmi' +``` + +The return type's [`data`](#data) property is inferrable via the combination of [`abi`](#abi), [`functionName`](#functionname), and [`args`](#args). Check out the [TypeScript docs](/react/typescript#const-assert-abis-typed-data) for more info. + + + +## Type Inference + +With [`abi`](/core/api/actions/writeContract#abi) setup correctly, TypeScript will infer the correct types for [`functionName`](/core/api/actions/writeContract#functionname), [`args`](/core/api/actions/writeContract#args), and the [`value`](/core/api/actions/writeContract##value). See the Wagmi [TypeScript docs](/react/typescript) for more information. + + + +## Action + +- [`writeContract`](/core/api/actions/writeContract) diff --git a/wagmi-project/site/react/api/hooks/useWriteContracts.md b/wagmi-project/site/react/api/hooks/useWriteContracts.md new file mode 100644 index 000000000..0e8e94aa7 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useWriteContracts.md @@ -0,0 +1,119 @@ +--- +title: useWriteContracts +description: Hook that requests for the wallet to sign and broadcast a batch of calls (transactions) to the network. +--- + + + +# useWriteContracts + +Hook that requests for the wallet to sign and broadcast a batch of write contract calls (transactions) to the network. + +[Read more.](https://github.com/ethereum/EIPs/blob/815028dc634463e1716fc5ce44c019a6040f0bef/EIPS/eip-5792.md#wallet_sendcalls) + +## Import + +```ts +import { useWriteContracts } from 'wagmi/experimental' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useWriteContracts } from 'wagmi/experimental' +import { parseAbi } from 'viem' + +const abi = parseAbi([ + 'function approve(address, uint256) returns (bool)', + 'function transferFrom(address, address, uint256) returns (bool)', +]) + +function App() { + const { writeContracts } = useWriteContracts() + + return ( + + ) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseWriteContractsParameters } from 'wagmi/experimental' +``` + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useWriteContracts } from 'wagmi/experimental' +import { config } from './config' // [!code focus] + +function App() { + const result = useWriteContracts({ + config, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseWriteContractsReturnType } from 'wagmi/experimental' +``` + + + + + +## Action + +- [`writeContracts`](/core/api/actions/writeContracts) diff --git a/wagmi-project/site/react/api/transports.md b/wagmi-project/site/react/api/transports.md new file mode 100644 index 000000000..5620b3c11 --- /dev/null +++ b/wagmi-project/site/react/api/transports.md @@ -0,0 +1,28 @@ + + +# Transports + +[`createConfig`](/react/api/createConfig) can be instantiated with a set of Transports for each chain. A Transport is the intermediary layer that is responsible for executing outgoing JSON-RPC requests to the RPC Provider (e.g. Alchemy, Infura, etc). + +## Import + +```ts +import { http } from 'wagmi' +``` + +## Built-In Transports + +Available via the `'wagmi'` entrypoint. + + diff --git a/wagmi-project/site/react/api/transports/custom.md b/wagmi-project/site/react/api/transports/custom.md new file mode 100644 index 000000000..d2ba5de55 --- /dev/null +++ b/wagmi-project/site/react/api/transports/custom.md @@ -0,0 +1,5 @@ + + + diff --git a/wagmi-project/site/react/api/transports/fallback.md b/wagmi-project/site/react/api/transports/fallback.md new file mode 100644 index 000000000..cffcd08f0 --- /dev/null +++ b/wagmi-project/site/react/api/transports/fallback.md @@ -0,0 +1,5 @@ + + + diff --git a/wagmi-project/site/react/api/transports/http.md b/wagmi-project/site/react/api/transports/http.md new file mode 100644 index 000000000..31d80d8a8 --- /dev/null +++ b/wagmi-project/site/react/api/transports/http.md @@ -0,0 +1,5 @@ + + + diff --git a/wagmi-project/site/react/api/transports/unstable_connector.md b/wagmi-project/site/react/api/transports/unstable_connector.md new file mode 100644 index 000000000..008b9aa3d --- /dev/null +++ b/wagmi-project/site/react/api/transports/unstable_connector.md @@ -0,0 +1,6 @@ + + + diff --git a/wagmi-project/site/react/api/transports/webSocket.md b/wagmi-project/site/react/api/transports/webSocket.md new file mode 100644 index 000000000..6eacdaabe --- /dev/null +++ b/wagmi-project/site/react/api/transports/webSocket.md @@ -0,0 +1,5 @@ + + + diff --git a/wagmi-project/site/react/api/utilities/cookieToInitialState.md b/wagmi-project/site/react/api/utilities/cookieToInitialState.md new file mode 100644 index 000000000..98363c60e --- /dev/null +++ b/wagmi-project/site/react/api/utilities/cookieToInitialState.md @@ -0,0 +1,5 @@ + + + diff --git a/wagmi-project/site/react/api/utilities/deserialize.md b/wagmi-project/site/react/api/utilities/deserialize.md new file mode 100644 index 000000000..24e9aa22c --- /dev/null +++ b/wagmi-project/site/react/api/utilities/deserialize.md @@ -0,0 +1,5 @@ + + + diff --git a/wagmi-project/site/react/api/utilities/normalizeChainId.md b/wagmi-project/site/react/api/utilities/normalizeChainId.md new file mode 100644 index 000000000..deceae7a4 --- /dev/null +++ b/wagmi-project/site/react/api/utilities/normalizeChainId.md @@ -0,0 +1,5 @@ + + + diff --git a/wagmi-project/site/react/api/utilities/serialize.md b/wagmi-project/site/react/api/utilities/serialize.md new file mode 100644 index 000000000..9ff2ff322 --- /dev/null +++ b/wagmi-project/site/react/api/utilities/serialize.md @@ -0,0 +1,5 @@ + + + diff --git a/wagmi-project/site/react/comparisons.md b/wagmi-project/site/react/comparisons.md new file mode 100644 index 000000000..8c614ed55 --- /dev/null +++ b/wagmi-project/site/react/comparisons.md @@ -0,0 +1,90 @@ +# Comparison + +There are multiple options when it comes to React libraries for Ethereum that help manage wallet connections, provide utility methods/hooks, etc. + +::: tip +Comparisons strive to be as accurate and as unbiased as possible. If you use any of these libraries and feel the information could be improved, feel free to suggest changes. +::: + +## Overview + +| | [wagmi](https://github.com/wagmi-dev/wagmi) | [web3-react](https://github.com/NoahZinsmeister/web3-react) | [useDApp](https://github.com/EthWorks/useDApp) | +| -------------------- | :---------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------ | :------------------------------------------------------------------------------------------------- | +| GitHub Stars | ![wagmi star count](https://img.shields.io/github/stars/wagmi-dev/wagmi?colorB=27292E&label=) | ![web3-react star count](https://img.shields.io/github/stars/Uniswap/web3-react?colorB=27292E&label=) | ![useDApp star count](https://img.shields.io/github/stars/EthWorks/useDApp?colorB=27292E&label=) | +| Open Issues | ![wagmi issue count](https://img.shields.io/github/issues/wagmi-dev/wagmi?colorB=27292E&label=) | ![web3-react issue count](https://img.shields.io/github/issues/Uniswap/web3-react?colorB=27292E&label=) | ![useDApp issue count](https://img.shields.io/github/issues/EthWorks/useDApp?colorB=27292E&label=) | +| Downloads | ![wagmi downloads](https://img.shields.io/npm/dw/wagmi?colorB=27292E&label=) | ![web3-react downloads](https://img.shields.io/npm/dw/@web3-react/core?colorB=27292E&label=) | ![useDApp downloads](https://img.shields.io/npm/dw/@usedapp/core?colorB=27292E&label=) | +| License | ![wagmi license](https://img.shields.io/github/license/wagmi-dev/wagmi?colorB=27292E&label=) | ![web3-react license](https://img.shields.io/github/license/Uniswap/web3-react?colorB=27292E&label=) | ![useDApp license](https://img.shields.io/github/license/EthWorks/useDApp?colorB=27292E&label=) | +| Their Comparison | – | none | none | +| Supported Frameworks | React, Vanilla JS | React | React | +| Documentation | ✅ | 🛑 | ✅ | +| TypeScript | ✅ | 🔶 | 🔶 | +| EIP-6963 Support | ✅ | 🔴 | 🔴 | +| Test Suite | ✅ | 🔶 | 🔶 | +| Examples | ✅ | 🔶 | ✅ | + +::: details Comparison Key + +1. Documentation + - Comprehensive documentation for all library features ✅ + - No documentation 🔴 +2. Typescript + - Infer types from ABIs, EIP-712 Typed Data, etc. ✅ + - Can add types with explicit generics, type annotations, etc. 🔶 +3. Test Suite + - Runs against forked Ethereum network(s) ✅ + - Mocking functionality (i.e. RPC calls) is 🔶 +4. EIP-6963 Support + - Fully compatible with EIP-6963 ✅ + - Not compatible with EIP-6963 🔴 +5. Examples + - Has multiple examples ✅ + - Has single example 🔶 +::: + +## [Wagmi](https://github.com/wagmi-dev/wagmi) + +### Pros + +- 20+ hooks for working with wallets, ENS, contracts, transactions, signing, etc. +- Built-in wallet connectors for injected providers (EIP-6963 support), WalletConnect, MetaMask, Coinbase Wallet +- Caching, request deduplication, and persistence powered by TanStack Query +- Auto-refresh data on wallet, block, and network changes +- Multicall support +- Test suite running against forked Ethereum networks +- TypeScript ready (infer types from ABIs and EIP-712 Typed Data) +- Extensive documentation and examples +- Used by Coinbase, Stripe, Shopify, Uniswap, Optimism, ENS, Sushi, and [many more](https://github.com/wagmi-dev/wagmi/discussions/201) +- MIT License + +### Cons + +- Not as many built-in connectors as `web3-react` + +## [web3-react](https://github.com/Uniswap/web3-react) + +### Pros + +- Supports many different connectors (conceptually similar to Wagmi's connectors) +- Basic hooks for managing account + +### Cons + +- Need to set up connectors and method for connecting wallet on your own +- Need to install connectors separately +- Almost no tests or documentation; infrequent updates +- GPL-3.0 License + +## [useDApp](https://github.com/EthWorks/useDApp) + +### Pros + +- Auto-refresh on new blocks and wallet changes +- Multicall support +- Transaction notifications +- Chrome extension and Firefox add-on +- MIT License + +### Cons + +- Non-standard hook API + diff --git a/wagmi-project/site/react/getting-started.md b/wagmi-project/site/react/getting-started.md new file mode 100644 index 000000000..3e4111cb4 --- /dev/null +++ b/wagmi-project/site/react/getting-started.md @@ -0,0 +1,214 @@ + + +# Getting Started + +## Overview + +Wagmi is a React Hooks library for Ethereum. You can learn more about the rationale behind the project in the [Why Wagmi](/react/why) section. + +## Automatic Installation + +For new projects, it is recommended to set up your Wagmi app using the [`create-wagmi`](/cli/create-wagmi) command line interface (CLI). This will create a new Wagmi project using TypeScript and install the required dependencies. + +::: code-group +```bash [pnpm] +pnpm create wagmi +``` + +```bash [npm] +npm create wagmi@latest +``` + +```bash [yarn] +yarn create wagmi +``` + +```bash [bun] +bun create wagmi +``` +::: + +Once the command runs, you'll see some prompts to complete. + +```ansi +Project name: wagmi-project +Select a framework: React / Vanilla +... +``` + +After the prompts, `create-wagmi` will create a directory with your project name and install the required dependencies. Check out the `README.md` for further instructions (if required). + +## Manual Installation + +To manually add Wagmi to your project, install the required packages. + +::: code-group +```bash-vue [pnpm] +pnpm add wagmi viem@{{viemVersion}} @tanstack/react-query +``` + +```bash-vue [npm] +npm install wagmi viem@{{viemVersion}} @tanstack/react-query +``` + +```bash-vue [yarn] +yarn add wagmi viem@{{viemVersion}} @tanstack/react-query +``` + +```bash-vue [bun] +bun add wagmi viem@{{viemVersion}} @tanstack/react-query +``` +::: + +- [Viem](https://viem.sh) is a TypeScript interface for Ethereum that performs blockchain operations. +- [TanStack Query](https://tanstack.com/query/v5) is an async state manager that handles requests, caching, and more. +- [TypeScript](/react/typescript) is optional, but highly recommended. Learn more about [TypeScript support](/react/typescript). + +### Create Config + +Create and export a new Wagmi config using `createConfig`. + +::: code-group +<<< @/snippets/react/config.ts[config.ts] +::: + +In this example, Wagmi is configured to use the Mainnet and Sepolia chains, and `injected` connector. Check out the [`createConfig` docs](/react/api/createConfig) for more configuration options. + + +::: details TypeScript Tip +If you are using TypeScript, you can "register" the Wagmi config or use the hook `config` property to get strong type-safety across React Context in places that wouldn't normally have type info. + +::: code-group +```ts twoslash [register config] +// @errors: 2322 +import { type Config } from 'wagmi' +import { mainnet, sepolia } from 'wagmi/chains' + +declare const config: Config +// ---cut--- +import { useBlockNumber } from 'wagmi' + +useBlockNumber({ chainId: 123 }) + +declare module 'wagmi' { + interface Register { + config: typeof config + } +} +``` + +```ts twoslash [hook config property] +// @errors: 2322 +import { type Config } from 'wagmi' +import { mainnet, sepolia } from 'wagmi/chains' + +declare const config: Config +// ---cut--- +import { useBlockNumber } from 'wagmi' + +useBlockNumber({ chainId: 123, config }) +``` + +By registering or using the hook `config` property, `useBlockNumber`'s `chainId` is strongly typed to only allow Mainnet and Sepolia IDs. Learn more by reading the [TypeScript docs](/react/typescript#config-types). +::: + +### Wrap App in Context Provider + +Wrap your app in the `WagmiProvider` React Context Provider and pass the `config` you created earlier to the `config` property. + +::: code-group +```tsx [app.tsx] +import { WagmiProvider } from 'wagmi' // [!code focus] +import { config } from './config' // [!code focus] + +function App() { + return ( + // [!code focus] + {/** ... */} // [!code focus] + // [!code focus] + ) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +Check out the [`WagmiProvider` docs](/react/api/WagmiProvider) to learn more about React Context in Wagmi. + +### Setup TanStack Query + +Inside the `WagmiProvider`, wrap your app in a TanStack Query React Context Provider, e.g. `QueryClientProvider`, and pass a new `QueryClient` instance to the `client` property. + +::: code-group +```tsx [app.tsx] +import { QueryClient, QueryClientProvider } from '@tanstack/react-query' // [!code focus] +import { WagmiProvider } from 'wagmi' +import { config } from './config' + +const queryClient = new QueryClient() // [!code focus] + +function App() { + return ( + + // [!code focus] + {/** ... */} // [!code focus] + // [!code focus] + + ) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +Check out the [TanStack Query docs](https://tanstack.com/query/latest/docs/framework/react) to learn about the library, APIs, and more. + +### Use Wagmi + +Now that everything is set up, every component inside the Wagmi and TanStack Query Providers can use Wagmi React Hooks. + +::: code-group +```tsx [profile.tsx] +import { useAccount, useEnsName } from 'wagmi' + +export function Profile() { + const { address } = useAccount() + const { data, error, status } = useEnsName({ address }) + if (status === 'pending') return
Loading ENS name
+ if (status === 'error') + return
Error fetching ENS name: {error.message}
+ return
ENS name: {data}
+} +``` + +```tsx [app.tsx] +import { QueryClient, QueryClientProvider } from '@tanstack/react-query' +import { WagmiProvider } from 'wagmi' +import { config } from './config' +import { Profile } from './profile' + +const queryClient = new QueryClient() + +function App() { + return ( + + + + + + ) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Next Steps + +For more information on what to do next, check out the following topics. + +- [**TypeScript**](/react/typescript) Learn how to get the most out of Wagmi's type-safety and inference for an enlightened developer experience. +- [**Connect Wallet**](/react/guides/connect-wallet) Learn how to enable wallets to connect to and disconnect from your apps and display information about connected accounts. +- [**React Hooks**](/react/api/hooks) Browse the collection of React Hooks and learn how to use them. +- [**Viem**](/react/guides/viem) Learn about Viem and how it works with Wagmi. diff --git a/wagmi-project/site/react/guides/chain-properties.md b/wagmi-project/site/react/guides/chain-properties.md new file mode 100644 index 000000000..9e4667a6e --- /dev/null +++ b/wagmi-project/site/react/guides/chain-properties.md @@ -0,0 +1,97 @@ +# Chain Properties + +Some chains support additional properties related to blocks and transactions. This is powered by Viem's [formatters](https://viem.sh/docs/chains/formatters) and [serializers](https://viem.sh/docs/chains/serializers). For example, Celo, ZkSync, OP Stack chains all support additional properties. In order to use these properties in a type-safe way, there are a few things you should be aware of. + +
+ +::: tip +Make sure you follow the TypeScript guide's [Config Types](/react/typescript#config-types) section before moving on. The easiest way to do this is to use [Declaration Merging](/react/typescript#declaration-merging) to "register" your `config` globally with TypeScript. + +<<< @/snippets/react/config-chain-properties.ts[config.ts] +::: + +## Narrowing Parameters + +Once your Config is registered with TypeScript, you are ready to access chain-specific properties! For example, Celo's `feeCurrency` is available. + +::: code-group +```ts [index.tsx] +import { parseEther } from 'viem' +import { useSimulateContract } from 'wagmi' + +const result = useSimulateContract({ + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), + feeCurrency: '0x…', // [!code focus] +}) +``` +<<< @/snippets/react/config-chain-properties.ts[config.ts] +::: + +This is great, but if you have multiple chains that support additional properties, your autocomplete could be overwhelmed with all of them. By setting the `chainId` property to a specific value (e.g. `celo.id`), you can narrow parameters to a single chain. + +::: code-group +```ts [index.tsx] +import { parseEther } from 'viem' +import { useSimulateContract } from 'wagmi' +import { celo } from 'wagmi/chains' + +const result = useSimulateContract({ + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), + chainId: celo.id, // [!code focus] + feeCurrency: '0x…', // [!code focus] + // ^? (property) feeCurrency?: `0x${string}` | undefined // [!code focus] +}) +``` +<<< @/snippets/react/config-chain-properties.ts[config.ts] +::: + +## Narrowing Return Types + +Return types can also have chain-specific properties attached to them. There are a couple approaches for extracting these properties. + +### `chainId` Parameter + +Not only can you use the `chainId` parameter to [narrow parameters](#narrowing-parameters), you can also use it to narrow the return type. + +::: code-group +```ts [index.tsx] +import { useWaitForTransactionReceipt } from 'wagmi' +import { zkSync } from 'wagmi/chains' + +const { data } = useWaitForTransactionReceipt({ + chainId: zkSync.id, + hash: '0x16854fcdd0219cacf5aec5e4eb2154dac9e406578a1510a6fc48bd0b67e69ea9', +}) + +data?.logs +// ^? (property) logs: ZkSyncLog[] | undefined +``` +<<< @/snippets/react/config-chain-properties.ts[config.ts] +::: + +### `chainId` Data Property + +Wagmi internally will set a `chainId` property on return types that you can use to narrow results. The `chainId` is determined from the `chainId` parameter or global state (e.g. connector). You can use this property to help TypeScript narrow the type. + +::: code-group +```ts [index.tsx] +import { useWaitForTransactionReceipt } from 'wagmi' +import { zkSync } from 'wagmi/chains' + +const { data } = useWaitForTransactionReceipt({ + hash: '0x16854fcdd0219cacf5aec5e4eb2154dac9e406578a1510a6fc48bd0b67e69ea9', +}) + +if (data?.chainId === zkSync.id) { + data?.logs + // ^? (property) logs: ZkSyncLog[] | undefined +} +``` +<<< @/snippets/react/config-chain-properties.ts[config.ts] +::: + +## Troubleshooting + +If chain properties aren't working, make sure [TypeScript](/react/guides/faq#type-inference-doesn-t-work) is configured correctly. Not all chains have additional properties, to check which ones do, see the [Viem repo](https://github.com/wevm/viem/tree/main/src/chains) (chains that have a top-level directory under [`src/chains`](https://github.com/wevm/viem/tree/main/src/chains) support additional properties). diff --git a/wagmi-project/site/react/guides/connect-wallet.md b/wagmi-project/site/react/guides/connect-wallet.md new file mode 100644 index 000000000..34a7e7bea --- /dev/null +++ b/wagmi-project/site/react/guides/connect-wallet.md @@ -0,0 +1,421 @@ +# Connect Wallet + +The ability for a user to connect their wallet is a core function for any Dapp. It allows users to perform tasks such as: writing to contracts, signing messages, or sending transactions. + +Wagmi contains everything you need to get started with building a Connect Wallet module. To get started, you can either use a [third-party library](#third-party-libraries) or [build your own](#build-your-own). + +## Third-party Libraries + +You can use a pre-built Connect Wallet module from a third-party library such as: + +- [ConnectKit](https://docs.family.co/connectkit) - [Guide](https://docs.family.co/connectkit/getting-started) +- [AppKit](https://reown.com/appkit) - [Guide](https://docs.reown.com/appkit/next/core/installation) +- [RainbowKit](https://www.rainbowkit.com/) - [Guide](https://www.rainbowkit.com/docs/installation) +- [Dynamic](https://www.dynamic.xyz/) - [Guide](https://docs.dynamic.xyz/quickstart) +- [Privy](https://privy.io) - [Guide](https://docs.privy.io/guide/react/wallets/usage/wagmi) + +The above libraries are all built on top of Wagmi, handle all the edge cases around wallet connection, and provide a seamless Connect Wallet UX that you can use in your Dapp. + +## Build Your Own + +Wagmi provides you with the Hooks to get started building your own Connect Wallet module. + +It takes less than five minutes to get up and running with Browser Wallets, WalletConnect, and Coinbase Wallet. + +### 1. Configure Wagmi + +Before we get started with building the functionality of the Connect Wallet module, we will need to set up the Wagmi configuration. + +Let's create a `config.ts` file and export a `config` object. + +::: code-group + +```tsx [config.ts] +import { http, createConfig } from 'wagmi' +import { base, mainnet, optimism } from 'wagmi/chains' +import { injected, metaMask, safe, walletConnect } from 'wagmi/connectors' + +const projectId = '' + +export const config = createConfig({ + chains: [mainnet, base], + connectors: [ + injected(), + walletConnect({ projectId }), + metaMask(), + safe(), + ], + transports: { + [mainnet.id]: http(), + [base.id]: http(), + }, +}) +``` + +::: + +In the above configuration, we want to set up connectors for Injected (browser), WalletConnect (browser + mobile), MetaMask, and Safe wallets. This configuration uses the **Mainnet** and **Base** chains, but you can use whatever you want. + +::: warning + +Make sure to replace the `projectId` with your own WalletConnect Project ID, if you wish to use WalletConnect! + +[Get your Project ID](https://cloud.reown.com/) + +::: + +### 2. Wrap App in Context Provider + +Next, we will need to wrap our React App with Context so that our application is aware of Wagmi & React Query's reactive state and in-memory caching. + +::: code-group + +```tsx [app.tsx] + // 1. Import modules +import { QueryClient, QueryClientProvider } from '@tanstack/react-query' +import { WagmiProvider } from 'wagmi' +import { config } from './config' + +// 2. Set up a React Query client. +const queryClient = new QueryClient() + +function App() { + // 3. Wrap app with Wagmi and React Query context. + return ( + + + {/** ... */} + + + ) +} +``` + +```tsx [config.ts] +import { http, createConfig } from 'wagmi' +import { base, mainnet, optimism } from 'wagmi/chains' +import { injected, metaMask, safe, walletConnect } from 'wagmi/connectors' + +const projectId = '' + +export const config = createConfig({ + chains: [mainnet, base], + connectors: [ + injected(), + walletConnect({ projectId }), + metaMask(), + safe(), + ], + transports: { + [mainnet.id]: http(), + [base.id]: http(), + }, +}) +``` + +::: + +### 3. Display Wallet Options + +After that, we will create a `WalletOptions` component that will display our connectors. This will allow users to select a wallet and connect. + +Below, we are rendering a list of `connectors` retrieved from `useConnect`. When the user clicks on a connector, the `connect` function will connect the users' wallet. + +::: code-group + +```tsx [wallet-options.tsx] +import * as React from 'react' +import { Connector, useConnect } from 'wagmi' + +export function WalletOptions() { + const { connectors, connect } = useConnect() + + return connectors.map((connector) => ( + + )) +} +``` + +```tsx [app.tsx] + // 1. Import modules +import { QueryClient, QueryClientProvider } from '@tanstack/react-query' +import { WagmiProvider } from 'wagmi' +import { config } from './config' + +// 2. Set up a React Query client. +const queryClient = new QueryClient() + +function App() { + // 3. Wrap app with Wagmi and React Query context. + return ( + + + {/* ... */} + + + ) +} +``` + +```tsx [config.ts] +import { http, createConfig } from 'wagmi' +import { base, mainnet, optimism } from 'wagmi/chains' +import { injected, metaMask, safe, walletConnect } from 'wagmi/connectors' + +const projectId = '' + +export const config = createConfig({ + chains: [mainnet, base], + connectors: [ + injected(), + walletConnect({ projectId }), + metaMask(), + safe(), + ], + transports: { + [mainnet.id]: http(), + [base.id]: http(), + }, +}) +``` + +::: + +### 4. Display Connected Account + +Lastly, if an account is connected, we want to show some basic information, like the connected address and ENS name and avatar. + +Below, we are using hooks like `useAccount`, `useEnsAvatar` and `useEnsName` to extract this information. + +We are also utilizing `useDisconnect` to show a "Disconnect" button so a user can disconnect their wallet. + +::: code-group + +```tsx [account.tsx] +import { useAccount, useDisconnect, useEnsAvatar, useEnsName } from 'wagmi' + +export function Account() { + const { address } = useAccount() + const { disconnect } = useDisconnect() + const { data: ensName } = useEnsName({ address }) + const { data: ensAvatar } = useEnsAvatar({ name: ensName! }) + + return ( +
+ {ensAvatar && ENS Avatar} + {address &&
{ensName ? `${ensName} (${address})` : address}
} + +
+ ) +} +``` + +```tsx [wallet-options.tsx] +import * as React from 'react' +import { Connector, useConnect } from 'wagmi' + +export function WalletOptions() { + const { connectors, connect } = useConnect() + + return connectors.map((connector) => ( + connect({ connector })} + /> + )) +} + +function WalletOption({ + connector, + onClick, +}: { + connector: Connector + onClick: () => void +}) { + const [ready, setReady] = React.useState(false) + + React.useEffect(() => { + ;(async () => { + const provider = await connector.getProvider() + setReady(!!provider) + })() + }, [connector]) + + return ( + + ) +} +``` + +```tsx [app.tsx] + // 1. Import modules +import { QueryClient, QueryClientProvider } from '@tanstack/react-query' +import { WagmiProvider } from 'wagmi' +import { config } from './config' + +// 2. Set up a React Query client. +const queryClient = new QueryClient() + +function App() { + // 3. Wrap app with Wagmi and React Query context. + return ( + + + {/* ... */} + + + ) +} +``` + +```tsx [config.ts] +import { http, createConfig } from 'wagmi' +import { base, mainnet, optimism } from 'wagmi/chains' +import { injected, metaMask, safe, walletConnect } from 'wagmi/connectors' + +const projectId = '' + +export const config = createConfig({ + chains: [mainnet, base], + connectors: [ + injected(), + walletConnect({ projectId }), + metaMask(), + safe(), + ], + transports: { + [mainnet.id]: http(), + [base.id]: http(), + }, +}) +``` + +::: + +### 5. Wire it up! + +Finally, we can wire up our Wallet Options and Account components to our application's entrypoint. + +::: code-group + +```tsx [app.tsx] +import { QueryClient, QueryClientProvider } from '@tanstack/react-query' +import { WagmiProvider, useAccount } from 'wagmi' +import { config } from './config' +import { Account } from './account' // [!code ++] +import { WalletOptions } from './wallet-options' // [!code ++] + +const queryClient = new QueryClient() + +function ConnectWallet() { // [!code ++] + const { isConnected } = useAccount() // [!code ++] + if (isConnected) return // [!code ++] + return // [!code ++] +} // [!code ++] + +function App() { + return ( + + + // [!code ++] + + + ) +} +``` + +```tsx [account.tsx] +import { useAccount, useDisconnect, useEnsAvatar, useEnsName } from 'wagmi' + +export function Account() { + const { address } = useAccount() + const { disconnect } = useDisconnect() + const { data: ensName } = useEnsName({ address }) + const { data: ensAvatar } = useEnsAvatar({ name: ensName! }) + + return ( +
+ {ensAvatar && ENS Avatar} + {address &&
{ensName ? `${ensName} (${address})` : address}
} + +
+ ) +} +``` + +```tsx [wallet-options.tsx] +import * as React from 'react' +import { Connector, useConnect } from 'wagmi' + +export function WalletOptions() { + const { connectors, connect } = useConnect() + + return connectors.map((connector) => ( + connect({ connector })} + /> + )) +} + +function WalletOption({ + connector, + onClick, +}: { + connector: Connector + onClick: () => void +}) { + const [ready, setReady] = React.useState(false) + + React.useEffect(() => { + ;(async () => { + const provider = await connector.getProvider() + setReady(!!provider) + })() + }, [connector]) + + return ( + + ) +} +``` + +```tsx [config.ts] +import { http, createConfig } from 'wagmi' +import { base, mainnet, optimism } from 'wagmi/chains' +import { injected, metaMask, safe, walletConnect } from 'wagmi/connectors' + +const projectId = '' + +export const config = createConfig({ + chains: [mainnet, base], + connectors: [ + injected(), + walletConnect({ projectId }), + metaMask(), + safe(), + ], + transports: { + [mainnet.id]: http(), + [base.id]: http(), + }, +}) +``` + +::: + +### Playground + +Want to see the above steps all wired up together in an end-to-end example? Check out the below StackBlitz playground. + +
+ + diff --git a/wagmi-project/site/react/guides/error-handling.md b/wagmi-project/site/react/guides/error-handling.md new file mode 100644 index 000000000..62dae72b5 --- /dev/null +++ b/wagmi-project/site/react/guides/error-handling.md @@ -0,0 +1,42 @@ +# Error Handling + +The `error` property in Wagmi Hooks is strongly typed with it's corresponding error type. This enables you to have granular precision with handling errors in your application. + +You can discriminate the error type by using the `name` property on the error object. + +::: code-group +```tsx twoslash [index.tsx] +// @noErrors +import { useBlockNumber } from 'wagmi' + +function App() { + const { data, error } = useBlockNumber() + // ^? + + error?.name + // ^? + + + + + + + if (error?.name === 'HttpRequestError') { + const { status } = error + // ^? + + + return
A HTTP error occurred. Status: {status}
+ } + if (error?.name === 'LimitExceededRpcError') { + const { code } = error + // ^? + + + return
Rate limit exceeded. Code: {code}
+ } + // ... +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: diff --git a/wagmi-project/site/react/guides/ethers.md b/wagmi-project/site/react/guides/ethers.md new file mode 100644 index 000000000..fe1b2ad59 --- /dev/null +++ b/wagmi-project/site/react/guides/ethers.md @@ -0,0 +1,285 @@ +# Ethers.js Adapters + +It is recommended for projects to migrate to [Viem](https://viem.sh) when using Wagmi, but there are some cases where you might still need to use [Ethers.js](https://ethers.org) in your project: + +- You may want to **incrementally migrate** Ethers.js usage to Viem +- Some **third-party libraries & SDKs** may only support Ethers.js +- Personal preference + +We have provided reference implementations for Viem → Ethers.js adapters that you can copy + paste in your project. + +## Client → Provider + +### Reference Implementation + +Copy the following reference implementation into a file of your choice: + +::: code-group + +```ts [Ethers v5] +import { providers } from 'ethers' +import { useMemo } from 'react' +import type { Chain, Client, Transport } from 'viem' +import { Config, useClient } from 'wagmi' + +export function clientToProvider(client: Client) { + const { chain, transport } = client + const network = { + chainId: chain.id, + name: chain.name, + ensAddress: chain.contracts?.ensRegistry?.address, + } + if (transport.type === 'fallback') + return new providers.FallbackProvider( + (transport.transports as ReturnType[]).map( + ({ value }) => new providers.JsonRpcProvider(value?.url, network), + ), + ) + return new providers.JsonRpcProvider(transport.url, network) +} + +/** Hook to convert a viem Client to an ethers.js Provider. */ +export function useEthersProvider({ + chainId, +}: { chainId?: number | undefined } = {}) { + const client = useClient({ chainId }) + return useMemo(() => (client ? clientToProvider(client) : undefined), [client]) +} +``` + +```ts [Ethers v6] +import { FallbackProvider, JsonRpcProvider } from 'ethers' +import { useMemo } from 'react' +import type { Chain, Client, Transport } from 'viem' +import { type Config, useClient } from 'wagmi' + +export function clientToProvider(client: Client) { + const { chain, transport } = client + const network = { + chainId: chain.id, + name: chain.name, + ensAddress: chain.contracts?.ensRegistry?.address, + } + if (transport.type === 'fallback') { + const providers = (transport.transports as ReturnType[]).map( + ({ value }) => new JsonRpcProvider(value?.url, network), + ) + if (providers.length === 1) return providers[0] + return new FallbackProvider(providers) + } + return new JsonRpcProvider(transport.url, network) +} + +/** Action to convert a viem Client to an ethers.js Provider. */ +export function useEthersProvider({ chainId }: { chainId?: number } = {}) { + const client = useClient({ chainId }) + return useMemo(() => (client ? clientToProvider(client) : undefined), [client]) +} +``` + +::: + +### Usage + +Now you can use the `useEthersProvider` function in your components: + +::: code-group + +```ts [example.ts] +import { useEthersProvider } from './ethers' + +function Example() { + const provider = useEthersProvider() + ... +} +``` + +```ts [ethers.ts (Ethers v5)] +import { providers } from 'ethers' +import { useMemo } from 'react' +import type { Chain, Client, Transport } from 'viem' +import { Config, useClient } from 'wagmi' + +export function clientToProvider(client: Client) { + const { chain, transport } = client + const network = { + chainId: chain.id, + name: chain.name, + ensAddress: chain.contracts?.ensRegistry?.address, + } + if (transport.type === 'fallback') + return new providers.FallbackProvider( + (transport.transports as ReturnType[]).map( + ({ value }) => new providers.JsonRpcProvider(value?.url, network), + ), + ) + return new providers.JsonRpcProvider(transport.url, network) +} + +/** Hook to convert a viem Client to an ethers.js Provider. */ +export function useEthersProvider({ + chainId, +}: { chainId?: number | undefined } = {}) { + const client = useClient({ chainId }) + return useMemo(() => (client ? clientToProvider(client) : undefined), [client]) +} +``` + +```ts [ethers.ts (Ethers v6)] +import { FallbackProvider, JsonRpcProvider } from 'ethers' +import { useMemo } from 'react' +import type { Chain, Client, Transport } from 'viem' +import { type Config, useClient } from 'wagmi' + +export function clientToProvider(client: Client) { + const { chain, transport } = client + const network = { + chainId: chain.id, + name: chain.name, + ensAddress: chain.contracts?.ensRegistry?.address, + } + if (transport.type === 'fallback') { + const providers = (transport.transports as ReturnType[]).map( + ({ value }) => new JsonRpcProvider(value?.url, network), + ) + if (providers.length === 1) return providers[0] + return new FallbackProvider(providers) + } + return new JsonRpcProvider(transport.url, network) +} + +/** Action to convert a viem Client to an ethers.js Provider. */ +export function useEthersProvider({ chainId }: { chainId?: number } = {}) { + const client = useClient({ chainId }) + return useMemo(() => (client ? clientToProvider(client) : undefined), [client]) +} +``` + +::: + +## Connector Client → Signer + +### Reference Implementation + +Copy the following reference implementation into a file of your choice: + +::: code-group + +```ts [Ethers v5] +import { providers } from 'ethers' +import { useMemo } from 'react' +import type { Account, Chain, Client, Transport } from 'viem' +import { Config, useConnectorClient } from 'wagmi' + +export function clientToSigner(client: Client) { + const { account, chain, transport } = client + const network = { + chainId: chain.id, + name: chain.name, + ensAddress: chain.contracts?.ensRegistry?.address, + } + const provider = new providers.Web3Provider(transport, network) + const signer = provider.getSigner(account.address) + return signer +} + +/** Hook to convert a Viem Client to an ethers.js Signer. */ +export function useEthersSigner({ chainId }: { chainId?: number } = {}) { + const { data: client } = useConnectorClient({ chainId }) + return useMemo(() => (client ? clientToSigner(client) : undefined), [client]) +} +``` + +```ts [Ethers v6] +import { BrowserProvider, JsonRpcSigner } from 'ethers' +import { useMemo } from 'react' +import type { Account, Chain, Client, Transport } from 'viem' +import { type Config, useConnectorClient } from 'wagmi' + +export function clientToSigner(client: Client) { + const { account, chain, transport } = client + const network = { + chainId: chain.id, + name: chain.name, + ensAddress: chain.contracts?.ensRegistry?.address, + } + const provider = new BrowserProvider(transport, network) + const signer = new JsonRpcSigner(provider, account.address) + return signer +} + +/** Hook to convert a viem Wallet Client to an ethers.js Signer. */ +export function useEthersSigner({ chainId }: { chainId?: number } = {}) { + const { data: client } = useConnectorClient({ chainId }) + return useMemo(() => (client ? clientToSigner(client) : undefined), [client]) +} +``` + +::: + +### Usage + +Now you can use the `useEthersSigner` function in your components: + +::: code-group + +```ts [example.ts] +import { useEthersSigner } from './ethers' + +function example() { + const signer = useEthersSigner() + ... +} +``` + +```ts [ethers.ts (Ethers v5)] +import { providers } from 'ethers' +import { useMemo } from 'react' +import type { Account, Chain, Client, Transport } from 'viem' +import { Config, useConnectorClient } from 'wagmi' + +export function clientToSigner(client: Client) { + const { account, chain, transport } = client + const network = { + chainId: chain.id, + name: chain.name, + ensAddress: chain.contracts?.ensRegistry?.address, + } + const provider = new providers.Web3Provider(transport, network) + const signer = provider.getSigner(account.address) + return signer +} + +/** Action to convert a Viem Client to an ethers.js Signer. */ +export function useEthersSigner({ chainId }: { chainId?: number } = {}) { + const { data: client } = useConnectorClient({ chainId }) + return useMemo(() => (client ? clientToSigner(client) : undefined), [client]) +} +``` + +```ts [ethers.ts (Ethers v6)] +import { BrowserProvider, JsonRpcSigner } from 'ethers' +import { useMemo } from 'react' +import type { Account, Chain, Client, Transport } from 'viem' +import { type Config, useConnectorClient } from 'wagmi' + +export function clientToSigner(client: Client) { + const { account, chain, transport } = client + const network = { + chainId: chain.id, + name: chain.name, + ensAddress: chain.contracts?.ensRegistry?.address, + } + const provider = new BrowserProvider(transport, network) + const signer = new JsonRpcSigner(provider, account.address) + return signer +} + +/** Hook to convert a viem Wallet Client to an ethers.js Signer. */ +export function useEthersSigner({ chainId }: { chainId?: number } = {}) { + const { data: client } = useConnectorClient({ chainId }) + return useMemo(() => (client ? clientToSigner(client) : undefined), [client]) +} +``` + +::: diff --git a/wagmi-project/site/react/guides/faq.md b/wagmi-project/site/react/guides/faq.md new file mode 100644 index 000000000..8628c5b1b --- /dev/null +++ b/wagmi-project/site/react/guides/faq.md @@ -0,0 +1,24 @@ + + +# FAQ / Troubleshooting + +Collection of frequently asked questions with ideas on how to troubleshoot and resolve them. + + + +## How does Wagmi work? + +Until there's a more in-depth write-up about Wagmi internals, here is the gist: + +- Wagmi is essentially a wrapper around [Viem](https://viem.sh) and TanStack Query that adds connector and multichain support. +- [Connectors](/react/api/connectors) allow Wagmi and Ethereum accounts to communicate with each other. +- The Wagmi [`Config`](/react/api/createConfig#config) manages connections established between Wagmi and Connectors, as well as some global state. [Connections](/react/api/createConfig#connection) come with one or more addresses and a chain ID. + - If there are connections, the Wagmi `Config` listens for connection changes and updates the [`chainId`](/react/api/createConfig#chainid) based on the ["current" connection](/react/api/createConfig#current). (The Wagmi `Config` can have [many connections established](/react/api/createConfig#connections) at once, but only one connection can be the "current" connection. Usually this is the connection from the last connector that is connected, but can change based on event emitted from other connectors or through the [`useSwitchAccount`](/react/api/hooks/useSwitchAccount) hook and [`switchAccount`](/core/api/actions/switchAccount) action.) + - If there are no connections, the Wagmi `Config` defaults the global state `chainId` to the first chain it was created with or last established connection. + - The global `chainId` can be changed directly using the [`useSwitchChain`](/react/api/hooks/useSwitchChain) hook and [`switchChain`](/core/api/actions/switchChain) action. This works when there are no connections as well as for most connectors (not all connectors support chain switching). +- Wagmi uses the global `chainId` (from the "current" connection or global state) to internally create Viem Client's, which are used by hooks and actions. +- Hooks are constructed by TanStack Query options helpers, exported by the `'@wagmi/core/query'` entrypoint, and some additional code to wire up type parameters, hook into React Context, etc. +- There are three types of hooks: query hooks, mutation hooks, and config hooks. Query hooks, like [`useCall`](/react/api/hooks/useCall), generally read blockchain state and mutation hooks, like [`useSendTransaction`](/react/api/hooks/useSendTransaction), usually change state through sending transactions via the "current" connection. Config hooks are for getting data from and managing the Wagmi `Config` instance, e.g. [`useChainId`](/react/api/hooks/useChainId) and `useSwitchAccount`. Query and mutation hooks usually have corresponding [Viem actions.](https://viem.sh) + diff --git a/wagmi-project/site/react/guides/migrate-from-v1-to-v2.md b/wagmi-project/site/react/guides/migrate-from-v1-to-v2.md new file mode 100644 index 000000000..1374fd6ee --- /dev/null +++ b/wagmi-project/site/react/guides/migrate-from-v1-to-v2.md @@ -0,0 +1,658 @@ +--- +title: Migrate from v1 to v2 +description: Guide for migrating from Wagmi v1 to v2. +--- + + + +# Migrate from v1 to v2 + +## Overview + +Wagmi v2 redesigns the core APIs to mesh better with [Viem](https://viem.sh) and [TanStack Query](https://tanstack.com/query/v5/docs/react). This major version transforms Wagmi into a light wrapper around these libraries, sprinkling in multichain support and account management. As such, there are some breaking changes and deprecations to be aware of outlined in this guide. + +To get started, install the latest version of Wagmi and it's required peer dependencies. + +::: code-group +```bash-vue [pnpm] +pnpm add wagmi viem@{{viemVersion}} @tanstack/react-query +``` + +```bash-vue [npm] +npm install wagmi viem@{{viemVersion}} @tanstack/react-query +``` + +```bash-vue [yarn] +yarn add wagmi viem@{{viemVersion}} @tanstack/react-query +``` + +```bash-vue [bun] +bun add wagmi viem@{{viemVersion}} @tanstack/react-query +``` +::: + +::: info Wagmi v2 should be the last major version that will have this many actionable breaking changes. +Moving forward after Wagmi v2, new functionality will be opt-in with old functionality being deprecated alongside the new features. This means upgrading to the latest major versions will not require immediate changes. +::: + +::: info Not ready to migrate yet? +The Wagmi v1 docs are still available at [1.x.wagmi.sh/react](https://1.x.wagmi.sh/react). +::: + +## Dependencies + +### Moved TanStack Query to peer dependencies + +Wagmi uses [TanStack Query](https://tanstack.com/query/v5/docs/react) to manage async state, handling requests, caching, and more. With Wagmi v1, TanStack Query was an internal implementation detail. With Wagmi v2, TanStack Query is a peer dependency. A lot of Wagmi users also use TanStack Query in their apps so making it a peer dependency gives them more control and removes some custom Wagmi code internally. + +If you don't normally use TanStack Query, all you need to do is set it up and mostly forget about it (we'll provide guidance around version updates). + +::: code-group +```tsx [app.tsx] +import { QueryClient, QueryClientProvider } from '@tanstack/react-query' // [!code ++] +import { WagmiProvider } from 'wagmi' +import { config } from './config' + +const queryClient = new QueryClient() // [!code ++] + +function App() { + return ( + + // [!code ++] + {/** ... */} + // [!code ++] + + ) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +For more information on setting up TanStack Query for Wagmi, follow the [Getting Started docs](/react/getting-started#setup-tanstack-query). If you want to set up persistence for your query cache (default behavior before Wagmi v2), check out the [TanStack Query docs](https://tanstack.com/query/v5/docs/react/plugins/persistQueryClient#usage-with-react). + +### Dropped CommonJS support + +Wagmi v2 no longer publishes a separate `cjs` tag since very few people use this tag and ESM is the future. See [Sindre Sorhus' guide](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c) for more info about switching to ESM. + +## Hooks + +### Removed mutation setup arguments + +Mutation hooks are hooks that change network or application state, sign data, or perform write operations through mutation functions. With Wagmi v1, you could pass arguments directly to these hooks instead of using them with their mutation functions. For example: + +```ts{3} +// Wagmi v1 +const { signMessage } = useSignMessage({ + message: 'foo bar baz', +}) +``` + +With Wagmi v2, you must pass arguments to the mutation function instead. This follows the same behavior as [TanStack Query](https://tanstack.com/query/v5/docs/react/guides/mutations) mutations and improves type-safety. + +```tsx +import { useSignMessage } from 'wagmi' + +const { signMessage } = useSignMessage({ message: 'foo bar baz' }) // [!code --] +const { signMessage } = useSignMessage() // [!code ++] + + +``` + +### Moved TanStack Query parameters to `query` property + +Previously, you could pass TanStack Query parameters, like `enabled` and `staleTime`, directly to hooks. In Wagmi v2, TanStack Query parameters are now moved to the `query` property. This allows Wagmi to better support TanStack Query type inference, control for future breaking changes since [TanStack Query is now a peer dependency](#moved-tanstack-query-to-peer-dependencies), and expose Wagmi-related hook property at the top-level of editor features, like autocomplete. + +```tsx +useReadContract({ + enabled: false, // [!code --] + staleTime: 1_000, // [!code --] + query: { // [!code ++] + enabled: false, // [!code ++] + staleTime: 1_000, // [!code ++] + }, // [!code ++] +}) +``` + +### Removed watch property + +The `watch` property was removed from all hooks besides [`useBlock`](/react/api/hooks/useBlock) and [`useBlockNumber`](/react/api/hooks/useBlockNumber). This property allowed hooks to internally listen for block changes and automatically refresh their data. In Wagmi v2, you can compose `useBlock` or `useBlockNumber` along with [`React.useEffect`](https://react.dev/reference/react/useEffect) to achieve the same behavior. Two different approaches are outlined for `useBalance` below. + +::: code-group +```ts [invalidateQueries] +import { useQueryClient } from '@tanstack/react-query' // [!code ++] +import { useEffect } from 'react' // [!code ++] +import { useBlockNumber, useBalance } from 'wagmi' // [!code ++] + +const queryClient = useQueryClient() // [!code ++] +const { data: blockNumber } = useBlockNumber({ watch: true }) // [!code ++] +const { data: balance, queryKey } = useBalance({ // [!code ++] + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', + watch: true, // [!code --] +}) + +useEffect(() => { // [!code ++] + queryClient.invalidateQueries({ queryKey }) // [!code ++] +}, [blockNumber, queryClient]) // [!code ++] +``` +```ts [refetch] +import { useEffect } from 'react' // [!code ++] +import { useBlockNumber, useBalance } from 'wagmi' // [!code ++] + +const { data: blockNumber } = useBlockNumber({ watch: true }) // [!code ++] +const { data: balance, refetch } = useBalance({ + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', + watch: true, // [!code --] +}) + +useEffect(() => { // [!code ++] + refetch() // [!code ++] +}, [blockNumber]) // [!code ++] +``` +::: + +This is a bit more code, but removes a lot of internal code from hooks that can slow down your app when not used and gives you more control. For example, you can easily refresh data every five blocks instead of every block. + +```ts +const { data: blockNumber } = useBlockNumber({ watch: true }) +const { data: balance, queryKey } = useBalance({ + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', +}) + +useEffect(() => { + if (blockNumber % 5 === 0) // [!code focus] + queryClient.invalidateQueries({ queryKey }) // [!code focus] +}, [blockNumber, queryClient]) +``` + +### Removed suspense property + +Wagmi used to support an experimental `suspense` property via TanStack Query. Since TanStack Query [removed `suspense`](https://tanstack.com/query/v5/docs/react/guides/migrating-to-v5#new-hooks-for-suspense) from its `useQuery` hook, it is no longer supported by Wagmi Hooks. + +Instead, you can use `useSuspenseQuery` along with TanStack Query-related exports from the `'wagmi/query'` entrypoint. + +```ts +import { useSuspenseQuery } from '@tanstack/react-query' // [!code ++] +import { useConfig } from 'wagmi' // [!code ++] +import { getBalanceQueryOptions } from 'wagmi/query' // [!code ++] +import { useBalance } from 'wagmi' // [!code --] + +const config = useConfig() // [!code ++] +const options = getBalanceQueryOptions(config, { address: '0x…' }) // [!code ++] +const result = useSuspenseQuery(options) // [!code ++] +const result = useBalance({ // [!code --] + address: '0x…', // [!code --] + suspense: true, // [!code --] +}) // [!code --] +``` + +### Removed prepare hooks + +`usePrepareContractWrite` and `usePrepareSendTransaction` were removed and replaced with idiomatic Viem alternatives. For `usePrepareContractWrite`, use [`useSimulateContract`](/react/api/hooks/useSimulateContract). Similar to `usePrepareContractWrite`, `useSimulateContract` composes well with `useWriteContract` + +```tsx +import { usePrepareContractWrite, useWriteContract } from 'wagmi' // [!code --] +import { useSimulateContract, useWriteContract } from 'wagmi' // [!code ++] + +const { config } = usePrepareContractWrite({ // [!code --] +const { data } = useSimulateContract({ // [!code ++] + address: '0x', + abi: [{ + type: 'function', + name: 'transferFrom', + stateMutability: 'nonpayable', + inputs: [ + { name: 'sender', type: 'address' }, + { name: 'recipient', type: 'address' }, + { name: 'amount', type: 'uint256' }, + ], + outputs: [{ type: 'bool' }], + }], + functionName: 'transferFrom', + args: ['0x', '0x', 123n], +}) +const { write } = useWriteContract(config) // [!code --] +const { writeContract } = useWriteContract() // [!code ++] + + +``` + +Instead of `usePrepareSendTransaction`, use [`useEstimateGas`](/react/api/hooks/useEstimateGas). You can pass `useEstimateGas` `data` to `useSendTransaction` to compose the two hooks. + +```tsx +import { usePrepareSendTransaction, useSendTransaction } from 'wagmi' // [!code --] +import { useEstimateGas, useSendTransaction } from 'wagmi' // [!code ++] +import { parseEther } from 'viem' + +const { config } = usePrepareSendTransaction({ // [!code --] +const { data } = useEstimateGas({ // [!code ++] + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), +}) +const { sendTransaction } = useSendTransaction(config) // [!code --] +const { sendTransaction } = useSendTransaction() // [!code ++] + + +``` + +This might seem like more work, but it gives you more control and is more accurate representation of what is happening under the hood. + +### Removed `useNetwork` hook + +The `useNetwork` hook was removed since the connected chain is typically based on the connected account. Use [`useAccount`](/react/api/hooks/useAccount) to get the connected `chain`. + +```ts +import { useNetwork } from 'wagmi' // [!code --] +import { useAccount } from 'wagmi' // [!code ++] + +const { chain } = useNetwork() // [!code --] +const { chain } = useAccount() // [!code ++] +``` + +Use `useConfig` for the list of `chains` set up with the Wagmi [`Config`](/react/api/createConfig#chains). + +```ts +import { useNetwork } from 'wagmi' // [!code --] +import { useConfig } from 'wagmi' // [!code ++] + +const { chains } = useNetwork() // [!code --] +const { chains } = useConfig() // [!code ++] +``` + +### Removed `onConnect` and `onDisconnect` callbacks from `useAccount` + +The `onConnect` and `onDisconnect` callbacks were removed from the `useAccount` hook since it is frequently used without these callbacks so it made sense to extract these into a new API, [`useAccountEffect`](/react/api/hooks/useAccountEffect), rather than clutter the `useAccount` hook. + +```ts +import { useAccount } from 'wagmi' // [!code --] +import { useAccountEffect } from 'wagmi' // [!code ++] + +useAccount({ // [!code --] +useAccountEffect({ // [!code ++] + onConnect(data) { + console.log('connected', data) + }, + onDisconnect() { + console.log('disconnected') + }, +}) +``` + +### Removed `useWebSocketPublicClient` + +The Wagmi [`Config`](/react/api/createConfig) does not separate transport types anymore. Simply use Viem's [`webSocket`](https://viem.sh/docs/clients/transports/websocket.html) transport instead when setting up your Wagmi `Config`. You can get Viem `Client` instance with this transport attached by using [`useClient`](/react/api/hooks/useClient) or [`usePublicClient`](/react/api/hooks/usePublicClient). + +### Removed `useInfiniteReadContracts` `paginatedIndexesConfig` + +In the spirit of removing unnecessary abstractions, `paginatedIndexesConfig` was removed. Use `useInfiniteReadContracts`'s `initialPageParam` and `getNextPageParam` parameters along with `fetchNextPage`/`fetchPreviousPage` from the result instead or copy `paginatedIndexesConfig`'s implementation to your codebase. + +See the [TanStack Query docs](https://tanstack.com/query/v5/docs/react/guides/infinite-queries) for more information on infinite queries. + +### Updated `useSendTransaction` and `useWriteContract` return type + +Updated [`useSendTransaction`](/react/api/hooks/useSendTransaction) and [`useWriteContract`](/react/api/hooks/useWriteContract) return type from `` { hash: `0x${string}` } `` to `` `0x${string}` ``. + +```ts +const result = useSendTransaction() +result.data?.hash // [!code --] +result.data // [!code ++] +``` + +### Updated `useConnect` return type + +Updated [`useConnect`](/react/api/hooks/useConnect) return type from `` { account: Address; chain: { id: number; unsupported?: boolean }; connector: Connector } `` to `` { accounts: readonly Address[]; chainId: number } ``. This better reflects the ability to have multiple accounts per connector. + +### Renamed parameters and return types + +All hook parameters and return types follow the naming pattern of `[PascalCaseHookName]Parameters` and `[PascalCaseHookName]ReturnType`. For example, `UseAccountParameters` and `UseAccountReturnType`. + +```ts +import { UseAccountConfig, UseAccountResult } from 'wagmi' // [!code --] +import { UseAccountParameters, UseAccountReturnType } from 'wagmi' // [!code ++] +``` + +## Connectors + +### Updated connector API + +In order to maximize type-safety and ease of creating connectors, the connector API changed. Follow the [Creating Connectors guide](/dev/creating-connectors) for more info on creating new connectors and converting Wagmi v1 connectors. + +### Removed individual entrypoints + +Previously, each connector had it's own entrypoint to optimize tree-shaking. Since all connectors now have [`package.json#sideEffects`](https://webpack.js.org/guides/tree-shaking/#mark-the-file-as-side-effect-free) enabled, this is no longer necessary and the entrypoint is unified. Use the `'wagmi/connectors'` entrypoint instead. + +```ts +import { InjectedConnector } from 'wagmi/connectors/injected' // [!code --] +import { CoinbaseWalletConnector } from 'wagmi/connectors/coinbaseWallet' // [!code --] +import { coinbaseWallet, injected } from 'wagmi/connectors' // [!code ++] +``` + +### Removed `MetaMaskConnector` + +The `MetaMaskConnector` was removed since it was nearly the same thing as the `InjectedConnector`. Use the [`injected`](/react/api/connectors/injected) connector instead, along with the [`target`](/react/api/connectors/injected#target) parameter set to `'metaMask'`, for the same behavior. + +```ts +import { MetaMaskConnector } from 'wagmi/connectors/metaMask' // [!code --] +import { injected } from 'wagmi/connectors' // [!code ++] + +const connector = new MetaMaskConnector() // [!code --] +const connector = injected({ target: 'metaMask' }) // [!code ++] +``` +### Renamed connectors + +In Wagmi v1, connectors were classes you needed to instantiate. In Wagmi v2, connectors are functions. As a result, the API has changed. Connectors have the following new names: + +- `CoinbaseWalletConnector` is now [`coinbaseWallet`](/react/api/connectors/coinbaseWallet). +- `InjectedConnector` is now [`injected`](/react/api/connectors/injected). +- `SafeConnector` is now [`safe`](/react/api/connectors/safe). +- `WalletConnectConnector` is now [`walletConnect`](/react/api/connectors/walletConnect). + +To create a connector, you now call the connector function with parameters. + +```ts +import { WalletConnectConnector } from 'wagmi/connectors/walletConnect' // [!code --] +import { walletConnect } from 'wagmi/connectors' // [!code ++] + +const connector = new WalletConnectConnector({ // [!code --] +const connector = walletConnect({ // [!code ++] + projectId: '3fcc6bba6f1de962d911bb5b5c3dba68', +}) +``` + +### Removed `WalletConnectLegacyConnector` + +WalletConnect v1 was sunset June 28, 2023. Use the [`walletConnect`](/react/api/connectors/walletConnect) connector instead. + +```ts +import { WalletConnectLegacyConnector } from 'wagmi/connectors/walletConnectLegacy' // [!code --] +import { walletConnect } from 'wagmi/connectors' // [!code ++] + +const connector = new WalletConnectLegacyConnector({ // [!code --] +const connector = walletConnect({ // [!code ++] + projectId: '3fcc6bba6f1de962d911bb5b5c3dba68', +}) +``` + +## Chains + +### Updated `'wagmi/chains'` entrypoint + +Chains now live in the [Viem repository](https://github.com/wevm/viem). As a result, the `'wagmi/chains'` entrypoint now proxies all chains from `'viem/chains'` directly. + +### Removed `mainnet` and `sepolia` from main entrypoint + +Since the `'wagmi/chains'` entrypoint now proxies `'viem/chains'`, `mainnet` and `sepolia` were removed from the main entrypoint. Use the `'wagmi/chains'` entrypoint instead. + +```ts +import { mainnet, sepolia } from 'wagmi' // [!code --] +import { mainnet, sepolia } from 'wagmi/chains' // [!code ++] +``` + +## Errors + +A number of errors were renamed to better reflect their functionality or replaced by Viem errors. + +## Miscellaneous + +### Removed internal ENS name normalization + +Before v2, Wagmi handled ENS name normalization internally for `useEnsAddress`, `useEnsAvatar`, and `useEnsResolver`, using Viem's [`normalize`](https://viem.sh/docs/ens/utilities/normalize.html) function. This added extra bundle size as full normalization is quite heavy. For v2, you must normalize ENS names yourself before passing them to these hooks. You can use Viem's `normalize` function or any other function that performs [UTS-46 normalization](https://unicode.org/reports/tr46). + +```ts +import { useEnsAddress } from 'wagmi' +import { normalize } from 'viem/ens' // [!code ++] + +const result = useEnsAddress({ + name: 'wevm.eth', // [!code --] + name: normalize('wevm.eth'), // [!code ++] +}) +``` + +By inverting control, Wagmi let's you choose how much normalization to do. For example, maybe your project only allows ENS names that are numeric so no normalization is not needed. Check out the [ENS documentation](https://docs.ens.domains/contract-api-reference/name-processing#normalising-names) for more information on normalizing names. + +### Removed `configureChains` + +The Wagmi v2 `Config` now has native multichain support using the [`chains`](/react/api/createConfig) parameter so the `configureChains` function is no longer required. + +```ts +import { configureChains, createConfig } from 'wagmi' // [!code --] +import { http, createConfig } from 'wagmi' // [!code ++] +import { mainnet, sepolia } from 'wagmi/chains' + +const { chains, publicClient } = configureChains( // [!code --] + [mainnet, sepolia], // [!code --] + [publicProvider(), publicProvider()], // [!code --] +) // [!code --] + +export const config = createConfig({ + publicClient, // [!code --] + chains: [mainnet, sepolia], // [!code ++] + transports: { // [!code ++] + [mainnet.id]: http(), // [!code ++] + [sepolia.id]: http(), // [!code ++] + }, // [!code ++] +}) +``` + +### Removed ABI exports + +Import from Viem instead. + +```ts +import { erc20ABI } from 'wagmi' // [!code --] +import { erc20Abi } from 'viem' // [!code ++] +``` + +### Removed `'wagmi/providers/*` entrypoints + +It never made sense that we would have provider URLs hardcoded in the Wagmi codebase. Use [Viem transports](https://viem.sh/docs/clients/intro.html#transports) along with RPC provider URLs instead. + +```ts +import { alchemyProvider } from 'wagmi/providers/alchemy' // [!code --] +import { http } from 'viem' // [!code ++] + +const transport = http('https://mainnet.example.com') +``` + +### Updated `createConfig` parameters + +- Removed `autoConnect`. The reconnecting behavior is now managed by React and not related to the Wagmi `Config`. Use `WagmiProvider` [`reconnectOnMount`](/react/api/WagmiProvider#reconnectonmount) or [`useReconnect`](/react/api/hooks/useReconnect) hook instead. +- Removed `publicClient` and `webSocketPublicClient`. Use [`transports`](/react/api/createConfig#transports) or [`client`](/react/api/createConfig#client) instead. +- Removed `logger`. Wagmi no longer logs debug information to console. + +### Updated `Config` object + +- Removed `config.connector`. Use `config.state.connections.get(config.state.current)?.connector` instead. +- Removed `config.data`. Use `config.state.connections.get(config.state.current)` instead. +- Removed `config.error`. Was unused and not needed. +- Removed `config.lastUsedChainId`. Use `config.state.connections.get(config.state.current)?.chainId` instead. +- Removed `config.publicClient`. Use [`config.getClient()`](/react/api/createConfig#getclient) or [`getPublicClient`](/core/api/actions/getPublicClient) instead. +- Removed `config.status`. Use [`config.state.status`](/react/api/createConfig#status) instead. +- Removed `config.webSocketClient`. Use [`config.getClient()`](/react/api/createConfig#getclient) or [`getPublicClient`](/core/api/actions/getPublicClient) instead. +- Removed `config.clearState`. Was unused and not needed. +- Removed `config.autoConnect()`. Use [`reconnect`](/core/api/actions/reconnect) action instead. +- Renamed `config.setConnectors`. Use `config._internal.setConnectors` instead. +- Removed `config.setLastUsedConnector`. Use `config.storage?.setItem('recentConnectorId', connectorId)` instead. +- Removed `getConfig`. `config` should be passed explicitly to actions instead of using global `config`. + +## Deprecations + +### Renamed `WagmiConfig` + +`WagmiConfig` was renamed to [`WagmiProvider`](/react/api/WagmiProvider) to reduce confusion with the Wagmi [`Config`](/react/api/createConfig) type. React Context Providers usually follow the naming schema `*Provider` so this is a more idiomatic name. Now that Wagmi no longer uses Ethers.js (since Wagmi v1), the term "Provider" is less overloaded. + +::: code-group +```tsx [app.tsx] +import { WagmiConfig } from 'wagmi' // [!code --] +import { WagmiProvider } from 'wagmi' // [!code ++] +import { config } from './config' + +function App() { + return ( + // [!code --] + // [!code ++] + {/** ... */} + // [!code ++] + // [!code --] + ) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### Deprecated `useBalance` `token` parameter + +Moving forward, `useBalance` will only work for native currencies, thus the `token` parameter is no longer supported. Use [`useReadContracts`](/react/api/hooks/useReadContracts) instead. + +```ts +import { useBalance } from 'wagmi' // [!code --] +import { useReadContracts } from 'wagmi' // [!code ++] +import { erc20Abi } from 'viem' // [!code ++] + +const result = useBalance({ // [!code --] + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', // [!code --] + token: '0x6B175474E89094C44Da98b954EedeAC495271d0F', // [!code --] +}) // [!code --] +const result = useReadContracts({ // [!code ++] + allowFailure: false, // [!code ++] + contracts: [ // [!code ++] + { // [!code ++] + address: '0x6B175474E89094C44Da98b954EedeAC495271d0F', // [!code ++] + abi: erc20Abi, // [!code ++] + functionName: 'balanceOf', // [!code ++] + args: ['0x4557B18E779944BFE9d78A672452331C186a9f48'], // [!code ++] + }, // [!code ++] + { // [!code ++] + address: '0x6B175474E89094C44Da98b954EedeAC495271d0F', // [!code ++] + abi: erc20Abi, // [!code ++] + functionName: 'decimals', // [!code ++] + }, // [!code ++] + { // [!code ++] + address: '0x6B175474E89094C44Da98b954EedeAC495271d0F', // [!code ++] + abi: erc20Abi, // [!code ++] + functionName: 'symbol', // [!code ++] + }, // [!code ++] + ] // [!code ++] +}) // [!code ++] +``` + +### Deprecated `useBalance` `unit` parameter and `formatted` return value + +Moving forward, `useBalance` will not accept the `unit` parameter or return a `formatted` value. Instead you can call `formatUnits` from Viem directly or use another number formatting library, like [dnum](https://github.com/bpierre/dnum) instead. + +```ts +import { formatUnits } from 'viem' // [!code ++] +import { useBalance } from 'wagmi' + +const result = useBalance({ + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', + unit: 'ether', // [!code --] +}) +result.data!.formatted // [!code --] +formatUnits(result.data!.value, result.data!.decimals) // [!code ++] +``` + +### Deprecated `useToken` + +Moving forward, `useToken` is no longer supported. Use [`useReadContracts`](/react/api/hooks/useReadContracts) instead. + +```ts +import { useToken } from 'wagmi' // [!code --] +import { useReadContracts } from 'wagmi' // [!code ++] +import { erc20Abi } from 'viem' // [!code ++] + +const result = useToken({ // [!code --] + address: '0x6B175474E89094C44Da98b954EedeAC495271d0F', // [!code --] +}) // [!code --] +const result = useReadContracts({ // [!code ++] + allowFailure: false, // [!code ++] + contracts: [ // [!code ++] + { // [!code ++] + address: '0x6B175474E89094C44Da98b954EedeAC495271d0F', // [!code ++] + abi: erc20Abi, // [!code ++] + functionName: 'decimals', // [!code ++] + }, // [!code ++] + { // [!code ++] + address: '0x6B175474E89094C44Da98b954EedeAC495271d0F', // [!code ++] + abi: erc20Abi, // [!code ++] + functionName: 'name', // [!code ++] + }, // [!code ++] + { // [!code ++] + address: '0x6B175474E89094C44Da98b954EedeAC495271d0F', // [!code ++] + abi: erc20Abi, // [!code ++] + functionName: 'symbol', // [!code ++] + }, // [!code ++] + { // [!code ++] + address: '0x6B175474E89094C44Da98b954EedeAC495271d0F', // [!code ++] + abi: erc20Abi, // [!code ++] + functionName: 'totalSupply', // [!code ++] + }, // [!code ++] + ] // [!code ++] +}) // [!code ++] +``` + +### Deprecated `formatUnits` parameters and return values + +The `formatUnits` parameter and related return values (e.g. `result.formatted`) are deprecated for the following hooks: + +- [`useEstimateFeesPerGas`](/react/api/hooks/useEstimateFeesPerGas) +- [`useToken`](/react/api/hooks/useToken) + +Instead you can call `formatUnits` from Viem directly or use another number formatting library, like [dnum](https://github.com/bpierre/dnum) instead. + +```ts +import { formatUnits } from 'viem' // [!code ++] + +const result = useToken({ + address: '0x6B175474E89094C44Da98b954EedeAC495271d0F', + formatUnits: 'ether', +}) +result.data!.totalSupply.formatted // [!code --] +formatUnits(result.data!.totalSupply.value, 18) // [!code ++] +``` + +This allows us to invert control to users so they can handle number formatting however they want, taking into account precision, localization, and more. + +### Renamed hooks + +The following hooks were renamed to better reflect their functionality and underlying [Viem](https://viem.sh) actions: + +- `useContractRead` is now [`useReadContract`](/react/api/hooks/useReadContract) +- `useContractReads` is now [`useReadContracts`](/react/api/hooks/useReadContracts) +- `useContractWrite` is now [`useWriteContract`](/react/api/hooks/useWriteContract) +- `useContractEvent` is now [`useWatchContractEvent`](/react/api/hooks/useWatchContractEvent) +- `useContractInfiniteReads` is now [`useInfiniteReadContracts`](/react/api/hooks/useInfiniteReadContracts) +- `useFeeData` is now [`useEstimateFeesPerGas`](/react/api/hooks/useEstimateFeesPerGas) +- `useSwitchNetwork` is now [`useSwitchChain`](/react/api/hooks/useSwitchChain) +- `useWaitForTransaction` is now [`useWaitForTransactionReceipt`](/react/api/hooks/useWaitForTransactionReceipt) + +### Miscellaneous + +- `WagmiConfigProps` renamed to [`WagmiProviderProps`](/react/api/WagmiProvider#parameters). +- `Context` renamed to [`WagmiContext`](/react/api/WagmiProvider#context). diff --git a/wagmi-project/site/react/guides/read-from-contract.md b/wagmi-project/site/react/guides/read-from-contract.md new file mode 100644 index 000000000..b41f5c569 --- /dev/null +++ b/wagmi-project/site/react/guides/read-from-contract.md @@ -0,0 +1,202 @@ +# Read from Contract + +The [`useReadContract` Hook](/react/api/hooks/useReadContract) allows you to read data on a smart contract, from a `view` or `pure` (read-only) function. They can only read the state of the contract, and cannot make any changes to it. Since read-only methods do not change the state of the contract, they do not require any gas to be executed, and can be called by any user without the need to pay for gas. + +The component below shows how to retrieve the token balance of an address from the [Wagmi Example](https://etherscan.io/token/0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2) contract + +:::code-group +```tsx [read-contract.tsx] +import { useReadContract } from 'wagmi' +import { wagmiContractConfig } from './contracts' + +function ReadContract() { + const { data: balance } = useReadContract({ + ...wagmiContractConfig, + functionName: 'balanceOf', + args: ['0x03A71968491d55603FFe1b11A9e23eF013f75bCF'], + }) + + return ( +
Balance: {balance?.toString()}
+ ) +} +``` +```ts [contracts.ts] +export const wagmiContractConfig = { + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + abi: [ + { + type: 'function', + name: 'balanceOf', + stateMutability: 'view', + inputs: [{ name: 'account', type: 'address' }], + outputs: [{ type: 'uint256' }], + }, + { + type: 'function', + name: 'totalSupply', + stateMutability: 'view', + inputs: [], + outputs: [{ name: 'supply', type: 'uint256' }], + }, + ], +} as const +``` +::: + +If `useReadContract` depends on another value (`address` in the example below), you can use the [`query.enabled`](/react/api/hooks/useReadContract#enabled) option to prevent the query from running until the dependency is ready. + +```tsx +const { data: balance } = useReadContract({ + ...wagmiContractConfig, + functionName: 'balanceOf', + args: [address], + query: { // [!code focus] + enabled: !!address, // [!code focus] + }, // [!code focus] +}) +``` + +## Loading & Error States + +The [`useReadContract` Hook](/react/api/hooks/useReadContract) also returns loading & error states, which can be used to display a loading indicator while the data is being fetched, or an error message if contract execution reverts. + +:::code-group + +```tsx [read-contract.tsx] +import { type BaseError, useReadContract } from 'wagmi' + +function ReadContract() { + const { + data: balance, + error, // [!code ++] + isPending // [!code ++] + } = useReadContract({ + ...wagmiContractConfig, + functionName: 'balanceOf', + args: ['0x03A71968491d55603FFe1b11A9e23eF013f75bCF'], + }) + + if (isPending) return
Loading...
// [!code ++] + + if (error) // [!code ++] + return ( // [!code ++] +
// [!code ++] + Error: {(error as BaseError).shortMessage || error.message} // [!code ++] +
// [!code ++] + ) // [!code ++] + + return ( +
Balance: {balance?.toString()}
+ ) +} +``` + +## Refetching On Blocks + +The [`useBlockNumber` Hook](/react/api/hooks/useBlockNumber) can be utilized to refetch or [invalidate](https://tanstack.com/query/latest/docs/framework/react/guides/query-invalidation) the contract data on a specific block interval. + +:::code-group +```tsx [read-contract.tsx (refetch)] +import { useEffect } from 'react' +import { useBlockNumber, useReadContract } from 'wagmi' + +function ReadContract() { + const { data: balance, refetch } = useReadContract({ + ...wagmiContractConfig, + functionName: 'balanceOf', + args: ['0x03A71968491d55603FFe1b11A9e23eF013f75bCF'], + }) + const { data: blockNumber } = useBlockNumber({ watch: true }) + + useEffect(() => { + // want to refetch every `n` block instead? use the modulo operator! + // if (blockNumber % 5 === 0) refetch() // refetch every 5 blocks + refetch() + }, [blockNumber]) + + return ( +
Balance: {balance?.toString()}
+ ) +} +``` +```tsx [read-contract.tsx (invalidate)] +import { useQueryClient } from '@tanstack/react-query' +import { useEffect } from 'react' +import { useBlockNumber, useReadContract } from 'wagmi' + +function ReadContract() { + const queryClient = useQueryClient() + const { data: balance, refetch } = useReadContract({ + ...wagmiContractConfig, + functionName: 'balanceOf', + args: ['0x03A71968491d55603FFe1b11A9e23eF013f75bCF'], + }) + const { data: blockNumber } = useBlockNumber({ watch: true }) + + useEffect(() => { + // if `useReadContract` is in a different hook/component, + // you can import `readContractQueryKey` from `'wagmi/query'` and + // construct a one-off query key to use for invalidation + queryClient.invalidateQueries({ queryKey }) + }, [blockNumber, queryClient]) + + return ( +
Balance: {balance?.toString()}
+ ) +} +``` +::: + +## Calling Multiple Functions + +We can use the [`useReadContract` Hook](/react/api/hooks/useReadContract) multiple times in a single component to call multiple functions on the same contract, but this ends up being hard to manage as the number of functions increases, especially when we also want to deal with loading & error states. + +Luckily, to make this easier, we can use the [`useReadContracts` Hook](/react/api/hooks/useReadContracts) to call multiple functions in a single call. + +:::code-group + +```tsx [read-contract.tsx] +import { type BaseError, useReadContracts } from 'wagmi' + +function ReadContract() { + const { + data, + error, + isPending + } = useReadContracts({ + contracts: [{ + ...wagmiContractConfig, + functionName: 'balanceOf', + args: ['0x03A71968491d55603FFe1b11A9e23eF013f75bCF'], + }, { + ...wagmiContractConfig, + functionName: 'ownerOf', + args: [69n], + }, { + ...wagmiContractConfig, + functionName: 'totalSupply', + }] + }) + const [balance, ownerOf, totalSupply] = data || [] + + if (isPending) return
Loading...
+ + if (error) + return ( +
+ Error: {(error as BaseError).shortMessage || error.message} +
+ ) + + return ( + <> +
Balance: {balance?.toString()}
+
Owner of Token 69: {ownerOf?.toString()}
+
Total Supply: {totalSupply?.toString()}
+ + ) +} +``` + +::: diff --git a/wagmi-project/site/react/guides/send-transaction.md b/wagmi-project/site/react/guides/send-transaction.md new file mode 100644 index 000000000..a6c5c1887 --- /dev/null +++ b/wagmi-project/site/react/guides/send-transaction.md @@ -0,0 +1,362 @@ +# Send Transaction + +The following guide teaches you how to send transactions in Wagmi. The example below builds on the [Connect Wallet guide](/react/guides/connect-wallet) and uses the [useSendTransaction](/react/api/hooks/useSendTransaction) & [useWaitForTransaction](/react/api/hooks/useWaitForTransactionReceipt) hooks. + +## Example + +Feel free to check out the example before moving on: + + + +## Steps + +### 1. Connect Wallet + +Follow the [Connect Wallet guide](/react/guides/connect-wallet) guide to get this set up. + +### 2. Create a new component + +Create your `SendTransaction` component that will contain the send transaction logic. + +::: code-group + +```tsx [send-transaction.tsx] +import * as React from 'react' + +export function SendTransaction() { + return ( +
+ + + +
+ ) +} +``` + +::: + +### 3. Add a form handler + +Next, we will need to add a handler to the form that will send the transaction when the user hits "Send". This will be a basic handler in this step. + +::: code-group + +```tsx [send-transaction.tsx] +import * as React from 'react' + +export function SendTransaction() { + async function submit(e: React.FormEvent) { // [!code ++] + e.preventDefault() // [!code ++] + const formData = new FormData(e.target as HTMLFormElement) // [!code ++] + const to = formData.get('address') as `0x${string}` // [!code ++] + const value = formData.get('value') as string // [!code ++] + } // [!code ++] + + return ( +
// [!code --] + // [!code ++] + + + +
+ ) +} +``` + +::: + +### 4. Hook up the `useSendTransaction` Hook + +Now that we have the form handler, we can hook up the [`useSendTransaction` Hook](/react/api/hooks/useSendTransaction) to send the transaction. + +::: code-group + +```tsx [send-transaction.tsx] +import * as React from 'react' +import { useSendTransaction } from 'wagmi' // [!code ++] +import { parseEther } from 'viem' // [!code ++] + +export function SendTransaction() { + const { data: hash, sendTransaction } = useSendTransaction() // [!code ++] + + async function submit(e: React.FormEvent) { + e.preventDefault() + const formData = new FormData(e.target as HTMLFormElement) + const to = formData.get('address') as `0x${string}` + const value = formData.get('value') as string + sendTransaction({ to, value: parseEther(value) }) // [!code ++] + } + + return ( +
+ + + + {hash &&
Transaction Hash: {hash}
} // [!code ++] +
+ ) +} +``` + +::: + +### 5. Add loading state (optional) + +We can optionally add a loading state to the "Send" button while we are waiting confirmation from the user's wallet. + +::: code-group + +```tsx [send-transaction.tsx] +import * as React from 'react' +import { useSendTransaction } from 'wagmi' +import { parseEther } from 'viem' + +export function SendTransaction() { + const { + data: hash, + isPending, // [!code ++] + sendTransaction + } = useSendTransaction() + + async function submit(e: React.FormEvent) { + e.preventDefault() + const formData = new FormData(e.target as HTMLFormElement) + const to = formData.get('address') as `0x${string}` + const value = formData.get('value') as string + sendTransaction({ to, value: parseEther(value) }) + } + + return ( +
+ + + + {hash &&
Transaction Hash: {hash}
} +
+ ) +} +``` + +::: + +### 6. Wait for transaction receipt (optional) + +We can also display the transaction confirmation status to the user by using the [`useWaitForTransactionReceipt` Hook](/react/api/hooks/useWaitForTransactionReceipt). + +::: code-group + +```tsx [send-transaction.tsx] +import * as React from 'react' +import { + useSendTransaction, + useWaitForTransactionReceipt // [!code ++] +} from 'wagmi' +import { parseEther } from 'viem' + +export function SendTransaction() { + const { + data: hash, + isPending, + sendTransaction + } = useSendTransaction() + + async function submit(e: React.FormEvent) { + e.preventDefault() + const formData = new FormData(e.target as HTMLFormElement) + const to = formData.get('address') as `0x${string}` + const value = formData.get('value') as string + sendTransaction({ to, value: parseEther(value) }) + } + + const { isLoading: isConfirming, isSuccess: isConfirmed } = // [!code ++] + useWaitForTransactionReceipt({ // [!code ++] + hash, // [!code ++] + }) // [!code ++] + + return ( +
+ + + + {hash &&
Transaction Hash: {hash}
} + {isConfirming &&
Waiting for confirmation...
} // [!code ++] + {isConfirmed &&
Transaction confirmed.
} // [!code ++] +
+ ) +} +``` + +::: + +### 7. Handle errors (optional) + +If the user rejects the transaction, or the user does not have enough funds to cover the transaction, we can display an error message to the user. + +::: code-group + +```tsx [send-transaction.tsx] +import * as React from 'react' +import { + type BaseError, // [!code ++] + useSendTransaction, + useWaitForTransactionReceipt +} from 'wagmi' +import { parseEther } from 'viem' + +export function SendTransaction() { + const { + data: hash, + error, // [!code ++] + isPending, + sendTransaction + } = useSendTransaction() + + async function submit(e: React.FormEvent) { + e.preventDefault() + const formData = new FormData(e.target as HTMLFormElement) + const to = formData.get('address') as `0x${string}` + const value = formData.get('value') as string + sendTransaction({ to, value: parseEther(value) }) + } + + const { isLoading: isConfirming, isSuccess: isConfirmed } = + useWaitForTransactionReceipt({ + hash, + }) + + return ( +
+ + + + {hash &&
Transaction Hash: {hash}
} + {isConfirming &&
Waiting for confirmation...
} + {isConfirmed &&
Transaction confirmed.
} + {error && ( // [!code ++] +
Error: {(error as BaseError).shortMessage || error.message}
// [!code ++] + )} // [!code ++] +
+ ) +} +``` + +::: + +### 8. Wire it up! + +Finally, we can wire up our Send Transaction component to our application's entrypoint. + +::: code-group + +```tsx [app.tsx] +import { QueryClient, QueryClientProvider } from '@tanstack/react-query' +import { WagmiProvider, useAccount } from 'wagmi' +import { config } from './config' +import { SendTransaction } from './send-transaction' // [!code ++] + +const queryClient = new QueryClient() + +function App() { + return ( + + + // [!code ++] + + + ) +} +``` + +```tsx [send-transaction.tsx] +import * as React from 'react' +import { + type BaseError, + useSendTransaction, + useWaitForTransactionReceipt +} from 'wagmi' +import { parseEther } from 'viem' + +export function SendTransaction() { + const { + data: hash, + error, + isPending, + sendTransaction + } = useSendTransaction() + + async function submit(e: React.FormEvent) { + e.preventDefault() + const formData = new FormData(e.target as HTMLFormElement) + const to = formData.get('address') as `0x${string}` + const value = formData.get('value') as string + sendTransaction({ to, value: parseEther(value) }) + } + + const { isLoading: isConfirming, isSuccess: isConfirmed } = + useWaitForTransactionReceipt({ + hash, + }) + + return ( +
+ + + + {hash &&
Transaction Hash: {hash}
} + {isConfirming &&
Waiting for confirmation...
} + {isConfirmed &&
Transaction confirmed.
} + {error && ( +
Error: {(error as BaseError).shortMessage || error.message}
+ )} +
+ ) +} +``` + +```tsx [config.ts] +import { http, createConfig } from 'wagmi' +import { base, mainnet, optimism } from 'wagmi/chains' +import { injected, metaMask, safe, walletConnect } from 'wagmi/connectors' + +const projectId = '' + +export const config = createConfig({ + chains: [mainnet, base], + connectors: [ + injected(), + walletConnect({ projectId }), + metaMask(), + safe(), + ], + transports: { + [mainnet.id]: http(), + [base.id]: http(), + }, +}) +``` + +::: + +[See the Example.](#example) diff --git a/wagmi-project/site/react/guides/ssr.md b/wagmi-project/site/react/guides/ssr.md new file mode 100644 index 000000000..131be1a2b --- /dev/null +++ b/wagmi-project/site/react/guides/ssr.md @@ -0,0 +1,168 @@ +--- +outline: deep +--- + +# SSR + +Wagmi uses client-only external stores (such as `localStorage` and `mipd`) to show the user the most relevant data as quickly as possible on first render. + +However, the caveat of using these external client stores is that frameworks which incorporate SSR (such as Next.js) will throw hydration warnings on the client when it identifies mismatches between the server-rendered HTML and the client-rendered HTML. + +To stop this from happening, you can toggle on the [`ssr`](/react/api/createConfig#ssr) property in the Wagmi Config. + +```tsx +import { createConfig, http } from 'wagmi' +import { mainnet, sepolia } from 'wagmi/chains' + +const config = createConfig({ // [!code focus:99] + chains: [mainnet, sepolia], + ssr: true, // [!code ++] + transports: { + [mainnet.id]: http(), + [sepolia.id]: http(), + }, +}) +``` + +Turning on the `ssr` property means that content from the external stores will be hydrated on the client after the initial mount. + +## Persistence using Cookies + +As a result of turning on the `ssr` property, external persistent stores like `localStorage` will be hydrated on the client **after the initial mount**. + +This means that you will still see a flash of "empty" data on the client (e.g. a `"disconnected"` account instead of a `"reconnecting"` account, or an empty address instead of the last connected address) until after the first mount, when the store hydrates. + +In order to persist data between the server and the client, you can use cookies. + +### 1. Set up cookie storage + +First, we will set up cookie storage in the Wagmi Config. + +```tsx +import { + createConfig, + http, + cookieStorage, // [!code ++] + createStorage // [!code ++] +} from 'wagmi' +import { mainnet, sepolia } from 'wagmi/chains' + +export function getConfig() { + return createConfig({ + chains: [mainnet, sepolia], + ssr: true, + storage: createStorage({ // [!code ++] + storage: cookieStorage, // [!code ++] + }), // [!code ++] + transports: { + [mainnet.id]: http(), + [sepolia.id]: http(), + }, + }) +} +``` + +### 2. Hydrate the cookie + +Next, we will need to add some mechanisms to hydrate the stored cookie in Wagmi. + +#### Next.js App Directory + +In our `app/layout.tsx` file (a [Server Component](https://nextjs.org/docs/app/building-your-application/rendering/server-components)), we will need to extract the cookie from the `headers` function and pass it to [`cookieToInitialState`](/react/api/utilities/cookieToInitialState). + +We will need to pass this result to the [`initialState` property](/react/api/WagmiProvider#initialstate) of the `WagmiProvider`. The `WagmiProvider` **must** be in a Client Component tagged with `"use client"` (see `app/providers.tsx` tab). + +::: code-group +```tsx [app/layout.tsx] +import { type ReactNode } from 'react' +import { headers } from 'next/headers' // [!code ++] +import { cookieToInitialState } from 'wagmi' // [!code ++] + +import { getConfig } from './config' +import { Providers } from './providers' + +export default async function Layout({ children }: { children: ReactNode }) { + const initialState = cookieToInitialState( // [!code ++] + getConfig(), // [!code ++] + (await headers()).get('cookie') // [!code ++] + ) // [!code ++] + return ( + + + // [!code --] + // [!code ++] + {children} + + + + ) +} + +``` + +```tsx [app/providers.tsx] +'use client' + +import { QueryClient, QueryClientProvider } from '@tanstack/react-query' +import { type ReactNode, useState } from 'react' +import { type State, WagmiProvider } from 'wagmi' + +import { getConfig } from './config' + +type Props = { + children: ReactNode, + initialState: State | undefined, // [!code ++] +} + +export function Providers({ children }: Props) { // [!code --] +export function Providers({ children, initialState }: Props) { // [!code ++] + const [config] = useState(() => getConfig()) + const [queryClient] = useState(() => new QueryClient()) + + return ( + // [!code --] + // [!code ++] + + {children} + + + ) +} + +``` + +```tsx [app/config.ts] +import { + createConfig, + http, + cookieStorage, + createStorage +} from 'wagmi' +import { mainnet, sepolia } from 'wagmi/chains' + +export function getConfig() { + return createConfig({ + chains: [mainnet, sepolia], + ssr: true, + storage: createStorage({ // [!code ++] + storage: cookieStorage, // [!code ++] + }), // [!code ++] + transports: { + [mainnet.id]: http(), + [sepolia.id]: http(), + }, + }) +} +``` +::: + +#### Next.js Pages Directory + +Would you like to contribute this content? Feel free to [open a Pull Request](https://github.com/wevm/wagmi/pulls)! + + +#### Vanilla SSR + +Would you like to contribute this content? Feel free to [open a Pull Request](https://github.com/wevm/wagmi/pulls)! + + diff --git a/wagmi-project/site/react/guides/tanstack-query.md b/wagmi-project/site/react/guides/tanstack-query.md new file mode 100644 index 000000000..e491695d7 --- /dev/null +++ b/wagmi-project/site/react/guides/tanstack-query.md @@ -0,0 +1,403 @@ +# TanStack Query + +Wagmi Hooks are not only a wrapper around the core [Wagmi Actions](/core/api/actions), but they also utilize [TanStack Query](https://tanstack.com/query/v5) to enable trivial and intuitive fetching, caching, synchronizing, and updating of asynchronous data in your React applications. + +Without an asynchronous data fetching abstraction, you would need to handle all the negative side-effects that comes as a result, such as: representing finite states (loading, error, success), handling race conditions, caching against a deterministic identifier, etc. + +## Queries & Mutations + +Wagmi Hooks represent either a **Query** or a **Mutation**. + +**Queries** are used for fetching data (e.g. fetching a block number, reading from a contract, etc), and are typically invoked on mount by default. All queries are coupled to a unique [Query Key](#query-keys), and can be used for further operations such as refetching, prefetching, or modifying the cached data. + +**Mutations** are used for mutating data (e.g. connecting/disconnecting accounts, writing to a contract, switching chains, etc), and are typically invoked in response to a user interaction. Unlike **Queries**, they are not coupled with a query key. + +## Terms + +- **Query**: An asynchronous data fetching (e.g. read data) operation that is tied against a unique Query Key. +- **Mutation**: An asynchronous mutating (e.g. create/update/delete data or side-effect) operation. +- **Query Key**: A unique identifier that is used to deterministically identify a query. It is typically a tuple of the query name and the query arguments. +- **Stale Data**: Data that is unused or inactive after a certain period of time. +- **Query Fetching**: The process of invoking an async query function. +- **Query Refetching**: The process of refetching **rendered** queries. +- **[Query Invalidation](https://tanstack.com/query/v5/docs/react/guides/query-invalidation)**: The process of marking query data as stale (e.g. inactive/unused), and refetching **rendered** queries. +- **[Query Prefetching](https://tanstack.com/query/v5/docs/react/guides/prefetching)**: The process of prefetching queries and seeding the cache. + +## Persistence via External Stores + +By default, TanStack Query persists all query data in-memory. This means that if you refresh the page, all in-memory query data will be lost. + +If you want to persist query data to an external storage, you can utilize TanStack Query's [`createSyncStoragePersister`](https://tanstack.com/query/v5/docs/react/plugins/createSyncStoragePersister) or [`createAsyncStoragePersister`](https://tanstack.com/query/v5/docs/react/plugins/createAsyncStoragePersister) to plug external storage like `localStorage`, `sessionStorage`, [IndexedDB](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API) or [`AsyncStorage`](https://reactnative.dev/docs/asyncstorage) (React Native). + +### Sync Storage + +Below is an example of how to set up Wagmi + TanStack Query with sync external storage like `localStorage` or `sessionStorage`. + +#### Install + +::: code-group +```bash [pnpm] +pnpm i @tanstack/query-sync-storage-persister @tanstack/react-query-persist-client +``` + +```bash [npm] +npm i @tanstack/query-sync-storage-persister @tanstack/react-query-persist-client +``` + +```bash [yarn] +yarn add @tanstack/query-sync-storage-persister @tanstack/react-query-persist-client +``` + +```bash [bun] +bun i @tanstack/query-sync-storage-persister @tanstack/react-query-persist-client +``` +::: + +#### Usage + +```tsx +// 1. Import modules. // [!code hl] +import { createSyncStoragePersister } from '@tanstack/query-sync-storage-persister' // [!code hl] +import { QueryClient } from '@tanstack/react-query' // [!code hl] +import { PersistQueryClientProvider } from '@tanstack/react-query-persist-client' // [!code hl] +import { WagmiProvider, deserialize, serialize } from 'wagmi' // [!code hl] + +// 2. Create a new Query Client with a default `gcTime`. // [!code hl] +const queryClient = new QueryClient({ // [!code hl] + defaultOptions: { // [!code hl] + queries: { // [!code hl] + gcTime: 1_000 * 60 * 60 * 24, // 24 hours // [!code hl] + }, // [!code hl] + }, // [!code hl] +}) // [!code hl] + +// 3. Set up the persister. // [!code hl] +const persister = createSyncStoragePersister({ // [!code hl] + serialize, // [!code hl] + storage: window.localStorage, // [!code hl] + deserialize, // [!code hl] +}) // [!code hl] + +function App() { + return ( + + {/* 4. Wrap app in PersistQueryClientProvider */} // [!code hl] + // [!code hl] + {/* ... */} + // [!code hl] + + ) +} +``` + +Read more about [Sync Storage Persistence](https://tanstack.com/query/v5/docs/react/plugins/createSyncStoragePersister). + +### Async Storage + +Below is an example of how to set up Wagmi + TanStack Query with async external storage like [`IndexedDB`](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API) or [`AsyncStorage`](https://reactnative.dev/docs/asyncstorage). + +#### Install + +::: code-group +```bash [pnpm] +pnpm i @tanstack/query-async-storage-persister @tanstack/react-query-persist-client +``` + +```bash [npm] +npm i @tanstack/query-async-storage-persister @tanstack/react-query-persist-client +``` + +```bash [yarn] +yarn add @tanstack/query-async-storage-persister @tanstack/react-query-persist-client +``` + +```bash [bun] +bun i @tanstack/query-async-storage-persister @tanstack/react-query-persist-client +``` +::: + +#### Usage + +```tsx +// 1. Import modules. // [!code hl] +import AsyncStorage from '@react-native-async-storage/async-storage' // [!code hl] +import { createAsyncStoragePersister } from '@tanstack/query-async-storage-persister' // [!code hl] +import { QueryClient } from '@tanstack/react-query' // [!code hl] +import { PersistQueryClientProvider } from '@tanstack/react-query-persist-client' // [!code hl] +import { WagmiProvider, deserialize, serialize } from 'wagmi' // [!code hl] + +// 2. Create a new Query Client with a default `gcTime`. // [!code hl] +const queryClient = new QueryClient({ // [!code hl] + defaultOptions: { // [!code hl] + queries: { // [!code hl] + gcTime: 1_000 * 60 * 60 * 24, // 24 hours // [!code hl] + }, // [!code hl] + }, // [!code hl] +}) // [!code hl] + +// 3. Set up the persister. // [!code hl] +const persister = createAsyncStoragePersister({ // [!code hl] + serialize, // [!code hl] + storage: AsyncStorage, // [!code hl] + deserialize, // [!code hl] +}) // [!code hl] + +function App() { + return ( + + {/* 4. Wrap app in PersistQueryClientProvider */} // [!code hl] + // [!code hl] + {/* ... */} + // [!code hl] + + ) +} +``` + +Read more about [Async Storage Persistence](https://tanstack.com/query/v5/docs/react/plugins/createAsyncStoragePersister). + +## Query Keys + +Query Keys are typically used to perform advanced operations on the query such as: invalidation, refetching, prefetching, etc. + +Wagmi exports Query Keys for every Hook, and they can be retrieved via the [Hook (React)](#hook-react) or via an [Import (Vanilla JS)](#import-vanilla-js). + +Read more about **Query Keys** on the [TanStack Query docs.](https://tanstack.com/query/v5/docs/react/guides/query-keys) + +### Hook (React) + +Each Hook returns a `queryKey` value. You would use this approach when you want to utilize the query key in a React component as it handles reactivity for you, unlike the [Import](#import-vanilla-js) method below. + +```ts +import { useBlock } from 'wagmi' // [!code hl] + +function App() { + const { queryKey } = useBlock() // [!code hl] +} +``` + +### Import (Vanilla JS) + +Each Hook has a corresponding `getQueryOptions` function that returns a query key. You would use this method when you want to utilize the query key outside of a React component in a Vanilla JS context, like in a utility function. + +```ts +import { getBlockQueryOptions } from 'wagmi/query' // [!code hl] +import { config } from './config' + +function perform() { + const { queryKey } = getBlockQueryOptions(config, { // [!code hl] + chainId: config.state.chainId // [!code hl] + }) // [!code hl] +} +``` + +::: warning + +The caveat of this method is that it does not handle reactivity for you (e.g. active account/chain changes, argument changes, etc). You would need to handle this yourself by explicitly passing through the arguments to `getQueryOptions`. + +::: + +## Invalidating Queries + +Invalidating a query is the process of marking the query data as stale (e.g. inactive/unused), and refetching the queries that are already rendered. + +Read more about **Invalidating Queries** on the [TanStack Query docs.](https://tanstack.com/query/v5/docs/react/guides/query-invalidation) + +#### Example: Watching a Users' Balance + +You may want to "watch" a users' balance, and invalidate the balance after each incoming block. We can invoke `invalidateQueries` inside a `useEffect` with the block number as it's only dependency – this will refetch all rendered balance queries when the `blockNumber` changes. + +```tsx +import { useQueryClient } from '@tanstack/react-query' +import { useEffect } from 'react' +import { useBlockNumber, useBalance } from 'wagmi' + +function App() { + const queryClient = useQueryClient() + const { data: blockNumber } = useBlockNumber({ watch: true }) // [!code hl] + const { data: balance, queryKey } = useBalance() // [!code hl] + + useEffect(() => { // [!code hl] + queryClient.invalidateQueries({ queryKey }) // [!code hl] + }, [blockNumber]) // [!code hl] + + return
{balance}
+} +``` + +#### Example: After User Interaction + +Maybe you want to invalidate a users' balance after some interaction. This would mark the balance as stale, and consequently refetch all rendered balance queries. + +```tsx +import { useBalance } from 'wagmi' + +function App() { + // 1. Extract `queryKey` from the useBalance Hook. // [!code hl] + const { queryKey } = useBalance() // [!code hl] + + return ( + + ) +} + +function Example() { + // 3. Other `useBalance` Hooks in your rendered React tree will be refetched! // [!code hl] + const { data: balance } = useBalance() // [!code hl] + + return
{balance}
+} +``` + +## Fetching Queries + +Fetching a query is the process of invoking the query function to retrieve data. If the query exists and the data is not invalidated or older than a given `staleTime`, then the data from the cache will be returned. Otherwise, the query will fetch for the latest data. + +::: code-group +```tsx [example.tsx] +import { getBlockQueryOptions } from 'wagmi' +import { queryClient } from './app' +import { config } from './config' + +export async function fetchBlockData() { + return queryClient.fetchQuery( // [!code hl] + getBlockQueryOptions(config, { // [!code hl] + chainId: config.state.chainId, // [!code hl] + } // [!code hl] + )) // [!code hl] +} +``` +<<< @/snippets/react/app.tsx[app.tsx] +<<< @/snippets/react/config.ts[config.ts] +::: + +## Retrieving & Updating Query Data + +You can retrieve and update query data imperatively with `getQueryData` and `setQueryData`. This is useful for scenarios where you want to retrieve or update a query outside of a React component. + +Note that these functions do not invalidate or refetch queries. + +::: code-group +```tsx [example.tsx] +import { getBlockQueryOptions } from 'wagmi' +import type { Block } from 'viem' +import { queryClient } from './app' +import { config } from './config' + +export function getPendingBlockData() { + return queryClient.getQueryData( // [!code hl] + getBlockQueryOptions(config, { // [!code hl] + chainId: config.state.chainId, // [!code hl] + tag: 'pending' // [!code hl] + } // [!code hl] + )) // [!code hl] +} + +export function setPendingBlockData(data: Block) { + return queryClient.setQueryData( // [!code hl] + getBlockQueryOptions(config, { // [!code hl] + chainId: config.state.chainId, // [!code hl] + tag: 'pending' // [!code hl] + }, // [!code hl] + data // [!code hl] + )) // [!code hl] +} +``` +<<< @/snippets/react/app.tsx[app.tsx] +<<< @/snippets/react/config.ts[config.ts] +::: + +## Prefetching Queries + +Prefetching a query is the process of fetching the data ahead of time and seeding the cache with the returned data. This is useful for scenarios where you want to fetch data before the user navigates to a page, or fetching data on the server to be reused on client hydration. + +Read more about **Prefetching Queries** on the [TanStack Query docs.](https://tanstack.com/query/v5/docs/react/guides/prefetching) + +#### Example: Prefetching in Event Handler + +```tsx +import { Link } from 'next/link' +import { getBlockQueryOptions } from 'wagmi' + +function App() { + const config = useConfig() + const chainId = useChainId() + + // 1. Set up a function to prefetch the block data. // [!code hl] + const prefetch = () => // [!code hl] + queryClient.prefetchQuery(getBlockQueryOptions(config, { chainId })) // [!code hl] + + + return ( + + Block details + + ) +} +``` + +## SSR + +It is possible to utilize TanStack Query's SSR strategies with Wagmi Hooks & Query Keys. Check out the [Server Rendering & Hydration](https://tanstack.com/query/v5/docs/react/guides/ssr) & [Advanced Server Rendering](https://tanstack.com/query/v5/docs/react/guides/advanced-ssr) guides. + +## Devtools + +TanStack Query includes dedicated [Devtools](https://tanstack.com/query/latest/docs/framework/react/devtools) that assist in visualizing and debugging your queries, their cache states, and much more. You will have to pass a custom `queryKeyFn` to your `QueryClient` for Devtools to correctly serialize BigInt values for display. Alternatively, You can use the `hashFn` from `@wagmi/core/query`, which already handles this serialization. + +#### Install + +::: code-group +```bash [pnpm] +pnpm i @tanstack/react-query-devtools +``` + +```bash [npm] +npm i @tanstack/react-query-devtools +``` + +```bash [yarn] +yarn add @tanstack/react-query-devtools +``` + +```bash [bun] +bun i @tanstack/react-query-devtools +``` +::: + +#### Usage + +```tsx +import { + QueryClient, + QueryClientProvider, +} from "@tanstack/react-query"; +import { ReactQueryDevtools } from "@tanstack/react-query-devtools"; // [!code hl] +import { hashFn } from "@wagmi/core/query"; // [!code hl] + +const queryClient = new QueryClient({ + defaultOptions: { // [!code hl] + queries: { // [!code hl] + queryKeyHashFn: hashFn, // [!code hl] + }, // [!code hl] + }, // [!code hl] +}); +``` diff --git a/wagmi-project/site/react/guides/testing.md b/wagmi-project/site/react/guides/testing.md new file mode 100644 index 000000000..fd198fa05 --- /dev/null +++ b/wagmi-project/site/react/guides/testing.md @@ -0,0 +1,2 @@ +# Testing + diff --git a/wagmi-project/site/react/guides/viem.md b/wagmi-project/site/react/guides/viem.md new file mode 100644 index 000000000..6539b3fe6 --- /dev/null +++ b/wagmi-project/site/react/guides/viem.md @@ -0,0 +1,150 @@ +# Viem + +[Viem](https://viem.sh) is a low-level TypeScript Interface for Ethereum that enables developers to interact with the Ethereum blockchain, including: JSON-RPC API abstractions, Smart Contract interaction, wallet & signing implementations, coding/parsing utilities and more. + +**Wagmi Core** is essentially a wrapper over **Viem** that provides multi-chain functionality via [Wagmi Config](/react/api/createConfig) and automatic account management via [Connectors](/react/api/connectors). + +## Leveraging Viem Actions + +All of the core [Wagmi Hooks](/react/api/actions) are friendly wrappers around [Viem Actions](https://viem.sh/docs/actions/public/introduction.html) that inject a multi-chain and connector aware [Wagmi Config](/react/api/createConfig). + +There may be cases where you might want to dig deeper and utilize Viem Actions directly (maybe a Hook doesn't exist in Wagmi yet). In these cases, you can create your own custom Wagmi Hook by importing Viem Actions directly via `viem/actions` and plugging in a Viem Client returned by the [`useClient` Hook](/react/api/hooks/useClient). + +The example below demonstrates two different ways to utilize Viem Actions: + +1. **Tree-shakable Actions (recommended):** Uses `useClient` (for public actions) and `useConnectorClient` (for wallet actions). +2. **Client Actions:** Uses `usePublicClient` (for public actions) and `useWalletClient` (for wallet actions). + +::: tip + +It is highly recommended to use the **tree-shakable** method to ensure that you are only pulling modules you use, and keep your bundle size low. + +::: + +::: code-group + +```tsx [Tree-shakable Actions] +// 1. Import modules. +import { useMutation, useQuery } from '@tanstack/react-query' +import { http, createConfig, useClient, useConnectorClient } from 'wagmi' +import { base, mainnet, optimism, zora } from 'wagmi/chains' +import { getLogs, watchAsset } from 'viem/actions' + +// 2. Set up a Wagmi Config +export const config = createConfig({ + chains: [base, mainnet, optimism, zora], + transports: { + [base.id]: http(), + [mainnet.id]: http(), + [optimism.id]: http(), + [zora.id]: http(), + }, +}) + +function Example() { + // 3. Extract a Viem Client for the current active chain. // [!code hl] + const publicClient = useClient({ config }) // [!code hl] + + // 4. Create a "custom" Query Hook that utilizes the Client. // [!code hl] + const { data: logs } = useQuery({ // [!code hl] + queryKey: ['logs', publicClient.uid], // [!code hl] + queryFn: () => getLogs(publicClient, /* ... */) // [!code hl] + }) // [!code hl] + + // 5. Extract a Viem Client for the current active chain & account. // [!code hl] + const { data: walletClient } = useConnectorClient({ config }) // [!code hl] + + // 6. Create a "custom" Mutation Hook that utilizes the Client. // [!code hl] + const { mutate } = useMutation({ // [!code hl] + mutationFn: (asset) => watchAsset(walletClient, asset) // [!code hl] + }) // [!code hl] + + return ( +
+ {/* ... */} +
+ ) +} +``` + +```tsx [Client Actions] +// 1. Import modules. +import { useMutation, useQuery } from '@tanstack/react-query' +import { http, createConfig, useClient, useConnectorClient } from 'wagmi' +import { base, mainnet, optimism, zora } from 'wagmi/chains' + +// 2. Set up a Wagmi Config +export const config = createConfig({ + chains: [base, mainnet, optimism, zora], + transports: { + [base.id]: http(), + [mainnet.id]: http(), + [optimism.id]: http(), + [zora.id]: http(), + }, +}) + +function Example() { + // 3. Extract a Viem Client for the current active chain. // [!code hl] + const publicClient = useClient({ config }) // [!code hl] + + // 4. Create a "custom" Query Hook that utilizes the Client. // [!code hl] + const { data: logs } = useQuery({ // [!code hl] + queryKey: ['logs', publicClient.uid], // [!code hl] + queryFn: () => publicClient.getLogs(/* ... */) // [!code hl] + }) // [!code hl] + + // 5. Extract a Viem Client for the current active chain & account. // [!code hl] + const { data: walletClient } = useConnectorClient({ config }) // [!code hl] + + // 6. Create a "custom" Mutation Hook that utilizes the Client. // [!code hl] + const { mutate } = useMutation({ // [!code hl] + mutationFn: (asset) => walletClient.watchAsset(asset) // [!code hl] + }) // [!code hl] + + return ( +
+ {/* ... */} +
+ ) +} +``` + +::: + +## Private Key & Mnemonic Accounts + +It is possible to utilize Viem's [Private Key & Mnemonic Accounts](https://viem.sh/docs/accounts/local.html) with Wagmi by explicitly passing through the account via the `account` argument on Wagmi Actions. + +```tsx +import { http, createConfig, useSendTransaction } from 'wagmi' +import { base, mainnet, optimism, zora } from 'wagmi/chains' +import { parseEther } from 'viem' +import { privateKeyToAccount } from 'viem/accounts' + +export const config = createConfig({ + chains: [base, mainnet, optimism, zora], + transports: { + [base.id]: http(), + [mainnet.id]: http(), + [optimism.id]: http(), + [zora.id]: http(), + }, +}) + +const account = privateKeyToAccount('0x...') // [!code hl] + +function Example() { + const { data: hash } = useSendTransaction({ + account, // [!code hl] + to: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC', + value: parseEther('0.001') + }) +} +``` + +::: info + +Wagmi currently does not support hoisting Private Key & Mnemonic Accounts to the top-level Wagmi Config – meaning you have to explicitly pass through the account to every Action. If you feel like this is a feature that should be added, please [open an discussion](https://github.com/wevm/wagmi/discussions/new?category=ideas). + +::: diff --git a/wagmi-project/site/react/guides/write-to-contract.md b/wagmi-project/site/react/guides/write-to-contract.md new file mode 100644 index 000000000..65914ae98 --- /dev/null +++ b/wagmi-project/site/react/guides/write-to-contract.md @@ -0,0 +1,438 @@ +# Write to Contract + +The [`useWriteContract` Hook](/react/api/hooks/useWriteContract) allows you to mutate data on a smart contract, from a `payable` or `nonpayable` (write) function. These types of functions require gas to be executed, hence a transaction is broadcasted in order to change the state. + +In the guide below, we will teach you how to implement a "Mint NFT" form that takes in a dynamic argument (token ID) using Wagmi. The example below builds on the [Connect Wallet guide](/react/guides/connect-wallet) and uses the [useWriteContract](/react/api/hooks/useWriteContract) & [useWaitForTransaction](/react/api/hooks/useWaitForTransactionReceipt) hooks. + +If you have already completed the [Sending Transactions guide](/react/guides/send-transaction), this guide will look very similar! That's because writing to a contract internally broadcasts & sends a transaction. + +## Example + +Feel free to check out the example before moving on: + + + +## Steps + +### 1. Connect Wallet + +Follow the [Connect Wallet guide](/react/guides/connect-wallet) guide to get this set up. + +### 2. Create a new component + +Create your `MintNFT` component that will contain the Mint NFT logic. + +::: code-group + +```tsx [mint-nft.tsx] +import * as React from 'react' + +export function MintNFT() { + return ( +
+ + +
+ ) +} +``` + +::: + +### 3. Add a form handler + +Next, we will need to add a handler to the form that will send the transaction when the user hits "Mint". This will be a basic handler in this step. + +::: code-group + +```tsx [mint-nft.tsx] +import * as React from 'react' + +export function MintNFT() { + async function submit(e: React.FormEvent) { // [!code ++] + e.preventDefault() // [!code ++] + const formData = new FormData(e.target as HTMLFormElement) // [!code ++] + const tokenId = formData.get('tokenId') as string // [!code ++] + } // [!code ++] + + return ( +
// [!code --] + // [!code ++] + + +
+ ) +} +``` + +::: + +### 4. Hook up the `useWriteContract` Hook + +Now that we have the form handler, we can hook up the [`useWriteContract` Hook](/react/api/hooks/useWriteContract) to send the transaction. + +::: code-group + +```tsx [mint-nft.tsx] +import * as React from 'react' +import { useWriteContract } from 'wagmi' // [!code ++] +import { abi } from './abi' // [!code ++] + +export function MintNFT() { + const { data: hash, writeContract } = useWriteContract() // [!code ++] + + async function submit(e: React.FormEvent) { + e.preventDefault() + const formData = new FormData(e.target as HTMLFormElement) + const tokenId = formData.get('tokenId') as string + writeContract({ // [!code ++] + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', // [!code ++] + abi, // [!code ++] + functionName: 'mint', // [!code ++] + args: [BigInt(tokenId)], // [!code ++] + }) // [!code ++] + } + + return ( +
+ + + {hash &&
Transaction Hash: {hash}
} // [!code ++] +
+ ) +} +``` + +```ts [abi.ts] +export const abi = [ + { + name: 'mint', + type: 'function', + stateMutability: 'nonpayable', + inputs: [{ internalType: 'uint32', name: 'tokenId', type: 'uint32' }], + outputs: [], + }, +] as const +``` + +::: + +### 5. Add loading state (optional) + +We can optionally add a loading state to the "Mint" button while we are waiting confirmation from the user's wallet. + +::: code-group + +```tsx [mint-nft.tsx] +import * as React from 'react' +import { useWriteContract } from 'wagmi' +import { abi } from './abi' + +export function MintNFT() { + const { + data: hash, + isPending, // [!code ++] + writeContract + } = useWriteContract() + + async function submit(e: React.FormEvent) { + e.preventDefault() + const formData = new FormData(e.target as HTMLFormElement) + const tokenId = formData.get('tokenId') as string + writeContract({ + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + abi, + functionName: 'mint', + args: [BigInt(tokenId)], + }) + } + + return ( +
+ + + {hash &&
Transaction Hash: {hash}
} +
+ ) +} +``` + +```ts [abi.ts] +export const abi = [ + { + name: 'mint', + type: 'function', + stateMutability: 'nonpayable', + inputs: [{ internalType: 'uint32', name: 'tokenId', type: 'uint32' }], + outputs: [], + }, +] as const +``` + +::: + +### 6. Wait for transaction receipt (optional) + +We can also display the transaction confirmation status to the user by using the [`useWaitForTransactionReceipt` Hook](/react/api/hooks/useWaitForTransactionReceipt). + +::: code-group + +```tsx [mint-nft.tsx] +import * as React from 'react' +import { + useWaitForTransactionReceipt, // [!code ++] + useWriteContract +} from 'wagmi' +import { abi } from './abi' + +export function MintNFT() { + const { + data: hash, + isPending, + writeContract + } = useWriteContract() + + async function submit(e: React.FormEvent) { + e.preventDefault() + const formData = new FormData(e.target as HTMLFormElement) + const tokenId = formData.get('tokenId') as string + writeContract({ + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + abi, + functionName: 'mint', + args: [BigInt(tokenId)], + }) + } + + const { isLoading: isConfirming, isSuccess: isConfirmed } = // [!code ++] + useWaitForTransactionReceipt({ // [!code ++] + hash, // [!code ++] + }) // [!code ++] + + return ( +
+ + + {hash &&
Transaction Hash: {hash}
} + {isConfirming &&
Waiting for confirmation...
} // [!code ++] + {isConfirmed &&
Transaction confirmed.
} // [!code ++] +
+ ) +} +``` + +```ts [abi.ts] +export const abi = [ + { + name: 'mint', + type: 'function', + stateMutability: 'nonpayable', + inputs: [{ internalType: 'uint32', name: 'tokenId', type: 'uint32' }], + outputs: [], + }, +] as const +``` + +::: + +### 7. Handle errors (optional) + +If the user rejects the transaction, or the contract reverts, we can display an error message to the user. + +::: code-group + +```tsx [mint-nft.tsx] +import * as React from 'react' +import { + type BaseError, // [!code ++] + useWaitForTransactionReceipt, + useWriteContract +} from 'wagmi' +import { abi } from './abi' + +export function MintNFT() { + const { + data: hash, + error, // [!code ++] + isPending, + writeContract + } = useWriteContract() + + async function submit(e: React.FormEvent) { + e.preventDefault() + const formData = new FormData(e.target as HTMLFormElement) + const tokenId = formData.get('tokenId') as string + writeContract({ + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + abi, + functionName: 'mint', + args: [BigInt(tokenId)], + }) + } + + const { isLoading: isConfirming, isSuccess: isConfirmed } = + useWaitForTransactionReceipt({ + hash, + }) + + return ( +
+ + + {hash &&
Transaction Hash: {hash}
} + {isConfirming &&
Waiting for confirmation...
} + {isConfirmed &&
Transaction confirmed.
} + {error && ( // [!code ++] +
Error: {(error as BaseError).shortMessage || error.message}
// [!code ++] + )} // [!code ++] +
+ ) +} +``` + +```ts [abi.ts] +export const abi = [ + { + name: 'mint', + type: 'function', + stateMutability: 'nonpayable', + inputs: [{ internalType: 'uint32', name: 'tokenId', type: 'uint32' }], + outputs: [], + }, +] as const +``` + +::: + +### 8. Wire it up! + +Finally, we can wire up our Mint NFT component to our application's entrypoint. + +::: code-group + +```tsx [app.tsx] +import { QueryClient, QueryClientProvider } from '@tanstack/react-query' +import { WagmiProvider, useAccount } from 'wagmi' +import { config } from './config' +import { MintNft } from './mint-nft' // [!code ++] + +const queryClient = new QueryClient() + +function App() { + return ( + + + // [!code ++] + + + ) +} +``` + +```tsx [mint-nft.tsx] +import * as React from 'react' +import { + type BaseError, + useWaitForTransactionReceipt, + useWriteContract +} from 'wagmi' +import { abi } from './abi' + +export function MintNFT() { + const { + data: hash, + error, + isPending, + writeContract + } = useWriteContract() + + async function submit(e: React.FormEvent) { + e.preventDefault() + const formData = new FormData(e.target as HTMLFormElement) + const tokenId = formData.get('tokenId') as string + writeContract({ + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + abi, + functionName: 'mint', + args: [BigInt(tokenId)], + }) + } + + const { isLoading: isConfirming, isSuccess: isConfirmed } = + useWaitForTransactionReceipt({ + hash, + }) + + return ( +
+ + + {hash &&
Transaction Hash: {hash}
} + {isConfirming &&
Waiting for confirmation...
} + {isConfirmed &&
Transaction confirmed.
} + {error && ( +
Error: {(error as BaseError).shortMessage || error.message}
+ )} +
+ ) +} +``` + +```ts [abi.ts] +export const abi = [ + { + name: 'mint', + type: 'function', + stateMutability: 'nonpayable', + inputs: [{ internalType: 'uint32', name: 'tokenId', type: 'uint32' }], + outputs: [], + }, +] as const +``` + +```tsx [config.ts] +import { http, createConfig } from 'wagmi' +import { base, mainnet, optimism } from 'wagmi/chains' +import { injected, metaMask, safe, walletConnect } from 'wagmi/connectors' + +const projectId = '' + +export const config = createConfig({ + chains: [mainnet, base], + connectors: [ + injected(), + walletConnect({ projectId }), + metaMask(), + safe(), + ], + transports: { + [mainnet.id]: http(), + [base.id]: http(), + }, +}) +``` + +::: + +[See the Example.](#example) diff --git a/wagmi-project/site/react/installation.md b/wagmi-project/site/react/installation.md new file mode 100644 index 000000000..7dd830679 --- /dev/null +++ b/wagmi-project/site/react/installation.md @@ -0,0 +1,56 @@ + + +# Installation + +Install Wagmi via your package manager, a ` +``` + +Check out the React docs for info on how to use [React without JSX](https://react.dev/reference/react/createElement#creating-an-element-without-jsx). + + diff --git a/wagmi-project/site/react/typescript.md b/wagmi-project/site/react/typescript.md new file mode 100644 index 000000000..1ed9d4246 --- /dev/null +++ b/wagmi-project/site/react/typescript.md @@ -0,0 +1,302 @@ + + +# TypeScript + +## Requirements + +Wagmi is designed to be as type-safe as possible! Things to keep in mind: + +- Types currently require using TypeScript {{typescriptVersion}}. +- [TypeScript doesn't follow semver](https://www.learningtypescript.com/articles/why-typescript-doesnt-follow-strict-semantic-versioning) and often introduces breaking changes in minor releases. +- Changes to types in this repository are considered non-breaking and are usually released as patch changes (otherwise every type enhancement would be a major version!). +- It is highly recommended that you lock your `wagmi` and `typescript` versions to specific patch releases and upgrade with the expectation that types may be fixed or upgraded between any release. +- The non-type-related public API of Wagmi still follows semver very strictly. + +To ensure everything works correctly, make sure your `tsconfig.json` has [`strict`](https://www.typescriptlang.org/tsconfig#strict) mode set to `true`. + +::: code-group +```json [tsconfig.json] +{ + "compilerOptions": { + "strict": true + } +} +``` +::: + +## Config Types + +By default React Context does not work well with type inference. To support strong type-safety across the React Context boundary, there are two options available: + +- Declaration merging to "register" your `config` globally with TypeScript. +- `config` property to pass your `config` directly to hooks. + +### Declaration Merging + +[Declaration merging](https://www.typescriptlang.org/docs/handbook/declaration-merging.html) allows you to "register" your `config` globally with TypeScript. The `Register` type enables Wagmi to infer types in places that wouldn't normally have access to type info via React Context alone. + +To set this up, add the following declaration to your project. Below, we co-locate the declaration merging and the `config` set up. + +```ts +import { createConfig, http } from 'wagmi' +import { mainnet, sepolia } from 'wagmi/chains' + +declare module 'wagmi' { // [!code focus] + interface Register { // [!code focus] + config: typeof config // [!code focus] + } // [!code focus] +} // [!code focus] + +export const config = createConfig({ + chains: [mainnet, sepolia], + transports: { + [mainnet.id]: http(), + [sepolia.id]: http(), + }, +}) +``` + +Since the `Register` type is global, you only need to add it once in your project. Once set up, you will get strong type-safety across your entire project. For example, query hooks will type `chainId` based on your `config`'s `chains`. + +```ts twoslash +// @errors: 2322 +import { type Config } from 'wagmi' +import { mainnet, sepolia } from 'wagmi/chains' + +declare module 'wagmi' { + interface Register { + config: Config + } +} +// ---cut--- +import { useBlockNumber } from 'wagmi' + +useBlockNumber({ chainId: 123 }) +``` + +You just saved yourself a runtime error and you didn't even need to pass your `config`. 🎉 + +### Hook `config` Property + +For cases where you have more than one Wagmi `config` or don't want to use the declaration merging approach, you can pass a specific `config` directly to hooks via the `config` property. + +```ts +import { createConfig, http } from 'wagmi' +import { mainnet, optimism } from 'wagmi/chains' + +export const configA = createConfig({ // [!code focus] + chains: [mainnet], // [!code focus] + transports: { // [!code focus] + [mainnet.id]: http(), // [!code focus] + }, // [!code focus] +}) // [!code focus] + +export const configB = createConfig({ // [!code focus] + chains: [optimism], // [!code focus] + transports: { // [!code focus] + [optimism.id]: http(), // [!code focus] + }, // [!code focus] +}) // [!code focus] +``` + +As you expect, `chainId` is inferred correctly for each `config`. + +```ts twoslash +// @errors: 2322 +import { type Config } from 'wagmi' +import { mainnet, optimism } from 'wagmi/chains' + +declare const configA: Config +declare const configB: Config +// ---cut--- +import { useBlockNumber } from 'wagmi' + +useBlockNumber({ chainId: 123, config: configA }) +useBlockNumber({ chainId: 123, config: configB }) +``` + +This approach is more explicit, but works well for advanced use-cases, if you don't want to use React Context or declaration merging, etc. + +## Const-Assert ABIs & Typed Data + +Wagmi can infer types based on [ABIs](https://docs.soliditylang.org/en/latest/abi-spec.html#json) and [EIP-712](https://eips.ethereum.org/EIPS/eip-712) Typed Data definitions, powered by [Viem](https://viem.sh) and [ABIType](https://github.com/wevm/abitype). This achieves full end-to-end type-safety from your contracts to your frontend and enlightened developer experience by autocompleting ABI item names, catching misspellings, inferring argument and return types (including overloads), and more. + +For this to work, you must either [const-assert](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-4.html#const-assertions) ABIs and Typed Data (more info below) or define them inline. For example, `useReadContract`'s `abi` configuration parameter: + +```ts +const { data } = useReadContract({ + abi: […], // <--- defined inline // [!code focus] +}) +``` + +```ts +const abi = […] as const // <--- const assertion // [!code focus] +const { data } = useReadContract({ abi }) +``` + +If type inference isn't working, it's likely you forgot to add a `const` assertion or define the configuration parameter inline. Also, make sure your ABIs, Typed Data definitions, and [TypeScript configuration](#requirements) are valid and set up correctly. + +::: tip +Unfortunately [TypeScript doesn't support importing JSON `as const` yet](https://github.com/microsoft/TypeScript/issues/32063). Check out the [Wagmi CLI](/cli/getting-started) to help with this! It can automatically fetch ABIs from Etherscan and other block explorers, resolve ABIs from your Foundry/Hardhat projects, generate React Hooks, and more. +::: + +Anywhere you see the `abi` or `types` configuration property, you can likely use const-asserted or inline ABIs and Typed Data to get type-safety and inference. These properties are also called out in the docs. + +Here's what [`useReadContract`](/react/api/hooks/useReadContract) looks like with and without a const-asserted `abi` property. + +::: code-group +```ts twoslash [Const-Asserted] +const erc721Abi = [ + { + name: 'balanceOf', + type: 'function', + stateMutability: 'view', + inputs: [{ type: 'address', name: 'owner' }], + outputs: [{ type: 'uint256' }], + }, + { + name: 'isApprovedForAll', + type: 'function', + stateMutability: 'view', + inputs: [ + { type: 'address', name: 'owner' }, + { type: 'address', name: 'operator' }, + ], + outputs: [{ type: 'bool' }], + }, + { + name: 'getApproved', + type: 'function', + stateMutability: 'view', + inputs: [{ type: 'uint256', name: 'tokenId' }], + outputs: [{ type: 'address' }], + }, + { + name: 'ownerOf', + type: 'function', + stateMutability: 'view', + inputs: [{ type: 'uint256', name: 'tokenId' }], + outputs: [{ type: 'address' }], + }, + { + name: 'tokenURI', + type: 'function', + stateMutability: 'pure', + inputs: [{ type: 'uint256', name: 'tokenId' }], + outputs: [{ type: 'string' }], + }, +] as const +// ---cut--- +import { useReadContract } from 'wagmi' + +const { data } = useReadContract({ + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + abi: erc721Abi, + functionName: 'balanceOf', + // ^? + + + + args: ['0xA0Cf798816D4b9b9866b5330EEa46a18382f251e'], + // ^? +}) + +data +// ^? +``` +```ts twoslash [Not Const-Asserted] +declare const erc721Abi: { + name: string; + type: string; + stateMutability: string; + inputs: { + type: string; + name: string; + }[]; + outputs: { + type: string; + }[]; +}[] +// ---cut--- +import { useReadContract } from 'wagmi' + +const { data } = useReadContract({ + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + abi: erc721Abi, + functionName: 'balanceOf', + // ^? + + + + args: ['0xA0Cf798816D4b9b9866b5330EEa46a18382f251e'], + // ^? +}) + +data +// ^? +``` +::: + +
+
+ +You can prevent runtime errors and be more productive by making sure your ABIs and Typed Data definitions are set up appropriately. 🎉 + +```ts twoslash +// @errors: 2820 +const erc721Abi = [ + { + name: 'balanceOf', + type: 'function', + stateMutability: 'view', + inputs: [{ type: 'address', name: 'owner' }], + outputs: [{ type: 'uint256' }], + }, + { + name: 'isApprovedForAll', + type: 'function', + stateMutability: 'view', + inputs: [ + { type: 'address', name: 'owner' }, + { type: 'address', name: 'operator' }, + ], + outputs: [{ type: 'bool' }], + }, + { + name: 'getApproved', + type: 'function', + stateMutability: 'view', + inputs: [{ type: 'uint256', name: 'tokenId' }], + outputs: [{ type: 'address' }], + }, + { + name: 'ownerOf', + type: 'function', + stateMutability: 'view', + inputs: [{ type: 'uint256', name: 'tokenId' }], + outputs: [{ type: 'address' }], + }, + { + name: 'tokenURI', + type: 'function', + stateMutability: 'pure', + inputs: [{ type: 'uint256', name: 'tokenId' }], + outputs: [{ type: 'string' }], + }, +] as const +// ---cut--- +import { useReadContract } from 'wagmi' + +useReadContract({ + abi: erc721Abi, + functionName: 'balanecOf', +}) +``` + +## Configure Internal Types + +For advanced use-cases, you may want to configure Wagmi's internal types. Most of Wagmi's types relating to ABIs and EIP-712 Typed Data are powered by [ABIType](https://github.com/wevm/abitype). See the [ABIType docs](https://abitype.dev) for more info on how to configure types. diff --git a/wagmi-project/site/react/why.md b/wagmi-project/site/react/why.md new file mode 100644 index 000000000..3b4bf2b89 --- /dev/null +++ b/wagmi-project/site/react/why.md @@ -0,0 +1,46 @@ +# Why Wagmi + +## The Problems + +Building Ethereum applications is hard. Apps need to support connecting wallets, multiple chains, signing messages and data, sending transactions, listening for events and state changes, refreshing stale blockchain data, and much more. This is all on top of solving for app-specific use-cases and providing polished user experiences. + +The ecosystem is also continuously evolving, meaning you need to adapt to new improvements or get left behind. App developers should not need to worry about connecting tens of different wallets, the intricacies of multi-chain support, typos accidentally sending an order of magnitude more ETH or calling a misspelled contract function, or accidentally spamming their RPC provider, costing thousands in compute units. + +Wagmi solves all these problems and more — allowing app developers to focus on building high-quality and performant experiences for Ethereum — by focusing on **developer experience**, **performance**, **feature coverage**, and **stability.** + +## Developer Experience + +Wagmi delivers a great developer experience through modular and composable APIs, automatic type safety and inference, and comprehensive documentation. + +It provides developers with intuitive building blocks to build their Ethereum apps. While Wagmi's APIs might seem more verbose at first, it makes Wagmi's modular building blocks extremely flexible. Easy to move around, change, and remove. It also allows developers to better understand Ethereum concepts as well as understand _what_ and _why_ certain properties are being passed through. Learning how to use Wagmi is a great way to learn how to interact with Ethereum in general. + +Wagmi also provides [strongly typed APIs](/react/typescript), allowing consumers to get the best possible experience through [autocomplete](https://twitter.com/awkweb/status/1555678944770367493), [type inference](https://twitter.com/jakemoxey/status/1570244174502588417?s=20), as well as static validation. You often just need to provide an ABI and Wagmi can help you autocomplete your way to success, identify type errors before your users do, drill into blockchain errors [at compile and runtimes](/react/guides/error-handling) with surgical precision, and much more. + +The API documentation is comprehensive and contains usage info for _every_ module in Wagmi. The core team uses a [documentation](https://gist.github.com/zsup/9434452) and [test driven](https://en.wikipedia.org/wiki/Test-driven_development#:~:text=Test%2Ddriven%20development%20(TDD),software%20against%20all%20test%20cases.) development approach to building modules, which leads to predictable and stable APIs. + +## Performance + +Performance is critical for applications on all sizes. Slow page load and interactions can cause users to stop using applications. Wagmi uses and is built by the same team behind [Viem](https://viem.sh), the most performant production-ready Ethereum library. + +End users should not be required to download a module of over 100kB in order to interact with Ethereum. Wagmi is optimized for tree-shaking and dead-code elimination, allowing apps to minimize bundle size for fast page load times. + +Data layer performance is also critical. Slow, unnecessary, and manual data fetching can make apps unusable and cost thousands in RPC compute units. Wagmi supports caching, deduplication, persistence, and much more through [TanStack Query](/react/guides/tanstack-query). + +## Feature Coverage + +Wagmi supports the most popular and commonly-used Ethereum features out of the box with 40+ React Hooks for accounts, wallets, contracts, transactions, signing, ENS, and more. Wagmi also supports just about any wallet out there through official [connectors](/react/api/connectors), [EIP-6963 support](/react/api/createConfig#multiinjectedproviderdiscovery), and [extensible API](/dev/creating-connectors). + +If you need lower-level control, you can always drop down to [Wagmi Core](/core/getting-started) or [Viem](https://viem.sh), which Wagmi uses internally to perform blockchain operations. Wagmi also manages multi-chain support automatically so developers can focus on their applications instead of adding custom code. + +Finally, Wagmi has a [CLI](/cli/getting-started) to manage ABIs as well as a robust ecosystem of third-party libraries, like [ConnectKit](https://docs.family.co/connectkit), [RainbowKit](https://www.rainbowkit.com), [AppKit](https://walletconnect.com/appkit), [Dynamic](https://www.dynamic.xyz), [Privy](https://privy.io), and many more, so you can get started quickly without needing to build everything from scratch. + +## Stability + +Stability is a fundamental principle for Wagmi. Many organizations, large and small, rely heavily on Wagmi and expect it to be entirely stable for their users and applications. + +Wagmi's test suite runs against forked Ethereum nodes to make sure functions work across chains. The test suite also runs type tests against many different versions of peer dependencies, like TypeScript, to ensure compatibility with the latest releases of other popular software. + +Wagmi follows semver so developers can upgrade between versions with confidence. Starting with Wagmi v2, new functionality will be opt-in with old functionality being deprecated alongside the new features. This means upgrading to the latest major versions will not require immediate changes. + +Lastly, the core team works full-time on Wagmi and [related projects](https://github.com/wevm), and is constantly improving Wagmi and keeping it up-to-date with industry trends and changes. + diff --git a/wagmi-project/site/shared/connectors/coinbaseWallet.md b/wagmi-project/site/shared/connectors/coinbaseWallet.md new file mode 100644 index 000000000..de70807ae --- /dev/null +++ b/wagmi-project/site/shared/connectors/coinbaseWallet.md @@ -0,0 +1,160 @@ + + +# coinbaseWallet + +Connector for the [Coinbase Wallet SDK](https://github.com/coinbase/coinbase-wallet-sdk). + +## Import + +```ts-vue +import { coinbaseWallet } from '{{connectorsPackageName}}' +``` + +## Usage + +```ts-vue +import { createConfig, http } from '{{packageName}}' +import { mainnet, sepolia } from '{{packageName}}/chains' +import { coinbaseWallet } from '{{connectorsPackageName}}' // [!code hl] + +export const config = createConfig({ + chains: [mainnet, sepolia], + connectors: [coinbaseWallet()], // [!code hl] + transports: { + [mainnet.id]: http(), + [sepolia.id]: http(), + }, +}) +``` + +:::warning +Before going to production, it is highly recommended to set an [`appName`](#appname) and [`appLogoUrl`](#applogourl) for your application that can be displayed upon connection to the wallet. +::: + +## Parameters + +```ts-vue +import { type CoinbaseWalletParameters } from '{{connectorsPackageName}}' +``` + +Check out the [Coinbase Wallet SDK docs](https://github.com/coinbase/coinbase-wallet-sdk) for more info. + +### appName + +`string` + +Application name. + +```ts-vue +import { coinbaseWallet } from '{{connectorsPackageName}}' + +const connector = coinbaseWallet({ + appName: 'My Wagmi App', // [!code focus] +}) +``` + +### appLogoUrl + +`string | null | undefined` + +Application logo image URL; favicon is used if unspecified. + +```ts-vue +import { coinbaseWallet } from '{{connectorsPackageName}}' + +const connector = coinbaseWallet({ + appName: 'My Wagmi App', + appLogoUrl: 'https://example.com/myLogoUrl.png', // [!code focus] +}) +``` + +### headlessMode + +`boolean | undefined` + +- Whether or not onboarding overlay popup should be displayed. +- `headlessMode` will be removed in the next major version. Upgrade to [`version: '4'`](#version). + +```ts-vue +import { coinbaseWallet } from '{{connectorsPackageName}}' + +const connector = coinbaseWallet({ + appName: 'My Wagmi App', + headlessMode: false, // [!code focus] +}) +``` + +### preference + +`"all" | "eoaOnly" | "smartWalletOnly"` + +Preference for the type of wallet to display. + +- `'eoaOnly'`: Uses EOA Browser Extension or Mobile Coinbase Wallet. +- `'smartWalletOnly'`: Displays Smart Wallet popup. +- `'all'` (default): Supports both `'eoaOnly'` and `'smartWalletOnly'` based on context. + +```ts-vue +import { coinbaseWallet } from '{{connectorsPackageName}}' + +const connector = coinbaseWallet({ + appName: 'My Wagmi App', + preference: 'smartWalletOnly', // [!code focus] +}) +``` + +::: warning +Passing `preference` as a string is deprecated and will be removed in the next major version. Instead you should use [`preference#options`](#options). +::: + +```ts-vue +import { coinbaseWallet } from '{{connectorsPackageName}}' + +const connector = coinbaseWallet({ + appName: 'My Wagmi App', + preference: { // [!code focus] + options: 'smartWalletOnly' // [!code focus] + }, // [!code focus] +}) +``` + +#### attribution + +`` { auto?: boolean | undefined; dataSuffix?: `0x${string}` | undefined } `` + +This option only applies to Coinbase Smart Wallet. When a valid data suffix is supplied, it is appended to the `initCode` and `executeBatch` calldata. Coinbase Smart Wallet expects a 16 byte hex string. If the data suffix is not a 16 byte hex string, the Smart Wallet will ignore the property. If auto is true, the Smart Wallet will generate a 16 byte hex string from the apps origin. + +#### keysUrl + +`string` + +- The URL for the keys popup. +- By default, `https://keys.coinbase.com/connect` is used for production. Use `https://keys-dev.coinbase.com/connect` for development environments. + +#### options + +`"all" | "eoaOnly" | "smartWalletOnly"` + +Preference for the type of wallet to display. + +- `'eoaOnly'`: Uses EOA Browser Extension or Mobile Coinbase Wallet. +- `'smartWalletOnly'`: Displays Smart Wallet popup. +- `'all'` (default): Supports both `'eoaOnly'` and `'smartWalletOnly'` based on context. + +### version + +- Coinbase Wallet SDK version +- Defaults to `'4'`. If [`headlessMode: true`](#headlessmode), defaults to `'3'`. + +```ts-vue +import { coinbaseWallet } from '{{connectorsPackageName}}' + +const connector = coinbaseWallet({ + appName: 'My Wagmi App', + version: '4', // [!code focus] +}) +``` + diff --git a/wagmi-project/site/shared/connectors/injected.md b/wagmi-project/site/shared/connectors/injected.md new file mode 100644 index 000000000..36583b4d8 --- /dev/null +++ b/wagmi-project/site/shared/connectors/injected.md @@ -0,0 +1,89 @@ + + +# injected + +Connector for [EIP-1193](https://eips.ethereum.org/EIPS/eip-1193) Ethereum Providers. + +## Import + +```ts-vue +import { injected } from '{{connectorsPackageName}}' +``` + +## Usage + +```ts-vue{3,7} +import { createConfig, http } from '{{packageName}}' +import { mainnet, sepolia } from '{{packageName}}/chains' +import { injected } from '{{connectorsPackageName}}' + +export const config = createConfig({ + chains: [mainnet, sepolia], + connectors: [injected()], + transports: { + [mainnet.id]: http(), + [sepolia.id]: http(), + }, +}) +``` + +## Parameters + +```ts-vue +import { type InjectedParameters } from '{{connectorsPackageName}}' +``` + +### shimDisconnect + +`boolean | undefined` + +- MetaMask and other injected providers do not support programmatic disconnect. +- This flag simulates the disconnect behavior by keeping track of connection status in storage. See [GitHub issue](https://github.com/MetaMask/metamask-extension/issues/10353) for more info. +- Defaults to `true`. + +```ts-vue +import { injected } from '{{connectorsPackageName}}' + +const connector = injected({ + shimDisconnect: false, // [!code focus] +}) +``` + +### target + +`TargetId | (TargetMap[TargetId] & { id: string }) | (() => (TargetMap[TargetId] & { id: string }) | undefined) | undefined` + +- [EIP-1193](https://eips.ethereum.org/EIPS/eip-1193) Ethereum Provider to target. +- [EIP-6963](https://eips.ethereum.org/EIPS/eip-6963) supported via `createConfig`'s `multiInjectedProviderDiscovery` property. + +```ts-vue +import { injected } from '{{connectorsPackageName}}' + +const connector = injected({ + target() { // [!code focus] + return { // [!code focus] + id: 'windowProvider', // [!code focus] + name: 'Window Provider', // [!code focus] + provider: window.ethereum, // [!code focus] + } // [!code focus] + }, // [!code focus] +}) +``` + +### unstable_shimAsyncInject + +`boolean | number | undefined` + +Watches for async provider injection via the `ethereum#initialized` event. When `true`, defaults to `1_000` milliseconds. Otherwise, uses a provided value of milliseconds. + +```ts-vue +import { injected } from '{{connectorsPackageName}}' + +const connector = injected({ + unstable_shimAsyncInject: 2_000, // [!code focus] +}) +``` diff --git a/wagmi-project/site/shared/connectors/metaMask.md b/wagmi-project/site/shared/connectors/metaMask.md new file mode 100644 index 000000000..08a6f4f9c --- /dev/null +++ b/wagmi-project/site/shared/connectors/metaMask.md @@ -0,0 +1,124 @@ + + +# metaMask + +Connector for [MetaMask SDK](https://github.com/MetaMask/metamask-sdk). + +Check out the [MetaMask SDK docs](https://docs.metamask.io/wallet/connect/metamask-sdk/javascript) for more information. + +## Import + +```ts-vue +import { metaMask } from '{{connectorsPackageName}}' +``` + +## Usage + +```ts-vue{3,7} +import { createConfig, http } from '{{packageName}}' +import { mainnet, sepolia } from '{{packageName}}/chains' +import { metaMask } from '{{connectorsPackageName}}' + +export const config = createConfig({ + chains: [mainnet, sepolia], + connectors: [metaMask()], + transports: { + [mainnet.id]: http(), + [sepolia.id]: http(), + }, +}) +``` + +## Parameters + +```ts-vue +import { type MetaMaskParameters } from '{{connectorsPackageName}}' +``` + +Check out the [MetaMask SDK docs](https://docs.metamask.io/wallet/connect/3rd-party-libraries/wagmi/) for more info. A few options are omitted that Wagmi manages internally. + +### dappMetadata + +`DappMetadata | undefined` + +Metadata is used to fill details for the UX on confirmation screens in MetaMask, including the following fields: + +- `name`: `string` - The name of the dapp. +- `url`: `string` - URL of the dapp (defaults to `window.location.origin`). +- `iconUrl`: `string` - URL to the dapp's favicon or icon. + +```ts-vue +import { metaMask } from '{{connectorsPackageName}}' + +const connector = metaMask({ + dappMetadata: { // [!code focus] + name: 'My Wagmi App', // [!code focus] + url: 'https://example.com', // [!code focus] + iconUrl: 'https://example.com/favicon.ico', // [!code focus] + } +}) +``` + +### logging + +`SDKLoggingOptions | undefined` + +Enables SDK-side logging to provide visibility into: + +- RPC methods being called. +- Events received for syncing the chain or active account. +- Raw RPC responses. + +In this context, this is especially useful to observe what calls are made through Wagmi hooks. + +Relevant options: + +```ts +{ + developerMode: boolean, // Enables developer mode logs + sdk: boolean // Enables SDK-specific logs +} +``` + +```ts +import { metaMask } from '{{connectorsPackageName}}' + +const connector = metaMask({ + logging: { developerMode: true, sdk: true } // [!code focus] +}) +``` + +### headless + +`boolean | undefined` + +- Enables headless mode, disabling MetaMask's built-in modal. +- Allows developers to create their own modal, such as for displaying a QR code. + +This is particularly relevant for web-only setups using Wagmi, where developers want complete control over the UI. + +To get the deeplink to display in the QR code, listen to the `display_uri` event. + +The default is `false`. + +```ts-vue +import { metaMask } from '{{connectorsPackageName}}' + +const connector = metaMask({ + headless: true // [!code focus] +}) +``` + +## Advanced + +By default, if the EIP-6963 MetaMask injected provider is detected, this connector will replace it. + +EIP-6963 defines a standard way for dapps to interact with multiple wallets simultaneously by injecting providers into the browser. Wallets that implement this standard can make their presence known to dapps in a consistent and predictable manner. + +When MetaMask SDK detects an EIP-6963-compliant provider (such as MetaMask itself), the connector will automatically replace the default injected provider (like `window.ethereum`) with the one provided by MetaMask SDK. + +See the [`rdns` property](https://wagmi.sh/dev/creating-connectors#properties) for more information. diff --git a/wagmi-project/site/shared/connectors/mock.md b/wagmi-project/site/shared/connectors/mock.md new file mode 100644 index 000000000..90d87b0b3 --- /dev/null +++ b/wagmi-project/site/shared/connectors/mock.md @@ -0,0 +1,128 @@ + + +# mock + +Connector for mocking Wagmi functionality. + +## Import + +```ts-vue +import { mock } from '{{connectorsPackageName}}' +``` + +## Usage + +```ts-vue{3,8-14} +import { createConfig, http } from '{{packageName}}' +import { mainnet, sepolia } from '{{packageName}}/chains' +import { mock } from '{{connectorsPackageName}}' + +export const config = createConfig({ + chains: [mainnet, sepolia], + connectors: [ + mock({ + accounts: [ + '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', + '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + '0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC', + ], + }), + ], + transports: { + [mainnet.id]: http(), + [sepolia.id]: http(), + }, +}) +``` + +## Parameters + +```ts-vue +import { type MockParameters } from '{{connectorsPackageName}}' +``` + +### accounts + +`readonly [Address, ...Address[]]` + +Accounts to use with the connector. + +```ts-vue +import { mock } from '{{connectorsPackageName}}' + +const connector = mock({ + accounts: [ // [!code focus] + '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', // [!code focus] + '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', // [!code focus] + '0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC', // [!code focus] + '0x90F79bf6EB2c4f870365E785982E1f101E93b906', // [!code focus] + '0x15d34aaf54267db7d7c367839aaf71a00a2c6a65', // [!code focus] + '0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc', // [!code focus] + '0x976EA74026E726554dB657fA54763abd0C3a0aa9', // [!code focus] + '0x14dC79964da2C08b23698B3D3cc7Ca32193d9955', // [!code focus] + '0x23618e81E3f5cdF7f54C3d65f7FBc0aBf5B21E8f', // [!code focus] + '0xa0Ee7A142d267C1f36714E4a8F75612F20a79720', // [!code focus] + ], // [!code focus] +}) +``` + +### features + +`{ connectError?: boolean | Error | undefined; reconnect?: boolean | undefined; signMessageError?: boolean | Error | undefined; signTypedDataError?: boolean | Error | undefined; switchChainError?: boolean | Error | undefined; } | undefined` + +Feature flags that change behavior of Wagmi internals. + +```ts-vue +import { mock } from '{{connectorsPackageName}}' +import { UserRejectedRequestError } from 'viem' + +const connector = mock({ + accounts: [ + '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', + '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + '0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC', + ], + features: { // [!code focus] + connectError: new UserRejectedRequestError(new Error('Failed to connect.')), // [!code focus] + reconnect: false, // [!code focus] + }, // [!code focus] +}) +``` +#### defaultConnected + +`boolean | undefined` + +Whether the connector is connected by default. + +#### connectError + +`boolean | Error | undefined` + +Whether to throw an error when `connector.connect` is called. + +#### reconnect + +`boolean | undefined` + +Enables reconnecting to connector. + +#### signMessageError + +`boolean | Error | undefined` + +Whether to throw an error when `'personal_sign'` is called. + +#### signTypedDataError + +`boolean | Error | undefined` + +Whether to throw an error when `'eth_signTypedData_v4'` is called. + +#### switchChainError + +`boolean | Error | undefined` + +Whether to throw an error when `connector.switchChain` is called. diff --git a/wagmi-project/site/shared/connectors/safe.md b/wagmi-project/site/shared/connectors/safe.md new file mode 100644 index 000000000..171010214 --- /dev/null +++ b/wagmi-project/site/shared/connectors/safe.md @@ -0,0 +1,77 @@ + + +# safe + +Connector for [Safe Apps SDK](https://github.com/safe-global/safe-apps-sdk). + +## Import + +```ts-vue +import { safe } from '{{connectorsPackageName}}' +``` + +## Usage + +```ts-vue{3,7} +import { createConfig, http } from '{{packageName}}' +import { mainnet, sepolia } from '{{packageName}}/chains' +import { safe } from '{{connectorsPackageName}}' + +export const config = createConfig({ + chains: [mainnet, sepolia], + connectors: [safe()], + transports: { + [mainnet.id]: http(), + [sepolia.id]: http(), + }, +}) +``` + +## Parameters + +```ts-vue +import { type SafeParameters } from '{{connectorsPackageName}}' +``` + +Check out the [Safe docs](https://github.com/safe-global/safe-apps-sdk/tree/main/packages/safe-apps-sdk) for more info. +### allowedDomains + +`RegExp[] | undefined` + +```ts-vue +import { safe } from '{{connectorsPackageName}}' + +const connector = safe({ + allowedDomains: [/app.safe.global$/], // [!code focus] +}) +``` + +### debug + +`boolean | undefined` + +```ts-vue +import { safe } from '{{connectorsPackageName}}' + +const connector = safe({ + debug: true, // [!code focus] +}) +``` + +### shimDisconnect + +`boolean | undefined` + +- This flag simulates disconnect behavior by keeping track of connection status in storage. +- Defaults to `false`. + +```ts-vue +import { safe } from '{{connectorsPackageName}}' + +const connector = safe({ + shimDisconnect: true, // [!code focus] +}) +``` diff --git a/wagmi-project/site/shared/connectors/walletConnect.md b/wagmi-project/site/shared/connectors/walletConnect.md new file mode 100644 index 000000000..48e7fcb95 --- /dev/null +++ b/wagmi-project/site/shared/connectors/walletConnect.md @@ -0,0 +1,215 @@ + + +# walletConnect + +Connector for [WalletConnect](https://walletconnect.com). + +## Import + +```ts-vue +import { walletConnect } from '{{connectorsPackageName}}' +``` + +## Usage + +```ts-vue{3,8-10} +import { createConfig, http } from '{{packageName}}' +import { mainnet, sepolia } from '{{packageName}}/chains' +import { walletConnect } from '{{connectorsPackageName}}' + +export const config = createConfig({ + chains: [mainnet, sepolia], + connectors: [ + walletConnect({ + projectId: '3fcc6bba6f1de962d911bb5b5c3dba68', + }), + ], + transports: { + [mainnet.id]: http(), + [sepolia.id]: http(), + }, +}) +``` + +## Parameters + +```ts-vue +import { type WalletConnectParameters } from '{{connectorsPackageName}}' +``` + +Check out the [WalletConnect docs](https://github.com/WalletConnect/walletconnect-monorepo/tree/v2.0/providers/ethereum-provider) for more info. A few options are omitted that Wagmi manages internally. + +### customStoragePrefix + +`string | undefined` + +Custom storage prefix for persisting provider state. + +```ts-vue +import { walletConnect } from '{{connectorsPackageName}}' + +const connector = walletConnect({ + customStoragePrefix: 'wagmi', // [!code focus] + projectId: '3fcc6bba6f1de962d911bb5b5c3dba68', +}) +``` + +### disableProviderPing + +`boolean | undefined` + +```ts-vue +import { walletConnect } from '{{connectorsPackageName}}' + +const connector = walletConnect({ + disableProviderPing: false, // [!code focus] + projectId: '3fcc6bba6f1de962d911bb5b5c3dba68', +}) +``` + +### isNewChainsStale + +`boolean | undefined` + +- If a new chain is added to a previously existing configured connector `chains`, this flag +will determine if that chain should be considered as stale. A stale chain is a chain that +WalletConnect has yet to establish a relationship with (e.g. the user has not approved or +rejected the chain). +- Defaults to `true`. + +```ts-vue +import { walletConnect } from '{{connectorsPackageName}}' + +const connector = walletConnect({ + isNewChainsStale: true, // [!code focus] + projectId: '3fcc6bba6f1de962d911bb5b5c3dba68', +}) +``` + +::: details More info +Preface: Whereas WalletConnect v1 supported dynamic chain switching, WalletConnect v2 requires +the user to pre-approve a set of chains up-front. This comes with consequent UX nuances (see below) when +a user tries to switch to a chain that they have not approved. + +This flag mainly affects the behavior when a wallet does not support dynamic chain authorization +with WalletConnect v2. + +If `true` (default), the new chain will be treated as a stale chain. If the user +has yet to establish a relationship (approved/rejected) with this chain in their WalletConnect +session, the connector will disconnect upon the dapp auto-connecting, and the user will have to +reconnect to the dapp (revalidate the chain) in order to approve the newly added chain. +This is the default behavior to avoid an unexpected error upon switching chains which may +be a confusing user experience (e.g. the user will not know they have to reconnect +unless the dapp handles these types of errors). + +If `false`, the new chain will be treated as a validated chain. This means that if the user +has yet to establish a relationship with the chain in their WalletConnect session, wagmi will successfully +auto-connect the user. This comes with the trade-off that the connector will throw an error +when attempting to switch to the unapproved chain. This may be useful in cases where a dapp constantly +modifies their configured chains, and they do not want to disconnect the user upon +auto-connecting. If the user decides to switch to the unapproved chain, it is important that the +dapp handles this error and prompts the user to reconnect to the dapp in order to approve +the newly added chain. +::: + +### metadata + +`CoreTypes.Metadata | undefined` + +Metadata related to the app requesting the connection. + +```ts-vue +import { walletConnect } from '{{connectorsPackageName}}' + +const connector = walletConnect({ + projectId: '3fcc6bba6f1de962d911bb5b5c3dba68', + metadata: { // [!code focus] + name: 'Example', // [!code focus] + description: 'Example website', // [!code focus] + url: 'https://example.com', // [!code focus] + }, // [!code focus] +}) +``` + +### projectId + +`string` + +WalletConnect Cloud project identifier. You can find your `projectId` on your [WalletConnect dashboard](https://cloud.reown.com/sign-in). + +```ts-vue +import { walletConnect } from '{{connectorsPackageName}}' + +const connector = walletConnect({ + projectId: '3fcc6bba6f1de962d911bb5b5c3dba68', // [!code focus] +}) +``` + +### qrModalOptions + +`QrModalOptions | undefined` + +Options for rendering QR modal. + +```ts-vue +import { walletConnect } from '{{connectorsPackageName}}' + +const connector = walletConnect({ + projectId: '3fcc6bba6f1de962d911bb5b5c3dba68', + qrModalOptions: { // [!code focus] + themeMode: 'dark', // [!code focus] + }, // [!code focus] +}) +``` + +### relayUrl + +`string | undefined` + +- WalletConnect relay URL to use. +- Defaults to `'wss://relay.walletconnect.com'`. + +```ts-vue +import { walletConnect } from '{{connectorsPackageName}}' + +const connector = walletConnect({ + projectId: '3fcc6bba6f1de962d911bb5b5c3dba68', + relayUrl: 'wss://relay.walletconnect.org', // [!code focus] +}) +``` + +### storageOptions + +`KeyValueStorageOptions | undefined` + +```ts-vue +import { walletConnect } from '{{connectorsPackageName}}' + +const connector = walletConnect({ + projectId: '3fcc6bba6f1de962d911bb5b5c3dba68', + storageOptions: {}, // [!code focus] +}) +``` + +### showQrModal + +`boolean | undefined` + +- Whether to show the QR code modal upon calling `connector.connect()`. +- Defaults to `true`. + +```ts-vue +import { walletConnect } from '{{connectorsPackageName}}' + +const connector = walletConnect({ + projectId: '3fcc6bba6f1de962d911bb5b5c3dba68', + showQrModal: true, // [!code focus] +}) +``` + +::: tip +This can be disabled and you can listen for a `'message'` event with payload `{ type: 'display_uri'; data: string }` if you want to render your own QR code. +::: diff --git a/wagmi-project/site/shared/create-chain.md b/wagmi-project/site/shared/create-chain.md new file mode 100644 index 000000000..da2a7194c --- /dev/null +++ b/wagmi-project/site/shared/create-chain.md @@ -0,0 +1,93 @@ +## Create Chain + +Import the `Chain` type from Viem and create a new object that is asserted `as const` and `satisfies` the type. You can also use the `defineChain` function from Viem. + +::: code-group +```ts twoslash [as const satisfies Chain] +// @errors: 1360 +import { type Chain } from 'viem' + +export const mainnet = {} as const satisfies Chain +``` +```ts twoslash [defineChain] +// @errors: 2345 +import { defineChain } from 'viem' + +export const mainnet = defineChain({}) +``` +::: + +Now, add the missing required properties to the object until the error goes away. + +::: code-group +```ts twoslash [as const satisfies Chain] +import { type Chain } from 'viem' + +export const mainnet = { + id: 1, + name: 'Ethereum', + nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 }, + rpcUrls: { + default: { http: ['https://eth.merkle.io'] }, + }, + blockExplorers: { + default: { name: 'Etherscan', url: 'https://etherscan.io' }, + }, + contracts: { + ensRegistry: { + address: '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e', + }, + ensUniversalResolver: { + address: '0xE4Acdd618deED4e6d2f03b9bf62dc6118FC9A4da', + blockCreated: 16773775, + }, + multicall3: { + address: '0xca11bde05977b3631167028862be2a173976ca11', + blockCreated: 14353601, + }, + }, +} as const satisfies Chain +``` +```ts twoslash [defineChain] +import { defineChain } from 'viem' + +export const mainnet = defineChain({ + id: 1, + name: 'Ethereum', + nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 }, + rpcUrls: { + default: { http: ['https://eth.merkle.io'] }, + }, + blockExplorers: { + default: { name: 'Etherscan', url: 'https://etherscan.io' }, + }, + contracts: { + ensRegistry: { + address: '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e', + }, + ensUniversalResolver: { + address: '0xE4Acdd618deED4e6d2f03b9bf62dc6118FC9A4da', + blockCreated: 16773775, + }, + multicall3: { + address: '0xca11bde05977b3631167028862be2a173976ca11', + blockCreated: 14353601, + }, + }, +}) +``` +::: + +The more properties you add, the better the chain will be to use with Wagmi. Most of these attributes exist within the [`ethereum-lists/chains` repository](https://github.com/ethereum-lists/chains/tree/3fbd4eeac7ce116579634bd042b84e2b1d89886a/_data/chains). + +- `id`: The chain ID for the network. This can be found by typing the network name into [ChainList](https://chainlist.org). Example: "Ethereum Mainnet" has a Chain ID of `1`. +- `name`: Human-readable name for the chain. Example: "Ethereum Mainnet" +- `nativeCurrency`: The native currency of the chain. Found from [`ethereum-lists/chains`](https://github.com/ethereum-lists/chains/blob/3fbd4eeac7ce116579634bd042b84e2b1d89886a/_data/chains/eip155-56.json#L20-L24). +- `rpcUrls`: At least one public, credible RPC URL. Found from [`ethereum-lists/chains`](https://github.com/ethereum-lists/chains/blob/3fbd4eeac7ce116579634bd042b84e2b1d89886a/_data/chains/eip155-56.json#L4-L18). +- `blockExplorers`: A set of block explorers for the chain. Found from [`ethereum-lists/chains`](https://github.com/ethereum-lists/chains/blob/3fbd4eeac7ce116579634bd042b84e2b1d89886a/_data/chains/eip155-56.json#L30-L36). +- `contracts`: A set of deployed contracts for the chain. If you are deploying one of the following contracts yourself, make sure it is verified. + - `multicall3` is optional, but it's address is most likely `0xca11bde05977b3631167028862be2a173976ca11` – you can find the deployed block number on the block explorer. Check out [`mds1/multicall`](https://github.com/mds1/multicall#multicall3-contract-addresses) for more info. + - `ensRegistry` is optional – not all Chains have a ENS Registry. See [ENS Deployments](https://docs.ens.domains/ens-deployments) for more info. + - `ensUniversalResolver` is optional – not all Chains have a ENS Universal Resolver. +- `sourceId`: Source Chain ID (e.g. the L1 chain). +- `testnet`: Whether or not the chain is a testnet. \ No newline at end of file diff --git a/wagmi-project/site/shared/createConfig.md b/wagmi-project/site/shared/createConfig.md new file mode 100644 index 000000000..bde260179 --- /dev/null +++ b/wagmi-project/site/shared/createConfig.md @@ -0,0 +1,485 @@ + + +# createConfig + +Creates new [`Config`](#config) object. + +## Import + +```ts-vue +import { createConfig } from '{{packageName}}' +``` + +## Usage + +```ts-vue +import { createConfig, http } from '{{packageName}}' +import { mainnet, sepolia } from '{{packageName}}/chains' + +const config = createConfig({ + chains: [mainnet, sepolia], + transports: { + [mainnet.id]: http('https://mainnet.example.com'), + [sepolia.id]: http('https://sepolia.example.com'), + }, +}) +``` + +::: tip Integrating a Viem Client + +Instead of using [`transports`](#transports), it's possible to provide a function that returns a Viem [`Client`](https://viem.sh/docs/clients/custom.html) via the [`client`](#client) property for more fine-grained control over Wagmi's internal `Client` creation. + +```ts-vue {3,7-9} +import { createConfig, http } from '{{packageName}}' +import { mainnet, sepolia } from '{{packageName}}/chains' +import { createClient } from 'viem' + +const config = createConfig({ + chains: [mainnet, sepolia], + client({ chain }) { + return createClient({ chain, transport: http() }) + }, +}) +``` +::: + +## Parameters + +```ts-vue +import { type CreateConfigParameters } from '{{packageName}}' +``` + +### chains + +`readonly [Chain, ...Chain[]]` + +- Chains used by the `Config`. +- See Chains for more details about built-in chains and the `Chain` type. + +```ts-vue +import { createConfig, http } from '{{packageName}}' +import { mainnet, sepolia } from '{{packageName}}/chains' + +const config = createConfig({ + chains: [mainnet, sepolia], // [!code focus] + transports: { + [mainnet.id]: http('https://mainnet.example.com'), + [sepolia.id]: http('https://sepolia.example.com'), + }, +}) +``` + +### connectors + +`CreateConnectorFn[] | undefined` + +Connectors used by the `Config`. + +```ts-vue +import { createConfig, http } from '{{packageName}}' +import { mainnet, sepolia } from '{{packageName}}/chains' +import { injected } from '{{connectorsPackageName}}' // [!code focus] + +const config = createConfig({ + chains: [mainnet, sepolia], + connectors: [injected()], // [!code focus] + transports: { + [mainnet.id]: http('https://mainnet.example.com'), + [sepolia.id]: http('https://sepolia.example.com'), + }, +}) +``` + +### multiInjectedProviderDiscovery + +`boolean | undefined` + +- Enables discovery of injected providers via [EIP-6963](https://eips.ethereum.org/EIPS/eip-6963) using the [`mipd`](https://github.com/wevm/mipd) library and converting to injected connectors. +- Defaults to `true`. + +```ts-vue +import { createConfig, http } from '{{packageName}}' +import { mainnet, sepolia } from '{{packageName}}/chains' + +const config = createConfig({ + chains: [mainnet, sepolia], + multiInjectedProviderDiscovery: false, // [!code focus] + transports: { + [mainnet.id]: http('https://mainnet.example.com'), + [sepolia.id]: http('https://sepolia.example.com'), + }, +}) +``` + +### ssr + +`boolean | undefined` + +Flag to indicate if the config is being used in a server-side rendering environment. Defaults to `false`. + +```ts-vue +import { createConfig, http } from '{{packageName}}' // [!code focus] +import { mainnet, sepolia } from '{{packageName}}/chains' + +const config = createConfig({ + chains: [mainnet, sepolia], + ssr: true, // [!code focus] + transports: { + [mainnet.id]: http('https://mainnet.example.com'), + [sepolia.id]: http('https://sepolia.example.com'), + }, +}) +``` + +### storage + +`Storage | null | undefined` + +- `Storage` used by the config. Persists `Config`'s [`State`](#state-1) between sessions. +- Defaults to `createStorage({ storage: typeof window !== 'undefined' && window.localStorage ? window.localStorage : noopStorage })`. + +```ts-vue +import { createConfig, createStorage, http } from '{{packageName}}' // [!code focus] +import { mainnet, sepolia } from '{{packageName}}/chains' + +const config = createConfig({ + chains: [mainnet, sepolia], + storage: createStorage({ storage: window.localStorage }), // [!code focus] + transports: { + [mainnet.id]: http('https://mainnet.example.com'), + [sepolia.id]: http('https://sepolia.example.com'), + }, +}) +``` + +### syncConnectedChain + +`boolean | undefined` + +- Keep the [`State['chainId']`](#chainid) in sync with the current connection. +- Defaults to `true`. + +```ts-vue +import { createConfig, http } from '{{packageName}}' +import { mainnet, sepolia } from '{{packageName}}/chains' + +const config = createConfig({ + chains: [mainnet, sepolia], + syncConnectedChain: false, // [!code focus] + transports: { + [mainnet.id]: http('https://mainnet.example.com'), + [sepolia.id]: http('https://sepolia.example.com'), + }, +}) +``` + +--- + +### batch + +`{ multicall?: boolean | { batchSize?: number | undefined; wait?: number | undefined } | undefined } | { [_ in chains[number]["id"]]?: { multicall?: boolean | { batchSize?: number | undefined; wait?: number | undefined } | undefined } | undefined } | undefined` + +- Batch settings. See [Viem docs](https://viem.sh/docs/clients/custom.html#batch-optional) for more info. +- Defaults to `{ multicall: true }`. + +```ts-vue +import { createConfig, http } from '{{packageName}}' +import { mainnet, sepolia } from '{{packageName}}/chains' + +const config = createConfig({ + chains: [mainnet, sepolia], + batch: { multicall: true }, // [!code focus] + transports: { + [mainnet.id]: http('https://mainnet.example.com'), + [sepolia.id]: http('https://sepolia.example.com'), + }, +}) +``` + +### cacheTime + +`number | { [_ in chains[number]['id']]?: number | undefined } | undefined` + +- Frequency in milliseconds for polling enabled features. See [Viem docs](https://viem.sh/docs/clients/public.html#cachetime-optional) for more info. +- Defaults to [`pollingInterval`](#pollinginterval) or `4_000`. + +```ts-vue +import { createConfig, http } from '{{packageName}}' +import { mainnet, sepolia } from '{{packageName}}/chains' + +const config = createConfig({ + chains: [mainnet, sepolia], + cacheTime: 4_000, // [!code focus] + transports: { + [mainnet.id]: http('https://mainnet.example.com'), + [sepolia.id]: http('https://sepolia.example.com'), + }, +}) +``` + +### pollingInterval + +`number | { [_ in chains[number]['id']]?: number | undefined } | undefined` + +- Frequency in milliseconds for polling enabled features. See [Viem docs](https://viem.sh/docs/clients/custom.html#pollinginterval-optional) for more info. +- Defaults to `4_000`. + +```ts-vue +import { createConfig, http } from '{{packageName}}' +import { mainnet, sepolia } from '{{packageName}}/chains' + +const config = createConfig({ + chains: [mainnet, sepolia], + pollingInterval: 4_000, // [!code focus] + transports: { + [mainnet.id]: http('https://mainnet.example.com'), + [sepolia.id]: http('https://sepolia.example.com'), + }, +}) +``` + +### transports + +`Record` + +Mapping of [chain IDs](#chains) to `Transport`s. This mapping is used internally when creating chain-aware Viem [`Client`](https://viem.sh/docs/clients/custom.html) objects. See the Transport docs for more info. + +```ts-vue +import { createConfig, fallback, http } from '{{packageName}}' // [!code focus] +import { mainnet, sepolia } from '{{packageName}}/chains' + +const config = createConfig({ + chains: [mainnet, sepolia], + transports: { // [!code focus] + [mainnet.id]: fallback([ // [!code focus] + http('https://...'), // [!code focus] + http('https://...'), // [!code focus] + ]), // [!code focus] + [sepolia.id]: http('https://...'), // [!code focus] + }, // [!code focus] +}) +``` + +--- + +### client + +`(parameters: { chain: chains[number] }) => Client` + +Function for creating new Viem [`Client`](https://viem.sh/docs/clients/custom.html) to be used internally. Exposes more control over the internal `Client` creation logic versus using the [`transports`](#transports) property. + +```ts-vue +import { createClient, http } from 'viem' // [!code focus] +import { createConfig } from '{{packageName}}' +import { mainnet, sepolia } from '{{packageName}}/chains' + +const config = createConfig({ + chains: [mainnet, sepolia], + client({ chain }) { // [!code focus] + return createClient({ chain, transport: http('https://...') }) // [!code focus] + }, // [!code focus] +}) +``` + +::: warning +When using this option, you likely want to pass `parameters.chain` straight through to [`createClient`](https://viem.sh/docs/clients/custom.html#createclient) to ensure the Viem `Client` is in sync with any active connections. +::: + +## Return Type + +```ts-vue +import { type Config } from '{{packageName}}' +``` + +## Config + +Object responsible for managing Wagmi state and internals. + +```ts-vue +import { type Config } from '{{packageName}}' +``` + +### chains + +`readonly [Chain, ...Chain[]]` + +[`chains`](#chains) passed to `createConfig`. + +### connectors + +`readonly Connector[]` + +Connectors set up from passing [`connectors`](#connectors) and [`multiInjectedProviderDiscovery`](#multiinjectedproviderdiscovery) to `createConfig`. + +### state + +`State` + +The `Config` object's internal state. See [`State`](#state-1) for more info. + +### storage + +`Storage | null` + +[`storage`](#storage) passed to `createConfig`. + +### getClient + +`(parameters?: { chainId?: chainId | chains[number]['id'] | undefined }): Client>` + +Creates new Viem [`Client`](https://viem.sh/docs/clients/custom.html) object. + +::: code-group +```ts-vue [index.ts] +import { config } from './config' + +const client = config.getClient({ chainId: 1 }) +``` + +```ts-vue [config.ts] +import { createConfig, http } from '{{packageName}}' +import { mainnet, sepolia } from '{{packageName}}/chains' + +export const config = createConfig({ + chains: [mainnet, sepolia], + transports: { + [mainnet.id]: http('https://mainnet.example.com'), + [sepolia.id]: http('https://sepolia.example.com'), + }, +}) +``` + +::: + +### setState + +`(value: State | ((state: State) => State)) => void` + +Updates the `Config` object's internal state. See [`State`](#state-1) for more info. + +::: code-group +```ts-vue [index.ts] +import { mainnet } from '{{packageName}}/chains' +import { config } from './config' + +config.setState((x) => ({ + ...x, + chainId: x.current ? x.chainId : mainnet.id, +})) +``` + +```ts-vue [config.ts] +import { createConfig, http } from '{{packageName}}' +import { mainnet, sepolia } from '{{packageName}}/chains' + +export const config = createConfig({ + chains: [mainnet, sepolia], + transports: { + [mainnet.id]: http('https://mainnet.example.com'), + [sepolia.id]: http('https://sepolia.example.com'), + }, +}) +``` + +::: + +::: warning +Exercise caution when using this method. It is intended for internal and advanced use-cases only. Manually setting state can cause unexpected behavior. +::: + +### subscribe + +`(selector: (state: State) => state, listener: (selectedState: state, previousSelectedState: state) => void, options?: { emitImmediately?: boolean | undefined; equalityFn?: ((a: state, b: state) => boolean) | undefined } | undefined) => (() => void)` + +Listens for state changes matching the `selector` function. Returns a function that can be called to unsubscribe the listener. + +::: code-group +```ts-vue [index.ts] +import { config } from './config' + +const unsubscribe = config.subscribe( + (state) => state.chainId, + (chainId) => console.log(`Chain ID changed to ${chainId}`), +) +unsubscribe() +``` + +```ts-vue [config.ts] +import { createConfig, http } from '{{packageName}}' +import { mainnet, sepolia } from '{{packageName}}/chains' + +export const config = createConfig({ + chains: [mainnet, sepolia], + transports: { + [mainnet.id]: http('https://mainnet.example.com'), + [sepolia.id]: http('https://sepolia.example.com'), + }, +}) +``` + +::: + +## State + +```ts-vue +import { type State } from '{{packageName}}' +``` + +### chainId + +`chains[number]['id']` + +Current chain ID. When `syncConnectedChain` is `true`, `chainId` is kept in sync with the current connection. Defaults to first chain in [`chains`](#chains). + +### connections + +`Map` + +Mapping of unique connector identifier to [`Connection`](#connection) object. + +### current + +`string | undefined` + +Unique identifier of the current connection. + +### status + +`'connected' | 'connecting' | 'disconnected' | 'reconnecting'` + +Current connection status. + +- `'connecting'` attempting to establish connection. +- `'reconnecting'` attempting to re-establish connection to one or more connectors. +- `'connected'` at least one connector is connected. +- `'disconnected'` no connection to any connector. + +## Connection + +```ts-vue +import { type Connection } from '{{packageName}}' +``` + +### accounts + +`readonly [Address, ...Address[]]` + +Array of addresses associated with the connection. + +### chainId + +`number` + +Chain ID associated with the connection. + +### connector + +`Connector` + +Connector associated with the connection. diff --git a/wagmi-project/site/shared/createStorage.md b/wagmi-project/site/shared/createStorage.md new file mode 100644 index 000000000..fe758569d --- /dev/null +++ b/wagmi-project/site/shared/createStorage.md @@ -0,0 +1,161 @@ + + +# createStorage + +Creates new [`Storage`](#storage) object. + +## Import + +```ts-vue +import { createStorage } from '{{packageName}}' +``` + +## Usage + +```ts-vue +import { createStorage } from '{{packageName}}' + +const storage = createStorage({ storage: localStorage }) +``` + +## Parameters + +```ts-vue +import { type CreateStorageParameters } from '{{packageName}}' +``` + +### deserialize + +`((value: string) => T) | undefined` + +- Function to deserialize data from storage. +- Defaults to `deserialize`. + +```ts-vue +import { createStorage, deserialize } from '{{packageName}}' // [!code focus] + +const storage = createStorage({ + deserialize, // [!code focus] + storage: localStorage, +}) +``` + +::: warning +If you use a custom `deserialize` function, make sure it can handle `bigint` and `Map` values. +::: + +### key + +`string | undefined` + +- Key prefix to use when persisting data. +- Defaults to `'wagmi'`. + +```ts-vue +import { createStorage } from '{{packageName}}' + +const storage = createStorage({ + key: 'my-app', // [!code focus] + storage: localStorage, +}) +``` + +### serialize + +`((value: T) => string) | undefined` + +- Function to serialize data for storage. +- Defaults to `serialize`. + +```ts-vue +import { createStorage, serialize } from '{{packageName}}' // [!code focus] + +const storage = createStorage({ + serialize, // [!code focus] + storage: localStorage, +}) +``` + +::: warning +If you use a custom `serialize` function, make sure it can handle `bigint` and `Map` values. +::: + +### storage + +`{ getItem(key: string): string | null | undefined | Promise; setItem(key: string, value: string): void | Promise; removeItem(key: string): void | Promise; }` + +- Storage interface to use for persisting data. +- Defaults to `localStorage`. +- Supports synchronous and asynchronous storage methods. + +```ts-vue +import { createStorage } from '{{packageName}}' +// Using IndexedDB via https://github.com/jakearchibald/idb-keyval // [!code focus] +import { del, get, set } from 'idb-keyval' // [!code focus] + +const storage = createStorage({ + storage: { // [!code focus] + async getItem(name) { // [!code focus] + return get(name)// [!code focus] + }, // [!code focus] + async setItem(name, value) { // [!code focus] + await set(name, value) // [!code focus] + }, // [!code focus] + async removeItem(name) { // [!code focus] + await del(name) // [!code focus] + }, // [!code focus] + }, // [!code focus] +}) +``` + +## Return Type + +```ts-vue +import { type Storage } from '{{packageName}}' +``` + +## Storage + +Object responsible for persisting Wagmi `State` and other data. + +```ts-vue +import { type Storage } from '{{packageName}}' +``` + +### getItem + +`getItem(key: string, defaultValue?: value | null | undefined): value | null | Promise` + +```ts-vue +import { createStorage } from '{{packageName}}' + +const storage = createStorage({ storage: localStorage }) +const recentConnectorId = storage.getItem('recentConnectorId') // [!code focus] +``` + +### setItem + +`setItem(key: string, value: any): void | Promise` + +```ts-vue +import { createStorage } from '{{packageName}}' + +const storage = createStorage({ storage: localStorage }) +storage.setItem('recentConnectorId', 'foo') // [!code focus] +``` + +### removeItem + +`removeItem(key: string): void | Promise` + +```ts-vue +import { createStorage } from '{{packageName}}' + +const storage = createStorage({ storage: localStorage }) +storage.removeItem('recentConnectorId') // [!code focus] +``` \ No newline at end of file diff --git a/wagmi-project/site/shared/errors.md b/wagmi-project/site/shared/errors.md new file mode 100644 index 000000000..c518172fc --- /dev/null +++ b/wagmi-project/site/shared/errors.md @@ -0,0 +1,90 @@ + + +## BaseError + +Error class extended by all errors. + +```ts-vue +import { BaseError } from '{{packageName}}' +``` + +## Config + +### ConnectorAccountNotFoundError + +When an account does not exist on the connector or is unable to be used. + +```ts-vue +import { ConnectorAccountNotFoundError } from '{{packageName}}' +``` + +### ConnectorAlreadyConnectedError + +When a connector is already connected. + +```ts-vue +import { ConnectorAlreadyConnectedError } from '{{packageName}}' +``` + +### ConnectorChainMismatchError + +When the Wagmi Config is out-of-sync with the connector's active chain ID. This is rare and likely an upstream wallet issue. + +```ts-vue +import { ConnectorChainMismatchError } from '{{packageName}}' +``` + +### ChainNotConfiguredError + +When a chain is not configured. You likely need to add the chain to `Config['chains']`. + +```ts-vue +import { ChainNotConfiguredError } from '{{packageName}}' +``` + +### ConnectorNotConnectedError + +When a connector is not connected. + +```ts-vue +import { ConnectorNotConnectedError } from '{{packageName}}' +``` + +### ConnectorNotFoundError + +When a connector is not found or able to be used. + +```ts-vue +import { ConnectorNotFoundError } from '{{packageName}}' +``` + +### ConnectorUnavailableReconnectingError + +During the reconnection step, the only connector methods guaranteed to be available are: `id`, `name`, `type`, `uuid`. All other methods are not guaranteed to be available until reconnection completes and connectors are fully restored. This error commonly occurs for connectors that asynchronously inject after reconnection has already started. + +```ts-vue +import { ConnectorUnavailableReconnectingError } from '{{packageName}}' +``` + +## Connector + +### ProviderNotFoundError + +When a connector's provider is not found or able to be used. + +```ts-vue +import { ProviderNotFoundError } from '{{packageName}}' +``` + +### SwitchChainNotSupportedError + +When switching chains is not supported by connectors. + +```ts-vue +import { SwitchChainNotSupportedError } from '{{packageName}}' +``` diff --git a/wagmi-project/site/shared/faq.md b/wagmi-project/site/shared/faq.md new file mode 100644 index 000000000..03e17693e --- /dev/null +++ b/wagmi-project/site/shared/faq.md @@ -0,0 +1,81 @@ + + +## Type inference doesn't work + +- Check that you set up TypeScript correctly with `"strict": true` in your `tsconfig.json` (TypeScript docs) +- Check that you const-asserted any ABIs or Typed Data you are using. +- Restart your language server or IDE, and check for type errors in your code. + +## My wallet doesn't work + +If you run into issues with a specific wallet, try another before opening up an issue. There are many different wallets and it's likely that the issue is with the wallet itself, not Wagmi. For example, if you are using Wallet X and sending a transaction doesn't work, try Wallet Y and see if it works. + +## `BigInt` Serialization + +Using native `BigInt` with `JSON.stringify` will raise a `TypeError` as +[`BigInt` values are not serializable](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt#use_within_json). There are two techniques to mitigate this: + +#### Lossless serialization + +Lossless serialization means that `BigInt` will be converted to a format that can be deserialized later (e.g. `69420n` → `"#bigint.69420"`). The trade-off is that these values are not human-readable and are not intended to be displayed to the user. + +Lossless serialization can be achieved with wagmi's `serialize` and `deserialize` utilities. + +```tsx +import { serialize, deserialize } from 'wagmi' + +const serialized = serialize({ value: 69420n }) +// '{"value":"#bigint.69420"}' + +const deserialized = deserialize(serialized) +// { value: 69420n } +``` + +#### Lossy serialization + +Lossy serialization means that the `BigInt` will be converted to a normal display string (e.g. `69420n` → `'69420'`). +The trade-off is that you will not be able to deserialize the `BigInt` with `JSON.parse` as it can not distinguish between a normal string and a `BigInt`. + +This method can be achieved by modifying `JSON.stringify` to include a BigInt `replacer`: + +```tsx +const replacer = (key, value) => + typeof value === 'bigint' ? value.toString() : value + +JSON.stringify({ value: 69420n }, replacer) +// '{"value":"69420"}' +``` + +## How do I support the project? + +Wagmi is an open source software project and free to use. If you enjoy using Wagmi or would like to support Wagmi development, you can: + +- [Become a sponsor on GitHub](https://github.com/sponsors/wevm) +- Send us crypto + - Mainnet: 0x4557B18E779944BFE9d78A672452331C186a9f48 + - Multichain: 0xd2135CfB216b74109775236E36d4b433F1DF507B +- [Become a supporter on Drips](https://www.drips.network/app/projects/github/wevm/wagmi) + +If you use Wagmi at work, consider asking your company to sponsor Wagmi. This may not be easy, but **business sponsorships typically make a much larger impact on the sustainability of OSS projects** than individual donations, so you will help us much more if you succeed. + +## Is Wagmi production ready? + +Yes. Wagmi is very stable and is used in production by thousands of organizations, like [Stripe](https://stripe.com), [Shopify](https://shopify.com), [Coinbase](https://coinbase.com), [Uniswap](https://uniswap.org), [ENS](https://ens.domains), [Optimism](https://optimism.com). + +## Is Wagmi strict with semver? + +Yes, Wagmi is very strict with [semantic versioning](https://semver.org) and we will never introduce breaking changes to the runtime API in a minor version bump. + +For exported types, we try our best to not introduce breaking changes in non-major versions, however, [TypeScript doesn't follow semver](https://www.learningtypescript.com/articles/why-typescript-doesnt-follow-strict-semantic-versioning) and often introduces breaking changes in minor releases that can cause Wagmi type issues. See the TypeScript docs for more information. + +## How can I contribute to Wagmi? + +The Wagmi team accepts all sorts of contributions. Check out the [Contributing](/dev/contributing) guide to get started. If you are interested in adding a new connector to Wagmi, check out the [Creating Connectors](/dev/creating-connectors) guide. + +## Anything else you want to know? + +Please create a new [GitHub Discussion thread](https://github.com/wevm/wagmi). You're also free to suggest changes to this or any other page on the site using the "Suggest changes to this page" button at the bottom of the page. diff --git a/wagmi-project/site/shared/getAccount-return-type.md b/wagmi-project/site/shared/getAccount-return-type.md new file mode 100644 index 000000000..315728261 --- /dev/null +++ b/wagmi-project/site/shared/getAccount-return-type.md @@ -0,0 +1,107 @@ + + +### address + +`Address | undefined` + +- Connected address from connector. +- Defaults to first address in [`addresses`](#addresses). + +### addresses + +`readonly Address[] | undefined` + +Connected addresses from connector. + +### chain + +`Chain | undefined` + +Connected chain from connector. If chain is not configured by config, it will be `undefined`. + +### chainId + +`number | undefined` + +Connected chain id from connector. + +### connector + +`Connector | undefined` + +Connected connector. + +### isConnecting / isReconnecting / isConnected / isDisconnected + +`boolean` + +Boolean variables derived from [`status`](#status). + +### status + +`'connecting' | 'reconnecting' | 'connected' | 'disconnected'` + +- `'connecting'` attempting to establish connection. +- `'reconnecting'` attempting to re-establish connection to one or more connectors. +- `'connected'` at least one connector is connected. +- `'disconnected'` no connection to any connector. + +::: info You can use `status` to narrow the return type. +For example, when `status` is `'connected'` properties like `address` are guaranteed to be defined. + +```ts twoslash +import { type GetAccountReturnType } from '@wagmi/core' +const account = {} as GetAccountReturnType +// ---cut--- +if (account.status === 'connected') { + account + // ^? + + + + + + + + + + + + + + + +} +``` + +Or when status is `'disconnected'` properties like `address` are guaranteed to be `undefined`: + +```ts twoslash +import { type GetAccountReturnType } from '@wagmi/core' +const account = {} as GetAccountReturnType +// ---cut--- +if (account.status === 'disconnected') { + account + // ^? + + + + + + + + + + + + + + + +} +``` +::: diff --git a/wagmi-project/site/shared/installation.md b/wagmi-project/site/shared/installation.md new file mode 100644 index 000000000..c96c14def --- /dev/null +++ b/wagmi-project/site/shared/installation.md @@ -0,0 +1,62 @@ + + +## Requirements + +Wagmi is optimized for modern browsers. It is compatible with the latest versions of the following browsers. + + + +::: tip +Depending on your environment, you might need to add polyfills. See [Viem Platform Compatibility](https://viem.sh/docs/compatibility.html) for more info. +::: + +## Using Unreleased Commits + +If you can't wait for a new release to test the latest features, you can either install from the `canary` tag (tracks the [`main`](https://github.com/wevm/wagmi/tree/main) branch). + +::: code-group +```bash-vue [pnpm] +pnpm add {{packageName}}@canary +``` + +```bash-vue [npm] +npm install {{packageName}}@canary +``` + +```bash-vue [yarn] +yarn add {{packageName}}@canary +``` + +```bash-vue [bun] +bun add {{packageName}}@canary +``` +::: + +Or clone the [Wagmi repo](https://github.com/wevm/wagmi) to your local machine, build, and link it yourself. + +```bash-vue +gh repo clone wevm/wagmi +cd wagmi +pnpm install +pnpm build +cd packages/{{packageDir}} +pnpm link --global +``` + +Then go to the project where you are using Wagmi and run `pnpm link --global {{packageName}}` (or the package manager that you used to link Wagmi globally). Make sure you installed any [required peer dependencies](#package-manager) and their versions are correct. + +## Security + +Ethereum-related projects are often targeted in attacks to steal users' assets. Make sure you follow security best-practices for your project. Some quick things to get started. + +- Pin package versions, upgrade mindfully, and inspect lockfile changes to minimize the risk of [supply-chain attacks](https://nodejs.org/en/guides/security/#supply-chain-attacks). +- Install the [Socket Security](https://socket.dev) [GitHub App](https://github.com/apps/socket-security) to help detect and block supply-chain attacks. +- Add a [Content Security Policy](https://cheatsheetseries.owasp.org/cheatsheets/Content_Security_Policy_Cheat_Sheet.html) to defend against external scripts running in your app. +- Pin [GitHub Action](https://x.com/paulmillr/status/1900948425325031448) versions to commits instead of tags. diff --git a/wagmi-project/site/shared/mutation-imports.md b/wagmi-project/site/shared/mutation-imports.md new file mode 100644 index 000000000..b538dcfab --- /dev/null +++ b/wagmi-project/site/shared/mutation-imports.md @@ -0,0 +1,19 @@ + + +## TanStack Query + +```ts-vue +import { + type {{typeName}}Data, + type {{typeName}}Variables, + type {{typeName}}Mutate, + type {{typeName}}MutateAsync, + {{actionName}}MutationOptions, +} from '{{packageName}}/query' +``` \ No newline at end of file diff --git a/wagmi-project/site/shared/mutation-options.md b/wagmi-project/site/shared/mutation-options.md new file mode 100644 index 000000000..b1eae4525 --- /dev/null +++ b/wagmi-project/site/shared/mutation-options.md @@ -0,0 +1,89 @@ + + +
+ +--- + +### mutation + +TanStack Query parameters. See the [TanStack Query mutation docs](https://tanstack.com/query/v5/docs/react/reference/useMutation) for more info. + +::: info Wagmi does not support passing all TanStack Query parameters +TanStack Query parameters, like `mutationFn` and `mutationKey`, are used internally to make Wagmi work and you cannot override them. Check out the [source](https://github.com/wevm/wagmi/blob/main/packages/react/src/utils/query.ts#L30) to see what parameters are not supported. All parameters listed below are supported. +::: + +#### gcTime + +`number | Infinity | undefined` + +- The time in milliseconds that unused/inactive cache data remains in memory. When a mutation's cache becomes unused or inactive, that cache data will be garbage collected after this duration. When different cache times are specified, the longest one will be used. +- If set to `Infinity`, will disable garbage collection + +#### meta + +`Record | undefined` + +If set, stores additional information on the mutation cache entry that can be used as needed. It will be accessible wherever [`{{mutate}}`](#mutate) is available (e.g. [`onError`](#onerror), [`onSuccess`](#onsuccess) functions). + +#### networkMode + +`'online' | 'always' | 'offlineFirst' | undefined` + +- defaults to `'online'` +- see [Network Mode](https://tanstack.com/query/v5/docs/react/guides/network-mode) for more information. + +#### onError + +`((error: {{TError}}, variables: {{TVariables}}, context?: context | undefined) => Promise | unknown) | undefined` + +This function will fire if the mutation encounters an error and will be passed the error. + +#### onMutate + +`((variables: {{TVariables}}) => Promise | context | void) | undefined` + +- This function will fire before the mutation function is fired and is passed the same variables the mutation function would receive +- Useful to perform optimistic updates to a resource in hopes that the mutation succeeds +- The value returned from this function will be passed to both the `onError` and `onSettled` functions in the event of a mutation failure and can be useful for rolling back optimistic updates. + +#### onSuccess + +`((data: {{TData}}, variables: {{TVariables}}, context?: context | undefined) => Promise | unknown) | undefined` + +This function will fire when the mutation is successful and will be passed the mutation's result. + +#### onSettled + +`((data: {{TData}}, error: {{TError}}, variables: {{TVariables}}, context?: context | undefined) => Promise | unknown) | undefined` + +This function will fire when the mutation is either successfully fetched or encounters an error and be passed either the data or error + +#### queryClient + +`QueryClient` + +Use this to use a custom `QueryClient`. Otherwise, the one from the nearest context will be used. + +#### retry + +`boolean | number | ((failureCount: number, error: {{TError}}) => boolean) | undefined` + +- Defaults to `0`. +- If `false`, failed mutations will not retry. +- If `true`, failed mutations will retry infinitely. +- If set to an `number`, e.g. `3`, failed mutations will retry until the failed mutations count meets that number. + +#### retryDelay + +`number | ((retryAttempt: number, error: {{TError}}) => number) | undefined` + +- This function receives a `retryAttempt` integer and the actual Error and returns the delay to apply before the next attempt in milliseconds. +- A function like `attempt => Math.min(attempt > 1 ? 2 ** attempt * 1000 : 1000, 30 * 1000)` applies exponential backoff. +- A function like `attempt => attempt * 1000` applies linear backoff. diff --git a/wagmi-project/site/shared/mutation-result.md b/wagmi-project/site/shared/mutation-result.md new file mode 100644 index 000000000..3dfaa2d70 --- /dev/null +++ b/wagmi-project/site/shared/mutation-result.md @@ -0,0 +1,122 @@ + + +
+ +--- + +[TanStack Query mutation docs](https://tanstack.com/query/v5/docs/react/reference/useMutation) + +### {{mutate}} + +`(variables: {{TVariables}}, { onSuccess, onSettled, onError }) => void` + +The mutation function you can call with variables to trigger the mutation and optionally hooks on additional callback options. + +- #### variables + + `{{TVariables}}` + + The variables object to pass to the `{{mutate}}` action. + +- #### onSuccess + + `(data: {{TData}}, variables: {{TVariables}}, context: TContext) => void` + + This function will fire when the mutation is successful and will be passed the mutation's result. + +- #### onError + + `(error: {{TError}}, variables: {{TVariables}}, context: TContext | undefined) => void` + + This function will fire if the mutation encounters an error and will be passed the error. + +- #### onSettled + + `(data: {{TData}} | undefined, error: {{TError}} | null, variables: {{TVariables}}, context: TContext | undefined) => void` + + - This function will fire when the mutation is either successfully fetched or encounters an error and be passed either the data or error + - If you make multiple requests, `onSuccess` will fire only after the latest call you've made. + +### {{mutate}}Async + +`(variables: {{TVariables}}, { onSuccess, onSettled, onError }) => Promise<{{TData}}>` + +Similar to [`{{mutate}}`](#mutate) but returns a promise which can be awaited. + +### data + +`{{TData}} | undefined` + +- `{{mutate}}` return type +- Defaults to `undefined` +- The last successfully resolved data for the mutation. + +### error + +`{{TError}} | null` + +The error object for the mutation, if an error was encountered. + +### failureCount + +`number` + +- The failure count for the mutation. +- Incremented every time the mutation fails. +- Reset to `0` when the mutation succeeds. + +### failureReason + +`{{TError}} | null` + +- The failure reason for the mutation retry. +- Reset to `null` when the mutation succeeds. + +### isError / isIdle / isPending / isSuccess + +`boolean` + +Boolean variables derived from [`status`](#status). + +### isPaused + +`boolean` + +- will be `true` if the mutation has been `paused`. +- see [Network Mode](https://tanstack.com/query/v5/docs/react/guides/network-mode) for more information. + +### reset + +`() => void` + +A function to clean the mutation internal state (e.g. it resets the mutation to its initial state). + +### status + +`'idle' | 'pending' | 'error' | 'success'` + +- `'idle'` initial status prior to the mutation function executing. +- `'pending'` if the mutation is currently executing. +- `'error'` if the last mutation attempt resulted in an error. +- `'success'` if the last mutation attempt was successful. + +### submittedAt + +`number` + +- The timestamp for when the mutation was submitted. +- Defaults to `0`. + +### variables + +`{{TVariables}} | undefined` + +- The variables object passed to [`{{mutate}}`](#mutate). +- Defaults to `undefined`. diff --git a/wagmi-project/site/shared/query-imports.md b/wagmi-project/site/shared/query-imports.md new file mode 100644 index 000000000..20eed55a0 --- /dev/null +++ b/wagmi-project/site/shared/query-imports.md @@ -0,0 +1,20 @@ + + +## TanStack Query + +```ts-vue +import { + type {{typeName}}Data, + type {{typeName}}Options, + type {{typeName}}QueryFnData, + type {{typeName}}QueryKey, + {{actionName}}QueryKey, + {{actionName}}QueryOptions, +} from '{{packageName}}/query' +``` \ No newline at end of file diff --git a/wagmi-project/site/shared/query-options.md b/wagmi-project/site/shared/query-options.md new file mode 100644 index 000000000..ac6f3f51f --- /dev/null +++ b/wagmi-project/site/shared/query-options.md @@ -0,0 +1,208 @@ + + +
+ +--- + +### query + +TanStack Query parameters. See the [TanStack Query query docs](https://tanstack.com/query/v5/docs/react/reference/useQuery) for more info. + +::: info Wagmi does not support passing all TanStack Query parameters +TanStack Query parameters, like `queryFn` and `queryKey`, are used internally to make Wagmi work and you cannot override them. Check out the [source](https://github.com/wevm/wagmi/blob/main/packages/react/src/types/properties.ts#L27) to see what parameters are not supported. All parameters listed below are supported. +::: + +#### enabled + +`boolean | undefined` + +- Set this to `false` to disable this query from automatically running. +- Can be used for [Dependent Queries](https://tanstack.com/query/v5/docs/react/guides/dependent-queries). + +
+ +#### gcTime + +`number | Infinity | undefined` + +- Defaults to `5 * 60 * 1000` (5 minutes) or `Infinity` during SSR +- The time in milliseconds that unused/inactive cache data remains in memory. When a query's cache becomes unused or inactive, that cache data will be garbage collected after this duration. When different garbage collection times are specified, the longest one will be used. +- If set to `Infinity`, will disable garbage collection + +
+ +#### initialData + +`{{TData}} | (() => {{TData}}) | undefined` + +- If set, this value will be used as the initial data for the query cache (as long as the query hasn't been created or cached yet) +- If set to a function, the function will be called **once** during the shared/root query initialization, and be expected to synchronously return the initialData +- Initial data is considered stale by default unless a `staleTime` has been set. +- `initialData` **is persisted** to the cache + +#### initialDataUpdatedAt + +`number | ((() => number | undefined)) | undefined` + +If set, this value will be used as the time (in milliseconds) of when the `initialData` itself was last updated. + +
+ +#### initialPageParam + +`{{TPageParam}}` + +The initial page parameter to be passed to the query function. + +#### getPreviousPageParam + +This function can be set to automatically get the previous cursor for infinite queries. +The result will also be used to determine the value of `hasPreviousPage`. + +`(firstPage: {{TData}}, allPages: {{TData}}[], firstPageParam: {{TPageParam}}, allPageParams: {{TPageParam}}[]) => {{TPageParam}} | undefined | null` + +#### getNextPageParam + +This function can be set to automatically get the previous cursor for infinite queries. +The result will also be used to determine the value of `hasPreviousPage`. + +`(lastPage: {{TData}}, allPages: {{TData}}[], lastPageParam: {{TPageParam}}, allPageParams: {{TPageParam}}[]) => {{TPageParam}} | undefined | null` + +
+ +#### meta + +`Record | undefined` + +If set, stores additional information on the query cache entry that can be used as needed. It will be accessible wherever the `query` is available, and is also part of the `QueryFunctionContext` provided to the `queryFn`. + +#### networkMode + +`online' | 'always' | 'offlineFirst' | undefined` + +- Defaults to `'online'` +- see [Network Mode](https://tanstack.com/query/v5/docs/react/guides/network-mode) for more information. + +#### notifyOnChangeProps + +`string[] | 'all' | (() => string[] | 'all') | undefined` + +- If set, the component will only re-render if any of the listed properties change. +- If set to `['data', 'error']` for example, the component will only re-render when the `data` or `error` properties change. +- If set to `'all'`, the component will opt-out of smart tracking and re-render whenever a query is updated. +- If set to a function, the function will be executed to compute the list of properties. +- By default, access to properties will be tracked, and the component will only re-render when one of the tracked properties change. + +#### placeholderData + +`{{TData}} | ((previousValue: {{TData}} | undefined; previousQuery: Query | undefined) => {{TData}}) | undefined` + +- If set, this value will be used as the placeholder data for this particular query observer while the query is still in the `pending` state. +- `placeholderData` is **not persisted** to the cache +- If you provide a function for `placeholderData`, as a first argument you will receive previously watched query data if available, and the second argument will be the complete previousQuery instance. + +#### queryClient + +`QueryClient | undefined` + +Use this to use a custom `QueryClient`. Otherwise, the one from the nearest context will be used. + +#### refetchInterval + +`number | false | ((data: {{TData}} | undefined, query: Query) => number | false | undefined) | undefined` + +- If set to a number, all queries will continuously refetch at this frequency in milliseconds +- If set to a function, the function will be executed with the latest data and query to compute a frequency + +#### refetchIntervalInBackground + +`boolean | undefined` + +If set to `true`, queries that are set to continuously refetch with a `refetchInterval` will continue to refetch while their tab/window is in the background + +#### refetchOnMount + +`boolean | 'always' | ((query: Query) => boolean | 'always') | undefined` + +- Defaults to `true` +- If set to `true`, the query will refetch on mount if the data is stale. +- If set to `false`, the query will not refetch on mount. +- If set to `'always'`, the query will always refetch on mount. +- If set to a function, the function will be executed with the query to compute the value + +#### refetchOnReconnect + +`boolean | 'always' | ((query: Query) => boolean | 'always') | undefined` + +- Defaults to `true` +- If set to `true`, the query will refetch on reconnect if the data is stale. +- If set to `false`, the query will not refetch on reconnect. +- If set to `'always'`, the query will always refetch on reconnect. +- If set to a function, the function will be executed with the query to compute the value + +#### refetchOnWindowFocus + +`boolean | 'always' | ((query: Query) => boolean | 'always') | undefined` + +- Defaults to `true` +- If set to `true`, the query will refetch on window focus if the data is stale. +- If set to `false`, the query will not refetch on window focus. +- If set to `'always'`, the query will always refetch on window focus. +- If set to a function, the function will be executed with the query to compute the value + +#### retry + +`boolean | number | ((failureCount: number, error: {{TError}}) => boolean) | undefined` + +- If `false`, failed queries will not retry by default. +- If `true`, failed queries will retry infinitely. +- If set to a `number`, e.g. `3`, failed queries will retry until the failed query count meets that number. +- Defaults to `3` on the client and `0` on the server + +#### retryDelay + +`number | ((retryAttempt: number, error: {{TError}}) => number) | undefined` + +- This function receives a `retryAttempt` integer and the actual Error and returns the delay to apply before the next attempt in milliseconds. +- A function like `attempt => Math.min(attempt > 1 ? 2 ** attempt * 1000 : 1000, 30 * 1000)` applies exponential backoff. +- A function like `attempt => attempt * 1000` applies linear backoff. + +#### retryOnMount + +`boolean | undefined` + +If set to `false`, the query will not be retried on mount if it contains an error. Defaults to `true`. + +#### select + +`((data: {{TData}}) => unknown) | undefined` + +This option can be used to transform or select a part of the data returned by the query function. It affects the returned `data` value, but does not affect what gets stored in the query cache. + +
+ +#### staleTime + +`number | Infinity | undefined` + +- Defaults to `0` +- The time in milliseconds after data is considered stale. This value only applies to the hook it is defined on. +- If set to `Infinity`, the data will never be considered stale + +
+ +#### structuralSharing + +`boolean | (((oldData: {{TData}} | undefined, newData: {{TData}}) => {{TData}})) | undefined` + +- Defaults to `true` +- If set to `false`, structural sharing between query results will be disabled. +- If set to a function, the old and new data values will be passed through this function, which should combine them into resolved data for the query. This way, you can retain references from the old data to improve performance even when that data contains non-serializable values. diff --git a/wagmi-project/site/shared/query-result.md b/wagmi-project/site/shared/query-result.md new file mode 100644 index 000000000..34e4b8e73 --- /dev/null +++ b/wagmi-project/site/shared/query-result.md @@ -0,0 +1,193 @@ + + +
+ +--- + +[TanStack Query query docs](https://tanstack.com/query/v5/docs/react/reference/useQuery) + +### data + +`{{TData}}` + +- The last successfully resolved data for the query. +- Defaults to `undefined`. + +### dataUpdatedAt + +`number` + +The timestamp for when the query most recently returned the `status` as `'success'`. + +### error + +`null | {{TError}}` + +- The error object for the query, if an error was thrown. +- Defaults to `null` + +### errorUpdatedAt + +`number` + +The timestamp for when the query most recently returned the `status` as `'error'`. + +### errorUpdateCount + +`number` + +The sum of all errors. + +### failureCount + +`number` + +- The failure count for the query. +- Incremented every time the query fails. +- Reset to `0` when the query succeeds. + +### failureReason + +`null | {{TError}}` + +- The failure reason for the query retry. +- Reset to `null` when the query succeeds. + +
+ +### fetchNextPage + +`(options?: FetchNextPageOptions) => Promise>` + +This function allows you to fetch the next "page" of results. + +### fetchPreviousPage + +`(options?: FetchPreviousPageOptions) => Promise>` + +This function allows you to fetch the previous "page" of results. + +### hasNextPage + +`boolean` + +This will be `true` if there is a next page to be fetched (known via the `getNextPageParam` option). + +### hasPreviousPage + +`boolean` + +This will be `true` if there is a previous page to be fetched (known via the `getPreviousPageParam` option). + +### isFetchingNextPage + +`boolean` + +Will be `true` while fetching the next page with `fetchNextPage`. + +### isFetchingPreviousPage + +`boolean` + +Will be `true` while fetching the previous page with `fetchPreviousPage`. + +
+ +### fetchStatus + +`'fetching' | 'idle' | 'paused'` + +- `fetching` Is `true` whenever the queryFn is executing, which includes initial `pending` as well as background refetches. +- `paused` The query wanted to fetch, but has been `paused`. +- `idle` The query is not fetching. +- See [Network Mode](https://tanstack.com/query/v5/docs/react/guides/network-mode) for more information. + +### isError / isPending / isSuccess + +`boolean` + +Boolean variables derived from [`status`](#status). + +### isFetched + +`boolean` + +Will be `true` if the query has been fetched. + +### isFetchedAfterMount + +`boolean` + +- Will be `true` if the query has been fetched after the component mounted. +- This property can be used to not show any previously cached data. + +### isFetching / isPaused + +`boolean` + +Boolean variables derived from [`fetchStatus`](#fetchstatus). + +### isLoading + +`boolean` + +- Is `true` whenever the first fetch for a query is in-flight +- Is the same as `isFetching && isPending` + +### isLoadingError + +`boolean` + +Will be `true` if the query failed while fetching for the first time. + +### isPlaceholderData + +`boolean` + +Will be `true` if the data shown is the placeholder data. + +### isRefetchError + +`boolean` + +Will be `true` if the query failed while refetching. + +### isRefetching + +`boolean` + +- Is `true` whenever a background refetch is in-flight, which _does not_ include initial `'pending'`. +- Is the same as `isFetching && !isPending` + +### isStale + +`boolean` + +Will be `true` if the data in the cache is invalidated or if the data is older than the given `staleTime`. + +### refetch + +`(options: { cancelRefetch?: boolean | undefined; throwOnError?: boolean | undefined }) => Promise>` + +- A function to manually refetch the query. +- `throwOnError` + - When set to `true`, an error will be thrown if the query fails. + - When set to `false`, an error will be logged if the query fails. +- `cancelRefetch` + - When set to `true`, a currently running request will be cancelled before a new request is made. + - When set to `false`, no refetch will be made if there is already a request running. + - Defaults to `true` + +### status + +`'error' | 'pending' | 'success'` + +- `pending` if there's no cached data and no query attempt was finished yet. +- `error` if the query attempt resulted in an error. The corresponding `error` property has the error received from the attempted fetch +- `success` if the query has received a response with no errors and is ready to display its data. The corresponding `data` property on the query is the data received from the successful fetch or if the query's `enabled` property is set to `false` and has not been fetched yet `data` is the first `initialData` supplied to the query on initialization. diff --git a/wagmi-project/site/shared/transports/custom.md b/wagmi-project/site/shared/transports/custom.md new file mode 100644 index 000000000..dee391608 --- /dev/null +++ b/wagmi-project/site/shared/transports/custom.md @@ -0,0 +1,110 @@ + + +# custom + +The `custom` Transport connects to a JSON-RPC API via custom. Wraps Viem's [`custom` Transport](https://viem.sh/docs/clients/transports/custom.html). + +## Import + +```ts-vue +import { custom } from '{{packageName}}' +``` + +## Usage + +```ts-vue +import { + createConfig, + custom // [!code hl] +} from '{{packageName}}' +import { mainnet } from '{{packageName}}/chains' +import { customRpc } from './rpc' + +export const config = createConfig({ + chains: [mainnet], + connectors: [injected()], + transports: { + [mainnet.id]: custom({ // [!code hl] + async request({ method, params }) { // [!code hl] + const response = await customRpc.request(method, params) // [!code hl] + return response // [!code hl] + } // [!code hl] + }) // [!code hl] + }, +}) +``` + +## Parameters + +### provider + +`{ request({ method: string, params: unknown[] }): Promise }` + +An [EIP-1193 `request` function](https://eips.ethereum.org/EIPS/eip-1193#request) function. + +```ts +import { customRpc } from './rpc' + +const transport = custom({ + async request({ method, params }) { // [!code focus:3] + const response = await customRpc.request(method, params) + return response + } +}) +``` + +### key (optional) + +`string` + +A key for the Transport. Defaults to `"custom"`. + +```ts +const transport = custom( + provider, + { + key: 'windowProvider', // [!code focus] + } +) +``` + +### name (optional) + +`string` + +A name for the Transport. Defaults to `"Ethereum Provider"`. + +```ts +const transport = custom( + provider, + { + name: 'Window Ethereum Provider', // [!code focus] + } +) +``` + +### retryCount (optional) + +`number` + +The max number of times to retry when a request fails. Defaults to `3`. + +```ts +const transport = custom(provider, { + retryCount: 5, // [!code focus] +}) +``` + +### retryDelay (optional) + +`number` + +The base delay (in ms) between retries. By default, the Transport will use [exponential backoff](https://en.wikipedia.org/wiki/Exponential_backoff) (`~~(1 << count) * retryDelay`), which means the time between retries is not constant. + +```ts +const transport = custom(provider, { + retryDelay: 100, // [!code focus] +}) +``` \ No newline at end of file diff --git a/wagmi-project/site/shared/transports/fallback.md b/wagmi-project/site/shared/transports/fallback.md new file mode 100644 index 000000000..befe9395e --- /dev/null +++ b/wagmi-project/site/shared/transports/fallback.md @@ -0,0 +1,36 @@ + + +# fallback + +The `fallback` Transport consumes **multiple** Transports. If a Transport request fails, it will fall back to the next one in the list. Wraps Viem's [`fallback` Transport](https://viem.sh/docs/clients/transports/fallback.html). + +## Import + +```ts-vue +import { fallback } from '{{packageName}}' +``` + +## Usage + +```ts-vue +import { + createConfig, + fallback, // [!code hl] + http, +} from '{{packageName}}' +import { mainnet } from '{{packageName}}/chains' + +export const config = createConfig({ + chains: [mainnet], + connectors: [injected()], + transports: { + [mainnet.id]: fallback([ // [!code hl] + http('https://foo-bar-baz.quiknode.pro/...'), // [!code hl] + http('https://mainnet.infura.io/v3/...'), // [!code hl] + ]) // [!code hl] + }, +}) +``` + diff --git a/wagmi-project/site/shared/transports/http.md b/wagmi-project/site/shared/transports/http.md new file mode 100644 index 000000000..1a1d86406 --- /dev/null +++ b/wagmi-project/site/shared/transports/http.md @@ -0,0 +1,178 @@ + + +# http + +The `http` Transport connects to a JSON-RPC API via HTTP. Wraps Viem's [`http` Transport](https://viem.sh/docs/clients/transports/http.html). + +## Import + +```ts-vue +import { http } from '{{packageName}}' +``` + +## Usage + +```ts-vue +import { + createConfig, + http // [!code hl] +} from '{{packageName}}' +import { mainnet, sepolia } from '{{packageName}}/chains' + +export const config = createConfig({ + chains: [mainnet, sepolia], + connectors: [injected()], + transports: { + [mainnet.id]: http('https://foo-bar-baz.quiknode.pro/...'), // [!code hl] + [sepolia.id]: http('https://foo-bar-sep.quiknode.pro/...'), // [!code hl] + }, +}) +``` + +::: warning +If no URL is provided, then the transport will fall back to a public RPC URL on the chain. It is highly recommended to provide an authenticated RPC URL to prevent rate-limiting. +::: + +### Batch JSON-RPC + +The `http` Transport supports Batch JSON-RPC. This means that multiple JSON-RPC requests can be sent in a single HTTP request. + +The Transport will batch up Actions over a given period and execute them in a single Batch JSON-RPC HTTP request. By default, this period is a [zero delay](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Event_loop#zero_delays) meaning that the batch request will be executed at the end of the current [JavaScript message queue](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Event_loop#queue). Consumers can specify a custom time period `wait` (in ms). + +You can enable Batch JSON-RPC by setting the `batch` flag to `true`: + +```ts +const transport = http('https://foo-bar-baz.quiknode.pro/...', { + batch: true // [!code hl] +}) +``` + +## Parameters + +### url + +`string` + +URL of the JSON-RPC API. Defaults to `chain.rpcUrls.default.http[0]`. + +```ts +const transport = http('https://foo-bar-baz.quiknode.pro/...') +``` + +### batch + +`boolean | BatchOptions` + +Toggle to enable Batch JSON-RPC. Defaults to `false` + +```ts +const transport = http('https://foo-bar-baz.quiknode.pro/...', { + batch: true // [!code focus] +}) +``` + +### batch.batchSize + +`number` + +The maximum number of JSON-RPC requests to send in a batch. Defaults to `1_000`. + +```ts +const transport = http('https://foo-bar-baz.quiknode.pro/...', { + batch: { + batchSize: 2_000 // [!code focus] + } +}) +``` + +### batch.wait + +`number` + +The maximum number of milliseconds to wait before sending a batch. Defaults to `0` ([zero delay](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Event_loop#zero_delays)). + +```ts +const transport = http('https://foo-bar-baz.quiknode.pro/...', { + batch: { + wait: 16 // [!code focus] + } +}) +``` + +### fetchOptions + +[`RequestInit`](https://developer.mozilla.org/en-US/docs/Web/API/fetch) + +[Fetch options](https://developer.mozilla.org/en-US/docs/Web/API/fetch) to pass to the internal `fetch` function. Useful for passing auth headers or cache options. + +```ts +const transport = http('https://foo-bar-baz.quiknode.pro/...', { + fetchOptions: { // [!code focus:5] + headers: { + 'Authorization': 'Bearer ...' + } + } +}) +``` + +### key + +`string` + +A key for the Transport. Defaults to `"http"`. + +```ts +const transport = http('https://foo-bar-baz.quiknode.pro/...', { + key: 'alchemy', // [!code focus] +}) +``` + +### name + +`string` + +A name for the Transport. Defaults to `"HTTP JSON-RPC"`. + +```ts +const transport = http('https://foo-bar-baz.quiknode.pro/...', { + name: 'Alchemy HTTP Provider', // [!code focus] +}) +``` + +### retryCount + +`number` + +The max number of times to retry when a request fails. Defaults to `3`. + +```ts +const transport = http('https://foo-bar-baz.quiknode.pro/...', { + retryCount: 5, // [!code focus] +}) +``` + +### retryDelay + +`number` + +The base delay (in ms) between retries. By default, the Transport will use [exponential backoff](https://en.wikipedia.org/wiki/Exponential_backoff) (`~~(1 << count) * retryDelay`), which means the time between retries is not constant. + +```ts +const transport = http('https://foo-bar-baz.quiknode.pro/...', { + retryDelay: 100, // [!code focus] +}) +``` + +### timeout + +`number` + +The timeout for requests. Defaults to `10_000`. + +```ts +const transport = http('https://foo-bar-baz.quiknode.pro/...', { + timeout: 60_000, // [!code focus] +}) +``` diff --git a/wagmi-project/site/shared/transports/unstable_connector.md b/wagmi-project/site/shared/transports/unstable_connector.md new file mode 100644 index 000000000..f858421c9 --- /dev/null +++ b/wagmi-project/site/shared/transports/unstable_connector.md @@ -0,0 +1,123 @@ + + +# unstable_connector + +The `unstable_connector` Transport connects to a JSON-RPC API via the provided Connector. + +For example, if the provided Connector is `injected` and the end-user uses MetaMask, then outgoing JSON-RPC requests will be sent via the MetaMask EIP-1193 Provider (`window.ethereum`). + +## Import + +```ts-vue +import { unstable_connector } from '{{packageName}}' +``` + +## Usage + +```ts-vue +import { + createConfig, + fallback, + unstable_connector, // [!code hl] +} from '{{packageName}}' +import { mainnet } from '{{packageName}}/chains' + +export const config = createConfig({ + chains: [mainnet], + connectors: [injected()], + transports: { + [mainnet.id]: fallback([ + unstable_connector(injected), // [!code hl] + http('https://foo-bar-baz.quiknode.pro/...') + ]) + }, +}) +``` + +::: warning +It is **highly recommended** to use the `unstable_connector` Transport inside of a `fallback` Transport. This ensures that if the Connector request fails, the Transport will fall back to a different Transport in the fallback set. + +Some common cases for a Connector request to fail are: + +- Chain ID mismatches, +- Connector RPC not supporting the requested method and/or only supporting a subset of methods for connected accounts, +- Rate-limiting of Connector RPC. +::: + +## Parameters + +### connector + +`Connector` + +The Connector to use for the Transport. + +```ts +import { unstable_connector } from 'wagmi' +import { safe } from 'wagmi/connectors' + +const transport = unstable_connector(safe) // [!code focus] +``` + +### key (optional) + +`string` + +A key for the Transport. Defaults to `"connector"`. + +```ts +import { unstable_connector } from 'wagmi' +import { injected } from 'wagmi/connectors' + +const transport = unstable_connector(injected, { + key: 'injected', // [!code focus] +}) +``` + +### name (optional) + +`string` + +A name for the Transport. Defaults to `"Connector"`. + +```ts +import { unstable_connector } from 'wagmi' +import { injected } from 'wagmi/connectors' + +const transport = unstable_connector(injected, { + name: 'Injected', // [!code focus] +}) +``` + +### retryCount (optional) + +`number` + +The max number of times to retry when a request fails. Defaults to `3`. + +```ts +import { unstable_connector } from 'wagmi' +import { injected } from 'wagmi/connectors' + +const transport = unstable_connector(injected, { + retryCount: 5, // [!code focus] +}) +``` + +### retryDelay (optional) + +`number` + +The base delay (in ms) between retries. By default, the Transport will use [exponential backoff](https://en.wikipedia.org/wiki/Exponential_backoff) (`~~(1 << count) * retryDelay`), which means the time between retries is not constant. + +```ts +import { unstable_connector } from 'wagmi' +import { injected } from 'wagmi/connectors' + +const transport = unstable_connector(injected, { + retryDelay: 100, // [!code focus] +}) +``` diff --git a/wagmi-project/site/shared/transports/webSocket.md b/wagmi-project/site/shared/transports/webSocket.md new file mode 100644 index 000000000..0b7911740 --- /dev/null +++ b/wagmi-project/site/shared/transports/webSocket.md @@ -0,0 +1,108 @@ + + +# webSocket + +The `webSocket` Transport connects to a JSON-RPC API via a WebSocket. Wraps Viem's [`webSocket` Transport](https://viem.sh/docs/clients/transports/websocket). + +## Import + +```ts-vue +import { webSocket } from '{{packageName}}' +``` + +## Usage + +```ts-vue +import { + createConfig, + webSocket // [!code hl] +} from '{{packageName}}' +import { mainnet, sepolia } from '{{packageName}}/chains' + +export const config = createConfig({ + chains: [mainnet, sepolia], + connectors: [injected()], + transports: { + [mainnet.id]: webSocket('wss://foo-bar-baz.quiknode.pro/...'), // [!code hl] + [sepolia.id]: webSocket('wss://foo-bar-sep.quiknode.pro/...'), // [!code hl] + }, +}) +``` + +::: warning +If no URL is provided, then the transport will fall back to a public RPC URL on the chain. It is highly recommended to provide an authenticated RPC URL to prevent rate-limiting. +::: + +## Parameters + +### url + +`string` + +URL of the JSON-RPC API. + +```ts +const transport = webSocket('wss://foo-bar-baz.quiknode.pro/...') +``` + +### key (optional) + +`string` + +A key for the Transport. Defaults to `"webSocket"`. + +```ts +const transport = webSocket('wss://foo-bar-baz.quiknode.pro/...', { + key: 'alchemy', // [!code focus] +}) +``` + +### name (optional) + +`string` + +A name for the Transport. Defaults to `"WebSocket JSON-RPC"`. + +```ts +const transport = webSocket('wss://foo-bar-baz.quiknode.pro/...', { + name: 'Alchemy WebSocket Provider', // [!code focus] +}) +``` + +### retryCount (optional) + +`number` + +The max number of times to retry when a request fails. Defaults to `3`. + +```ts +const transport = webSocket('wss://foo-bar-baz.quiknode.pro/...', { + retryCount: 5, // [!code focus] +}) +``` + +### retryDelay (optional) + +`number` + +The base delay (in ms) between retries. By default, the Transport will use [exponential backoff](https://en.wikipedia.org/wiki/Exponential_backoff) (`~~(1 << count) * retryDelay`), which means the time between retries is not constant. + +```ts +const transport = webSocket('wss://foo-bar-baz.quiknode.pro/...', { + retryDelay: 100, // [!code focus] +}) +``` + +### timeout (optional) + +`number` + +The timeout for async WebSocket requests. Defaults to `10_000`. + +```ts +const transport = webSocket('wss://foo-bar-baz.quiknode.pro/...', { + timeout: 60_000, // [!code focus] +}) +``` diff --git a/wagmi-project/site/shared/utilities/cookieToInitialState.md b/wagmi-project/site/shared/utilities/cookieToInitialState.md new file mode 100644 index 000000000..0850b4502 --- /dev/null +++ b/wagmi-project/site/shared/utilities/cookieToInitialState.md @@ -0,0 +1,74 @@ + + +# cookieToInitialState + +Helper to convert a cookie string into [initial state](/react/api/WagmiProvider#initialstate). + +## Import + +```ts-vue +import { cookieToInitialState } from '{{packageName}}' +``` + +## Usage + +::: code-group + +```ts-vue [server.ts] +import { cookieToInitialState } from '{{packageName}}' +import config from './config' + +function handler(req: Request) { + const initialState = cookieToInitialState(config, req.headers.cookie) + // ... +} +``` + +```ts-vue [config.ts] +import { + createConfig, + http, + cookieStorage, + createStorage +} from '{{packageName}}' +import { mainnet, sepolia } from '{{packageName}}/chains' + +export const config = createConfig({ + chains: [mainnet, sepolia], + ssr: true, + storage: createStorage({ + storage: cookieStorage, + }), + transports: { + [mainnet.id]: http(), + [sepolia.id]: http(), + }, +}) +``` + +::: + +## Parameters + +### config + +`Config` + +Wagmi Config + + +### cookie + +`string | null | undefined` + +The cookie string. + +## Return Type + +`State` + +Initial state. \ No newline at end of file diff --git a/wagmi-project/site/shared/utilities/deserialize.md b/wagmi-project/site/shared/utilities/deserialize.md new file mode 100644 index 000000000..c355e5a15 --- /dev/null +++ b/wagmi-project/site/shared/utilities/deserialize.md @@ -0,0 +1,44 @@ + + +# deserialize + +Deserialize function that supports `bigint` and `Map`. + +## Import + +```ts-vue +import { deserialize } from '{{packageName}}' +``` + +## Usage + +```ts-vue +import { deserialize } from '{{packageName}}' + +const result = deserialize('{"foo":"wagmi","bar":{"__type":"bigint","value":"123"}}') +``` + +## Parameters + +### value + +`string` + +The string to deserialize. + + +### reviver + +`(key: string, value: any) => any` + +A custom reviver function for handling standard values. + +## Return Type + +`unknown` + +Parsed value. \ No newline at end of file diff --git a/wagmi-project/site/shared/utilities/normalizeChainId.md b/wagmi-project/site/shared/utilities/normalizeChainId.md new file mode 100644 index 000000000..6cc1cad75 --- /dev/null +++ b/wagmi-project/site/shared/utilities/normalizeChainId.md @@ -0,0 +1,56 @@ + + +# normalizeChainId + +Normalizes a chain ID to a number. + +## Import + +```ts-vue +import { normalizeChainId } from '{{packageName}}' +``` + +## Usage + +:::warning Deprecated +Use `Number` instead. + +```ts-vue +import { normalizeChainId } from '{{packageName}}' // [!code --] +const chainId = normalizeChainId(123n) // [!code --] +const chainId = Number(123n) // [!code ++] +``` +::: + +```ts-vue +import { normalizeChainId } from '{{packageName}}' + +const result = normalizeChainId('0x1') +``` + +## Parameters + + +### chainId + +`bigint | number | string` + +The chain ID to normalize. + +```ts-vue +import { normalizeChainId } from '{{packageName}}' + +normalizeChainId(1n) +normalizeChainId(1) +normalizeChainId('0x1') +``` + +## Return Type + +`number` + +The normalized chain ID. diff --git a/wagmi-project/site/shared/utilities/serialize.md b/wagmi-project/site/shared/utilities/serialize.md new file mode 100644 index 000000000..9ce6608e7 --- /dev/null +++ b/wagmi-project/site/shared/utilities/serialize.md @@ -0,0 +1,53 @@ + + +# serialize + +Serialize function that supports `bigint` and `Map`. + +## Import + +```ts-vue +import { serialize } from '{{packageName}}' +``` + +## Usage + +```ts-vue +import { serialize } from '{{packageName}}' + +const result = serialize({ foo: 'wagmi', bar: 123n }) +``` + +## Parameters + +### value + +`any` + +The value to stringify. + +### replacer + +`(key: string, value: any) => any` + +A custom replacer function for handling standard values. + +### indent + +`number | null | undefined` + +The number of spaces to indent the output by. + +### circularReplacer + +A custom replacer function for handling circular values. + +## Return Type + +`string` + +Stringified value. \ No newline at end of file diff --git a/wagmi-project/site/snippets/abi-event.ts b/wagmi-project/site/snippets/abi-event.ts new file mode 100644 index 000000000..2d5b344ae --- /dev/null +++ b/wagmi-project/site/snippets/abi-event.ts @@ -0,0 +1,20 @@ +export const abi = [ + { + type: 'event', + name: 'Approval', + inputs: [ + { indexed: true, name: 'owner', type: 'address' }, + { indexed: true, name: 'spender', type: 'address' }, + { indexed: false, name: 'value', type: 'uint256' }, + ], + }, + { + type: 'event', + name: 'Transfer', + inputs: [ + { indexed: true, name: 'from', type: 'address' }, + { indexed: true, name: 'to', type: 'address' }, + { indexed: false, name: 'value', type: 'uint256' }, + ], + }, +] as const diff --git a/wagmi-project/site/snippets/abi-infinite-read.ts b/wagmi-project/site/snippets/abi-infinite-read.ts new file mode 100644 index 000000000..7e0a2b28e --- /dev/null +++ b/wagmi-project/site/snippets/abi-infinite-read.ts @@ -0,0 +1,23 @@ +export const abi = [ + { + inputs: [{ internalType: 'uint256', name: 'tokenId', type: 'uint256' }], + name: 'getChest', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'tokenId', type: 'uint256' }], + name: 'getFoot', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'tokenId', type: 'uint256' }], + name: 'getHand', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, +] as const diff --git a/wagmi-project/site/snippets/abi-read.ts b/wagmi-project/site/snippets/abi-read.ts new file mode 100644 index 000000000..f893ed2b2 --- /dev/null +++ b/wagmi-project/site/snippets/abi-read.ts @@ -0,0 +1,16 @@ +export const abi = [ + { + type: 'function', + name: 'balanceOf', + stateMutability: 'view', + inputs: [{ name: 'account', type: 'address' }], + outputs: [{ type: 'uint256' }], + }, + { + type: 'function', + name: 'totalSupply', + stateMutability: 'view', + inputs: [], + outputs: [{ name: 'supply', type: 'uint256' }], + }, +] as const diff --git a/wagmi-project/site/snippets/abi-write.ts b/wagmi-project/site/snippets/abi-write.ts new file mode 100644 index 000000000..93c1b8bb8 --- /dev/null +++ b/wagmi-project/site/snippets/abi-write.ts @@ -0,0 +1,23 @@ +export const abi = [ + { + type: 'function', + name: 'approve', + stateMutability: 'nonpayable', + inputs: [ + { name: 'spender', type: 'address' }, + { name: 'amount', type: 'uint256' }, + ], + outputs: [{ type: 'bool' }], + }, + { + type: 'function', + name: 'transferFrom', + stateMutability: 'nonpayable', + inputs: [ + { name: 'sender', type: 'address' }, + { name: 'recipient', type: 'address' }, + { name: 'amount', type: 'uint256' }, + ], + outputs: [{ type: 'bool' }], + }, +] as const diff --git a/wagmi-project/site/snippets/core/config-chain-properties.ts b/wagmi-project/site/snippets/core/config-chain-properties.ts new file mode 100644 index 000000000..d9d407cff --- /dev/null +++ b/wagmi-project/site/snippets/core/config-chain-properties.ts @@ -0,0 +1,11 @@ +import { http, createConfig } from '@wagmi/core' +import { base, celo, mainnet } from '@wagmi/core/chains' + +export const config = createConfig({ + chains: [base, celo, mainnet], + transports: { + [base.id]: http(), + [celo.id]: http(), + [mainnet.id]: http(), + }, +}) diff --git a/wagmi-project/site/snippets/core/config.ts b/wagmi-project/site/snippets/core/config.ts new file mode 100644 index 000000000..956f6efa0 --- /dev/null +++ b/wagmi-project/site/snippets/core/config.ts @@ -0,0 +1,10 @@ +import { http, createConfig } from '@wagmi/core' +import { mainnet, sepolia } from '@wagmi/core/chains' + +export const config = createConfig({ + chains: [mainnet, sepolia], + transports: { + [mainnet.id]: http(), + [sepolia.id]: http(), + }, +}) diff --git a/wagmi-project/site/snippets/react/app.tsx b/wagmi-project/site/snippets/react/app.tsx new file mode 100644 index 000000000..6fb247a54 --- /dev/null +++ b/wagmi-project/site/snippets/react/app.tsx @@ -0,0 +1,16 @@ +import { QueryClient, QueryClientProvider } from '@tanstack/react-query' +import * as React from 'react' +import { WagmiProvider } from 'wagmi' +import { config } from './config' + +export const queryClient = new QueryClient() + +export function App() { + return ( + + + {/** ... */} + + + ) +} diff --git a/wagmi-project/site/snippets/react/config-chain-properties.ts b/wagmi-project/site/snippets/react/config-chain-properties.ts new file mode 100644 index 000000000..9c7133102 --- /dev/null +++ b/wagmi-project/site/snippets/react/config-chain-properties.ts @@ -0,0 +1,17 @@ +import { http, createConfig } from 'wagmi' +import { base, celo, mainnet } from 'wagmi/chains' + +export const config = createConfig({ + chains: [base, celo, mainnet], + transports: { + [base.id]: http(), + [celo.id]: http(), + [mainnet.id]: http(), + }, +}) + +declare module 'wagmi' { + interface Register { + config: typeof config + } +} diff --git a/wagmi-project/site/snippets/react/config.ts b/wagmi-project/site/snippets/react/config.ts new file mode 100644 index 000000000..9739c926c --- /dev/null +++ b/wagmi-project/site/snippets/react/config.ts @@ -0,0 +1,10 @@ +import { http, createConfig } from 'wagmi' +import { mainnet, sepolia } from 'wagmi/chains' + +export const config = createConfig({ + chains: [mainnet, sepolia], + transports: { + [mainnet.id]: http(), + [sepolia.id]: http(), + }, +}) diff --git a/wagmi-project/site/snippets/typedData.ts b/wagmi-project/site/snippets/typedData.ts new file mode 100644 index 000000000..90f01a415 --- /dev/null +++ b/wagmi-project/site/snippets/typedData.ts @@ -0,0 +1,13 @@ +import type { TypedData } from 'viem' + +export const types = { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], +} as const satisfies TypedData diff --git a/wagmi-project/site/snippets/vue/App.vue b/wagmi-project/site/snippets/vue/App.vue new file mode 100644 index 000000000..ae2a44fd7 --- /dev/null +++ b/wagmi-project/site/snippets/vue/App.vue @@ -0,0 +1,5 @@ + + + \ No newline at end of file diff --git a/wagmi-project/site/snippets/vue/config-chain-properties.ts b/wagmi-project/site/snippets/vue/config-chain-properties.ts new file mode 100644 index 000000000..3c3a9bcaf --- /dev/null +++ b/wagmi-project/site/snippets/vue/config-chain-properties.ts @@ -0,0 +1,17 @@ +import { http, createConfig } from '@wagmi/vue' +import { base, celo, mainnet } from '@wagmi/vue/chains' + +export const config = createConfig({ + chains: [base, celo, mainnet], + transports: { + [base.id]: http(), + [celo.id]: http(), + [mainnet.id]: http(), + }, +}) + +declare module '@wagmi/vue' { + interface Register { + config: typeof config + } +} diff --git a/wagmi-project/site/snippets/vue/config.ts b/wagmi-project/site/snippets/vue/config.ts new file mode 100644 index 000000000..558ae12e3 --- /dev/null +++ b/wagmi-project/site/snippets/vue/config.ts @@ -0,0 +1,10 @@ +import { http, createConfig } from '@wagmi/vue' +import { mainnet, sepolia } from '@wagmi/vue/chains' + +export const config = createConfig({ + chains: [mainnet, sepolia], + transports: { + [mainnet.id]: http(), + [sepolia.id]: http(), + }, +}) diff --git a/wagmi-project/site/snippets/vue/main.ts b/wagmi-project/site/snippets/vue/main.ts new file mode 100644 index 000000000..27ca843af --- /dev/null +++ b/wagmi-project/site/snippets/vue/main.ts @@ -0,0 +1,13 @@ +import { QueryClient, VueQueryPlugin } from '@tanstack/vue-query' +import { WagmiPlugin } from '@wagmi/vue' +import { createApp } from 'vue' + +import App from './App.vue' +import { config } from './config' + +export const queryClient = new QueryClient() + +createApp(App) + .use(WagmiPlugin, { config }) + .use(VueQueryPlugin, { queryClient }) + .mount('#app') diff --git a/wagmi-project/site/tsconfig.json b/wagmi-project/site/tsconfig.json new file mode 100644 index 000000000..053a800ac --- /dev/null +++ b/wagmi-project/site/tsconfig.json @@ -0,0 +1,23 @@ +{ + "compilerOptions": { + "baseUrl": ".", + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "jsx": "preserve", + "lib": ["DOM", "ESNext"], + "module": "ESNext", + "moduleResolution": "node", + "noUnusedLocals": true, + "paths": { + "~/*": ["src/*"] + }, + "resolveJsonModule": true, + "skipLibCheck": true, + "strict": true, + "strictNullChecks": true, + "target": "esnext", + "types": ["vite/client", "vitepress"] + }, + "include": ["./*.ts", "./.vitepress/**/*.ts", "./.vitepress/**/*.vue"], + "exclude": ["dist", "node_modules", "snippets"] +} diff --git a/wagmi-project/site/vercel.json b/wagmi-project/site/vercel.json new file mode 100644 index 000000000..f7abbb998 --- /dev/null +++ b/wagmi-project/site/vercel.json @@ -0,0 +1,148 @@ +{ + "cleanUrls": true, + "redirects": [ + { + "source": "/cli", + "destination": "/cli/getting-started", + "permanent": true + }, + + { + "source": "/core", + "destination": "/core/getting-started", + "permanent": true + }, + { + "source": "/core/migration-guide", + "destination": "/core/guides/migrate-from-v1-to-v2", + "permanent": true + }, + { + "source": "/core/:name(faq)", + "destination": "/core/guides/:name", + "permanent": true + }, + { + "source": "/core/ethers-adapters", + "destination": "/core/guides/ethers-web3", + "permanent": true + }, + { + "source": "/core/:section(chains)", + "destination": "/core/api/:section", + "permanent": true + }, + { + "source": "/core/:section(actions|connectors)/:name", + "destination": "/core/api/:section/:name", + "permanent": true + }, + { + "source": "/core/config", + "destination": "/core/api/createConfig", + "permanent": true + }, + + { + "source": "/react", + "destination": "/react/getting-started", + "permanent": true + }, + { + "source": "/react/comparison", + "destination": "/react/comparisons", + "permanent": true + }, + { + "source": "/react/migration-guide", + "destination": "/react/guides/migrate-from-v1-to-v2", + "permanent": true + }, + { + "source": "/react/:name(faq)", + "destination": "/react/guides/:name", + "permanent": true + }, + { + "source": "/react/ethers-adapters", + "destination": "/react/guides/ethers", + "permanent": true + }, + { + "source": "/react/:section(actions|chains)", + "destination": "/react/api/:section", + "permanent": true + }, + { + "source": "/react/:section(connectors|hooks)/:name", + "destination": "/react/api/:section/:name", + "permanent": true + }, + { + "source": "/react/config", + "destination": "/react/api/createConfig", + "permanent": true + }, + { + "source": "/react/WagmiConfig", + "destination": "/react/api/WagmiProvider", + "permanent": true + }, + { + "source": "/react/prepare-hooks/usePrepareContractWrite", + "destination": "/react/api/hooks/useSimulateContract", + "permanent": true + }, + { + "source": "/react/prepare-hooks/usePrepareSendTransaction", + "destination": "/react/api/hooks/useEstimateFeesPerGas", + "permanent": true + }, + + { + "source": "/examples/connect-wallet", + "destination": "/react/guides/connect-wallet", + "permanent": true + }, + { + "source": "/examples/send-transaction", + "destination": "/react/guides/send-transaction", + "permanent": true + }, + { + "source": "/react/guides/sending-transactions", + "destination": "/react/guides/send-transaction", + "permanent": true + }, + { + "source": "/react/guides/reading-contracts", + "destination": "/react/guides/read-from-contract", + "permanent": true + }, + { + "source": "/examples/contract-write(-dynamic)?", + "destination": "/react/guides/write-to-contract", + "permanent": true + }, + { + "source": "/react/guides/writing-to-contracts", + "destination": "/react/guides/write-to-contract", + "permanent": true + }, + { + "source": "/examples/custom-connector", + "destination": "/dev/creating-connectors", + "permanent": true + }, + { + "source": "/examples/sign-message", + "destination": "https://1.x.wagmi.sh/examples/sign-message", + "permanent": false + }, + { + "source": "/examples/sign-in-with-ethereum", + "destination": "https://1.x.wagmi.sh/examples/sign-in-with-ethereum", + "permanent": false + } + ] +} diff --git a/wagmi-project/site/vue/api/Nuxt.md b/wagmi-project/site/vue/api/Nuxt.md new file mode 100644 index 000000000..e785cfd70 --- /dev/null +++ b/wagmi-project/site/vue/api/Nuxt.md @@ -0,0 +1,27 @@ +# Nuxt + +[Nuxt Module](https://nuxt.com/docs/guide/concepts/modules) for Wagmi. Adds all [Composables](/vue/api/composables) as [auto-imports](https://nuxt.com/docs/guide/concepts/auto-imports). + +## Usage + +::: code-group +```ts twoslash [nuxt.config.ts] +import { defineNuxtConfig } from 'nuxt/config' + +export default defineNuxtConfig({ + modules: ['@wagmi/vue/nuxt'], +}) +``` +```vue [index.vue] + + + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + diff --git a/wagmi-project/site/vue/api/WagmiPlugin.md b/wagmi-project/site/vue/api/WagmiPlugin.md new file mode 100644 index 000000000..96d2dff97 --- /dev/null +++ b/wagmi-project/site/vue/api/WagmiPlugin.md @@ -0,0 +1,113 @@ +# WagmiPlugin + +[Vue Plugin](https://vuejs.org/guide/reusability/plugins.html#plugins) for Wagmi. + +## Import + +```ts +import { WagmiPlugin } from '@wagmi/vue' +``` + +## Usage + +::: code-group +```ts [main.ts] +import { createApp } from 'vue' +import { WagmiPlugin } from '@wagmi/vue' + +import App from './App.vue' +import { config } from './config' + +createApp(App) + .use(WagmiPlugin, { config }) + .mount('#app') +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type WagmiPluginProps } from '@wagmi/vue' +``` + +### config + +[`Config`](/vue/api/createConfig#config) object to inject with context. + +::: code-group +```ts [main.ts] +import { createApp } from 'vue' +import { WagmiPlugin } from '@wagmi/vue' + +import App from './App.vue' +import { config } from './config' + +createApp(App) + .use(WagmiPlugin, { + config // [!code focus] + }) + .mount('#app') +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### initialState + +`State | undefined` + +- Initial state to hydrate into the [Wagmi Config](/vue/api/createConfig). Useful for SSR. + +::: code-group +```ts [main.ts] +import { createApp } from 'vue' +import { WagmiPlugin } from '@wagmi/vue' + +import App from './App.vue' +import { config } from './config' + +createApp(App) + .use(WagmiPlugin, { + config, + initialState: /* ... */ // [!code focus] + }) + .mount('#app') +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### reconnectOnMount + +`boolean | undefined` + +- Whether or not to reconnect previously connected [connectors](/vue/api/createConfig#connectors) on mount. +- Defaults to `true`. + +::: code-group +```ts [main.ts] +import { createApp } from 'vue' +import { WagmiPlugin } from '@wagmi/vue' + +import App from './App.vue' +import { config } from './config' + +createApp(App) + .use(WagmiPlugin, { + config, + reconnectOnMount: false // [!code focus] + }) + .mount('#app') +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +## configKey + +Key to use to provide/inject `Config` via `WagmiPlugin`. + +```ts +import { configKey, type Config } from '@wagmi/vue' +import { inject } from 'vue' + +inject(configKey) +``` diff --git a/wagmi-project/site/vue/api/actions.md b/wagmi-project/site/vue/api/actions.md new file mode 100644 index 000000000..fa47b78a4 --- /dev/null +++ b/wagmi-project/site/vue/api/actions.md @@ -0,0 +1,30 @@ +# Actions + +Sometimes the declarative nature of Vue Composables doesn't work for parts of your app. For those cases, you can use Wagmi Core Actions directly! + +All the Wagmi Core Actions are importable using the `@wagmi/vue/actions` entrypoint. For example, you can use the `watchBlockNumber` action to watch for block number changes. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +See the [Wagmi Core docs](/core/api/actions) for more info on what actions are available. diff --git a/wagmi-project/site/vue/api/chains.md b/wagmi-project/site/vue/api/chains.md new file mode 100644 index 000000000..5693e9554 --- /dev/null +++ b/wagmi-project/site/vue/api/chains.md @@ -0,0 +1,26 @@ + + +# Chains + +Viem `Chain` objects. More info at the [Viem docs](https://viem.sh/docs/chains/introduction). + +## Import + +Import via the `'@wagmi/vue/chains'` entrypoint (proxies all chains from `'viem/chains'`). + +```ts +import { mainnet } from '@wagmi/vue/chains' +``` + +## Available Chains + +Chain definitions as of `viem@{{viemVersion}}`. For `viem@latest`, visit the [Viem repo](https://github.com/wevm/viem/blob/main/src/chains/index.ts). + + + + diff --git a/wagmi-project/site/vue/api/composables.md b/wagmi-project/site/vue/api/composables.md new file mode 100644 index 000000000..8d1babb98 --- /dev/null +++ b/wagmi-project/site/vue/api/composables.md @@ -0,0 +1,25 @@ + + +# Composables + +Vue Composables for accounts, wallets, contracts, transactions, signing, ENS, and more. + +## Import + +```ts +import { useAccount } from '@wagmi/vue' +``` + +## Available Composables + + diff --git a/wagmi-project/site/vue/api/composables/useAccount.md b/wagmi-project/site/vue/api/composables/useAccount.md new file mode 100644 index 000000000..41bf8727c --- /dev/null +++ b/wagmi-project/site/vue/api/composables/useAccount.md @@ -0,0 +1,80 @@ +--- +title: useAccount +description: Composable for getting current account. +--- + +# useAccount + +Composable for getting current account. + +## Import + +```ts +import { useAccount } from '@wagmi/vue' +``` + +## Usage + +::: code-group +```vue twoslash [index.vue] + + + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +## Parameters + +```ts twoslash +import { type UseAccountParameters } from '@wagmi/vue' +``` + +### config + +`Config | undefined` + +[`Config`](/vue/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiPlugin`](/vue/api/WagmiPlugin). + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +## Return Type + +```ts twoslash +import { type UseAccountReturnType } from '@wagmi/vue' +``` + + + +## Action + +- [`getAccount`](/core/api/actions/getAccount) diff --git a/wagmi-project/site/vue/api/composables/useAccountEffect.md b/wagmi-project/site/vue/api/composables/useAccountEffect.md new file mode 100644 index 000000000..8f42d593d --- /dev/null +++ b/wagmi-project/site/vue/api/composables/useAccountEffect.md @@ -0,0 +1,113 @@ +--- +title: useAccountEffect +description: Composable for listening to account lifecycle events. +--- + +# useAccountEffect + +Composable for listening to account lifecycle events. + +## Import + +```ts +import { useAccountEffect } from '@wagmi/vue' +``` + +## Usage + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type useAccountEffectParameters } from '@wagmi/vue' +``` + +### config + +`Config | undefined` + +[`Config`](/vue/api/createConfig#config) to use instead of retrieving from the [`WagmiPlugin`](/vue/api/WagmiPlugin). + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### onConnect + +`` MaybeRef<((data: { address: `0x${string}`; addresses: readonly [`0x${string}`, ...`0x${string}`[]]; chain: Chain | undefined chainId: number; connector: Connector; isReconnected: boolean }) => void)> | undefined `` + +Callback that is called when accounts are connected. + +::: code-group +```tsx [index.tsx] +import { useAccountEffect } from '@wagmi/vue' + +function App() { + useAccountEffect({ + onConnect(data) { // [!code focus] + console.log('Connected!', data) // [!code focus] + }, // [!code focus] + }) +} +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### onDisconnect + +`MaybeRef<(() => void)> | undefined` + +Callback that is called when no more accounts are connected. + +::: code-group +```tsx [index.tsx] +import { useAccountEffect } from '@wagmi/vue' + +function App() { + useAccountEffect({ + onDisconnect() { // [!code focus] + console.log('Disconnected!') // [!code focus] + }, // [!code focus] + }) +} +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +## Action + +- [`getAccount`](/core/api/actions/getAccount) +- [`watchAccount`](/core/api/actions/watchAccount) diff --git a/wagmi-project/site/vue/api/composables/useBalance.md b/wagmi-project/site/vue/api/composables/useBalance.md new file mode 100644 index 000000000..a84f6ba88 --- /dev/null +++ b/wagmi-project/site/vue/api/composables/useBalance.md @@ -0,0 +1,226 @@ +--- +title: useBalance +description: Composable for fetching native currency or token balance. +--- + + + +# useBalance + +Composable for fetching native currency or token balance. + +## Import + +```ts +import { useBalance } from '@wagmi/vue' +``` + +## Usage + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseBalanceParameters } from '@wagmi/vue' +``` + +### address + +`Address | undefined` + +Address to get balance for. [`enabled`](#enabled) set to `false` if `address` is `undefined`. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +--- + +### blockNumber + +`bigint | undefined` + +Block number to get balance at. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Block tag to get balance at. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +--- + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/vue/api/createConfig#config) to use instead of retrieving from the [`WagmiPlugin`](/vue/api/WagmiPlugin). + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Hooks that have identical context will share the same cache. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### token + +`Address | undefined` + +ERC-20 token address to get balance for. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### unit + +`'ether' | 'gwei' | 'wei' | number | undefined` + +- Units to use when formatting result. +- Defaults to `'ether'`. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseBalanceReturnType } from '@wagmi/vue' +``` + + + + + +## Action + +- [`getBalance`](/core/api/actions/getBalance) diff --git a/wagmi-project/site/vue/api/composables/useBlockNumber.md b/wagmi-project/site/vue/api/composables/useBlockNumber.md new file mode 100644 index 000000000..ae8d8956e --- /dev/null +++ b/wagmi-project/site/vue/api/composables/useBlockNumber.md @@ -0,0 +1,172 @@ +--- +title: useBlockNumber +description: Composable for fetching the number of the most recent block seen. +--- + + + +# useBlockNumber + +Composable for fetching the number of the most recent block seen. + +## Import + +```ts +import { useBlockNumber } from '@wagmi/vue' +``` + +## Usage + +::: code-group +```vue [index.vue] + + + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseBlockNumberParameters } from '@wagmi/vue' +``` + +### cacheTime + +`MaybeRef | undefined` + +Time in milliseconds that cached block number will remain in memory. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### chainId + +`MaybeRef | undefined` + +ID of chain to use when fetching data. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/vue/api/createConfig#config) to use instead of retrieving from the [`WagmiPlugin`](/vue/api/WagmiPlugin). + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### scopeKey + +`MaybeRef | undefined` + +Scopes the cache to a given context. Composables that have identical context will share the same cache. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### watch + +`MaybeRef | undefined` + +- Enables/disables listening for block number changes. +- Can pass a subset of [`UseWatchBlockNumberParameters`](/vue/api/composables/useWatchBlockNumber#parameters) directly to [`useWatchBlockNumber`](/vue/api/composables/useWatchBlockNumber). + +::: code-group +```vue [index.vue] + +``` + +```vue [index-2.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseBlockNumberReturnType } from '@wagmi/vue' +``` + + + + + +## Action + +- [`getBlockNumber`](/core/api/actions/getBlockNumber) +- [`watchBlockNumber`](/core/api/actions/watchBlockNumber) diff --git a/wagmi-project/site/vue/api/composables/useBytecode.md b/wagmi-project/site/vue/api/composables/useBytecode.md new file mode 100644 index 000000000..a6aa3cca6 --- /dev/null +++ b/wagmi-project/site/vue/api/composables/useBytecode.md @@ -0,0 +1,209 @@ +--- +title: useBytecode +description: Composable for retrieving the bytecode at an address. +--- + + + +# useBytecode + +Composable for retrieving the bytecode at an address. + +## Import + +```ts +import { useBytecode } from '@wagmi/vue' +``` + +## Usage + +::: code-group +```vue [index.vue] + + + +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseBytecodeParameters } from '@wagmi/vue' +``` + +### address + +`Address | undefined` + +The contract address. + +::: code-group +```vue [index.vue] + + + +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### blockNumber + +`bigint | undefined` + +The block number to check the bytecode at. + +::: code-group +```vue [index.vue] + + + +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +The block tag to check the bytecode at. + +::: code-group +```vue [index.vue] + + + +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +The chain ID to check the bytecode at. + +::: code-group +```vue [index.vue] + + + +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```vue [index.vue] + + + +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Hooks that have identical context will share the same cache. + +::: code-group +```vue [index.vue] + + + +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseBytecodeReturnType } from '@wagmi/vue' +``` + + + + + +## Action + +- [`getBytecode`](/core/api/actions/getBytecode) diff --git a/wagmi-project/site/vue/api/composables/useChainId.md b/wagmi-project/site/vue/api/composables/useChainId.md new file mode 100644 index 000000000..141914874 --- /dev/null +++ b/wagmi-project/site/vue/api/composables/useChainId.md @@ -0,0 +1,74 @@ +--- +title: useChainId +description: Composable for getting current chain ID. +--- + +# useChainId + +Composable for getting current chain ID. + +## Import + +```ts +import { useChainId } from '@wagmi/vue' +``` + +## Usage + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseChainIdParameters } from '@wagmi/vue' +``` + +### config + +`Config | undefined` + +[`Config`](/vue/api/createConfig#config) to use instead of retrieving from the [`WagmiPlugin`](/vue/api/WagmiPlugin). + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type UseChainIdReturnType } from '@wagmi/vue' +``` + +`number` + +Current chain ID from [`config.state.chainId`](/vue/api/createConfig#chainid). + +::: info +Only returns chain IDs for chains configured via `createConfig`'s [`chains`](/vue/api/createConfig#chains) parameter. + +If the active [connection](/vue/api/createConfig#connection) [`chainId`](/vue/api/createConfig#chainid-1) is not from a chain included in your Wagmi `Config`, `useChainId` will return the last configured chain ID. +::: + +## Action + +- [`getChainId`](/core/api/actions/getChainId) +- [`watchChainId`](/core/api/actions/watchChainId) diff --git a/wagmi-project/site/vue/api/composables/useChains.md b/wagmi-project/site/vue/api/composables/useChains.md new file mode 100644 index 000000000..52daf6602 --- /dev/null +++ b/wagmi-project/site/vue/api/composables/useChains.md @@ -0,0 +1,67 @@ +--- +title: useChains +description: Composable for getting configured chains +--- + +# useChains + +Composable for getting configured chains + +## Import + +```ts +import { useChains } from '@wagmi/vue' +``` + +## Usage + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseChainsParameters } from '@wagmi/vue' +``` + +### config + +`Config | undefined` + +[`Config`](/vue/api/createConfig#config) to use instead of retrieving from the [`WagmiPlugin`](/vue/api/WagmiPlugin). + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type UseChainsReturnType } from '@wagmi/vue' +``` + +`readonly [Chain, ...Chain[]]` + +Chains from [`config.chains`](/vue/api/createConfig#chains). + +## Action + +- [`getChains`](/core/api/actions/getChains) diff --git a/wagmi-project/site/vue/api/composables/useClient.md b/wagmi-project/site/vue/api/composables/useClient.md new file mode 100644 index 000000000..18b3ca91f --- /dev/null +++ b/wagmi-project/site/vue/api/composables/useClient.md @@ -0,0 +1,89 @@ +--- +title: useClient +description: Composable for getting Viem `Client` instance. +--- + +# useClient + +Composable for getting Viem [`Client`](https://viem.sh/docs/clients/custom.html) instance. + +## Import + +```ts +import { useClient } from '@wagmi/vue' +``` + +## Usage + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseClientParameters } from '@wagmi/vue' +``` + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when getting Viem Client. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/vue/api/createConfig#config) to use instead of retrieving from the [`WagmiPlugin`](/vue/api/WagmiPlugin). + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type UseClientReturnType } from '@wagmi/vue' +``` + +`Client | undefined` + +Viem [`Client`](https://viem.sh/docs/clients/custom.html) instance. + +## Action + +- [`getClient`](/core/api/actions/getClient) +- [`watchClient`](/core/api/actions/watchClient) diff --git a/wagmi-project/site/vue/api/composables/useConfig.md b/wagmi-project/site/vue/api/composables/useConfig.md new file mode 100644 index 000000000..755504335 --- /dev/null +++ b/wagmi-project/site/vue/api/composables/useConfig.md @@ -0,0 +1,33 @@ +--- +title: useConfig +description: Composable for getting `Config` from the `WagmiPlugin`. +--- + +# useConfig + +Composable for getting [`Config`](/vue/api/createConfig#config) from the [`WagmiPlugin`](/vue/api/WagmiPlugin). + +## Import + +```ts +import { useConfig } from 'wagmi' +``` + +## Usage + +::: code-group +```vue [index.vue] + +``` + +::: + +## Return Type + +```ts +import { type UseConfigReturnType } from 'wagmi' +``` diff --git a/wagmi-project/site/vue/api/composables/useConnect.md b/wagmi-project/site/vue/api/composables/useConnect.md new file mode 100644 index 000000000..d1d586c56 --- /dev/null +++ b/wagmi-project/site/vue/api/composables/useConnect.md @@ -0,0 +1,115 @@ +--- +title: useConnect +description: Composable for connecting accounts with connectors. +--- + + + +# useConnect + +Composable for connecting accounts with [connectors](/vue/api/connectors). + +## Import + +```ts +import { useConnect } from '@wagmi/vue' +``` + +## Usage + +::: code-group +```vue [index.vue] + + + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseConnectParameters } from '@wagmi/vue' +``` + +### config + +`Config | undefined` + +[`Config`](/vue/api/createConfig#config) to use instead of retrieving from the [`WagmiPlugin`](/vue/api/WagmiPlugin). + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseConnectReturnType } from '@wagmi/vue' +``` + +### connectors + +`readonly Connector[]` + +Globally configured connectors via [`createConfig`](/vue/api/createConfig#connectors). Useful for rendering a list of available connectors. + +::: code-group +```vue [index.vue] + + + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + + + +::: tip +Not all connectors support connecting directly to a `chainId` (e.g. they don't support programmatic chain switching). In those cases, the connector will connect to whatever chain the connector's provider (e.g. wallet) is connected to. +::: + + + +## Action + +- [`connect`](/core/api/actions/connect) diff --git a/wagmi-project/site/vue/api/composables/useConnections.md b/wagmi-project/site/vue/api/composables/useConnections.md new file mode 100644 index 000000000..c6fa350f9 --- /dev/null +++ b/wagmi-project/site/vue/api/composables/useConnections.md @@ -0,0 +1,64 @@ +--- +title: useConnections +description: Composable for getting active connections. +--- + +# useConnections + +Composable for getting active connections. + +## Import + +```ts +import { useConnections } from 'wagmi' +``` + +## Usage + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseConnectionsParameters } from 'wagmi' +``` + +### config + +`Config | undefined` + +[`Config`](/vue/api/createConfig#config) to use instead of retrieving from the [`WagmiPlugin`](/vue/api/WagmiPlugin). + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type UseConnectionsReturnType } from 'wagmi' +``` + +## Action + +- [`getConnections`](/core/api/actions/getConnections) +- [`watchConnections`](/core/api/actions/watchConnections) diff --git a/wagmi-project/site/vue/api/composables/useConnectorClient.md b/wagmi-project/site/vue/api/composables/useConnectorClient.md new file mode 100644 index 000000000..61f56ca61 --- /dev/null +++ b/wagmi-project/site/vue/api/composables/useConnectorClient.md @@ -0,0 +1,128 @@ +--- +title: useConnectorClient +description: Composable for getting a Viem `Client` object for the current or provided connector. +--- + + + +# useConnectorClient + +Composable for getting a Viem [`Client`](https://viem.sh/docs/clients/custom.html) object for the current or provided connector. + +## Import + +```ts +import { useConnectorClient } from '@wagmi/vue' +``` + +## Usage + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseConnectorClientParameters } from '@wagmi/vue' +``` + +### account + +`Address | Account | undefined` + +Account to use with client. Throws if account is not found on [`connector`](#connector). + +```vue + +``` + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use with client. + +```vue + +``` + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### connector + +`Connector | undefined` + +- Connector to get client for. +- Defaults to current connector. + +```vue + +``` + + + +## Return Type + +```ts +import { type UseConnectorClientReturnType } from '@wagmi/vue' +``` + + + + + +## Action + +- [`getConnectorClient`](/core/api/actions/getConnectorClient) diff --git a/wagmi-project/site/vue/api/composables/useConnectors.md b/wagmi-project/site/vue/api/composables/useConnectors.md new file mode 100644 index 000000000..c05bc3d38 --- /dev/null +++ b/wagmi-project/site/vue/api/composables/useConnectors.md @@ -0,0 +1,41 @@ +--- +title: useConnectors +description: Composable for getting configured connectors. +--- + +# useConnectors + +Composable for getting configured connectors. + +## Import + +```ts +import { useConnectors } from '@wagmi/vue' +``` + +## Usage + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type UseConnectorsReturnType } from '@wagmi/vue' +``` + +`readonly Connector[]` + +Connectors from [`config.connectors`](/vue/api/createConfig#connectors-1). + +## Action + +- [`getConnectors`](/core/api/actions/getConnectors) diff --git a/wagmi-project/site/vue/api/composables/useDisconnect.md b/wagmi-project/site/vue/api/composables/useDisconnect.md new file mode 100644 index 000000000..66635c3c0 --- /dev/null +++ b/wagmi-project/site/vue/api/composables/useDisconnect.md @@ -0,0 +1,111 @@ +--- +title: useDisconnect +description: Composable for disconnecting connections. +--- + + + +# useDisconnect + +Composable for disconnecting connections. + +## Import + +```ts +import { useDisconnect } from '@wagmi/vue' +``` + +## Usage + +::: code-group +```vue [index.vue] + + + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseDisconnectParameters } from '@wagmi/vue' +``` + +### config + +`Config | undefined` + +[`Config`](/vue/api/createConfig#config) to use instead of retrieving from the [`WagmiPlugin`](/vue/api/WagmiPlugin). + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseDisconnectReturnType } from '@wagmi/vue' +``` + +### connectors + +`readonly Connector[]` + +Connectors that are currently connected. Useful for rendering a list of connectors to disconnect. + +::: code-group +```vue [index.vue] + + + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + + + + + +## Action + +- [`disconnect`](/core/api/actions/connect) diff --git a/wagmi-project/site/vue/api/composables/useEnsAddress.md b/wagmi-project/site/vue/api/composables/useEnsAddress.md new file mode 100644 index 000000000..7aa72eed6 --- /dev/null +++ b/wagmi-project/site/vue/api/composables/useEnsAddress.md @@ -0,0 +1,238 @@ +--- +title: useEnsAddress +description: Composable for fetching ENS address for name. +--- + + + +# useEnsAddress + +Composable for fetching ENS address for name. + +## Import + +```ts +import { useEnsAddress } from '@wagmi/vue' +``` + +## Usage + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +::: warning +Since ENS names prohibit certain forbidden characters (e.g. underscore) and have other validation rules, you likely want to [normalize ENS names](https://docs.ens.domains/contract-api-reference/name-processing#normalising-names) with [UTS-46 normalization](https://unicode.org/reports/tr46) before passing them to `useEnsAddress`. You can use Viem's built-in [`normalize`](https://viem.sh/docs/ens/utilities/normalize) function for this. +::: + +## Parameters + +```ts +import { type UseEnsAddressParameters } from '@wagmi/vue' +``` + +--- + +### blockNumber + +`bigint | undefined` + +Block number to get ENS address at. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Block tag to get ENS address at. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +--- + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### coinType + +`number | undefined` + +The [ENSIP-9](https://docs.ens.domains/ens-improvement-proposals/ensip-9-multichain-address-resolution) coin type to fetch the address for. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/vue/api/createConfig#config) to use instead of retrieving from the [`WagmiPlugin`](/vue/api/WagmiPlugin). + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### name + +`string | undefined` + +Name to get the address for. [`enabled`](#enabled) set to `false` if `name` is `undefined`. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Composables that have identical context will share the same cache. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### universalResolverAddress + +`Address | undefined` + +- Address of ENS Universal Resolver Contract. +- Defaults to current chain's Universal Resolver Contract address. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseEnsAddressReturnType } from '@wagmi/vue' +``` + + + + + +## Action + +- [`getEnsAddress`](/core/api/actions/getEnsAddress) diff --git a/wagmi-project/site/vue/api/composables/useEnsAvatar.md b/wagmi-project/site/vue/api/composables/useEnsAvatar.md new file mode 100644 index 000000000..5f352e255 --- /dev/null +++ b/wagmi-project/site/vue/api/composables/useEnsAvatar.md @@ -0,0 +1,262 @@ +--- +title: useEnsAvatar +description: Composable for fetching ENS avatar for name. +--- + + + +# useEnsAvatar + +Composable for fetching ENS avatar for name. + +## Import + +```ts +import { useEnsAvatar } from '@wagmi/vue' +``` + +## Usage + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +::: warning +Since ENS names prohibit certain forbidden characters (e.g. underscore) and have other validation rules, you likely want to [normalize ENS names](https://docs.ens.domains/contract-api-reference/name-processing#normalising-names) with [UTS-46 normalization](https://unicode.org/reports/tr46) before passing them to `useEnsAvatar`. You can use Viem's built-in [`normalize`](https://viem.sh/docs/ens/utilities/normalize) function for this. +::: + +## Parameters + +```ts +import { type UseEnsAvatarParameters } from '@wagmi/vue' +``` + +--- + +### assetGatewayUrls + +`{ ipfs?: string | undefined; arweave?: string | undefined } | undefined` + +Gateway urls to resolve IPFS and/or Arweave assets. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### blockNumber + +`bigint | undefined` + +Block number to get ENS avatar at. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Block tag to get ENS avatar at. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +--- + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/vue/api/createConfig#config) to use instead of retrieving from the [`WagmiPlugin`](/vue/api/WagmiPlugin). + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### gatewayUrls + +`string[] | undefined` + +A set of Universal Resolver gateways, used for resolving CCIP-Read requests made through the ENS Universal Resolver Contract. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### name + +`string | undefined` + +Name to get the avatar for. [`enabled`](#enabled) set to `false` if `name` is `undefined`. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Composables that have identical context will share the same cache. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### universalResolverAddress + +`Address | undefined` + +- Address of ENS Universal Resolver Contract. +- Defaults to current chain's Universal Resolver Contract address. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseEnsAvatarReturnType } from '@wagmi/vue' +``` + + + + + +## Action + +- [`getEnsAvatar`](/core/api/actions/getEnsAvatar) diff --git a/wagmi-project/site/vue/api/composables/useEnsName.md b/wagmi-project/site/vue/api/composables/useEnsName.md new file mode 100644 index 000000000..74461c996 --- /dev/null +++ b/wagmi-project/site/vue/api/composables/useEnsName.md @@ -0,0 +1,206 @@ +--- +title: useEnsName +description: Composable for fetching primary ENS name for address. +--- + + + +# useEnsName + +Composable for fetching primary ENS name for address. + +## Import + +```ts +import { useEnsName } from '@wagmi/vue' +``` + +## Usage + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseEnsNameParameters } from '@wagmi/vue' +``` + +### address + +`Address | undefined` + +Name to get the resolver for. [`enabled`](#enabled) set to `false` if `address` is `undefined`. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +--- + +### blockNumber + +`bigint | undefined` + +Block number to get ENS name at. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Block tag to get ENS name at. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +--- + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/vue/api/createConfig#config) to use instead of retrieving from the [`WagmiPlugin`](/vue/api/WagmiPlugin). + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Composables that have identical context will share the same cache. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### universalResolverAddress + +`Address | undefined` + +- Address of ENS Universal Resolver Contract. +- Defaults to current chain's Universal Resolver Contract address. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseEnsNameReturnType } from '@wagmi/vue' +``` + + + + + +## Action + +- [`getEnsName`](/core/api/actions/getEnsName) diff --git a/wagmi-project/site/vue/api/composables/useEstimateGas.md b/wagmi-project/site/vue/api/composables/useEstimateGas.md new file mode 100644 index 000000000..4c05fa767 --- /dev/null +++ b/wagmi-project/site/vue/api/composables/useEstimateGas.md @@ -0,0 +1,387 @@ +--- +title: useEstimateGas +description: Composable for estimating the gas necessary to complete a transaction without submitting it to the network. +--- + + + +# useEstimateGas + +Composable for estimating the gas necessary to complete a transaction without submitting it to the network. + +## Import + +```ts +import { useEstimateGas } from '@wagmi/vue' +``` + +## Usage + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseEstimateGasParameters } from '@wagmi/vue' +``` + +### accessList + +`AccessList | undefined` + +The access list. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### account + +`Address | Account | undefined` + +Account to use when estimating gas. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +Chain ID to target when estimating gas. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### connector + +`Connector | undefined` + +Connector to estimate with. If no [`account`](#account) is provided, will use default account from connector. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### data + +`` `0x${string}` | undefined `` + +A contract hashed method call with encoded function data. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### gas + +`bigint | undefined` + +Gas provided for transaction execution. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +--- + +### gasPrice + +`bigint | undefined` + +The price in wei to pay per gas. Only applies to [Legacy Transactions](https://viem.sh/docs/glossary/terms.html#legacy-transaction). + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### maxFeePerGas + +`bigint | undefined` + +Total fee per gas in wei, inclusive of [`maxPriorityFeePerGas`](#maxPriorityFeePerGas). Only applies to [EIP-1559 Transactions](https://viem.sh/docs/glossary/terms.html#eip-1559-transaction). + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### maxPriorityFeePerGas + +`bigint | undefined` + +Max priority fee per gas in wei. Only applies to [EIP-1559 Transactions](https://viem.sh/docs/glossary/terms.html#eip-1559-transaction). + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +--- + +### nonce + +`number` + +Unique number identifying this transaction. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Composables that have identical context will share the same cache. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### to + +`Address | undefined` + +The transaction recipient or contract address. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### type + +`'legacy' | 'eip1559' | 'eip2930' | undefined` + +Optional transaction request type to narrow parameters. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### value + +`bigint | undefined` + +Value in wei sent with this transaction. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseEstimateGasReturnType } from '@wagmi/vue' +``` + + + + + +## Action + +- [`estimateGas`](/core/api/actions/estimateGas) diff --git a/wagmi-project/site/vue/api/composables/useReadContract.md b/wagmi-project/site/vue/api/composables/useReadContract.md new file mode 100644 index 000000000..98e44af8c --- /dev/null +++ b/wagmi-project/site/vue/api/composables/useReadContract.md @@ -0,0 +1,410 @@ +--- +title: useReadContract +description: Composable for calling a read-only function on a contract, and returning the response. +--- + + + +# useReadContract + +Composable for calling a **read-only** function on a contract, and returning the response. + +A **read-only** function (constant function) on a Solidity contract is denoted by a pure or view keyword. They can only read the state of the contract, and cannot make any changes to it. Since read-only methods do not change the state of the contract, they do not require any gas to be executed, and can be called by any user without the need to pay for gas. + +## Import + +```ts +import { useReadContract } from '@wagmi/vue' +``` + +## Usage + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/abi-read.ts[abi.ts] +<<< @/snippets/vue/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseReadContractParameters } from '@wagmi/vue' +``` + +### abi + +`Abi | undefined` + +The contract's ABI. Check out the [TypeScript docs](/vue/typescript#const-assert-abis-typed-data) for how to set up ABIs for maximum type inference and safety. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/abi-read.ts[abi.ts] +<<< @/snippets/vue/config.ts[config.ts] +::: + +### account + +`Account | undefined` + +Account to use when calling the contract (`msg.sender`). + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/abi-read.ts[abi.ts] +<<< @/snippets/vue/config.ts[config.ts] +::: + +### address + +`Address | undefined` + +The contract's address. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/abi-read.ts[abi.ts] +<<< @/snippets/vue/config.ts[config.ts] +::: + +### args + +`readonly unknown[] | undefined` + +- Arguments to pass when calling the contract. +- Inferred from [`abi`](#abi) and [`functionName`](#functionname). + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/abi-read.ts[abi.ts] +<<< @/snippets/vue/config.ts[config.ts] +::: + +--- + +### blockNumber + +`bigint | undefined` + +Block number to call contract at. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/abi-read.ts[abi.ts] +<<< @/snippets/vue/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Block tag to call contract at. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/abi-read.ts[abi.ts] +<<< @/snippets/vue/config.ts[config.ts] +::: + +--- + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/abi-read.ts[abi.ts] +<<< @/snippets/vue/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/vue/api/createConfig#config) to use instead of retrieving from the [`WagmiPlugin`](/vue/api/WagmiPlugin). + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/abi-read.ts[abi.ts] +<<< @/snippets/vue/config.ts[config.ts] +::: + +### functionName + +`string | undefined` + +- Function to call on the contract. +- Inferred from [`abi`](#abi). + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/abi-read.ts[abi.ts] +<<< @/snippets/vue/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Composables that have identical context will share the same cache. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/abi-read.ts[abi.ts] +<<< @/snippets/vue/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseReadContractReturnType } from '@wagmi/vue' +``` + +The return type's [`data`](#data) property is inferrable via the combination of [`abi`](#abi), [`functionName`](#functionname), and [`args`](#args). Check out the [TypeScript docs](/vue/typescript#const-assert-abis-typed-data) for more info. + + + +## Type Inference + +With [`abi`](#abi) setup correctly, TypeScript will infer the correct types for [`functionName`](#functionname), [`args`](#args), and the return type. See the Wagmi [TypeScript docs](/vue/typescript) for more information. + +::: code-group +```ts twoslash [Inline] +import { createConfig, http, useReadContract } from '@wagmi/vue' +import { mainnet, sepolia } from 'wagmi/chains' + +const config = createConfig({ + chains: [mainnet, sepolia], + transports: { + [mainnet.id]: http(), + [sepolia.id]: http(), + }, +}) +// ---cut--- +const result = useReadContract({ + abi: [ + { + type: 'function', + name: 'balanceOf', + stateMutability: 'view', + inputs: [{ name: 'account', type: 'address' }], + outputs: [{ type: 'uint256' }], + }, + { + type: 'function', + name: 'totalSupply', + stateMutability: 'view', + inputs: [], + outputs: [{ name: 'supply', type: 'uint256' }], + }, + ], + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'balanceOf', + // ^? + + + args: ['0x6b175474e89094c44da98b954eedeac495271d0f'], + // ^? + + + +}) + +result.data +// ^? +``` + +```ts twoslash [Const-Asserted] +import { createConfig, http, useReadContract } from '@wagmi/vue' +import { mainnet, sepolia } from 'wagmi/chains' + +const config = createConfig({ + chains: [mainnet, sepolia], + transports: { + [mainnet.id]: http(), + [sepolia.id]: http(), + }, +}) +// ---cut--- +const abi = [ + { + type: 'function', + name: 'balanceOf', + stateMutability: 'view', + inputs: [{ name: 'account', type: 'address' }], + outputs: [{ type: 'uint256' }], + }, + { + type: 'function', + name: 'totalSupply', + stateMutability: 'view', + inputs: [], + outputs: [{ name: 'supply', type: 'uint256' }], + }, +] as const + +const result = useReadContract({ + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'balanceOf', + // ^? + + + args: ['0x6b175474e89094c44da98b954eedeac495271d0f'], + // ^? +}) + +result.data +// ^? +``` +::: + + + +## Action + +- [`readContract`](/core/api/actions/readContract) diff --git a/wagmi-project/site/vue/api/composables/useReconnect.md b/wagmi-project/site/vue/api/composables/useReconnect.md new file mode 100644 index 000000000..56316fee5 --- /dev/null +++ b/wagmi-project/site/vue/api/composables/useReconnect.md @@ -0,0 +1,106 @@ +--- +title: useReconnect +description: Composable for reconnecting connectors. +--- + + + +# useReconnect + +Composable for reconnecting [connectors](/core/api/connectors). + +## Import + +```ts +import { useReconnect } from '@wagmi/vue' +``` + +## Usage + +::: code-group +```vue [index.vue] + +``` + +::: + +::: tip +When [`WagmiPlugin['reconnectOnMount']`](/vue/api/WagmiPlugin#reconnectonmount) is `true`, `reconnect` is called automatically on mount. +::: + +## Parameters + +```ts +import { type UseReconnectParameters } from '@wagmi/vue' +``` + +### config + +`Config | undefined` + +[`Config`](/vue/api/createConfig#config) to use instead of retrieving from the [`WagmiPlugin`](/vue/api/WagmiPlugin). + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseReconnectReturnType } from '@wagmi/vue' +``` + +### connectors + +`readonly Connector[]` + +Globally configured connectors via [`createConfig`](/vue/api/createConfig#connectors). + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + + + + + +## Action + +- [`reconnect`](/core/api/actions/reconnect) diff --git a/wagmi-project/site/vue/api/composables/useSendTransaction.md b/wagmi-project/site/vue/api/composables/useSendTransaction.md new file mode 100644 index 000000000..62f581143 --- /dev/null +++ b/wagmi-project/site/vue/api/composables/useSendTransaction.md @@ -0,0 +1,91 @@ +--- +title: useSendTransaction +description: Composable for creating, signing, and sending transactions to networks. +--- + + + +# useSendTransaction + +Composable for creating, signing, and sending transactions to networks. + +## Import + +```ts +import { useSendTransaction } from '@wagmi/vue' +``` + +## Usage + +::: code-group +```vue [index.vue] + + + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseSendTransactionParameters } from '@wagmi/vue' +``` + +### config + +`Config | undefined` + +[`Config`](/vue/api/createConfig#config) to use instead of retrieving from the [`WagmiPlugin`](/vue/api/WagmiPlugin). + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseSendTransactionReturnType } from '@wagmi/vue' +``` + + + + + +## Action + +- [`sendTransaction`](/core/api/actions/sendTransaction) diff --git a/wagmi-project/site/vue/api/composables/useSignMessage.md b/wagmi-project/site/vue/api/composables/useSignMessage.md new file mode 100644 index 000000000..dacbc6153 --- /dev/null +++ b/wagmi-project/site/vue/api/composables/useSignMessage.md @@ -0,0 +1,85 @@ +--- +title: useSignMessage +description: Composable for signing messages. +--- + + + +# useSignMessage + +Composable for signing messages. + +## Import + +```ts +import { useSignMessage } from '@wagmi/vue' +``` + +## Usage + +::: code-group +```vue [index.vue] + + + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseSignMessageParameters } from '@wagmi/vue' +``` + +### config + +`Config | undefined` + +[`Config`](/vue/api/createConfig#config) to use instead of retrieving from the [`WagmiPlugin`](/vue/api/WagmiPlugin). + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseSignMessageReturnType } from '@wagmi/vue' +``` + + + + + +## Action + +- [`signMessage`](/core/api/actions/signMessage) diff --git a/wagmi-project/site/vue/api/composables/useSignTypedData.md b/wagmi-project/site/vue/api/composables/useSignTypedData.md new file mode 100644 index 000000000..6c21a0901 --- /dev/null +++ b/wagmi-project/site/vue/api/composables/useSignTypedData.md @@ -0,0 +1,214 @@ +--- +title: useSignTypedData +description: Composable for signing typed data and calculating an Ethereum-specific EIP-712 signature. +--- + + + +# useSignTypedData + +Composable for signing typed data and calculating an Ethereum-specific [EIP-712](https://eips.ethereum.org/EIPS/eip-712) signature. + +## Import + +```ts +import { useSignTypedData } from '@wagmi/vue' +``` + +## Usage + +::: code-group +```vue [index.vue] + + + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseSignTypedDataParameters } from '@wagmi/vue' +``` + +### config + +`Config | undefined` + +[`Config`](/vue/api/createConfig#config) to use instead of retrieving from the [`WagmiPlugin`](/vue/api/WagmiPlugin). + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseSignTypedDataReturnType } from '@wagmi/vue' +``` + + + +## Type Inference + +With [`types`](/core/api/actions/signTypedData#types) setup correctly, TypeScript will infer the correct types for [`domain`](/core/api/actions/signTypedData#domain), [`message`](/core/api/actions/signTypedData#message), and [`primaryType`](/core/api/actions/signTypedData#primarytype). See the Wagmi [TypeScript docs](/vue/typescript) for more information. + +::: code-group +```ts twoslash [Inline] +import { useSignTypedData } from '@wagmi/vue' +// ---cut--- +const { signTypedData } = useSignTypedData() + +signTypedData({ + types: { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], + }, + primaryType: 'Mail', + // ^? + + + message: { + // ^? + + + + + + + + + + + + + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, +}) +``` +```ts twoslash [Const-Asserted] +import { useSignTypedData } from '@wagmi/vue' +// ---cut--- +const types = { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], +} as const + +const { signTypedData } = useSignTypedData() + +signTypedData({ + types, + primaryType: 'Mail', + // ^? + + + message: { + // ^? + + + + + + + + + + + + + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, +}) +``` +::: + + + +## Action + +- [`signTypedData`](/core/api/actions/signTypedData) diff --git a/wagmi-project/site/vue/api/composables/useSimulateContract.md b/wagmi-project/site/vue/api/composables/useSimulateContract.md new file mode 100644 index 000000000..7e10c486d --- /dev/null +++ b/wagmi-project/site/vue/api/composables/useSimulateContract.md @@ -0,0 +1,686 @@ +--- +title: useSimulateContract +description: Composable for simulating/validating a contract interaction. +--- + + + +# useSimulateContract + +Composable for simulating/validating a contract interaction. + +## Import + +```ts +import { useSimulateContract } from '@wagmi/vue' +``` + +## Usage + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/vue/config.ts[config.ts] +::: + + + +## Parameters + +```ts +import { type UseSimulateContractParameters } from '@wagmi/vue' +``` + +### abi + +`Abi | undefined` + +The contract's ABI. Check out the [TypeScript docs](/vue/typescript#const-assert-abis-typed-data) for how to set up ABIs for maximum type inference and safety. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/vue/config.ts[config.ts] +::: + +### accessList + +`AccessList | undefined` + +The access list. + +::: code-group +```vue [index.ts] + +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/vue/config.ts[config.ts] +::: + +### account + +`Account | undefined` + +Account to use when calling the contract (`msg.sender`). Throws if account is not found on [`connector`](#connector). + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/vue/config.ts[config.ts] +::: + +### address + +`Address | undefined` + +The contract's address. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/vue/config.ts[config.ts] +::: + +### args + +`readonly unknown[] | undefined` + +- Arguments to pass when calling the contract. +- Inferred from [`abi`](#abi) and [`functionName`](#functionname). + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/vue/config.ts[config.ts] +::: + +--- + +### blockNumber + +`bigint | undefined` + +Block number to call contract at. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/vue/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Block tag to call contract at. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/vue/config.ts[config.ts] +::: + +--- + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/vue/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/vue/api/createConfig#config) to use instead of retrieving from the [`WagmiPlugin`](/vue/api/WagmiPlugin). + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/vue/config.ts[config.ts] +::: + +### connector + +`Connector | undefined` + +[Connector](/vue/api/connectors) to simulate transaction with. + +::: code-group +```vue [index.ts] + +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/vue/config.ts[config.ts] +::: + +### dataSuffix + +`` `0x${string}` | undefined `` + +Data to append to the end of the calldata. Useful for adding a ["domain" tag](https://opensea.notion.site/opensea/Seaport-Order-Attributions-ec2d69bf455041a5baa490941aad307f). + +::: code-group +```vue [index.ts] + +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/vue/config.ts[config.ts] +::: + +### functionName + +`string | undefined` + +- Function to call on the contract. +- Inferred from [`abi`](#abi). + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/vue/config.ts[config.ts] +::: + +### gas + +`bigint | undefined` + +Gas provided for transaction execution. + +::: code-group +```vue [index.ts] + +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/vue/config.ts[config.ts] +::: + +--- + +### gasPrice + +`bigint | undefined` + +The price in wei to pay per gas. Only applies to [Legacy Transactions](https://viem.sh/docs/glossary/terms.html#legacy-transaction). + +::: code-group +```vue [index.ts] + +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/vue/config.ts[config.ts] +::: + +### maxFeePerGas + +`bigint | undefined` + +Total fee per gas in wei, inclusive of [`maxPriorityFeePerGas`](#maxPriorityFeePerGas). Only applies to [EIP-1559 Transactions](https://viem.sh/docs/glossary/terms.html#eip-1559-transaction). + +::: code-group +```vue [index.ts] + +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/vue/config.ts[config.ts] +::: + +### maxPriorityFeePerGas + +`bigint | undefined` + +Max priority fee per gas in wei. Only applies to [EIP-1559 Transactions](https://viem.sh/docs/glossary/terms.html#eip-1559-transaction). + +::: code-group +```vue [index.ts] + +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/vue/config.ts[config.ts] +::: + +--- + +### nonce + +`number` + +Unique number identifying this transaction. + +::: code-group +```vue [index.ts] + +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/vue/config.ts[config.ts] +::: + +### type + +`'legacy' | 'eip1559' | 'eip2930' | undefined` + +Optional transaction request type to narrow parameters. + +::: code-group +```vue [index.ts] + +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/vue/config.ts[config.ts] +::: + +### value + +`bigint | undefined` + +Value in wei sent with this transaction. + +::: code-group +```vue [index.ts] + +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/vue/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Composables that have identical context will share the same cache. + +::: code-group +```vue [index.ts] + +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/vue/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseSimulateContractReturnType } from '@wagmi/vue' +``` + +The return type's [`data`](#data) property is inferrable via the combination of [`abi`](#abi), [`functionName`](#functionname), and [`args`](#args). Check out the [TypeScript docs](/vue/typescript#const-assert-abis-typed-data) for more info. + + + +## Type Inference + +With [`abi`](#abi) setup correctly, TypeScript will infer the correct types for [`functionName`](#functionname), [`args`](#args), and [`value`](#value). See the Wagmi [TypeScript docs](/vue/typescript) for more information. + + + +## Action + +- [`simulateContract`](/core/api/actions/simulateContract) diff --git a/wagmi-project/site/vue/api/composables/useSwitchAccount.md b/wagmi-project/site/vue/api/composables/useSwitchAccount.md new file mode 100644 index 000000000..bf965bbeb --- /dev/null +++ b/wagmi-project/site/vue/api/composables/useSwitchAccount.md @@ -0,0 +1,120 @@ +--- +title: useSwitchAccount +description: Composable for switching the current account. +--- + + + +# useSwitchAccount + +Composable for switching the current account. + +## Import + +```ts +import { useSwitchAccount } from 'wagmi' +``` + +## Usage + +::: code-group +```vue [index.vue] + + + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseSwitchAccountParameters } from 'wagmi' +``` + +### config + +`Config | undefined` + +[`Config`](/vue/api/createConfig#config) to use instead of retrieving from the [`WagmiPlugin`](/vue/api/WagmiPlugin). + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseSwitchAccountReturnType } from 'wagmi' +``` + +### connectors + +`readonly Connector[]` + +Globally configured and actively connected connectors. Useful for rendering a list of available connectors to switch to. + +::: code-group +```vue [index.vue] + + + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + + + + + +## Action + +- [`switchAccount`](/core/api/actions/switchAccount) diff --git a/wagmi-project/site/vue/api/composables/useSwitchChain.md b/wagmi-project/site/vue/api/composables/useSwitchChain.md new file mode 100644 index 000000000..c7dace93e --- /dev/null +++ b/wagmi-project/site/vue/api/composables/useSwitchChain.md @@ -0,0 +1,124 @@ +--- +title: useSwitchChain +description: Composable for switching the target chain for a connector or the Wagmi `Config`. +--- + + + +# useSwitchChain + +Composable for switching the target chain for a connector or the Wagmi [`Config`](/vue/api/createConfig#config). + +## Import + +```ts +import { useSwitchChain } from '@wagmi/vue' +``` + +## Usage + +::: code-group +```vue [index.vue] + + + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +::: tip +When connected, `switchChain` will switch the target chain for the connector. When not connected, `switchChain` will switch the target chain for the Wagmi [`Config`](/vue/api/createConfig#config). +::: + +## Parameters + +```ts +import { type UseSwitchChainParameters } from '@wagmi/vue' +``` + +### config + +`Config | undefined` + +[`Config`](/vue/api/createConfig#config) to use instead of retrieving from the [`WagmiPlugin`](/vue/api/WagmiPlugin). + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseSwitchChainReturnType } from '@wagmi/vue' +``` + +### chains + +`readonly [Chain, ...Chain[]]` + +Globally configured chains. Useful for rendering a list of available chains to switch to. + +::: code-group +```vue [index.vue] + + + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + + + + + +## Action + +- [`switchChain`](/core/api/actions/switchChain) diff --git a/wagmi-project/site/vue/api/composables/useTransaction.md b/wagmi-project/site/vue/api/composables/useTransaction.md new file mode 100644 index 000000000..80fedc53d --- /dev/null +++ b/wagmi-project/site/vue/api/composables/useTransaction.md @@ -0,0 +1,184 @@ +--- +title: useTransaction +description: Composable for fetching transactions given hashes or block identifiers. +--- + + + +# useTransaction + +Composable for fetching transactions given hashes or block identifiers. + +## Import + +```ts +import { useTransaction } from '@wagmi/vue' +``` + +## Usage + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseTransactionParameters } from '@wagmi/vue' +``` + +--- + +### blockHash + +`bigint | undefined` + +Block hash to get transaction at (with [`index`](#index)). + +```vue + +``` + +### blockNumber + +`bigint | undefined` + +Block number to get transaction at (with [`index`](#index)). + +```vue + +``` + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Block tag to get transaction at (with [`index`](#index)). + +```vue + +``` + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +```vue + +``` + +### config + +`Config | undefined` + +[`Config`](/vue/api/createConfig#config) to use instead of retrieving from the [`WagmiPlugin`](/vue/api/WagmiPlugin). + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### hash + +`` `0x${string}` | undefined `` + +Hash to get transaction. [`enabled`](#enabled) set to `false` if `hash` and [`index`](#index) are `undefined`. + +```vue + +``` + +### index + +`number | undefined` + +An index to be used with a block identifier ([hash](#blockhash), [number](#blocknumber), or [tag](#blocktag)). [`enabled`](#enabled) set to `false` if `index` and [`hash`](#hash) are `undefined`. + +```vue + +``` + + + +## Return Type + +```ts +import { type UseTransactionReturnType } from '@wagmi/vue' +``` + + + + + +## Action + +- [`getTransaction`](/core/api/actions/getTransaction) diff --git a/wagmi-project/site/vue/api/composables/useTransactionReceipt.md b/wagmi-project/site/vue/api/composables/useTransactionReceipt.md new file mode 100644 index 000000000..e610c2384 --- /dev/null +++ b/wagmi-project/site/vue/api/composables/useTransactionReceipt.md @@ -0,0 +1,141 @@ +--- +title: useTransactionReceipt +description: Composable for return the Transaction Receipt given a Transaction hash. +--- + + + +# useTransactionReceipt + +Composable for return the [Transaction Receipt](https://viem.sh/docs/glossary/terms.html#transaction-receipt) given a [Transaction](https://viem.sh/docs/glossary/terms.html#transaction) hash. + +## Import + +```ts +import { useTransactionReceipt } from '@wagmi/vue' +``` + +## Usage + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseTransactionReceiptParameters } from '@wagmi/vue' +``` + +### hash + +`` `0x${string}` | undefined `` + +A transaction hash. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +The ID of chain to return the transaction receipt from. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/vue/api/createConfig#config) to use instead of retrieving from the [`WagmiPlugin`](/vue/api/WagmiPlugin). + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Composables that have identical context will share the same cache. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseTransactionReceiptReturnType } from '@wagmi/vue' +``` + + + + + +## Action + +- [`getTransactionReceipt`](/core/api/actions/getTransactionReceipt) diff --git a/wagmi-project/site/vue/api/composables/useWaitForTransactionReceipt.md b/wagmi-project/site/vue/api/composables/useWaitForTransactionReceipt.md new file mode 100644 index 000000000..80c887a8f --- /dev/null +++ b/wagmi-project/site/vue/api/composables/useWaitForTransactionReceipt.md @@ -0,0 +1,168 @@ +--- +title: useWaitForTransactionReceipt +description: Composable that waits for the transaction to be included on a block, and then returns the transaction receipt. If the transaction reverts, then the action will throw an error. Replacement detection (e.g. sped up transactions) is also supported. +--- + + + +# useWaitForTransactionReceipt + +Composable that waits for the transaction to be included on a block, and then returns the transaction receipt. If the transaction reverts, then the action will throw an error. Replacement detection (e.g. sped up transactions) is also supported. + +## Import + +```ts +import { useWaitForTransactionReceipt } from '@wagmi/vue' +``` + +## Usage + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type WaitForTransactionReceiptParameters } from '@wagmi/core' +``` + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +```vue [index.vue] + +``` + +### config + +`Config | undefined` + +[`Config`](/vue/api/createConfig#config) to use instead of retrieving from the [`WagmiPlugin`](/vue/api/WagmiPlugin). + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### confirmations + +`number | undefined` + +The number of confirmations (blocks that have passed) to wait before resolving. + +```vue [index.vue] + +``` + +### onReplaced + +` +(({ reason: 'replaced' | 'repriced' | 'cancelled'; replacedTransaction: Transaction; transaction: Transaction; transactionReceipt: TransactionReceipt }) => void) | undefined +` + +Optional callback to emit if the transaction has been replaced. + +```vue [index.vue] + +``` + +### pollingInterval + +`number | undefined` + +- Polling frequency (in milliseconds). +- Defaults to the [Config's `pollingInterval` config](/vue/api/createConfig#pollinginterval). + +```vue [index.vue] + +``` + +### hash + +`` `0x${string}` | undefined `` + +The transaction hash to wait for. [`enabled`](#enabled) set to `false` if `hash` is `undefined`. + +```vue [index.vue] + +``` + + + +## Return Type + +```ts +import { type UseWaitForTransactionReceiptReturnType } from '@wagmi/vue' +``` + + + + + +## Action + +- [`waitForTransactionReceipt`](/core/api/actions/waitForTransactionReceipt) diff --git a/wagmi-project/site/vue/api/composables/useWatchBlockNumber.md b/wagmi-project/site/vue/api/composables/useWatchBlockNumber.md new file mode 100644 index 000000000..5d0a561cd --- /dev/null +++ b/wagmi-project/site/vue/api/composables/useWatchBlockNumber.md @@ -0,0 +1,109 @@ +# useWatchBlockNumber + +Composable that watches for block number changes. + +## Import + +```ts +import { useWatchBlockNumber } from '@wagmi/vue' +``` + +## Usage + +::: code-group +```ts [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseWatchBlockNumberParameters } from '@wagmi/vue' +``` + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to watch blocks at. + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +### emitMissed + +`boolean` + +Whether or not to emit missed blocks to the callback. Defaults to `false`. + +Missed blocks may occur in instances where internet connection is lost, or the block time is lesser than the polling interval of the client. + +### emitOnBegin + +`boolean` + +Whether or not to emit the block to the callback when the subscription opens. Defaults to `false`. + +### enabled + +`boolean` + +Whether or not to watch for blocks. Defaults to `true`. + +### onBlockNumber + +`(block: Block, prevblock: Block | undefined) => void` + +Callback for when block changes. + +### onError + +`((error: Error) => void) | undefined` + +Error thrown from getting the block. + +### poll + +`boolean | undefined` + +- Whether or not to use a polling mechanism to check for new blocks instead of a WebSocket subscription. +- Defaults to `false` for WebSocket Clients, and `true` for non-WebSocket Clients. + +### pollingInterval + +`number | undefined` + +- Polling frequency (in milliseconds). +- Defaults to the [Config's `pollingInterval` config](/core/api/createConfig#pollinginterval). + +### syncConnectedChain + +`boolean | undefined` + +- Set up subscriber for connected chain changes. +- Defaults to [`Config['syncConnectedChain']`](/core/api/createConfig#syncconnectedchain). + +## Return Type + +```ts +import { type UseWatchBlockNumberReturnType } from '@wagmi/vue' +``` + +Function for cleaning up watcher. + +## Action + +- [`watchBlockNumber`](/core/api/actions/watchBlockNumber) diff --git a/wagmi-project/site/vue/api/composables/useWatchContractEvent.md b/wagmi-project/site/vue/api/composables/useWatchContractEvent.md new file mode 100644 index 000000000..5467c49a5 --- /dev/null +++ b/wagmi-project/site/vue/api/composables/useWatchContractEvent.md @@ -0,0 +1,134 @@ +# useWatchContractEvent + +Composable that watches and returns emitted contract event logs. + +## Import + +```ts +import { useWatchContractEvent } from '@wagmi/vue' +``` + +## Usage + +::: code-group +```ts [index.vue] + +``` +<<< @/snippets/abi-event.ts[abi.ts] +<<< @/snippets/vue/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseWatchContractEventParameters } from '@wagmi/vue' +``` + +### abi + +`Abi` + +The contract's ABI. Check out the [TypeScript docs](/vue/typescript#const-assert-abis-typed-data) for how to set up ABIs for maximum type inference and safety. + +### address + +`Address | undefined` + +The contract's address. + +### args + +`object | readonly unknown[] | undefined` + +- Arguments to pass when calling the contract. +- Inferred from [`abi`](#abi) and [`eventName`](#eventname). + +### batch + +`boolean | undefined` + +- Whether or not the events should be batched on each invocation. +- Defaults to `true`. + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +### eventName + +`string` + +- Event to listen for the contract. +- Inferred from [`abi`](#abi). + +### onError + +`((error: Error) => void) | undefined` + +Error thrown from getting the block number. + +### onLogs + +`(logs: Log[], prevLogs: Log[] | undefined) => void` + +Callback for when logs changes. + +### poll + +`boolean | undefined` + +- Whether or not to use a polling mechanism to check for new blocks instead of a WebSocket subscription. +- Defaults to `false` for WebSocket Clients, and `true` for non-WebSocket Clients. + +### pollingInterval + +`number | undefined` + +- Polling frequency (in milliseconds). +- Defaults to the [Config's `pollingInterval` config](/core/api/createConfig#pollinginterval). + +### strict + +`boolean | undefined` + +- Defaults to `false`. + +### syncConnectedChain + +`boolean | undefined` + +- Set up subscriber for connected chain changes. +- Defaults to [`Config['syncConnectedChain']`](/core/api/createConfig#syncconnectedchain). + +## Return Type + +```ts +import { type UseWatchContractEventReturnType } from '@wagmi/vue' +``` + +Hook returns `void` + +## Action + +- [`watchContractEvent`](/core/api/actions/watchContractEvent) + diff --git a/wagmi-project/site/vue/api/composables/useWriteContract.md b/wagmi-project/site/vue/api/composables/useWriteContract.md new file mode 100644 index 000000000..122134585 --- /dev/null +++ b/wagmi-project/site/vue/api/composables/useWriteContract.md @@ -0,0 +1,112 @@ +--- +title: useWriteContract +description: Composable for executing a write function on a contract. +--- + + + +# useWriteContract + +Composable for executing a write function on a contract. + +A "write" function on a Solidity contract modifies the state of the blockchain. These types of functions require gas to be executed, hence a transaction is broadcasted in order to change the state. + +## Import + +```ts +import { useWriteContract } from '@wagmi/vue' +``` + +## Usage + +::: code-group + +```vue [index.vue] + + + +``` + +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/vue/config.ts[config.ts] +::: + + + + + +## Parameters + +```ts +import { type UseWriteContractParameters } from '@wagmi/vue' +``` + +### config + +`Config | undefined` + +[`Config`](/vue/api/createConfig#config) to use instead of retrieving from the [`WagmiPlugin`](/vue/api/WagmiPlugin). + +::: code-group + +```vue [index.vue] + +``` + +<<< @/snippets/vue/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseWriteContractReturnType } from '@wagmi/vue' +``` + +The return type's [`data`](#data) property is inferrable via the combination of [`abi`](#abi), [`functionName`](#functionname), and [`args`](#args). Check out the [TypeScript docs](/vue/typescript#const-assert-abis-typed-data) for more info. + + + +## Type Inference + +With [`abi`](/core/api/actions/writeContract#abi) setup correctly, TypeScript will infer the correct types for [`functionName`](/core/api/actions/writeContract#functionname), [`args`](/core/api/actions/writeContract#args), and the [`value`](/core/api/actions/writeContract##value). See the Wagmi [TypeScript docs](/vue/typescript) for more information. + + + +## Action + +- [`writeContract`](/core/api/actions/writeContract) diff --git a/wagmi-project/site/vue/api/connectors.md b/wagmi-project/site/vue/api/connectors.md new file mode 100644 index 000000000..6d3a18993 --- /dev/null +++ b/wagmi-project/site/vue/api/connectors.md @@ -0,0 +1,28 @@ + + +# Connectors + +Connectors for popular wallet providers and protocols. + +## Import + +Import via the `'@wagmi/vue/connectors'` entrypoint. + +```ts +import { injected } from '@wagmi/vue/connectors' +``` + +## Available Connectors + + diff --git a/wagmi-project/site/vue/api/connectors/coinbaseWallet.md b/wagmi-project/site/vue/api/connectors/coinbaseWallet.md new file mode 100644 index 000000000..839a80f56 --- /dev/null +++ b/wagmi-project/site/vue/api/connectors/coinbaseWallet.md @@ -0,0 +1,6 @@ + + + \ No newline at end of file diff --git a/wagmi-project/site/vue/api/connectors/injected.md b/wagmi-project/site/vue/api/connectors/injected.md new file mode 100644 index 000000000..45c5e158e --- /dev/null +++ b/wagmi-project/site/vue/api/connectors/injected.md @@ -0,0 +1,7 @@ + + + diff --git a/wagmi-project/site/vue/api/connectors/metaMask.md b/wagmi-project/site/vue/api/connectors/metaMask.md new file mode 100644 index 000000000..30d15d779 --- /dev/null +++ b/wagmi-project/site/vue/api/connectors/metaMask.md @@ -0,0 +1,7 @@ + + + diff --git a/wagmi-project/site/vue/api/connectors/mock.md b/wagmi-project/site/vue/api/connectors/mock.md new file mode 100644 index 000000000..532cc19fb --- /dev/null +++ b/wagmi-project/site/vue/api/connectors/mock.md @@ -0,0 +1,6 @@ + + + diff --git a/wagmi-project/site/vue/api/connectors/safe.md b/wagmi-project/site/vue/api/connectors/safe.md new file mode 100644 index 000000000..85fb516ca --- /dev/null +++ b/wagmi-project/site/vue/api/connectors/safe.md @@ -0,0 +1,6 @@ + + + diff --git a/wagmi-project/site/vue/api/connectors/walletConnect.md b/wagmi-project/site/vue/api/connectors/walletConnect.md new file mode 100644 index 000000000..c3840c397 --- /dev/null +++ b/wagmi-project/site/vue/api/connectors/walletConnect.md @@ -0,0 +1,6 @@ + + + diff --git a/wagmi-project/site/vue/api/createConfig.md b/wagmi-project/site/vue/api/createConfig.md new file mode 100644 index 000000000..8210634c0 --- /dev/null +++ b/wagmi-project/site/vue/api/createConfig.md @@ -0,0 +1,7 @@ + + + diff --git a/wagmi-project/site/vue/api/createStorage.md b/wagmi-project/site/vue/api/createStorage.md new file mode 100644 index 000000000..f4901773c --- /dev/null +++ b/wagmi-project/site/vue/api/createStorage.md @@ -0,0 +1,6 @@ + + + diff --git a/wagmi-project/site/vue/api/errors.md b/wagmi-project/site/vue/api/errors.md new file mode 100644 index 000000000..d91415215 --- /dev/null +++ b/wagmi-project/site/vue/api/errors.md @@ -0,0 +1,10 @@ + + +# Errors + +Error classes used by Wagmi. + + \ No newline at end of file diff --git a/wagmi-project/site/vue/api/transports.md b/wagmi-project/site/vue/api/transports.md new file mode 100644 index 000000000..c35d06b63 --- /dev/null +++ b/wagmi-project/site/vue/api/transports.md @@ -0,0 +1,28 @@ + + +# Transports + +[`createConfig`](/vue/api/createConfig) can be instantiated with a set of Transports for each chain. A Transport is the intermediary layer that is responsible for executing outgoing JSON-RPC requests to the RPC Provider (e.g. Alchemy, Infura, etc). + +## Import + +```ts +import { http } from '@wagmi/vue' +``` + +## Built-In Transports + +Available via the `'@wagmi/vue'` entrypoint. + + diff --git a/wagmi-project/site/vue/api/transports/custom.md b/wagmi-project/site/vue/api/transports/custom.md new file mode 100644 index 000000000..4ece9d2d4 --- /dev/null +++ b/wagmi-project/site/vue/api/transports/custom.md @@ -0,0 +1,5 @@ + + + diff --git a/wagmi-project/site/vue/api/transports/fallback.md b/wagmi-project/site/vue/api/transports/fallback.md new file mode 100644 index 000000000..084762db3 --- /dev/null +++ b/wagmi-project/site/vue/api/transports/fallback.md @@ -0,0 +1,5 @@ + + + diff --git a/wagmi-project/site/vue/api/transports/http.md b/wagmi-project/site/vue/api/transports/http.md new file mode 100644 index 000000000..93e1fc3c9 --- /dev/null +++ b/wagmi-project/site/vue/api/transports/http.md @@ -0,0 +1,5 @@ + + + diff --git a/wagmi-project/site/vue/api/transports/unstable_connector.md b/wagmi-project/site/vue/api/transports/unstable_connector.md new file mode 100644 index 000000000..8bb1bfc52 --- /dev/null +++ b/wagmi-project/site/vue/api/transports/unstable_connector.md @@ -0,0 +1,6 @@ + + + diff --git a/wagmi-project/site/vue/api/transports/webSocket.md b/wagmi-project/site/vue/api/transports/webSocket.md new file mode 100644 index 000000000..3559e6ff8 --- /dev/null +++ b/wagmi-project/site/vue/api/transports/webSocket.md @@ -0,0 +1,5 @@ + + + diff --git a/wagmi-project/site/vue/api/utilities/deserialize.md b/wagmi-project/site/vue/api/utilities/deserialize.md new file mode 100644 index 000000000..871aabe90 --- /dev/null +++ b/wagmi-project/site/vue/api/utilities/deserialize.md @@ -0,0 +1,5 @@ + + + diff --git a/wagmi-project/site/vue/api/utilities/serialize.md b/wagmi-project/site/vue/api/utilities/serialize.md new file mode 100644 index 000000000..63abbda16 --- /dev/null +++ b/wagmi-project/site/vue/api/utilities/serialize.md @@ -0,0 +1,5 @@ + + + diff --git a/wagmi-project/site/vue/getting-started.md b/wagmi-project/site/vue/getting-started.md new file mode 100644 index 000000000..c36bceab0 --- /dev/null +++ b/wagmi-project/site/vue/getting-started.md @@ -0,0 +1,217 @@ + + +# Getting Started + +## Overview + +Wagmi is a collection of Vue composition utilities for Ethereum. You can learn more about the rationale behind the project in the [Why Wagmi](/vue/why) section. + +## Automatic Installation + +For new projects, it is recommended to set up your Wagmi app using the [`create-wagmi`](/cli/create-wagmi) command line interface (CLI). This will create a new Wagmi project using TypeScript and install the required dependencies. + +::: code-group +```bash [pnpm] +pnpm create wagmi +``` + +```bash [npm] +npm create wagmi@latest +``` + +```bash [yarn] +yarn create wagmi +``` + +```bash [bun] +bun create wagmi +``` +::: + +Once the command runs, you'll see some prompts to complete. + +```ansi +Project name: wagmi-project +Select a framework: Vue / Vanilla +... +``` + +After the prompts, `create-wagmi` will create a directory with your project name and install the required dependencies. Check out the `README.md` for further instructions (if required). + +## Manual Installation + +To manually add Wagmi to your project, install the required packages. + +::: code-group +```bash-vue [pnpm] +pnpm add @wagmi/vue viem@{{viemVersion}} @tanstack/vue-query +``` + +```bash-vue [npm] +npm install @wagmi/vue viem@{{viemVersion}} @tanstack/vue-query +``` + +```bash-vue [yarn] +yarn add @wagmi/vue viem@{{viemVersion}} @tanstack/vue-query +``` + +```bash-vue [bun] +bun add @wagmi/vue viem@{{viemVersion}} @tanstack/vue-query +``` +::: + +- [Viem](https://viem.sh) is a TypeScript interface for Ethereum that performs blockchain operations. +- [TanStack Query](https://tanstack.com/query/v5) is an async state manager that handles requests, caching, and more. +- [TypeScript](/vue/typescript) is optional, but highly recommended. Learn more about [TypeScript support](/vue/typescript). + +### Create Config + +Create and export a new Wagmi config using `createConfig`. + +::: code-group +<<< @/snippets/vue/config.ts[config.ts] +::: + +In this example, Wagmi is configured to use the Mainnet and Sepolia chains, and `injected` connector. Check out the [`createConfig` docs](/vue/api/createConfig) for more configuration options. + +::: details TypeScript Tip +If you are using TypeScript, you can "register" the Wagmi config or use the hook `config` property to get strong type-safety in places that wouldn't normally have type info. + +::: code-group +```ts twoslash [register config] +// @errors: 2322 +import { type Config } from '@wagmi/vue' +import { mainnet, sepolia } from '@wagmi/vue/chains' + +declare const config: Config +// ---cut--- +import { useBlockNumber } from '@wagmi/vue' + +useBlockNumber({ chainId: 123 }) + +declare module '@wagmi/vue' { + interface Register { + config: typeof config + } +} +``` + +```ts twoslash [hook config property] +// @errors: 2322 +import { type Config } from '@wagmi/vue' +import { mainnet, sepolia } from '@wagmi/vue/chains' + +declare const config: Config +// ---cut--- +import { useBlockNumber } from '@wagmi/vue' + +useBlockNumber({ chainId: 123, config }) +``` + +By registering or using the hook `config` property, `useBlockNumber`'s `chainId` is strongly typed to only allow Mainnet and Sepolia IDs. Learn more by reading the [TypeScript docs](/vue/typescript#config-types). +::: + +### Add Plugin to App + +Add the `WagmiPlugin` to your app instance and pass the `config` you created earlier to the plugin options. + +::: code-group +```tsx [main.ts] +import { WagmiPlugin } from '@wagmi/vue' // [!code focus] +import { createApp } from 'vue' +import { config } from './config' // [!code focus] +import App from './App.vue' + +createApp(App) + .use(WagmiPlugin, { config }) // [!code focus] + .mount('#app') +``` +```vue [App.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +Check out the [`WagmiPlugin` docs](/vue/api/WagmiPlugin) to learn more about the plugin API. + +### Setup TanStack Query + +After the `WagmiPlugin`, attach the `VueQueryPlugin` to your app, and pass a new `QueryClient` instance to the `queryClient` property. + +::: code-group +```tsx [main.ts] +import { QueryClient, VueQueryPlugin } from '@tanstack/vue-query' // [!code focus] +import { WagmiPlugin } from '@wagmi/vue' +import { createApp } from 'vue' +import { config } from './config' +import App from './App.vue' + +const queryClient = new QueryClient() // [!code focus] + +createApp(App) + .use(WagmiPlugin, { config }) + .use(VueQueryPlugin, { queryClient }) // [!code focus] + .mount('#app') +``` +```vue [App.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +Check out the [TanStack Query docs](https://tanstack.com/query/latest/docs/framework/vue) to learn about the library, APIs, and more. + +### Use Wagmi + +Now that everything is set up, every component inside your app can use Wagmi Vue Composables. + +::: code-group +```vue [App.vue] + + + +``` +```tsx [main.ts] +import { QueryClient, VueQueryPlugin } from '@tanstack/vue-query' +import { WagmiPlugin } from '@wagmi/vue' +import { createApp } from 'vue' +import { config } from './config' +import App from './App.vue' + +const queryClient = new QueryClient() + +createApp(App) + .use(WagmiPlugin, { config }) + .use(VueQueryPlugin, { queryClient }) + .mount('#app') +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + + +## Next Steps + +For more information on what to do next, check out the following topics. + +- [**TypeScript**](/vue/typescript) Learn how to get the most out of Wagmi's type-safety and inference for an enlightened developer experience. +- [**Connect Wallet**](/vue/guides/connect-wallet) Learn how to enable wallets to connect to and disconnect from your apps and display information about connected accounts. +- [**Vue Composables**](/vue/api/composables) Browse the collection of Vue Composables and learn how to use them. +- [**Viem**](/vue/guides/viem) Learn about Viem and how it works with Wagmi. + diff --git a/wagmi-project/site/vue/guides/chain-properties.md b/wagmi-project/site/vue/guides/chain-properties.md new file mode 100644 index 000000000..0f41ef41c --- /dev/null +++ b/wagmi-project/site/vue/guides/chain-properties.md @@ -0,0 +1,97 @@ +# Chain Properties + +Some chains support additional properties related to blocks and transactions. This is powered by Viem's [formatters](https://viem.sh/docs/chains/formatters) and [serializers](https://viem.sh/docs/chains/serializers). For example, Celo, ZkSync, OP Stack chains support all support additional properties. In order to use these properties in a type-safe way, there are a few things you should be aware of. + +
+ +::: tip +Make sure you follow the TypeScript guide's [Config Types](/vue/typescript#config-types) section before moving on. The easiest way to do this is to use [Declaration Merging](/vue/typescript#declaration-merging) to "register" your `config` globally with TypeScript. + +<<< @/snippets/vue/config-chain-properties.ts[config.ts] +::: + +## Narrowing Parameters + +Once your Config is registered with TypeScript, you are ready to access chain-specific properties! For example, Celo's `feeCurrency` is available. + +::: code-group +```ts [index.tsx] +import { parseEther } from 'viem' +import { useSimulateContract } from '@wagmi/vue' + +const result = useSimulateContract({ + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), + feeCurrency: '0x…', // [!code focus] +}) +``` +<<< @/snippets/vue/config-chain-properties.ts[config.ts] +::: + +This is great, but if you have multiple chains that support additional properties, your autocomplete could be overwhelmed with all of them. By setting the `chainId` property to a specific value (e.g. `celo.id`), you can narrow parameters to a single chain. + +::: code-group +```ts [index.tsx] +import { parseEther } from 'viem' +import { useSimulateContract } from '@wagmi/vue' +import { celo } from '@wagmi/vue/chains' + +const result = useSimulateContract({ + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), + chainId: celo.id, // [!code focus] + feeCurrency: '0x…', // [!code focus] + // ^? (property) feeCurrency?: `0x${string}` | undefined // [!code focus] +}) +``` +<<< @/snippets/vue/config-chain-properties.ts[config.ts] +::: + +## Narrowing Return Types + +Return types can also have chain-specific properties attached to them. There are a couple approaches for extracting these properties. + +### `chainId` Parameter + +Not only can you use the `chainId` parameter to [narrow parameters](#narrowing-parameters), you can also use it to narrow the return type. + +::: code-group +```ts [index.tsx] +import { useWaitForTransactionReceipt } from '@wagmi/vue' +import { zkSync } from '@wagmi/vue/chains' + +const { data } = useWaitForTransactionReceipt({ + chainId: zkSync.id, + hash: '0x16854fcdd0219cacf5aec5e4eb2154dac9e406578a1510a6fc48bd0b67e69ea9', +}) + +data?.logs +// ^? (property) logs: ZkSyncLog[] | undefined +``` +<<< @/snippets/vue/config-chain-properties.ts[config.ts] +::: + +### `chainId` Data Property + +Wagmi internally will set a `chainId` property on return types that you can use to narrow results. The `chainId` is determined from the `chainId` parameter or global state (e.g. connector). You can use this property to help TypeScript narrow the type. + +::: code-group +```ts [index.tsx] +import { useWaitForTransactionReceipt } from '@wagmi/vue' +import { zkSync } from '@wagmi/vue/chains' + +const { data } = useWaitForTransactionReceipt({ + hash: '0x16854fcdd0219cacf5aec5e4eb2154dac9e406578a1510a6fc48bd0b67e69ea9', +}) + +if (data?.chainId === zkSync.id) { + data?.logs + // ^? (property) logs: ZkSyncLog[] | undefined +} +``` +<<< @/snippets/vue/config-chain-properties.ts[config.ts] +::: + +## Troubleshooting + +If chain properties aren't working, make sure [TypeScript](/vue/guides/faq#type-inference-doesn-t-work) is configured correctly. Not all chains have additional properties, to check which ones do, see the [Viem repo](https://github.com/wevm/viem/tree/main/src/chains) (chains that have a top-level directory under [`src/chains`](https://github.com/wevm/viem/tree/main/src/chains) support additional properties). diff --git a/wagmi-project/site/vue/guides/connect-wallet.md b/wagmi-project/site/vue/guides/connect-wallet.md new file mode 100644 index 000000000..89e795ac7 --- /dev/null +++ b/wagmi-project/site/vue/guides/connect-wallet.md @@ -0,0 +1,387 @@ +# Connect Wallet + +The ability for a user to connect their wallet is a core function for any Dapp. It allows users to perform tasks such as: writing to contracts, signing messages, or sending transactions. + +Wagmi contains everything you need to get started with building a Connect Wallet module. To get started, you can either use a [third-party library](#third-party-libraries) or [build your own](#build-your-own). + +## Third-party Libraries + +You can use a pre-built Connect Wallet module from a third-party library such as: + +- [AppKit](https://walletconnect.com/appkit) - [Guide](https://docs.walletconnect.com/appkit/vue/core/installation) + +The above libraries are all built on top of Wagmi, handle all the edge cases around wallet connection, and provide a seamless Connect Wallet UX that you can use in your Dapp. + +## Build Your Own + +Wagmi provides you with the Composables to get started building your own Connect Wallet module. + +It takes less than five minutes to get up and running with Browser Wallets, WalletConnect, and Coinbase Wallet. + +### 1. Configure Wagmi + +Before we get started with building the functionality of the Connect Wallet module, we will need to set up the Wagmi configuration. + +Let's create a `config.ts` file and export a `config` object. + +::: code-group + +```tsx [config.ts] +import { http, createConfig } from '@wagmi/vue' +import { base, mainnet, optimism } from '@wagmi/vue/chains' +import { injected, metaMask, safe, walletConnect } from '@wagmi/vue/connectors' + +const projectId = '' + +export const config = createConfig({ + chains: [mainnet, base], + connectors: [ + injected(), + walletConnect({ projectId }), + metaMask(), + safe(), + ], + transports: { + [mainnet.id]: http(), + [base.id]: http(), + }, +}) +``` + +::: + +In the above configuration, we want to set up connectors for Injected (browser), WalletConnect (browser + mobile), MetaMask, and Safe wallets. This configuration uses the **Mainnet** and **Base** chains, but you can use whatever you want. + +::: warning + +Make sure to replace the `projectId` with your own WalletConnect Project ID, if you wish to use WalletConnect! + +[Get your Project ID](https://cloud.walletconnect.com/) + +::: + +### 2. Inject the WagmiPlugin onto your App + +Next, we will need to inject our App with plugins so that our application is aware of Wagmi & Vue Query's reactive state and in-memory caching. + +::: code-group + +```ts [main.ts] +// 1. Import modules. +import { VueQueryPlugin } from '@tanstack/vue-query'; +import { WagmiPlugin } from '@wagmi/vue'; +import { createApp } from 'vue'; + +import App from './App.vue'; +import { config } from './wagmi'; + +createApp(App) + // 2. Inject the Wagmi plugin. + .use(WagmiPlugin, { config }) + // 3. Inject the Vue Query plugin. + .use(VueQueryPlugin, {}) + .mount('#app'); +``` + +```vue [App.vue] + + + +``` + +```ts [config.ts] +import { http, createConfig } from '@wagmi/vue' +import { base, mainnet, optimism } from '@wagmi/vue/chains' +import { injected, metaMask, safe, walletConnect } from '@wagmi/vue/connectors' + +const projectId = '' + +export const config = createConfig({ + chains: [mainnet, base], + connectors: [ + injected(), + walletConnect({ projectId }), + metaMask(), + safe(), + ], + transports: { + [mainnet.id]: http(), + [base.id]: http(), + }, +}) +``` + +::: + +### 3. Display Wallet Options + +After that, we will create a `Connect` component that will display our connectors. This will allow users to select a wallet and connect. + +Below, we are rendering a list of `connectors` retrieved from `useConnect`. When the user clicks on a connector, the `connect` function will connect the users' wallet. + +::: code-group + +```vue [Connect.vue] + + + +``` + +```vue [App.vue] + + + +``` + +```ts [main.ts] +// 1. Import modules. +import { VueQueryPlugin } from '@tanstack/vue-query'; +import { WagmiPlugin } from '@wagmi/vue'; +import { createApp } from 'vue'; + +import App from './App.vue'; +import { config } from './wagmi'; + +createApp(App) + // 2. Inject the Wagmi plugin. + .use(WagmiPlugin, { config }) + // 3. Inject the Vue Query plugin. + .use(VueQueryPlugin, {}) + .mount('#app'); +``` + +```ts [config.ts] +import { http, createConfig } from '@wagmi/vue' +import { base, mainnet, optimism } from '@wagmi/vue/chains' +import { injected, metaMask, safe, walletConnect } from '@wagmi/vue/connectors' + +const projectId = '' + +export const config = createConfig({ + chains: [mainnet, base], + connectors: [ + injected(), + walletConnect({ projectId }), + metaMask(), + safe(), + ], + transports: { + [mainnet.id]: http(), + [base.id]: http(), + }, +}) +``` + +::: + +### 4. Display Connected Account + +Lastly, if an account is connected, we want to show some basic information, like the connected address and ENS name and avatar. + +Below, we are using hooks like `useAccount`, `useEnsAvatar` and `useEnsName` to extract this information. + +We are also utilizing `useDisconnect` to show a "Disconnect" button so a user can disconnect their wallet. + +::: code-group + +```vue [Account.vue] + + + +``` + +```vue [Connect.vue] + + + +``` + +```vue [App.vue] + + + +``` + +```ts [main.ts] +// 1. Import modules. +import { VueQueryPlugin } from '@tanstack/vue-query'; +import { WagmiPlugin } from '@wagmi/vue'; +import { createApp } from 'vue'; + +import App from './App.vue'; +import { config } from './wagmi'; + +createApp(App) + // 2. Inject the Wagmi plugin. + .use(WagmiPlugin, { config }) + // 3. Inject the Vue Query plugin. + .use(VueQueryPlugin, {}) + .mount('#app'); +``` + +```ts [config.ts] +import { http, createConfig } from '@wagmi/vue' +import { base, mainnet, optimism } from '@wagmi/vue/chains' +import { injected, metaMask, safe, walletConnect } from '@wagmi/vue/connectors' + +const projectId = '' + +export const config = createConfig({ + chains: [mainnet, base], + connectors: [ + injected(), + walletConnect({ projectId }), + metaMask(), + safe(), + ], + transports: { + [mainnet.id]: http(), + [base.id]: http(), + }, +}) +``` + +::: + +### 5. Wire it up! + +Finally, we can wire up our Connect and Account components to our application's entrypoint. + +::: code-group + +```vue [App.vue] + + + + +``` + +```vue [Account.vue] + + + +``` + +```vue [Connect.vue] + + + +``` + +```ts [main.ts] +// 1. Import modules. +import { VueQueryPlugin } from '@tanstack/vue-query'; +import { WagmiPlugin } from '@wagmi/vue'; +import { createApp } from 'vue'; + +import App from './App.vue'; +import { config } from './wagmi'; + +createApp(App) + // 2. Inject the Wagmi plugin. + .use(WagmiPlugin, { config }) + // 3. Inject the Vue Query plugin. + .use(VueQueryPlugin, {}) + .mount('#app'); +``` + +```ts [config.ts] +import { http, createConfig } from '@wagmi/vue' +import { base, mainnet, optimism } from '@wagmi/vue/chains' +import { injected, metaMask, safe, walletConnect } from '@wagmi/vue/connectors' + +const projectId = '' + +export const config = createConfig({ + chains: [mainnet, base], + connectors: [ + injected(), + walletConnect({ projectId }), + metaMask(), + safe(), + ], + transports: { + [mainnet.id]: http(), + [base.id]: http(), + }, +}) +``` + +::: + +### Playground + +Want to see the above steps all wired up together in an end-to-end example? Check out the below StackBlitz playground. + +
+ + diff --git a/wagmi-project/site/vue/guides/error-handling.md b/wagmi-project/site/vue/guides/error-handling.md new file mode 100644 index 000000000..8cb7e9b50 --- /dev/null +++ b/wagmi-project/site/vue/guides/error-handling.md @@ -0,0 +1,39 @@ +# Error Handling + +The `error` property in Wagmi Composables is strongly typed with it's corresponding error type. This enables you to have granular precision with handling errors in your application. + +You can discriminate the error type by using the `name` property on the error object. + +::: code-group +```vue twoslash [index.vue] + + + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: diff --git a/wagmi-project/site/vue/guides/faq.md b/wagmi-project/site/vue/guides/faq.md new file mode 100644 index 000000000..61def1c79 --- /dev/null +++ b/wagmi-project/site/vue/guides/faq.md @@ -0,0 +1,9 @@ + + +# FAQ / Troubleshooting + +Collection of frequently asked questions with ideas on how to troubleshoot and resolve them. + + diff --git a/wagmi-project/site/vue/guides/read-from-contract.md b/wagmi-project/site/vue/guides/read-from-contract.md new file mode 100644 index 000000000..8bf78acc9 --- /dev/null +++ b/wagmi-project/site/vue/guides/read-from-contract.md @@ -0,0 +1,206 @@ +# Read from Contract + +## Overview + +The [`useReadContract` Composable](/vue/api/composables/useReadContract) allows you to read data on a smart contract, from a `view` or `pure` (read-only) function. They can only read the state of the contract, and cannot make any changes to it. Since read-only methods do not change the state of the contract, they do not require any gas to be executed, and can be called by any user without the need to pay for gas. + +The component below shows how to retrieve the token balance of an address from the [Wagmi Example](https://etherscan.io/token/0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2) contract + +:::code-group + +```vue [ReadContract.vue] + + + +``` +```ts [contracts.ts] +export const wagmiContractConfig = { + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + abi: [ + { + type: 'function', + name: 'balanceOf', + stateMutability: 'view', + inputs: [{ name: 'account', type: 'address' }], + outputs: [{ type: 'uint256' }], + }, + { + type: 'function', + name: 'totalSupply', + stateMutability: 'view', + inputs: [], + outputs: [{ name: 'supply', type: 'uint256' }], + }, + ], +} as const +``` +::: + + +If `useReadContract` depends on another value (`address` in the example below), you can use the [`query.enabled`](/vue/api/composables/useReadContract#enabled) option to prevent the query from running until the dependency is ready. + +```tsx +const { data: balance } = useReadContract({ + ...wagmiContractConfig, + functionName: 'balanceOf', + args: [address], + query: { // [!code focus] + enabled: !!address, // [!code focus] + }, // [!code focus] +}) +``` + + +## Loading & Error States + +The [`useReadContract` Composable](/vue/api/composables/useReadContract) also returns loading & error states, which can be used to display a loading indicator while the data is being fetched, or an error message if contract execution reverts. + +:::code-group + +```vue [ReadContract.vue] + + + +``` + +::: + + + + diff --git a/wagmi-project/site/vue/guides/send-transaction.md b/wagmi-project/site/vue/guides/send-transaction.md new file mode 100644 index 000000000..6686e720b --- /dev/null +++ b/wagmi-project/site/vue/guides/send-transaction.md @@ -0,0 +1,311 @@ +# Send Transaction + +The following guide teaches you how to send transactions in Wagmi. The example below builds on the [Connect Wallet guide](/vue/guides/connect-wallet) and uses the [useSendTransaction](/vue/api/composables/useSendTransaction) & [useWaitForTransaction](/vue/api/composables/useWaitForTransactionReceipt) composables. + +## Example + +Feel free to check out the example before moving on: + + + +## Steps + +### 1. Connect Wallet + +Follow the [Connect Wallet guide](/vue/guides/connect-wallet) guide to get this set up. + +### 2. Create a new component + +Create your `SendTransaction` component that will contain the send transaction logic. + +::: code-group + +```tsx [SendTransaction.vue] + + + +``` + +::: + +### 3. Add a form handler + +Next, we will need to add a handler to the form that will send the transaction when the user hits "Send". This will be a basic handler in this step. + +::: code-group + +```vue [SendTransaction.vue] + + + +``` + +::: + +### 4. Hook up the `useSendTransaction` Composable + +Now that we have the form handler, we can hook up the [`useSendTransaction` Composable](/vue/api/composables/useSendTransaction) to send the transaction. + +::: code-group + +```vue [SendTransaction.vue] + + + +``` + +::: + +### 5. Add loading state (optional) + +We can optionally add a loading state to the "Send" button while we are waiting confirmation from the user's wallet. + +::: code-group + +```vue [SendTransaction.vue] + + + +``` + +::: + +### 6. Wait for transaction receipt (optional) + +We can also display the transaction confirmation status to the user by using the [`useWaitForTransactionReceipt` Composable](/vue/api/composables/useWaitForTransactionReceipt). + +::: code-group + +```vue [SendTransaction.vue] + + + +``` + +::: + +### 7. Handle errors (optional) + +If the user rejects the transaction, or the user does not have enough funds to cover the transaction, we can display an error message to the user. + +::: code-group + +```vue [SendTransaction.vue] + + + +``` + +::: + +### 8. Wire it up! + +Finally, we can wire up our Send Transaction component to our application's entrypoint. + +:::code-group +```vue [App.vue] + + + +``` +```vue [SendTransaction.vue] + + + +``` +::: + +[See the Example.](#example) diff --git a/wagmi-project/site/vue/guides/ssr.md b/wagmi-project/site/vue/guides/ssr.md new file mode 100644 index 000000000..bf6fc4e2e --- /dev/null +++ b/wagmi-project/site/vue/guides/ssr.md @@ -0,0 +1,77 @@ +--- +outline: deep +--- + +# SSR + +Wagmi uses client-only external stores (such as `localStorage` and `mipd`) to show the user the most relevant data as quickly as possible on first render. + +However, the caveat of using these external client stores is that frameworks which incorporate SSR (such as Next.js) will throw hydration warnings on the client when it identifies mismatches between the server-rendered HTML and the client-rendered HTML. + +To stop this from happening, you can toggle on the [`ssr`](/vue/api/createConfig#ssr) property in the Wagmi Config. + +```tsx +import { createConfig, http } from '@wagmi/vue' +import { mainnet, sepolia } from '@wagmi/vue/chains' + +const config = createConfig({ // [!code focus:99] + chains: [mainnet, sepolia], + ssr: true, // [!code ++] + transports: { + [mainnet.id]: http(), + [sepolia.id]: http(), + }, +}) +``` + +Turning on the `ssr` property means that content from the external stores will be hydrated on the client after the initial mount. + +## Persistence using Cookies + +As a result of turning on the `ssr` property, external persistent stores like `localStorage` will be hydrated on the client **after the initial mount**. + +This means that you will still see a flash of "empty" data on the client (e.g. a `"disconnected"` account instead of a `"reconnecting"` account, or an empty address instead of the last connected address) until after the first mount, when the store hydrates. + +In order to persist data between the server and the client, you can use cookies. + +### 1. Set up cookie storage + +First, we will set up cookie storage in the Wagmi Config. + +```tsx +import { + createConfig, + http, + cookieStorage, // [!code ++] + createStorage // [!code ++] +} from '@wagmi/vue' +import { mainnet, sepolia } from '@wagmi/vue/chains' + +export const config = createConfig({ + chains: [mainnet, sepolia], + ssr: true, + storage: createStorage({ // [!code ++] + storage: cookieStorage, // [!code ++] + }), // [!code ++] + transports: { + [mainnet.id]: http(), + [sepolia.id]: http(), + }, +}) +``` + +### 2. Hydrate the cookie + +Next, we will need to add some mechanisms to hydrate the stored cookie in Wagmi. + +#### Nuxt.js + +Would you like to contribute this content? Feel free to [open a Pull Request](https://github.com/wevm/wagmi/pulls)! + + +#### Vanilla SSR + +Would you like to contribute this content? Feel free to [open a Pull Request](https://github.com/wevm/wagmi/pulls)! + + + diff --git a/wagmi-project/site/vue/guides/tanstack-query.md b/wagmi-project/site/vue/guides/tanstack-query.md new file mode 100644 index 000000000..9d5efb4d7 --- /dev/null +++ b/wagmi-project/site/vue/guides/tanstack-query.md @@ -0,0 +1,287 @@ +# TanStack Query + +Wagmi Composables are not only a wrapper around the core [Wagmi Actions](/core/api/actions), but they also utilize [TanStack Query](https://tanstack.com/query/v5) to enable trivial and intuitive fetching, caching, synchronizing, and updating of asynchronous data in your Vue applications. + +Without an asynchronous data fetching abstraction, you would need to handle all the negative side-effects that comes as a result, such as: representing finite states (loading, error, success), handling race conditions, caching against a deterministic identifier, etc. + +## Queries & Mutations + +Wagmi Composables represent either a **Query** or a **Mutation**. + +**Queries** are used for fetching data (e.g. fetching a block number, reading from a contract, etc), and are typically invoked on mount by default. All queries are coupled to a unique [Query Key](#query-keys), and can be used for further operations such as refetching, prefetching, or modifying the cached data. + +**Mutations** are used for mutating data (e.g. connecting/disconnecting accounts, writing to a contract, switching chains, etc), and are typically invoked in response to a user interaction. Unlike **Queries**, they are not coupled with a query key. + +## Terms + +- **Query**: An asynchronous data fetching (e.g. read data) operation that is tied against a unique Query Key. +- **Mutation**: An asynchronous mutating (e.g. create/update/delete data or side-effect) operation. +- **Query Key**: A unique identifier that is used to deterministically identify a query. It is typically a tuple of the query name and the query arguments. +- **Stale Data**: Data that is unused or inactive after a certain period of time. +- **Query Fetching**: The process of invoking an async query function. +- **Query Refetching**: The process of refetching **rendered** queries. +- **[Query Invalidation](https://tanstack.com/query/v5/docs/vue/guides/query-invalidation)**: The process of marking query data as stale (e.g. inactive/unused), and refetching **rendered** queries. +- **[Query Prefetching](https://tanstack.com/query/v5/docs/vue/guides/prefetching)**: The process of prefetching queries and seeding the cache. + + + +## Query Keys + +Query Keys are typically used to perform advanced operations on the query such as: invalidation, refetching, prefetching, etc. + +Wagmi exports Query Keys for every Composable, and they can be retrieved via the [Composable (Vue)](#composable-vue) or via an [Import (Vanilla JS)](#import-vanilla-js). + +Read more about **Query Keys** on the [TanStack Query docs.](https://tanstack.com/query/v5/docs/vue/guides/query-keys) + +### Composable (Vue) + +Each Composable returns a `queryKey` value. You would use this approach when you want to utilize the query key in a Vue component as it handles reactivity for you, unlike the [Import](#import-vanilla-js) method below. + +```vue [index.vue] + + + +``` + +### Import (Vanilla JS) + +Each Hook has a corresponding `getQueryOptions` function that returns a query key. You would use this method when you want to utilize the query key outside of a Vue component in a Vanilla JS context, like in a utility function. + +```ts +import { getBalanceQueryOptions } from '@wagmi/vue/query' // [!code hl] +import { config } from './config' + +function perform() { + const { queryKey } = getBalanceQueryOptions(config, { // [!code hl] + chainId: config.state.chainId // [!code hl] + }) // [!code hl] +} +``` + +::: warning + +The caveat of this method is that it does not handle reactivity for you (e.g. active account/chain changes, argument changes, etc). You would need to handle this yourself by explicitly passing through the arguments to `getQueryOptions`. + +::: + +## Invalidating Queries + +Invalidating a query is the process of marking the query data as stale (e.g. inactive/unused), and refetching the queries that are already rendered. + +Read more about **Invalidating Queries** on the [TanStack Query docs.](https://tanstack.com/query/v5/docs/vue/guides/query-invalidation) + +#### Example: Watching a Users' Balance + +You may want to "watch" a users' balance, and invalidate the balance after each incoming block. We can invoke `invalidateQueries` inside a `watchEffect` – this will refetch all rendered balance queries when the `blockNumber` changes. + +```vue + + + +``` + +#### Example: After User Interaction + +Maybe you want to invalidate a users' balance after some interaction. This would mark the balance as stale, and consequently refetch all rendered balance queries. + +```vue + + + +``` + +```vue + + + +``` + +## Fetching Queries + +Fetching a query is the process of invoking the query function to retrieve data. If the query exists and the data is not invalidated or older than a given `staleTime`, then the data from the cache will be returned. Otherwise, the query will fetch for the latest data. + +::: code-group +```tsx [example.tsx] +import { getBlockQueryOptions } from '@wagmi/vue/query' +import { queryClient } from './main' +import { config } from './config' + +export async function fetchBlockData() { + return queryClient.fetchQuery( // [!code hl] + getBlockQueryOptions(config, { // [!code hl] + chainId: config.state.chainId, // [!code hl] + } // [!code hl] + )) // [!code hl] +} +``` +<<< @/snippets/vue/main.ts[main.ts] +<<< @/snippets/vue/config.ts[config.ts] +::: + +## Retrieving & Updating Query Data + +You can retrieve and update query data imperatively with `getQueryData` and `setQueryData`. This is useful for scenarios where you want to retrieve or update a query outside of a Vue component. + +Note that these functions do not invalidate or refetch queries. + +::: code-group +```tsx [example.tsx] +import type { GetBalanceReturnType } from '@wagmi/vue/actions' +import { getBalanceQueryOptions } from '@wagmi/vue/query' +import { queryClient } from './app' +import { config } from './config' + +export function getBalanceData() { + return queryClient.getQueryData( // [!code hl] + getBalanceQueryOptions(config, { // [!code hl] + chainId: config.state.chainId, // [!code hl] + } // [!code hl] + )) // [!code hl] +} + +export function setBalanceData(parameters: Partial) { + return queryClient.setQueryData( // [!code hl] + getBalanceQueryOptions(config, { // [!code hl] + chainId: config.state.chainId, // [!code hl] + }, // [!code hl] + data => ({ ...data, ...parameters }) // [!code hl] + )) // [!code hl] +} +``` +<<< @/snippets/vue/main.ts[main.ts] +<<< @/snippets/vue/config.ts[config.ts] +::: + +## Prefetching Queries + +Prefetching a query is the process of fetching the data ahead of time and seeding the cache with the returned data. This is useful for scenarios where you want to fetch data before the user navigates to a page, or fetching data on the server to be reused on client hydration. + +Read more about **Prefetching Queries** on the [TanStack Query docs.](https://tanstack.com/query/v5/docs/vue/guides/prefetching) + +#### Example: Prefetching in Event Handler + +```vue + + + +``` + +## SSR + +It is possible to utilize TanStack Query's SSR strategies with Wagmi Composables & Query Keys. Check out the [SSR guide](https://tanstack.com/query/latest/docs/framework/vue/guides/ssr). + +## Devtools + +TanStack Query includes dedicated [Devtools](https://tanstack.com/query/latest/docs/framework/vue/devtools) that assist in visualizing and debugging your queries, their cache states, and much more. You will have to pass a custom `queryKeyFn` to your `QueryClient` for Devtools to correctly serialize BigInt values for display. Alternatively, You can use the `hashFn` from `@wagmi/core/query`, which already handles this serialization. + +#### Install + +::: code-group +```bash [pnpm] +pnpm i @tanstack/vue-query-devtools +``` + +```bash [npm] +npm i @tanstack/vue-query-devtools +``` + +```bash [yarn] +yarn add @tanstack/vue-query-devtools +``` + +```bash [bun] +bun i @tanstack/vue-query-devtools +``` +::: + +#### Usage + +::: code-group +```vue [App.vue] + + + +``` + +```vue [main.vue] + +``` +::: \ No newline at end of file diff --git a/wagmi-project/site/vue/guides/viem.md b/wagmi-project/site/vue/guides/viem.md new file mode 100644 index 000000000..a4b7da32d --- /dev/null +++ b/wagmi-project/site/vue/guides/viem.md @@ -0,0 +1,94 @@ +# Viem + +[Viem](https://viem.sh) is a low-level TypeScript Interface for Ethereum that enables developers to interact with the Ethereum blockchain, including: JSON-RPC API abstractions, Smart Contract interaction, wallet & signing implementations, coding/parsing utilities and more. + +**Wagmi Core** is essentially a wrapper over **Viem** that provides multi-chain functionality via [Wagmi Config](/react/api/createConfig) and automatic account management via [Connectors](/react/api/connectors). + +## Leveraging Viem Actions + +All of the core [Wagmi Composables](/vue/api/composables) are friendly wrappers around [Viem Actions](https://viem.sh/docs/actions/public/introduction.html) that inject a multi-chain and connector aware [Wagmi Config](/vue/api/createConfig). + +There may be cases where you might want to dig deeper and utilize Viem Actions directly (maybe a Composable doesn't exist in Wagmi yet). In these cases, you can create your own custom Wagmi Composable by importing Viem Actions directly via `viem/actions` and plugging in a Viem Client returned by the [`useClient` Composable](/vue/api/composables/useClient). + +There are two categories of Viem Actions: + +- **[Public Actions](https://viem.sh/docs/actions/public/introduction):** Actions that are "read-only" and do not require a wallet connection. +- **[Wallet Actions](https://viem.sh/docs/actions/wallet/introduction):** Actions that interface with a Wallet and require a wallet connection. + +While it is not mandatory, it is also recommended to pair Actions with either `useQuery` or `useMutation` to effectively leverage the reactivity and caching capabilities of [Tanstack Query](/vue/guides/tanstack-query). + +### Public Actions + +The example below demonstrates how to utilize Viem's `getLogs` Action with a `useQuery` Composable to create your own abstraction akin to a `useLogs` Composable. + +```vue + +``` + +### Wallet Actions + +The example below demonstrates how to utilize Viem's `watchAsset` Action with a `useMutation` Composable to create your own abstraction akin to a `useWatchAsset` Composable. + +```vue + +``` + +## Private Key & Mnemonic Accounts + +It is possible to utilize Viem's [Private Key & Mnemonic Accounts](https://viem.sh/docs/accounts/local.html) with Wagmi by explicitly passing through the account via the `account` argument on Wagmi Actions. + +```vue + +``` + +::: info + +Wagmi currently does not support hoisting Private Key & Mnemonic Accounts to the top-level Wagmi Config – meaning you have to explicitly pass through the account to every Action. If you feel like this is a feature that should be added, please [open an discussion](https://github.com/wevm/wagmi/discussions/new?category=ideas). + +::: diff --git a/wagmi-project/site/vue/guides/write-to-contract.md b/wagmi-project/site/vue/guides/write-to-contract.md new file mode 100644 index 000000000..9bdc78842 --- /dev/null +++ b/wagmi-project/site/vue/guides/write-to-contract.md @@ -0,0 +1,387 @@ +# Write to Contract + +The [`useWriteContract` Composable](/vue/api/composables/useWriteContract) allows you to mutate data on a smart contract, from a `payable` or `nonpayable` (write) function. These types of functions require gas to be executed, hence a transaction is broadcasted in order to change the state. + +In the guide below, we will teach you how to implement a "Mint NFT" form that takes in a dynamic argument (token ID) using Wagmi. The example below builds on the [Connect Wallet guide](/vue/guides/connect-wallet) and uses the [useWriteContract](/vue/api/composables/useWriteContract) & [useWaitForTransaction](/vue/api/composables/useWaitForTransactionReceipt) composables. + +If you have already completed the [Sending Transactions guide](/vue/guides/send-transaction), this guide will look very similar! That's because writing to a contract internally broadcasts & sends a transaction. + +## Example + +Feel free to check out the example before moving on: + + + +## Steps + +### 1. Connect Wallet + +Follow the [Connect Wallet guide](/vue/guides/connect-wallet) guide to get this set up. + +### 2. Create a new component + +Create your `MintNft` component that will contain the Mint NFT logic. + +::: code-group + +```vue [MintNft.vue] + + + +``` + +::: + +### 3. Add a form handler + +Next, we will need to add a handler to the form that will send the transaction when the user hits "Mint". This will be a basic handler in this step. + +::: code-group + +```vue [MintNft.vue] + + + +``` + +::: + +### 4. Hook up the `useWriteContract` Composable + +Now that we have the form handler, we can hook up the [`useWriteContract` Composable](/vue/api/composables/useWriteContract) to send the transaction. + +::: code-group + +```vue [MintNft.vue] + + + +``` + +```ts [abi.ts] +export const abi = [ + { + name: 'mint', + type: 'function', + stateMutability: 'nonpayable', + inputs: [{ internalType: 'uint32', name: 'tokenId', type: 'uint32' }], + outputs: [], + }, +] as const +``` + +::: + +### 5. Add loading state (optional) + +We can optionally add a loading state to the "Mint" button while we are waiting confirmation from the user's wallet. + +::: code-group + +```vue [MintNft.vue] + + + +``` + +```ts [abi.ts] +export const abi = [ + { + name: 'mint', + type: 'function', + stateMutability: 'nonpayable', + inputs: [{ internalType: 'uint32', name: 'tokenId', type: 'uint32' }], + outputs: [], + }, +] as const +``` + +::: + +### 6. Wait for transaction receipt (optional) + +We can also display the transaction confirmation status to the user by using the [`useWaitForTransactionReceipt` Composable](/vue/api/composables/useWaitForTransactionReceipt). + +::: code-group + +```vue [MintNft.vue] + + + +``` + +```ts [abi.ts] +export const abi = [ + { + name: 'mint', + type: 'function', + stateMutability: 'nonpayable', + inputs: [{ internalType: 'uint32', name: 'tokenId', type: 'uint32' }], + outputs: [], + }, +] as const +``` + +::: + +### 7. Handle errors (optional) + +If the user rejects the transaction, or the user does not have enough funds to cover the transaction, we can display an error message to the user. + +::: code-group + +```vue [MintNft.vue] + + + +``` + +```ts [abi.ts] +export const abi = [ + { + name: 'mint', + type: 'function', + stateMutability: 'nonpayable', + inputs: [{ internalType: 'uint32', name: 'tokenId', type: 'uint32' }], + outputs: [], + }, +] as const +``` + +::: + +### 8. Wire it up! + +Finally, we can wire up our Send Transaction component to our application's entrypoint. + +:::code-group +```vue [App.vue] + + + +``` + +```vue [MintNft.vue] + + + +``` + +```ts [abi.ts] +export const abi = [ + { + name: 'mint', + type: 'function', + stateMutability: 'nonpayable', + inputs: [{ internalType: 'uint32', name: 'tokenId', type: 'uint32' }], + outputs: [], + }, +] as const +``` +::: + +[See the Example.](#example) \ No newline at end of file diff --git a/wagmi-project/site/vue/installation.md b/wagmi-project/site/vue/installation.md new file mode 100644 index 000000000..82676c43f --- /dev/null +++ b/wagmi-project/site/vue/installation.md @@ -0,0 +1,41 @@ + + +# Installation + +Install Wagmi via your package manager, a ` + +# TypeScript + +## Requirements + +Wagmi is designed to be as type-safe as possible! Things to keep in mind: + +- Types currently require using TypeScript {{typescriptVersion}}. +- [TypeScript doesn't follow semver](https://www.learningtypescript.com/articles/why-typescript-doesnt-follow-strict-semantic-versioning) and often introduces breaking changes in minor releases. +- Changes to types in this repository are considered non-breaking and are usually released as patch changes (otherwise every type enhancement would be a major version!). +- It is highly recommended that you lock your `wagmi` and `typescript` versions to specific patch releases and upgrade with the expectation that types may be fixed or upgraded between any release. +- The non-type-related public API of Wagmi still follows semver very strictly. + +To ensure everything works correctly, make sure your `tsconfig.json` has [`strict`](https://www.typescriptlang.org/tsconfig#strict) mode set to `true`. + +::: code-group +```json [tsconfig.json] +{ + "compilerOptions": { + "strict": true + } +} +``` +::: + +## Config Types + +By default Vue Plugins does not work well with type inference. To support strong type-safety across the Vue Plugins boundary, there are two options available: + +- Declaration merging to "register" your `config` globally with TypeScript. +- `config` property to pass your `config` directly to composables. + +### Declaration Merging + +[Declaration merging](https://www.typescriptlang.org/docs/handbook/declaration-merging.html) allows you to "register" your `config` globally with TypeScript. The `Register` type enables Wagmi to infer types in places that wouldn't normally have access to type info via a Vue Plugin alone. + +To set this up, add the following declaration to your project. Below, we co-locate the declaration merging and the `config` set up. + +```ts +import { createConfig, http } from '@wagmi/vue' +import { mainnet, sepolia } from 'wagmi/chains' + +declare module '@wagmi/vue' { // [!code focus] + interface Register { // [!code focus] + config: typeof config // [!code focus] + } // [!code focus] +} // [!code focus] + +export const config = createConfig({ + chains: [mainnet, sepolia], + transports: { + [mainnet.id]: http(), + [sepolia.id]: http(), + }, +}) +``` + +Since the `Register` type is global, you only need to add it once in your project. Once set up, you will get strong type-safety across your entire project. For example, query composables will type `chainId` based on your `config`'s `chains`. + +```ts twoslash +// @errors: 2322 +import { type Config } from '@wagmi/vue' +import { mainnet, sepolia } from 'wagmi/chains' + +declare module '@wagmi/vue' { + interface Register { + config: Config + } +} +// ---cut--- +import { useBlockNumber } from '@wagmi/vue' + +useBlockNumber({ chainId: 123 }) +``` + +You just saved yourself a runtime error and you didn't even need to pass your `config`. 🎉 + +### Hook `config` Property + +For cases where you have more than one Wagmi `config` or don't want to use the declaration merging approach, you can pass a specific `config` directly to composables via the `config` property. + +```ts +import { createConfig, http } from '@wagmi/vue' +import { mainnet, optimism } from '@wagmi/vue/chains' + +export const configA = createConfig({ // [!code focus] + chains: [mainnet], // [!code focus] + transports: { // [!code focus] + [mainnet.id]: http(), // [!code focus] + }, // [!code focus] +}) // [!code focus] + +export const configB = createConfig({ // [!code focus] + chains: [optimism], // [!code focus] + transports: { // [!code focus] + [optimism.id]: http(), // [!code focus] + }, // [!code focus] +}) // [!code focus] +``` + +As you expect, `chainId` is inferred correctly for each `config`. + +```ts twoslash +// @errors: 2322 +import { type Config } from '@wagmi/vue' +import { mainnet, optimism } from '@wagmi/vue/chains' + +declare const configA: Config +declare const configB: Config +// ---cut--- +import { useBlockNumber } from '@wagmi/vue' + +useBlockNumber({ chainId: 123, config: configA }) +useBlockNumber({ chainId: 123, config: configB }) +``` + +This approach is more explicit, but works well for advanced use-cases, if you don't want to use a Vue Plugin or declaration merging, etc. + +## Const-Assert ABIs & Typed Data + +Wagmi can infer types based on [ABIs](https://docs.soliditylang.org/en/latest/abi-spec.html#json) and [EIP-712](https://eips.ethereum.org/EIPS/eip-712) Typed Data definitions, powered by [Viem](https://viem.sh) and [ABIType](https://github.com/wevm/abitype). This achieves full end-to-end type-safety from your contracts to your frontend and enlightened developer experience by autocompleting ABI item names, catching misspellings, inferring argument and return types (including overloads), and more. + +For this to work, you must either [const-assert](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-4.html#const-assertions) ABIs and Typed Data (more info below) or define them inline. For example, `useReadContract`'s `abi` configuration parameter: + +```ts +const { data } = useReadContract({ + abi: […], // <--- defined inline // [!code focus] +}) +``` + +```ts +const abi = […] as const // <--- const assertion // [!code focus] +const { data } = useReadContract({ abi }) +``` + +If type inference isn't working, it's likely you forgot to add a `const` assertion or define the configuration parameter inline. Also, make sure your ABIs, Typed Data definitions, and [TypeScript configuration](#requirements) are valid and set up correctly. + +::: tip +Unfortunately [TypeScript doesn't support importing JSON `as const` yet](https://github.com/microsoft/TypeScript/issues/32063). Check out the [Wagmi CLI](/cli/getting-started) to help with this! It can automatically fetch ABIs from Etherscan and other block explorers, resolve ABIs from your Foundry/Hardhat projects, generate Vue Composables, and more. +::: + +Anywhere you see the `abi` or `types` configuration property, you can likely use const-asserted or inline ABIs and Typed Data to get type-safety and inference. These properties are also called out in the docs. + +Here's what [`useReadContract`](/vue/api/composables/useReadContract) looks like with and without a const-asserted `abi` property. + +::: code-group +```ts twoslash [Const-Asserted] +const erc721Abi = [ + { + name: 'balanceOf', + type: 'function', + stateMutability: 'view', + inputs: [{ type: 'address', name: 'owner' }], + outputs: [{ type: 'uint256' }], + }, + { + name: 'isApprovedForAll', + type: 'function', + stateMutability: 'view', + inputs: [ + { type: 'address', name: 'owner' }, + { type: 'address', name: 'operator' }, + ], + outputs: [{ type: 'bool' }], + }, + { + name: 'getApproved', + type: 'function', + stateMutability: 'view', + inputs: [{ type: 'uint256', name: 'tokenId' }], + outputs: [{ type: 'address' }], + }, + { + name: 'ownerOf', + type: 'function', + stateMutability: 'view', + inputs: [{ type: 'uint256', name: 'tokenId' }], + outputs: [{ type: 'address' }], + }, + { + name: 'tokenURI', + type: 'function', + stateMutability: 'pure', + inputs: [{ type: 'uint256', name: 'tokenId' }], + outputs: [{ type: 'string' }], + }, +] as const +// ---cut--- +import { useReadContract } from '@wagmi/vue' + +const { data } = useReadContract({ + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + abi: erc721Abi, + functionName: 'balanceOf', + // ^? + + + + args: ['0xA0Cf798816D4b9b9866b5330EEa46a18382f251e'], + // ^? +}) + +data +// ^? +``` +```ts twoslash [Not Const-Asserted] +declare const erc721Abi: { + name: string; + type: string; + stateMutability: string; + inputs: { + type: string; + name: string; + }[]; + outputs: { + type: string; + }[]; +}[] +// ---cut--- +import { useReadContract } from '@wagmi/vue' + +const { data } = useReadContract({ + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + abi: erc721Abi, + functionName: 'balanceOf', + // ^? + + + + args: ['0xA0Cf798816D4b9b9866b5330EEa46a18382f251e'], + // ^? +}) + +data +// ^? +``` +::: + +
+
+ +You can prevent runtime errors and be more productive by making sure your ABIs and Typed Data definitions are set up appropriately. 🎉 + +```ts twoslash +// @errors: 2820 +const erc721Abi = [ + { + name: 'balanceOf', + type: 'function', + stateMutability: 'view', + inputs: [{ type: 'address', name: 'owner' }], + outputs: [{ type: 'uint256' }], + }, + { + name: 'isApprovedForAll', + type: 'function', + stateMutability: 'view', + inputs: [ + { type: 'address', name: 'owner' }, + { type: 'address', name: 'operator' }, + ], + outputs: [{ type: 'bool' }], + }, + { + name: 'getApproved', + type: 'function', + stateMutability: 'view', + inputs: [{ type: 'uint256', name: 'tokenId' }], + outputs: [{ type: 'address' }], + }, + { + name: 'ownerOf', + type: 'function', + stateMutability: 'view', + inputs: [{ type: 'uint256', name: 'tokenId' }], + outputs: [{ type: 'address' }], + }, + { + name: 'tokenURI', + type: 'function', + stateMutability: 'pure', + inputs: [{ type: 'uint256', name: 'tokenId' }], + outputs: [{ type: 'string' }], + }, +] as const +// ---cut--- +import { useReadContract } from '@wagmi/vue' + +useReadContract({ + abi: erc721Abi, + functionName: 'balanecOf', +}) +``` + +## Configure Internal Types + +For advanced use-cases, you may want to configure Wagmi's internal types. Most of Wagmi's types relating to ABIs and EIP-712 Typed Data are powered by [ABIType](https://github.com/wevm/abitype). See the [ABIType docs](https://abitype.dev) for more info on how to configure types. diff --git a/wagmi-project/site/vue/why.md b/wagmi-project/site/vue/why.md new file mode 100644 index 000000000..4a3560c13 --- /dev/null +++ b/wagmi-project/site/vue/why.md @@ -0,0 +1,46 @@ +# Why Wagmi + +## The Problems + +Building Ethereum applications is hard. Apps need to support connecting wallets, multiple chains, signing messages and data, sending transactions, listening for events and state changes, refreshing stale blockchain data, and much more. This is all on top of solving for app-specific use-cases and providing polished user experiences. + +The ecosystem is also continuously evolving, meaning you need to adapt to new improvements or get left behind. App developers should not need to worry about connecting tens of different wallets, the intricacies of multi-chain support, typos accidentally sending an order of magnitude more ETH or calling a misspelled contract function, or accidentally spamming their RPC provider, costing thousands in compute units. + +Wagmi solves all these problems and more — allowing app developers to focus on building high-quality and performant experiences for Ethereum — by focusing on **developer experience**, **performance**, **feature coverage**, and **stability.** + +## Developer Experience + +Wagmi delivers a great developer experience through modular and composable APIs, automatic type safety and inference, and comprehensive documentation. + +It provides developers with intuitive building blocks to build their Ethereum apps. While Wagmi's APIs might seem more verbose at first, it makes Wagmi's modular building blocks extremely flexible. Easy to move around, change, and remove. It also allows developers to better understand Ethereum concepts as well as understand _what_ and _why_ certain properties are being passed through. Learning how to use Wagmi is a great way to learn how to interact with Ethereum in general. + +Wagmi also provides [strongly typed APIs](/vue/typescript), allowing consumers to get the best possible experience through [autocomplete](https://twitter.com/awkweb/status/1555678944770367493), [type inference](https://twitter.com/jakemoxey/status/1570244174502588417?s=20), as well as static validation. You often just need to provide an ABI and Wagmi can help you autocomplete your way to success, identify type errors before your users do, drill into blockchain errors [at compile and runtimes](/vue/guides/error-handling) with surgical precision, and much more. + +The API documentation is comprehensive and contains usage info for _every_ module in Wagmi. The core team uses a [documentation](https://gist.github.com/zsup/9434452) and [test driven](https://en.wikipedia.org/wiki/Test-driven_development#:~:text=Test%2Ddriven%20development%20(TDD),software%20against%20all%20test%20cases.) development approach to building modules, which leads to predictable and stable APIs. + +## Performance + +Performance is critical for applications on all sizes. Slow page load and interactions can cause users to stop using applications. Wagmi uses and is built by the same team behind [Viem](https://viem.sh), the most performant production-ready Ethereum library. + +End users should not be required to download a module of over 100kB in order to interact with Ethereum. Wagmi is optimized for tree-shaking and dead-code elimination, allowing apps to minimize bundle size for fast page load times. + +Data layer performance is also critical. Slow, unnecessary, and manual data fetching can make apps unusable and cost thousands in RPC compute units. Wagmi supports caching, deduplication, persistence, and much more through [TanStack Query](/vue/guides/tanstack-query). + +## Feature Coverage + +Wagmi supports the most popular and commonly-used Ethereum features out of the box with 40+ Vue Composables for accounts, wallets, contracts, transactions, signing, ENS, and more. Wagmi also supports just about any wallet out there through it's official [connectors](/vue/api/connectors), [EIP-6963 support](/vue/api/createConfig#multiinjectedproviderdiscovery), and [extensible API](/dev/creating-connectors). + +If you need lower-level control, you can always drop down to [Wagmi Core](/core/getting-started) or [Viem](https://viem.sh), which Wagmi uses internally to perform blockchain operations. Wagmi also manages multi-chain support automatically so developers can focus on their applications instead of adding custom code. + +Finally, Wagmi has a [CLI](/cli/getting-started) to manage ABIs as well as a robust ecosystem of third-party libraries, like [ConnectKit](https://docs.family.co/connectkit), [RainbowKit](https://www.rainbowkit.com), [AppKit](https://walletconnect.com/appkit), [Dynamic](https://www.dynamic.xyz), [Privy](https://privy.io), and many more, so you can get started quickly without needing to build everything from scratch. + +## Stability + +Stability is a fundamental principle for Wagmi. Many organizations, large and small, rely heavily on Wagmi and expect it to be entirely stable for their users and applications. + +Wagmi's test suite runs against forked Ethereum nodes to make sure functions work across chains. The test suite also runs type tests against many different versions of peer dependencies, like TypeScript, to ensure compatibility with the latest releases of other popular software. + +Wagmi follows semver so developers can upgrade between versions with confidence. Starting with Wagmi v2, new functionality will be opt-in with old functionality being deprecated alongside the new features. This means upgrading to the latest major versions will not require immediate changes. + +Lastly, the core team works full-time on Wagmi and [related projects](https://github.com/wevm), and is constantly improving Wagmi and keeping it up-to-date with industry trends and changes. + diff --git a/wagmi-project/tsconfig.base.json b/wagmi-project/tsconfig.base.json new file mode 100644 index 000000000..0d11f77ba --- /dev/null +++ b/wagmi-project/tsconfig.base.json @@ -0,0 +1,42 @@ +{ + // This tsconfig file contains the shared config for the build (tsconfig.build.json) and type checking (tsconfig.json) config. + "include": [], + "compilerOptions": { + // Incremental builds + // NOTE: Enabling incremental builds speeds up `tsc`. Keep in mind though that it does not reliably bust the cache when the `tsconfig.json` file changes. + "incremental": true, + + // Type checking + "strict": true, + // "exactOptionalPropertyTypes": true, // Enabled once supported in tanstack query https://github.com/TanStack/query/issues/7641 + "noFallthroughCasesInSwitch": true, // Not enabled by default in `strict` mode. + "noImplicitOverride": true, // Not enabled by default in `strict` mode. + "noImplicitReturns": true, // Not enabled by default in `strict` mode. + "noUncheckedIndexedAccess": true, + "noUnusedLocals": true, // Not enabled by default in `strict` mode. + "noUnusedParameters": true, // Not enabled by default in `strict` mode. + "useDefineForClassFields": true, // Not enabled by default in `strict` mode unless we bump `target` to ES2022. + "useUnknownInCatchVariables": true, + + // JavaScript support + "allowJs": false, + "checkJs": false, + + // Interop constraints + "forceConsistentCasingInFileNames": true, + "verbatimModuleSyntax": true, + + // Language and environment + "moduleResolution": "NodeNext", + "module": "NodeNext", + "target": "ES2021", // Setting this to `ES2021` enables native support for `Node v16+`: https://github.com/microsoft/TypeScript/wiki/Node-Target-Mapping. + "lib": [ + "ES2022", // By using ES2022 we get access to the `.cause` property on `Error` instances. + "DOM" // We are adding `DOM` here to get the `fetch`, etc. types. This should be removed once these types are available via DefinitelyTyped. + ], + + // Skip type checking for node modules + "skipLibCheck": true, + "noErrorTruncation": true + } +} diff --git a/wagmi-project/tsconfig.json b/wagmi-project/tsconfig.json index a7fc6fbf2..506583064 100644 --- a/wagmi-project/tsconfig.json +++ b/wagmi-project/tsconfig.json @@ -1,25 +1,8 @@ { + "extends": "./tsconfig.base.json", + "include": ["scripts/**/*.ts", "vitest.workspace.ts", "vitest.config.ts"], + "exclude": [], "compilerOptions": { - "target": "ES2020", - "useDefineForClassFields": true, - "lib": ["ES2020", "DOM", "DOM.Iterable"], - "module": "ESNext", - "skipLibCheck": true, - - /* Bundler mode */ - "moduleResolution": "bundler", - "allowImportingTsExtensions": true, - "resolveJsonModule": true, - "isolatedModules": true, - "noEmit": true, - "jsx": "react-jsx", - - /* Linting */ - "strict": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "noFallthroughCasesInSwitch": true - }, - "include": ["src"], - "references": [{ "path": "./tsconfig.node.json" }] + "types": ["@types/bun"] + } } diff --git a/wagmi-project/vitest.config.ts b/wagmi-project/vitest.config.ts new file mode 100644 index 000000000..c3215d85d --- /dev/null +++ b/wagmi-project/vitest.config.ts @@ -0,0 +1,27 @@ +import { defineConfig } from 'vitest/config' + +export default defineConfig({ + server: { + watch: { + ignored: ['**/templates/**'], + }, + }, + test: { + coverage: { + all: false, + reporter: process.env.CI ? ['lcov'] : ['text', 'json', 'html'], + exclude: [ + '**/dist/**', + '**/*.test.ts', + '**/*.test-d.ts', + 'packages/cli/**', + 'packages/test/**', + // ignore third-party connectors + 'packages/connectors/**', + 'packages/core/src/connectors/injected.ts', + ], + }, + globalSetup: ['./packages/test/src/globalSetup.ts'], + setupFiles: ['./packages/test/src/setup.ts'], + }, +}) diff --git a/wagmi-project/vitest.workspace.ts b/wagmi-project/vitest.workspace.ts new file mode 100644 index 000000000..0c187c040 --- /dev/null +++ b/wagmi-project/vitest.workspace.ts @@ -0,0 +1,85 @@ +import path from 'node:path' +import { defineWorkspace } from 'vitest/config' + +const alias = { + '@wagmi/connectors': path.resolve( + __dirname, + './packages/connectors/src/exports', + ), + '@wagmi/core': path.resolve(__dirname, './packages/core/src/exports'), + '@wagmi/test': path.resolve(__dirname, './packages/test/src/exports'), + '@wagmi/vue': path.resolve(__dirname, './packages/vue/src/exports'), + wagmi: path.resolve(__dirname, './packages/react/src/exports'), +} + +export default defineWorkspace([ + { + test: { + name: '@wagmi/cli', + environment: 'node', + include: ['./packages/cli/src/**/*.test.ts'], + testTimeout: 10_000, + setupFiles: ['./packages/cli/test/setup.ts'], + }, + }, + { + test: { + name: '@wagmi/connectors', + include: ['./packages/connectors/src/**/*.test.ts'], + environment: 'happy-dom', + }, + resolve: { alias }, + }, + { + test: { + name: '@wagmi/core', + include: ['./packages/core/src/**/*.test.ts'], + environment: 'happy-dom', + testTimeout: 10_000, + setupFiles: ['./packages/core/test/setup.ts'], + }, + resolve: { alias }, + }, + { + test: { + name: 'create-wagmi', + include: ['./packages/create-wagmi/src/**/*.test.ts'], + environment: 'node', + testTimeout: 10_000, + }, + }, + { + test: { + name: 'wagmi', + include: ['./packages/react/src/**/*.test.ts?(x)'], + environment: 'happy-dom', + testTimeout: 10_000, + setupFiles: ['./packages/react/test/setup.ts'], + }, + resolve: { alias }, + }, + { + test: { + name: '@wagmi/vue', + include: ['./packages/vue/src/**/*.test.ts?(x)'], + environment: 'happy-dom', + testTimeout: 10_000, + setupFiles: ['./packages/vue/test/setup.ts'], + }, + resolve: { alias }, + }, + { + test: { + name: 'react-register', + include: ['./packages/register-tests/react/src/**/*.test.ts'], + }, + resolve: { alias }, + }, + { + test: { + name: '@wagmi/test', + include: ['./packages/test/src/**/*.test.ts'], + }, + resolve: { alias }, + }, +]) From 224f7612cd574849b75e17056859f0a208a24aa1 Mon Sep 17 00:00:00 2001 From: dargon789 <64915515+Dargon789@users.noreply.github.com> Date: Fri, 26 Dec 2025 03:19:19 +0700 Subject: [PATCH 31/39] sequence-core-1.0.0 --- .../sequence-core-1.0.0/.changeset/README.md | 8 + .../.changeset/config.json | 11 + .../sequence-core-1.0.0/.github/CODEOWNERS | 1 + .../.github/ISSUE_TEMPLATE/bug_report.md | 40 + .../.github/ISSUE_TEMPLATE/custom.md | 7 + .../.github/ISSUE_TEMPLATE/feature_request.md | 19 + .../actions/install-dependencies/action.yml | 39 + .../workflows/on_pr_pnpm-format-label.yml | 23 + .../.github/workflows/pnpm-format.yml | 27 + .../.github/workflows/publish-dists.yml | 88 + .../.github/workflows/tests.yml | 63 + .../packages/sequence-core-1.0.0/.gitmodules | 3 + .../packages/sequence-core-1.0.0/.prettierrc | 5 + .../sequence-core-1.0.0/.vscode/launch.json | 28 + .../sequence-core-1.0.0/.vscode/settings.json | 7 + .../packages/sequence-core-1.0.0/LICENSE | 202 + .../packages/sequence-core-1.0.0/README.md | 39 + .../packages/sequence-core-1.0.0/corepack.tgz | Bin 0 -> 4311947 bytes .../sequence-core-1.0.0/extras/docs/README.md | 36 + .../extras/docs/app/favicon.ico | Bin 0 -> 25931 bytes .../extras/docs/app/fonts/GeistMonoVF.woff | Bin 0 -> 67864 bytes .../extras/docs/app/fonts/GeistVF.woff | Bin 0 -> 66268 bytes .../extras/docs/app/globals.css | 50 + .../extras/docs/app/layout.tsx | 29 + .../extras/docs/app/page.module.css | 188 + .../extras/docs/app/page.tsx | 80 + .../extras/docs/eslint.config.js | 4 + .../extras/docs/next.config.js | 4 + .../extras/docs/package.json | 28 + .../extras/docs/public/file-text.svg | 3 + .../extras/docs/public/globe.svg | 10 + .../extras/docs/public/next.svg | 1 + .../extras/docs/public/turborepo-dark.svg | 19 + .../extras/docs/public/turborepo-light.svg | 19 + .../extras/docs/public/vercel.svg | 10 + .../extras/docs/public/window.svg | 3 + .../extras/docs/tsconfig.json | 12 + .../sequence-core-1.0.0/extras/web/README.md | 36 + .../extras/web/app/favicon.ico | Bin 0 -> 25931 bytes .../extras/web/app/fonts/GeistMonoVF.woff | Bin 0 -> 67864 bytes .../extras/web/app/fonts/GeistVF.woff | Bin 0 -> 66268 bytes .../extras/web/app/globals.css | 50 + .../extras/web/app/layout.tsx | 29 + .../extras/web/app/page.module.css | 188 + .../extras/web/app/page.tsx | 80 + .../extras/web/eslint.config.js | 4 + .../extras/web/next.config.js | 4 + .../extras/web/package.json | 28 + .../extras/web/public/file-text.svg | 3 + .../extras/web/public/globe.svg | 10 + .../extras/web/public/next.svg | 1 + .../extras/web/public/turborepo-dark.svg | 19 + .../extras/web/public/turborepo-light.svg | 19 + .../extras/web/public/vercel.svg | 10 + .../extras/web/public/window.svg | 3 + .../extras/web/tsconfig.json | 12 + .../packages/sequence-core-1.0.0/foundry.lock | 1 + .../packages/sequence-core-1.0.0/lefthook.yml | 12 + .../lib/signals-implicit-mode/.env.sample | 1 + .../.github/workflows/test.yml | 56 + .../lib/signals-implicit-mode/.gitmodules | 9 + .../lib/signals-implicit-mode/README.md | 84 + .../lib/signals-implicit-mode/foundry.toml | 22 + .../lib/forge-std/.gitattributes | 1 + .../lib/forge-std/.github/CODEOWNERS | 1 + .../lib/forge-std/.github/workflows/ci.yml | 95 + .../lib/forge-std/.github/workflows/sync.yml | 31 + .../lib/forge-std/CONTRIBUTING.md | 193 + .../lib/forge-std/LICENSE-APACHE | 203 + .../lib/forge-std/LICENSE-MIT | 25 + .../lib/forge-std/README.md | 268 + .../lib/forge-std/RELEASE_CHECKLIST.md | 12 + .../lib/forge-std/foundry.toml | 27 + .../lib/forge-std/package.json | 16 + .../lib/forge-std/scripts/vm.py | 646 + .../lib/forge-std/src/Base.sol | 48 + .../lib/forge-std/src/Config.sol | 60 + .../lib/forge-std/src/LibVariable.sol | 477 + .../lib/forge-std/src/Script.sol | 28 + .../lib/forge-std/src/StdAssertions.sol | 764 + .../lib/forge-std/src/StdChains.sol | 287 + .../lib/forge-std/src/StdCheats.sol | 829 + .../lib/forge-std/src/StdConfig.sol | 612 + .../lib/forge-std/src/StdConstants.sol | 30 + .../lib/forge-std/src/StdError.sol | 15 + .../lib/forge-std/src/StdInvariant.sol | 122 + .../lib/forge-std/src/StdJson.sol | 283 + .../lib/forge-std/src/StdMath.sol | 43 + .../lib/forge-std/src/StdStorage.sol | 473 + .../lib/forge-std/src/StdStyle.sol | 333 + .../lib/forge-std/src/StdToml.sol | 283 + .../lib/forge-std/src/StdUtils.sol | 208 + .../lib/forge-std/src/Test.sol | 34 + .../lib/forge-std/src/Vm.sol | 2494 + .../lib/forge-std/src/console.sol | 1560 + .../lib/forge-std/src/console2.sol | 4 + .../lib/forge-std/src/interfaces/IERC1155.sol | 105 + .../lib/forge-std/src/interfaces/IERC165.sol | 12 + .../lib/forge-std/src/interfaces/IERC20.sol | 43 + .../lib/forge-std/src/interfaces/IERC4626.sol | 190 + .../lib/forge-std/src/interfaces/IERC6909.sol | 72 + .../lib/forge-std/src/interfaces/IERC721.sol | 164 + .../lib/forge-std/src/interfaces/IERC7540.sol | 150 + .../lib/forge-std/src/interfaces/IERC7575.sol | 241 + .../forge-std/src/interfaces/IMulticall3.sol | 73 + .../lib/forge-std/src/safeconsole.sol | 13937 ++++++ .../lib/forge-std/test/CommonBase.t.sol | 44 + .../lib/forge-std/test/Config.t.sol | 352 + .../lib/forge-std/test/LibVariable.t.sol | 434 + .../lib/forge-std/test/StdAssertions.t.sol | 141 + .../lib/forge-std/test/StdChains.t.sol | 227 + .../lib/forge-std/test/StdCheats.t.sol | 639 + .../lib/forge-std/test/StdConstants.t.sol | 38 + .../lib/forge-std/test/StdError.t.sol | 120 + .../lib/forge-std/test/StdJson.t.sol | 49 + .../lib/forge-std/test/StdMath.t.sol | 202 + .../lib/forge-std/test/StdStorage.t.sol | 488 + .../lib/forge-std/test/StdStyle.t.sol | 110 + .../lib/forge-std/test/StdToml.t.sol | 49 + .../lib/forge-std/test/StdUtils.t.sol | 342 + .../lib/forge-std/test/Vm.t.sol | 18 + .../test/compilation/CompilationScript.sol | 10 + .../compilation/CompilationScriptBase.sol | 10 + .../test/compilation/CompilationTest.sol | 10 + .../test/compilation/CompilationTestBase.sol | 10 + .../test/fixtures/broadcast.log.json | 187 + .../lib/forge-std/test/fixtures/config.toml | 81 + .../lib/forge-std/test/fixtures/test.json | 8 + .../lib/forge-std/test/fixtures/test.toml | 6 + .../lib/sequence-v3/.env.sample | 7 + .../sequence-v3/.github/workflows/tests.yml | 148 + .../lib/sequence-v3/.gitmodules | 12 + .../lib/sequence-v3/.prettierignore | 4 + .../lib/sequence-v3/.prettierrc | 7 + .../lib/sequence-v3/LICENSE | 201 + .../lib/sequence-v3/README.md | 53 + .../lib/sequence-v3/build_proxy.sh | 21 + .../lib/sequence-v3/docs/CHAINED.md | 450 + .../lib/sequence-v3/docs/CONFIGURATIONS.md | 279 + .../lib/sequence-v3/docs/PAYLOAD.md | 392 + .../lib/sequence-v3/docs/SESSIONS.md | 502 + .../lib/sequence-v3/docs/SIGNATURE.md | 367 + .../lib/sequence-v3/foundry.toml | 31 + .../lib/sequence-v3/lefthook.yml | 8 + .../lib/account-abstraction/.eslintrc.js | 79 + .../.github/workflows/build.yml | 89 + .../lib/account-abstraction/.solcover.js | 8 + .../lib/account-abstraction/.solhint.json | 12 + .../lib/account-abstraction/.solhintignore | 1 + .../lib/account-abstraction/LICENSE | 674 + .../lib/account-abstraction/README.md | 11 + ...bstraction_Incremental_Audit_Feb_2023.pdf" | Bin 0 -> 565821 bytes .../contracts/core/BaseAccount.sol | 113 + .../contracts/core/BasePaymaster.sol | 151 + .../contracts/core/EntryPoint.sol | 800 + .../contracts/core/EntryPointSimulations.sol | 190 + .../contracts/core/Helpers.sol | 106 + .../contracts/core/NonceManager.sol | 43 + .../contracts/core/SenderCreator.sol | 38 + .../contracts/core/StakeManager.sol | 145 + .../contracts/core/UserOperationLib.sol | 139 + .../contracts/interfaces/IAccount.sol | 39 + .../contracts/interfaces/IAccountExecute.sol | 20 + .../contracts/interfaces/IAggregator.sol | 44 + .../contracts/interfaces/IEntryPoint.sol | 223 + .../interfaces/IEntryPointSimulations.sol | 73 + .../contracts/interfaces/INonceManager.sol | 27 + .../contracts/interfaces/IPaymaster.sol | 63 + .../contracts/interfaces/IStakeManager.sol | 111 + .../interfaces/PackedUserOperation.sol | 28 + .../contracts/package.json | 29 + .../samples/LegacyTokenPaymaster.sol | 115 + .../contracts/samples/SimpleAccount.sol | 150 + .../samples/SimpleAccountFactory.sol | 52 + .../contracts/samples/TokenPaymaster.sol | 217 + .../contracts/samples/VerifyingPaymaster.sol | 96 + .../contracts/samples/bls/BLSAccount.sol | 65 + .../samples/bls/BLSAccountFactory.sol | 61 + .../contracts/samples/bls/BLSHelper.sol | 232 + .../samples/bls/BLSSignatureAggregator.sol | 171 + .../contracts/samples/bls/IBLSAccount.sol | 16 + .../contracts/samples/bls/lib/BLSOpen.sol | 64 + .../hubble-contracts/contracts/libs/BLS.sol | 440 + .../contracts/libs/ModExp.sol | 652 + .../samples/callback/TokenCallbackHandler.sol | 51 + .../contracts/samples/utils/IOracle.sol | 10 + .../contracts/samples/utils/OracleHelper.sol | 170 + .../contracts/samples/utils/UniswapHelper.sol | 111 + .../contracts/utils/Exec.sol | 70 + .../deploy/1_deploy_entrypoint.ts | 19 + .../deploy/2_deploy_SimpleAccountFactory.ts | 33 + .../deployments/arbitrum/.chainId | 1 + .../deployments/arbitrum/EntryPoint.json | 1318 + .../a4c52f0671aad8941c53d6ead2063803.json | 68 + .../deployments/gnosis/.chainId | 1 + .../deployments/gnosis/EntryPoint.json | 1318 + .../a4c52f0671aad8941c53d6ead2063803.json | 68 + .../deployments/goerli/.chainId | 1 + .../deployments/goerli/EntryPoint.json | 1318 + .../a4c52f0671aad8941c53d6ead2063803.json | 68 + .../deployments/kovan/.chainId | 1 + .../deployments/kovan/EntryPoint.json | 1073 + .../deployments/kovan/SimpleWallet.json | 338 + .../deployments/kovan/TestCounter.json | 118 + .../9255faacf3ae4e81db1326413027bfa0.json | 86 + .../deployments/mainnet/.chainId | 1 + .../deployments/mainnet/EntryPoint.json | 1318 + .../mainnet/SimpleAccountFactory.json | 107 + .../02113a2ed1850c3774563305ee607f11.json | 329 + .../a4c52f0671aad8941c53d6ead2063803.json | 68 + .../cfbebdf1101dd2bc0f310cb0b7d62cb7.json | 59 + .../deployments/matic/.chainId | 1 + .../deployments/matic/EntryPoint.json | 1318 + .../a4c52f0671aad8941c53d6ead2063803.json | 68 + .../cfbebdf1101dd2bc0f310cb0b7d62cb7.json | 59 + .../deployments/mumbai/.chainId | 1 + .../deployments/mumbai/EntryPoint.json | 1318 + .../a4c52f0671aad8941c53d6ead2063803.json | 68 + .../deployments/optimism/.chainId | 1 + .../deployments/optimism/EntryPoint.json | 1318 + .../a4c52f0671aad8941c53d6ead2063803.json | 68 + .../deployments/sepolia/.chainId | 1 + .../deployments/sepolia/EntryPoint.json | 1318 + .../a4c52f0671aad8941c53d6ead2063803.json | 68 + .../account-abstraction/erc/ERCS/erc-4337.md | 1017 + .../account-abstraction/erc/ERCS/erc-7562.md | 393 + .../erc/assets/erc-4337/bundle-seq-pm.svg | 1 + .../erc/assets/erc-4337/bundle-seq.svg | 1 + .../erc/assets/erc-4337/image1.png | Bin 0 -> 32181 bytes .../erc/assets/erc-4337/image2.png | Bin 0 -> 27514 bytes .../gascalc/0-init-gas-checker.ts | 12 + .../gascalc/1-simple-wallet.gas.ts | 17 + .../gascalc/2-paymaster.gas.ts | 59 + .../gascalc/3-huge-tx-gas.ts | 27 + .../gascalc/4-paymaster-postop.gas.ts | 62 + .../gascalc/5-token-paymaster.gas.ts | 159 + .../account-abstraction/gascalc/GasChecker.ts | 459 + .../lib/account-abstraction/hardhat.config.ts | 86 + .../lib/account-abstraction/package.json | 71 + .../reports/gas-checker.txt | 55 + .../scripts/check-gas-reports | 17 + .../scripts/docker-gascalc | 7 + .../scripts/docker-gascalc.yml | 20 + .../lib/account-abstraction/scripts/gascalc | 15 + .../account-abstraction/scripts/hh-wrapper | 5 + .../scripts/postpack-contracts-package.sh | 6 + .../scripts/prepack-contracts-package.sh | 17 + .../scripts/sample-script.js | 32 + .../account-abstraction/scripts/solcErrors | 12 + .../lib/account-abstraction/src/AASigner.ts | 458 + .../account-abstraction/src/Create2Factory.ts | 126 + .../lib/account-abstraction/src/Utils.ts | 15 + .../lib/account-abstraction/src/runop.ts | 158 + .../test/0-create2factory.test.ts | 43 + .../lib/account-abstraction/test/UserOp.ts | 364 + .../account-abstraction/test/UserOperation.ts | 30 + .../lib/account-abstraction/test/aa.init.ts | 8 + .../account-abstraction/test/chaiHelper.ts | 73 + .../lib/account-abstraction/test/debugTx.ts | 34 + .../test/entrypoint.test.ts | 1929 + .../test/entrypointsimulations.test.ts | 534 + .../account-abstraction/test/helpers.test.ts | 74 + .../test/paymaster.test.ts | 415 + .../test/samples/OracleHelper.test.ts | 287 + .../test/samples/TokenPaymaster.test.ts | 588 + .../test/simple-wallet.test.ts | 208 + .../account-abstraction/test/solidityTypes.ts | 11 + .../test/testExecAccount.test.ts | 61 + .../lib/account-abstraction/test/testutils.ts | 529 + .../test/verifying_paymaster.test.ts | 191 + .../account-abstraction/test/y.bls.test.ts | 249 + .../lib/account-abstraction/tsconfig.json | 31 + .../lib/account-abstraction/yarn.lock | 10171 ++++ .../lib/erc2470-libs/.gitattributes | 1 + .../lib/erc2470-libs/.githooks/pre-commit | 30 + .../erc2470-libs/.github/workflows/test.yml | 34 + .../sequence-v3/lib/erc2470-libs/.gitmodules | 3 + .../lib/erc2470-libs/.solhint.json | 9 + .../sequence-v3/lib/erc2470-libs/README.md | 80 + .../sequence-v3/lib/erc2470-libs/foundry.toml | 6 + .../erc2470-libs/lib/forge-std/.gitattributes | 1 + .../lib/forge-std/.github/workflows/ci.yml | 128 + .../lib/forge-std/.github/workflows/sync.yml | 31 + .../erc2470-libs/lib/forge-std/LICENSE-APACHE | 203 + .../erc2470-libs/lib/forge-std/LICENSE-MIT | 25 + .../lib/erc2470-libs/lib/forge-std/README.md | 252 + .../erc2470-libs/lib/forge-std/foundry.toml | 21 + .../erc2470-libs/lib/forge-std/package.json | 16 + .../erc2470-libs/lib/forge-std/scripts/vm.py | 635 + .../erc2470-libs/lib/forge-std/src/Base.sol | 35 + .../erc2470-libs/lib/forge-std/src/Script.sol | 27 + .../lib/forge-std/src/StdAssertions.sol | 669 + .../lib/forge-std/src/StdChains.sol | 263 + .../lib/forge-std/src/StdCheats.sol | 817 + .../lib/forge-std/src/StdError.sol | 15 + .../lib/forge-std/src/StdInvariant.sol | 122 + .../lib/forge-std/src/StdJson.sol | 283 + .../lib/forge-std/src/StdMath.sol | 43 + .../lib/forge-std/src/StdStorage.sol | 473 + .../lib/forge-std/src/StdStyle.sol | 333 + .../lib/forge-std/src/StdToml.sol | 283 + .../lib/forge-std/src/StdUtils.sol | 226 + .../erc2470-libs/lib/forge-std/src/Test.sol | 33 + .../lib/erc2470-libs/lib/forge-std/src/Vm.sol | 1968 + .../lib/forge-std/src/console.sol | 1560 + .../lib/forge-std/src/console2.sol | 4 + .../lib/forge-std/src/interfaces/IERC1155.sol | 105 + .../lib/forge-std/src/interfaces/IERC165.sol | 12 + .../lib/forge-std/src/interfaces/IERC20.sol | 43 + .../lib/forge-std/src/interfaces/IERC4626.sol | 190 + .../lib/forge-std/src/interfaces/IERC721.sol | 164 + .../forge-std/src/interfaces/IMulticall3.sol | 73 + .../lib/forge-std/src/mocks/MockERC20.sol | 234 + .../lib/forge-std/src/mocks/MockERC721.sol | 231 + .../lib/forge-std/src/safeconsole.sol | 13937 ++++++ .../lib/forge-std/test/StdAssertions.t.sol | 145 + .../lib/forge-std/test/StdChains.t.sol | 228 + .../lib/forge-std/test/StdCheats.t.sol | 618 + .../lib/forge-std/test/StdError.t.sol | 120 + .../lib/forge-std/test/StdJson.t.sol | 49 + .../lib/forge-std/test/StdMath.t.sol | 202 + .../lib/forge-std/test/StdStorage.t.sol | 471 + .../lib/forge-std/test/StdStyle.t.sol | 110 + .../lib/forge-std/test/StdToml.t.sol | 49 + .../lib/forge-std/test/StdUtils.t.sol | 342 + .../erc2470-libs/lib/forge-std/test/Vm.t.sol | 18 + .../test/compilation/CompilationScript.sol | 10 + .../compilation/CompilationScriptBase.sol | 10 + .../test/compilation/CompilationTest.sol | 10 + .../test/compilation/CompilationTestBase.sol | 10 + .../test/fixtures/broadcast.log.json | 187 + .../lib/forge-std/test/fixtures/test.json | 8 + .../lib/forge-std/test/fixtures/test.toml | 6 + .../lib/forge-std/test/mocks/MockERC20.t.sol | 441 + .../lib/forge-std/test/mocks/MockERC721.t.sol | 721 + .../script/MockERC20Deployer.s.sol | 14 + .../script/SingletonDeployer.s.sol | 66 + .../erc2470-libs/src/ISingletonFactory.sol | 12 + .../sequence-v3/lib/forge-std/.gitattributes | 1 + .../lib/forge-std/.github/workflows/ci.yml | 128 + .../lib/forge-std/.github/workflows/sync.yml | 31 + .../sequence-v3/lib/forge-std/CONTRIBUTING.md | 193 + .../sequence-v3/lib/forge-std/LICENSE-APACHE | 203 + .../lib/sequence-v3/lib/forge-std/LICENSE-MIT | 25 + .../lib/sequence-v3/lib/forge-std/README.md | 268 + .../sequence-v3/lib/forge-std/foundry.toml | 23 + .../sequence-v3/lib/forge-std/package.json | 16 + .../sequence-v3/lib/forge-std/scripts/vm.py | 646 + .../sequence-v3/lib/forge-std/src/Base.sol | 42 + .../sequence-v3/lib/forge-std/src/Script.sol | 28 + .../lib/forge-std/src/StdAssertions.sol | 669 + .../lib/forge-std/src/StdChains.sol | 286 + .../lib/forge-std/src/StdCheats.sol | 829 + .../lib/forge-std/src/StdConstants.sol | 30 + .../lib/forge-std/src/StdError.sol | 15 + .../lib/forge-std/src/StdInvariant.sol | 122 + .../sequence-v3/lib/forge-std/src/StdJson.sol | 283 + .../sequence-v3/lib/forge-std/src/StdMath.sol | 43 + .../lib/forge-std/src/StdStorage.sol | 473 + .../lib/forge-std/src/StdStyle.sol | 333 + .../sequence-v3/lib/forge-std/src/StdToml.sol | 283 + .../lib/forge-std/src/StdUtils.sol | 209 + .../sequence-v3/lib/forge-std/src/Test.sol | 34 + .../lib/sequence-v3/lib/forge-std/src/Vm.sol | 2397 + .../sequence-v3/lib/forge-std/src/console.sol | 1560 + .../lib/forge-std/src/console2.sol | 4 + .../lib/forge-std/src/interfaces/IERC1155.sol | 105 + .../lib/forge-std/src/interfaces/IERC165.sol | 12 + .../lib/forge-std/src/interfaces/IERC20.sol | 43 + .../lib/forge-std/src/interfaces/IERC4626.sol | 190 + .../lib/forge-std/src/interfaces/IERC6909.sol | 72 + .../lib/forge-std/src/interfaces/IERC721.sol | 164 + .../lib/forge-std/src/interfaces/IERC7540.sol | 150 + .../lib/forge-std/src/interfaces/IERC7575.sol | 241 + .../forge-std/src/interfaces/IMulticall3.sol | 73 + .../lib/forge-std/src/safeconsole.sol | 13937 ++++++ .../lib/forge-std/test/CommonBase.t.sol | 44 + .../lib/forge-std/test/StdAssertions.t.sol | 141 + .../lib/forge-std/test/StdChains.t.sol | 227 + .../lib/forge-std/test/StdCheats.t.sol | 639 + .../lib/forge-std/test/StdConstants.t.sol | 38 + .../lib/forge-std/test/StdError.t.sol | 120 + .../lib/forge-std/test/StdJson.t.sol | 49 + .../lib/forge-std/test/StdMath.t.sol | 202 + .../lib/forge-std/test/StdStorage.t.sol | 488 + .../lib/forge-std/test/StdStyle.t.sol | 110 + .../lib/forge-std/test/StdToml.t.sol | 49 + .../lib/forge-std/test/StdUtils.t.sol | 342 + .../sequence-v3/lib/forge-std/test/Vm.t.sol | 18 + .../test/compilation/CompilationScript.sol | 10 + .../compilation/CompilationScriptBase.sol | 10 + .../test/compilation/CompilationTest.sol | 10 + .../test/compilation/CompilationTestBase.sol | 10 + .../test/fixtures/broadcast.log.json | 187 + .../lib/forge-std/test/fixtures/test.json | 8 + .../lib/forge-std/test/fixtures/test.toml | 6 + .../.changeset/config.json | 12 + .../lib/openzeppelin-contracts/.codecov.yml | 16 + .../lib/openzeppelin-contracts/.editorconfig | 21 + .../openzeppelin-contracts/.githooks/pre-push | 8 + .../.github/ISSUE_TEMPLATE/bug_report.md | 20 + .../.github/ISSUE_TEMPLATE/config.yml | 4 + .../.github/ISSUE_TEMPLATE/feature_request.md | 15 + .../.github/PULL_REQUEST_TEMPLATE.md | 19 + .../.github/actions/gas-compare/action.yml | 50 + .../.github/actions/setup/action.yml | 22 + .../.github/actions/storage-layout/action.yml | 56 + .../.github/workflows/actionlint.yml | 18 + .../.github/workflows/changeset.yml | 28 + .../.github/workflows/checks.yml | 136 + .../.github/workflows/docs.yml | 19 + .../.github/workflows/formal-verification.yml | 86 + .../.github/workflows/release-cycle.yml | 212 + .../.github/workflows/upgradeable.yml | 34 + .../lib/openzeppelin-contracts/.gitmodules | 10 + .../lib/openzeppelin-contracts/.mocharc.js | 4 + .../lib/openzeppelin-contracts/.prettierrc | 15 + .../lib/openzeppelin-contracts/.solcover.js | 21 + .../lib/openzeppelin-contracts/CHANGELOG.md | 1158 + .../openzeppelin-contracts/CODE_OF_CONDUCT.md | 73 + .../openzeppelin-contracts/CONTRIBUTING.md | 36 + .../lib/openzeppelin-contracts/FUNDING.json | 7 + .../lib/openzeppelin-contracts/GUIDELINES.md | 154 + .../lib/openzeppelin-contracts/LICENSE | 22 + .../lib/openzeppelin-contracts/README.md | 106 + .../lib/openzeppelin-contracts/RELEASING.md | 45 + .../lib/openzeppelin-contracts/SECURITY.md | 43 + .../openzeppelin-contracts/audits/2017-03.md | 293 + .../openzeppelin-contracts/audits/2018-10.pdf | Bin 0 -> 1000527 bytes .../audits/2022-10-Checkpoints.pdf | Bin 0 -> 155606 bytes .../audits/2022-10-ERC4626.pdf | Bin 0 -> 204184 bytes .../audits/2023-05-v4.9.pdf | Bin 0 -> 485395 bytes .../audits/2023-10-v5.0.pdf | Bin 0 -> 910284 bytes .../audits/2024-10-v5.1.pdf | Bin 0 -> 395831 bytes .../openzeppelin-contracts/audits/README.md | 18 + .../openzeppelin-contracts/certora/Makefile | 54 + .../openzeppelin-contracts/certora/README.md | 60 + .../access_manager_AccessManager.sol.patch | 97 + .../AccessControlDefaultAdminRulesHarness.sol | 46 + .../harnesses/AccessControlHarness.sol | 6 + .../harnesses/AccessManagedHarness.sol | 36 + .../harnesses/AccessManagerHarness.sol | 116 + .../harnesses/DoubleEndedQueueHarness.sol | 58 + .../harnesses/ERC20FlashMintHarness.sol | 36 + .../certora/harnesses/ERC20PermitHarness.sol | 16 + .../certora/harnesses/ERC20WrapperHarness.sol | 34 + .../harnesses/ERC3156FlashBorrowerHarness.sol | 13 + .../certora/harnesses/ERC721Harness.sol | 33 + .../harnesses/ERC721ReceiverHarness.sol | 11 + .../harnesses/EnumerableMapHarness.sol | 55 + .../harnesses/EnumerableSetHarness.sol | 35 + .../harnesses/InitializableHarness.sol | 23 + .../certora/harnesses/NoncesHarness.sol | 14 + .../certora/harnesses/Ownable2StepHarness.sol | 10 + .../certora/harnesses/OwnableHarness.sol | 10 + .../certora/harnesses/PausableHarness.sol | 18 + .../harnesses/TimelockControllerHarness.sol | 13 + .../certora/reports/2021-10.pdf | Bin 0 -> 92882 bytes .../certora/reports/2022-03.pdf | Bin 0 -> 199401 bytes .../certora/reports/2022-05.pdf | Bin 0 -> 132223 bytes .../lib/openzeppelin-contracts/certora/run.js | 160 + .../openzeppelin-contracts/certora/specs.json | 110 + .../certora/specs/AccessControl.spec | 119 + .../specs/AccessControlDefaultAdminRules.spec | 464 + .../certora/specs/AccessManaged.spec | 34 + .../certora/specs/AccessManager.spec | 826 + .../certora/specs/DoubleEndedQueue.spec | 300 + .../certora/specs/ERC20.spec | 352 + .../certora/specs/ERC20FlashMint.spec | 55 + .../certora/specs/ERC20Wrapper.spec | 198 + .../certora/specs/ERC721.spec | 679 + .../certora/specs/EnumerableMap.spec | 333 + .../certora/specs/EnumerableSet.spec | 246 + .../certora/specs/Initializable.spec | 165 + .../certora/specs/Nonces.spec | 92 + .../certora/specs/Ownable.spec | 77 + .../certora/specs/Ownable2Step.spec | 108 + .../certora/specs/Pausable.spec | 96 + .../certora/specs/TimelockController.spec | 274 + .../certora/specs/helpers/helpers.spec | 12 + .../certora/specs/methods/IAccessControl.spec | 8 + .../IAccessControlDefaultAdminRules.spec | 36 + .../certora/specs/methods/IAccessManaged.spec | 5 + .../certora/specs/methods/IAccessManager.spec | 33 + .../certora/specs/methods/IERC20.spec | 11 + .../certora/specs/methods/IERC2612.spec | 5 + .../specs/methods/IERC3156FlashBorrower.spec | 3 + .../specs/methods/IERC3156FlashLender.spec | 5 + .../certora/specs/methods/IERC5313.spec | 3 + .../certora/specs/methods/IERC721.spec | 17 + .../specs/methods/IERC721Receiver.spec | 3 + .../certora/specs/methods/IOwnable.spec | 5 + .../certora/specs/methods/IOwnable2Step.spec | 7 + .../contracts/access/AccessControl.sol | 209 + .../contracts/access/IAccessControl.sol | 98 + .../contracts/access/Ownable.sol | 100 + .../contracts/access/Ownable2Step.sol | 67 + .../contracts/access/README.adoc | 45 + .../AccessControlDefaultAdminRules.sol | 396 + .../extensions/AccessControlEnumerable.sol | 82 + .../IAccessControlDefaultAdminRules.sol | 192 + .../extensions/IAccessControlEnumerable.sol | 31 + .../access/manager/AccessManaged.sol | 113 + .../access/manager/AccessManager.sol | 740 + .../access/manager/AuthorityUtils.sol | 32 + .../access/manager/IAccessManaged.sol | 32 + .../access/manager/IAccessManager.sol | 401 + .../contracts/access/manager/IAuthority.sol | 14 + .../contracts/account/README.adoc | 12 + .../account/utils/draft-ERC4337Utils.sol | 170 + .../account/utils/draft-ERC7579Utils.sol | 278 + .../contracts/finance/README.adoc | 14 + .../contracts/finance/VestingWallet.sol | 159 + .../contracts/finance/VestingWalletCliff.sol | 54 + .../contracts/governance/Governor.sol | 833 + .../contracts/governance/IGovernor.sol | 441 + .../contracts/governance/README.adoc | 181 + .../governance/TimelockController.sol | 472 + .../extensions/GovernorCountingFractional.sol | 196 + .../GovernorCountingOverridable.sol | 225 + .../extensions/GovernorCountingSimple.sol | 102 + .../extensions/GovernorPreventLateQuorum.sol | 92 + .../extensions/GovernorSettings.sol | 112 + .../governance/extensions/GovernorStorage.sol | 125 + .../extensions/GovernorTimelockAccess.sol | 349 + .../extensions/GovernorTimelockCompound.sol | 167 + .../extensions/GovernorTimelockControl.sol | 170 + .../governance/extensions/GovernorVotes.sol | 64 + .../GovernorVotesQuorumFraction.sol | 110 + .../contracts/governance/utils/IVotes.sol | 59 + .../contracts/governance/utils/Votes.sol | 252 + .../governance/utils/VotesExtended.sol | 84 + .../contracts/interfaces/IERC1155.sol | 6 + .../interfaces/IERC1155MetadataURI.sol | 6 + .../contracts/interfaces/IERC1155Receiver.sol | 6 + .../contracts/interfaces/IERC1271.sol | 17 + .../contracts/interfaces/IERC1363.sol | 86 + .../contracts/interfaces/IERC1363Receiver.sol | 32 + .../contracts/interfaces/IERC1363Spender.sol | 26 + .../contracts/interfaces/IERC165.sol | 6 + .../interfaces/IERC1820Implementer.sol | 20 + .../contracts/interfaces/IERC1820Registry.sol | 112 + .../contracts/interfaces/IERC1967.sol | 24 + .../contracts/interfaces/IERC20.sol | 6 + .../contracts/interfaces/IERC20Metadata.sol | 6 + .../contracts/interfaces/IERC2309.sol | 19 + .../contracts/interfaces/IERC2612.sol | 8 + .../contracts/interfaces/IERC2981.sol | 26 + .../contracts/interfaces/IERC3156.sol | 7 + .../interfaces/IERC3156FlashBorrower.sol | 27 + .../interfaces/IERC3156FlashLender.sol | 41 + .../contracts/interfaces/IERC4626.sol | 230 + .../contracts/interfaces/IERC4906.sol | 20 + .../contracts/interfaces/IERC5267.sol | 28 + .../contracts/interfaces/IERC5313.sol | 16 + .../contracts/interfaces/IERC5805.sol | 9 + .../contracts/interfaces/IERC6372.sol | 17 + .../contracts/interfaces/IERC721.sol | 6 + .../interfaces/IERC721Enumerable.sol | 6 + .../contracts/interfaces/IERC721Metadata.sol | 6 + .../contracts/interfaces/IERC721Receiver.sol | 6 + .../contracts/interfaces/IERC777.sol | 200 + .../contracts/interfaces/IERC777Recipient.sol | 35 + .../contracts/interfaces/IERC777Sender.sol | 35 + .../contracts/interfaces/README.adoc | 85 + .../contracts/interfaces/draft-IERC1822.sol | 20 + .../contracts/interfaces/draft-IERC4337.sol | 253 + .../contracts/interfaces/draft-IERC6093.sol | 161 + .../contracts/interfaces/draft-IERC7579.sol | 226 + .../contracts/interfaces/draft-IERC7674.sol | 17 + .../contracts/metatx/ERC2771Context.sol | 86 + .../contracts/metatx/ERC2771Forwarder.sol | 369 + .../contracts/metatx/README.adoc | 17 + .../contracts/mocks/AccessManagedTarget.sol | 34 + .../contracts/mocks/AccessManagerMock.sol | 21 + .../contracts/mocks/ArraysMock.sol | 127 + .../contracts/mocks/AuthorityMock.sol | 69 + .../contracts/mocks/Base64Dirty.sol | 19 + .../contracts/mocks/BatchCaller.sol | 20 + .../contracts/mocks/CallReceiverMock.sol | 73 + .../contracts/mocks/ConstructorMock.sol | 34 + .../contracts/mocks/ContextMock.sol | 35 + .../contracts/mocks/DummyImplementation.sol | 65 + .../contracts/mocks/EIP712Verifier.sol | 16 + .../contracts/mocks/ERC1271WalletMock.sol | 24 + .../ERC165/ERC165InterfacesSupported.sol | 58 + .../mocks/ERC165/ERC165MaliciousData.sol | 12 + .../mocks/ERC165/ERC165MissingData.sol | 7 + .../mocks/ERC165/ERC165NotSupported.sol | 5 + .../mocks/ERC165/ERC165ReturnBomb.sol | 18 + .../contracts/mocks/ERC2771ContextMock.sol | 28 + .../mocks/ERC3156FlashBorrowerMock.sol | 53 + .../contracts/mocks/EtherReceiverMock.sol | 17 + .../contracts/mocks/InitializableMock.sol | 130 + .../mocks/MerkleProofCustomHashMock.sol | 62 + .../contracts/mocks/MerkleTreeMock.sol | 44 + .../contracts/mocks/MulticallHelper.sol | 23 + .../MultipleInheritanceInitializableMocks.sol | 131 + .../contracts/mocks/PausableMock.sol | 31 + .../contracts/mocks/ReentrancyAttack.sol | 12 + .../contracts/mocks/ReentrancyMock.sol | 50 + .../mocks/ReentrancyTransientMock.sol | 50 + .../mocks/RegressionImplementation.sol | 61 + .../SingleInheritanceInitializableMocks.sol | 49 + .../contracts/mocks/Stateless.sol | 49 + .../contracts/mocks/StorageSlotMock.sol | 87 + .../contracts/mocks/TimelockReentrant.sol | 26 + .../contracts/mocks/TransientSlotMock.sol | 61 + .../contracts/mocks/UpgradeableBeaconMock.sol | 27 + .../contracts/mocks/VotesExtendedMock.sol | 42 + .../contracts/mocks/VotesMock.sol | 42 + .../mocks/account/utils/ERC7579UtilsMock.sol | 23 + .../contracts/mocks/compound/CompTimelock.sol | 174 + .../mocks/docs/ERC20WithAutoMinerReward.sol | 22 + .../contracts/mocks/docs/ERC4626Fees.sol | 109 + .../contracts/mocks/docs/MyNFT.sol | 9 + .../AccessControlERC20MintBase.sol | 25 + .../AccessControlERC20MintMissing.sol | 24 + .../AccessControlERC20MintOnlyRole.sol | 23 + .../access-control/AccessControlModified.sol | 14 + .../AccessControlNonRevokableAdmin.sol | 17 + .../AccessManagedERC20MintBase.sol | 16 + .../docs/access-control/MyContractOwnable.sol | 17 + .../mocks/docs/governance/MyGovernor.sol | 81 + .../mocks/docs/governance/MyToken.sol | 21 + .../docs/governance/MyTokenTimestampBased.sol | 32 + .../mocks/docs/governance/MyTokenWrapped.sol | 28 + .../mocks/docs/token/ERC1155/GameItems.sol | 21 + .../token/ERC1155/MyERC115HolderContract.sol | 7 + .../mocks/docs/token/ERC20/GLDToken.sol | 11 + .../mocks/docs/token/ERC721/GameItem.sol | 19 + .../mocks/docs/utilities/Base64NFT.sol | 27 + .../mocks/docs/utilities/Multicall.sol | 15 + .../GovernorCountingOverridableMock.sol | 18 + .../governance/GovernorFractionalMock.sol | 14 + .../mocks/governance/GovernorMock.sol | 14 + .../GovernorPreventLateQuorumMock.sol | 40 + .../mocks/governance/GovernorStorageMock.sol | 79 + .../governance/GovernorTimelockAccessMock.sol | 70 + .../GovernorTimelockCompoundMock.sol | 69 + .../GovernorTimelockControlMock.sol | 69 + .../mocks/governance/GovernorVoteMock.sol | 20 + .../governance/GovernorWithParamsMock.sol | 51 + .../contracts/mocks/proxy/BadBeacon.sol | 11 + .../mocks/proxy/ClashingImplementation.sol | 19 + .../mocks/proxy/UUPSUpgradeableMock.sol | 35 + .../mocks/token/ERC1155ReceiverMock.sol | 74 + .../mocks/token/ERC1363ForceApproveMock.sol | 14 + .../mocks/token/ERC1363NoReturnMock.sol | 34 + .../mocks/token/ERC1363ReceiverMock.sol | 52 + .../mocks/token/ERC1363ReturnFalseMock.sol | 34 + .../mocks/token/ERC1363SpenderMock.sol | 47 + .../mocks/token/ERC20ApprovalMock.sol | 10 + .../mocks/token/ERC20DecimalsMock.sol | 17 + .../mocks/token/ERC20ExcessDecimalsMock.sol | 9 + .../mocks/token/ERC20FlashMintMock.sol | 26 + .../mocks/token/ERC20ForceApproveMock.sol | 13 + .../mocks/token/ERC20GetterHelper.sol | 38 + .../contracts/mocks/token/ERC20Mock.sol | 16 + .../mocks/token/ERC20MulticallMock.sol | 8 + .../mocks/token/ERC20NoReturnMock.sol | 28 + .../contracts/mocks/token/ERC20Reentrant.sol | 39 + .../mocks/token/ERC20ReturnFalseMock.sol | 19 + .../ERC20VotesAdditionalCheckpointsMock.sol | 31 + .../mocks/token/ERC20VotesLegacyMock.sol | 253 + .../mocks/token/ERC20VotesTimestampMock.sol | 29 + .../mocks/token/ERC4626LimitsMock.sol | 23 + .../contracts/mocks/token/ERC4626Mock.sol | 17 + .../mocks/token/ERC4626OffsetMock.sol | 17 + .../contracts/mocks/token/ERC4646FeesMock.sol | 40 + .../token/ERC721ConsecutiveEnumerableMock.sol | 42 + .../mocks/token/ERC721ConsecutiveMock.sol | 61 + .../mocks/token/ERC721ReceiverMock.sol | 47 + .../mocks/token/ERC721URIStorageMock.sol | 17 + .../contracts/package.json | 32 + .../contracts/proxy/Clones.sol | 262 + .../contracts/proxy/ERC1967/ERC1967Proxy.sol | 40 + .../contracts/proxy/ERC1967/ERC1967Utils.sol | 177 + .../contracts/proxy/Proxy.sol | 69 + .../contracts/proxy/README.adoc | 87 + .../contracts/proxy/beacon/BeaconProxy.sol | 57 + .../contracts/proxy/beacon/IBeacon.sol | 16 + .../proxy/beacon/UpgradeableBeacon.sol | 70 + .../proxy/transparent/ProxyAdmin.sol | 45 + .../TransparentUpgradeableProxy.sol | 118 + .../contracts/proxy/utils/Initializable.sol | 228 + .../contracts/proxy/utils/UUPSUpgradeable.sol | 147 + .../contracts/token/ERC1155/ERC1155.sol | 401 + .../contracts/token/ERC1155/IERC1155.sol | 123 + .../token/ERC1155/IERC1155Receiver.sol | 59 + .../contracts/token/ERC1155/README.adoc | 43 + .../ERC1155/extensions/ERC1155Burnable.sol | 28 + .../ERC1155/extensions/ERC1155Pausable.sol | 38 + .../ERC1155/extensions/ERC1155Supply.sol | 90 + .../ERC1155/extensions/ERC1155URIStorage.sol | 61 + .../extensions/IERC1155MetadataURI.sol | 20 + .../token/ERC1155/utils/ERC1155Holder.sol | 42 + .../token/ERC1155/utils/ERC1155Utils.sol | 88 + .../contracts/token/ERC20/ERC20.sol | 312 + .../contracts/token/ERC20/IERC20.sol | 79 + .../contracts/token/ERC20/README.adoc | 75 + .../token/ERC20/extensions/ERC1363.sol | 137 + .../token/ERC20/extensions/ERC20Burnable.sol | 39 + .../token/ERC20/extensions/ERC20Capped.sol | 56 + .../token/ERC20/extensions/ERC20FlashMint.sol | 134 + .../token/ERC20/extensions/ERC20Pausable.sol | 33 + .../token/ERC20/extensions/ERC20Permit.sol | 83 + .../token/ERC20/extensions/ERC20Votes.sol | 83 + .../token/ERC20/extensions/ERC20Wrapper.sol | 91 + .../token/ERC20/extensions/ERC4626.sol | 282 + .../token/ERC20/extensions/IERC20Metadata.sol | 26 + .../token/ERC20/extensions/IERC20Permit.sol | 90 + .../draft-ERC20TemporaryApproval.sol | 119 + .../token/ERC20/utils/ERC1363Utils.sol | 95 + .../contracts/token/ERC20/utils/SafeERC20.sol | 198 + .../contracts/token/ERC721/ERC721.sol | 456 + .../contracts/token/ERC721/IERC721.sol | 135 + .../token/ERC721/IERC721Receiver.sol | 28 + .../contracts/token/ERC721/README.adoc | 69 + .../ERC721/extensions/ERC721Burnable.sol | 26 + .../ERC721/extensions/ERC721Consecutive.sol | 176 + .../ERC721/extensions/ERC721Enumerable.sol | 174 + .../ERC721/extensions/ERC721Pausable.sol | 37 + .../token/ERC721/extensions/ERC721Royalty.sol | 27 + .../ERC721/extensions/ERC721URIStorage.sol | 61 + .../token/ERC721/extensions/ERC721Votes.sol | 47 + .../token/ERC721/extensions/ERC721Wrapper.sol | 102 + .../ERC721/extensions/IERC721Enumerable.sol | 29 + .../ERC721/extensions/IERC721Metadata.sol | 27 + .../token/ERC721/utils/ERC721Holder.sol | 24 + .../token/ERC721/utils/ERC721Utils.sol | 50 + .../contracts/token/common/ERC2981.sol | 143 + .../contracts/token/common/README.adoc | 10 + .../contracts/utils/Address.sol | 150 + .../contracts/utils/Arrays.sol | 482 + .../contracts/utils/Base64.sol | 123 + .../contracts/utils/Bytes.sol | 114 + .../contracts/utils/CAIP10.sol | 54 + .../contracts/utils/CAIP2.sol | 51 + .../contracts/utils/Comparators.sol | 19 + .../contracts/utils/Context.sol | 28 + .../contracts/utils/Create2.sol | 92 + .../contracts/utils/Errors.sol | 34 + .../contracts/utils/Multicall.sol | 37 + .../contracts/utils/Nonces.sol | 46 + .../contracts/utils/NoncesKeyed.sol | 74 + .../contracts/utils/Packing.sol | 1656 + .../contracts/utils/Panic.sol | 57 + .../contracts/utils/Pausable.sol | 119 + .../contracts/utils/README.adoc | 149 + .../contracts/utils/ReentrancyGuard.sol | 87 + .../utils/ReentrancyGuardTransient.sol | 61 + .../contracts/utils/ShortStrings.sol | 122 + .../contracts/utils/SlotDerivation.sol | 155 + .../contracts/utils/StorageSlot.sol | 143 + .../contracts/utils/Strings.sol | 441 + .../contracts/utils/TransientSlot.sol | 183 + .../contracts/utils/cryptography/ECDSA.sol | 180 + .../contracts/utils/cryptography/EIP712.sol | 160 + .../contracts/utils/cryptography/Hashes.sol | 31 + .../utils/cryptography/MerkleProof.sol | 514 + .../utils/cryptography/MessageHashUtils.sol | 84 + .../contracts/utils/cryptography/P256.sol | 370 + .../contracts/utils/cryptography/RSA.sol | 154 + .../utils/cryptography/SignatureChecker.sol | 50 + .../contracts/utils/introspection/ERC165.sol | 27 + .../utils/introspection/ERC165Checker.sol | 124 + .../contracts/utils/introspection/IERC165.sol | 25 + .../contracts/utils/math/Math.sol | 685 + .../contracts/utils/math/SafeCast.sol | 1162 + .../contracts/utils/math/SignedMath.sol | 68 + .../contracts/utils/structs/BitMaps.sol | 60 + .../contracts/utils/structs/Checkpoints.sol | 630 + .../utils/structs/CircularBuffer.sol | 140 + .../utils/structs/DoubleEndedQueue.sol | 156 + .../contracts/utils/structs/EnumerableMap.sol | 905 + .../contracts/utils/structs/EnumerableSet.sol | 375 + .../contracts/utils/structs/Heap.sol | 256 + .../contracts/utils/structs/MerkleTree.sol | 175 + .../contracts/utils/types/Time.sol | 133 + .../vendor/compound/ICompoundTimelock.sol | 86 + .../contracts/vendor/compound/LICENSE | 11 + .../lib/openzeppelin-contracts/docs/README.md | 16 + .../openzeppelin-contracts/docs/antora.yml | 7 + .../lib/openzeppelin-contracts/docs/config.js | 21 + .../ROOT/images/access-control-multiple.svg | 97 + .../ROOT/images/access-manager-functions.svg | 47 + .../modules/ROOT/images/access-manager.svg | 99 + .../modules/ROOT/images/erc4626-attack-3a.png | Bin 0 -> 60433 bytes .../modules/ROOT/images/erc4626-attack-3b.png | Bin 0 -> 66184 bytes .../modules/ROOT/images/erc4626-attack-6.png | Bin 0 -> 56290 bytes .../modules/ROOT/images/erc4626-attack.png | Bin 0 -> 58886 bytes .../modules/ROOT/images/erc4626-deposit.png | Bin 0 -> 115497 bytes .../docs/modules/ROOT/images/erc4626-mint.png | Bin 0 -> 112787 bytes .../ROOT/images/erc4626-rate-linear.png | Bin 0 -> 50813 bytes .../ROOT/images/erc4626-rate-loglog.png | Bin 0 -> 72818 bytes .../ROOT/images/erc4626-rate-loglogext.png | Bin 0 -> 109923 bytes .../docs/modules/ROOT/images/tally-exec.png | Bin 0 -> 231859 bytes .../docs/modules/ROOT/images/tally-vote.png | Bin 0 -> 40507 bytes .../docs/modules/ROOT/nav.adoc | 23 + .../modules/ROOT/pages/access-control.adoc | 288 + .../ROOT/pages/backwards-compatibility.adoc | 48 + .../docs/modules/ROOT/pages/crowdsales.adoc | 11 + .../docs/modules/ROOT/pages/drafts.adoc | 19 + .../docs/modules/ROOT/pages/erc1155.adoc | 118 + .../docs/modules/ROOT/pages/erc20-supply.adoc | 71 + .../docs/modules/ROOT/pages/erc20.adoc | 67 + .../docs/modules/ROOT/pages/erc4626.adoc | 214 + .../docs/modules/ROOT/pages/erc721.adoc | 58 + .../ROOT/pages/extending-contracts.adoc | 51 + .../docs/modules/ROOT/pages/faq.adoc | 13 + .../docs/modules/ROOT/pages/governance.adoc | 239 + .../docs/modules/ROOT/pages/index.adoc | 70 + .../docs/modules/ROOT/pages/tokens.adoc | 31 + .../docs/modules/ROOT/pages/upgradeable.adoc | 77 + .../docs/modules/ROOT/pages/utilities.adoc | 388 + .../docs/modules/ROOT/pages/wizard.adoc | 15 + .../docs/templates/contract.hbs | 137 + .../docs/templates/helpers.js | 46 + .../docs/templates/page.hbs | 4 + .../docs/templates/properties.js | 72 + .../openzeppelin-contracts/eslint.config.mjs | 26 + .../lib/openzeppelin-contracts/foundry.toml | 15 + .../fv-requirements.txt | 4 + .../openzeppelin-contracts/hardhat.config.js | 124 + .../hardhat/async-test-sanity.js | 3 + .../hardhat/env-artifacts.js | 29 + .../hardhat/ignore-unreachable-warnings.js | 45 + .../hardhat/remappings.js | 18 + .../hardhat/skip-foundry-tests.js | 6 + .../hardhat/task-test-get-files.js | 25 + .../lib/erc4626-tests/ERC4626.prop.sol | 404 + .../lib/erc4626-tests/ERC4626.test.sol | 349 + .../lib/erc4626-tests/LICENSE | 661 + .../lib/erc4626-tests/README.md | 121 + .../lib/forge-std/.gitattributes | 1 + .../lib/forge-std/.github/workflows/ci.yml | 128 + .../lib/forge-std/.github/workflows/sync.yml | 31 + .../lib/forge-std/LICENSE-APACHE | 203 + .../lib/forge-std/LICENSE-MIT | 25 + .../lib/forge-std/README.md | 235 + .../lib/forge-std/foundry.toml | 21 + .../lib/forge-std/package.json | 16 + .../lib/forge-std/scripts/vm.py | 635 + .../lib/forge-std/src/Base.sol | 35 + .../lib/forge-std/src/Script.sol | 27 + .../lib/forge-std/src/StdAssertions.sol | 669 + .../lib/forge-std/src/StdChains.sol | 263 + .../lib/forge-std/src/StdCheats.sol | 817 + .../lib/forge-std/src/StdError.sol | 15 + .../lib/forge-std/src/StdInvariant.sol | 122 + .../lib/forge-std/src/StdJson.sol | 283 + .../lib/forge-std/src/StdMath.sol | 43 + .../lib/forge-std/src/StdStorage.sol | 473 + .../lib/forge-std/src/StdStyle.sol | 333 + .../lib/forge-std/src/StdToml.sol | 283 + .../lib/forge-std/src/StdUtils.sol | 226 + .../lib/forge-std/src/Test.sol | 33 + .../lib/forge-std/src/Vm.sol | 1968 + .../lib/forge-std/src/console.sol | 1560 + .../lib/forge-std/src/console2.sol | 4 + .../lib/forge-std/src/interfaces/IERC1155.sol | 105 + .../lib/forge-std/src/interfaces/IERC165.sol | 12 + .../lib/forge-std/src/interfaces/IERC20.sol | 43 + .../lib/forge-std/src/interfaces/IERC4626.sol | 190 + .../lib/forge-std/src/interfaces/IERC721.sol | 164 + .../forge-std/src/interfaces/IMulticall3.sol | 73 + .../lib/forge-std/src/mocks/MockERC20.sol | 234 + .../lib/forge-std/src/mocks/MockERC721.sol | 231 + .../lib/forge-std/src/safeconsole.sol | 13937 ++++++ .../lib/forge-std/test/StdAssertions.t.sol | 145 + .../lib/forge-std/test/StdChains.t.sol | 228 + .../lib/forge-std/test/StdCheats.t.sol | 618 + .../lib/forge-std/test/StdError.t.sol | 120 + .../lib/forge-std/test/StdJson.t.sol | 49 + .../lib/forge-std/test/StdMath.t.sol | 202 + .../lib/forge-std/test/StdStorage.t.sol | 471 + .../lib/forge-std/test/StdStyle.t.sol | 110 + .../lib/forge-std/test/StdToml.t.sol | 49 + .../lib/forge-std/test/StdUtils.t.sol | 342 + .../lib/forge-std/test/Vm.t.sol | 18 + .../test/compilation/CompilationScript.sol | 10 + .../compilation/CompilationScriptBase.sol | 10 + .../test/compilation/CompilationTest.sol | 10 + .../test/compilation/CompilationTestBase.sol | 10 + .../test/fixtures/broadcast.log.json | 187 + .../lib/forge-std/test/fixtures/test.json | 8 + .../lib/forge-std/test/fixtures/test.toml | 6 + .../lib/forge-std/test/mocks/MockERC20.t.sol | 441 + .../lib/forge-std/test/mocks/MockERC721.t.sol | 721 + .../lib/halmos-cheatcodes/LICENSE | 661 + .../lib/halmos-cheatcodes/README.md | 100 + .../lib/halmos-cheatcodes/src/SVM.sol | 35 + .../lib/halmos-cheatcodes/src/SymTest.sol | 11 + .../lib/openzeppelin-contracts/logo.svg | 15 + .../lib/openzeppelin-contracts/netlify.toml | 3 + .../openzeppelin-contracts/package-lock.json | 11419 +++++ .../lib/openzeppelin-contracts/package.json | 92 + .../lib/openzeppelin-contracts/remappings.txt | 1 + .../lib/openzeppelin-contracts/renovate.json | 4 + .../scripts/checks/compare-layout.js | 20 + .../scripts/checks/compareGasReports.js | 247 + .../scripts/checks/coverage.sh | 18 + .../scripts/checks/extract-layout.js | 38 + .../scripts/checks/generation.sh | 6 + .../scripts/checks/inheritance-ordering.js | 55 + .../scripts/checks/pragma-consistency.js | 49 + .../openzeppelin-contracts/scripts/gen-nav.js | 41 + .../scripts/generate/format-lines.js | 16 + .../scripts/generate/helpers/sanitize.js | 5 + .../scripts/generate/run.js | 58 + .../scripts/generate/templates/Arrays.js | 384 + .../scripts/generate/templates/Arrays.opts.js | 3 + .../scripts/generate/templates/Checkpoints.js | 242 + .../generate/templates/Checkpoints.opts.js | 17 + .../generate/templates/Checkpoints.t.js | 137 + .../generate/templates/EnumerableMap.js | 272 + .../generate/templates/EnumerableMap.opts.js | 19 + .../generate/templates/EnumerableSet.js | 247 + .../generate/templates/EnumerableSet.opts.js | 12 + .../scripts/generate/templates/MerkleProof.js | 187 + .../generate/templates/MerkleProof.opts.js | 11 + .../scripts/generate/templates/Packing.js | 92 + .../generate/templates/Packing.opts.js | 3 + .../scripts/generate/templates/Packing.t.js | 48 + .../scripts/generate/templates/SafeCast.js | 136 + .../scripts/generate/templates/Slot.opts.js | 15 + .../generate/templates/SlotDerivation.js | 119 + .../generate/templates/SlotDerivation.t.js | 127 + .../scripts/generate/templates/StorageSlot.js | 77 + .../generate/templates/StorageSlotMock.js | 57 + .../generate/templates/TransientSlot.js | 80 + .../generate/templates/TransientSlotMock.js | 35 + .../scripts/generate/templates/conversion.js | 30 + .../scripts/git-user-config.sh | 6 + .../openzeppelin-contracts/scripts/helpers.js | 7 + .../openzeppelin-contracts/scripts/prepack.sh | 23 + .../scripts/prepare-docs.sh | 26 + .../openzeppelin-contracts/scripts/prepare.sh | 5 + .../scripts/release/format-changelog.js | 33 + .../scripts/release/synchronize-versions.js | 15 + .../scripts/release/update-comment.js | 34 + .../scripts/release/version.sh | 11 + .../release/workflow/exit-prerelease.sh | 8 + .../release/workflow/github-release.js | 48 + .../release/workflow/integrity-check.sh | 20 + .../scripts/release/workflow/pack.sh | 26 + .../scripts/release/workflow/publish.sh | 26 + .../scripts/release/workflow/rerun.js | 7 + .../workflow/set-changesets-pr-title.js | 17 + .../scripts/release/workflow/start.sh | 35 + .../scripts/release/workflow/state.js | 112 + .../scripts/remove-ignored-artifacts.js | 45 + .../scripts/solhint-custom/index.js | 84 + .../scripts/solhint-custom/package.json | 5 + .../scripts/update-docs-branch.js | 65 + .../scripts/upgradeable/README.md | 21 + .../scripts/upgradeable/patch-apply.sh | 19 + .../scripts/upgradeable/patch-save.sh | 18 + .../scripts/upgradeable/transpile-onto.sh | 54 + .../scripts/upgradeable/transpile.sh | 50 + .../scripts/upgradeable/upgradeable.patch | 361 + .../slither.config.json | 5 + .../openzeppelin-contracts/solhint.config.js | 26 + .../openzeppelin-contracts/test/TESTING.md | 3 + .../test/access/AccessControl.behavior.js | 874 + .../test/access/AccessControl.test.js | 19 + .../test/access/Ownable.test.js | 79 + .../test/access/Ownable2Step.test.js | 102 + .../AccessControlDefaultAdminRules.test.js | 32 + .../AccessControlEnumerable.test.js | 24 + .../test/access/manager/AccessManaged.test.js | 146 + .../access/manager/AccessManager.behavior.js | 257 + .../access/manager/AccessManager.predicate.js | 456 + .../test/access/manager/AccessManager.test.js | 2489 + .../access/manager/AuthorityUtils.test.js | 102 + .../account/utils/draft-ERC4337Utils.test.js | 288 + .../account/utils/draft-ERC7579Utils.t.sol | 421 + .../account/utils/draft-ERC7579Utils.test.js | 353 + .../test/bin/EntryPoint070.abi | 1 + .../test/bin/EntryPoint070.bytecode | Bin 0 -> 16035 bytes .../test/bin/SenderCreator070.abi | 1 + .../test/bin/SenderCreator070.bytecode | Bin 0 -> 451 bytes .../test/finance/VestingWallet.behavior.js | 87 + .../test/finance/VestingWallet.test.js | 65 + .../test/finance/VestingWalletCliff.test.js | 70 + .../test/governance/Governor.t.sol | 55 + .../test/governance/Governor.test.js | 992 + .../governance/TimelockController.test.js | 1279 + .../GovernorCountingFractional.test.js | 248 + .../GovernorCountingOverridable.test.js | 346 + .../extensions/GovernorERC721.test.js | 131 + .../GovernorPreventLateQuorum.test.js | 185 + .../extensions/GovernorStorage.test.js | 155 + .../extensions/GovernorTimelockAccess.test.js | 864 + .../GovernorTimelockCompound.test.js | 448 + .../GovernorTimelockControl.test.js | 504 + .../GovernorVotesQuorumFraction.test.js | 165 + .../extensions/GovernorWithParams.test.js | 245 + .../test/governance/utils/ERC6372.behavior.js | 28 + .../test/governance/utils/Votes.behavior.js | 325 + .../test/governance/utils/Votes.test.js | 102 + .../governance/utils/VotesExtended.test.js | 152 + .../test/helpers/access-manager.js | 85 + .../test/helpers/account.js | 14 + .../test/helpers/chains.js | 109 + .../test/helpers/constants.js | 4 + .../test/helpers/deploy.js | 14 + .../test/helpers/eip712-types.js | 59 + .../test/helpers/eip712.js | 45 + .../test/helpers/enums.js | 12 + .../test/helpers/erc4337-entrypoint.js | 31 + .../test/helpers/erc4337.js | 111 + .../test/helpers/erc7579.js | 58 + .../test/helpers/governance.js | 215 + .../test/helpers/iterate.js | 36 + .../test/helpers/math.js | 33 + .../test/helpers/methods.js | 14 + .../test/helpers/random.js | 19 + .../test/helpers/storage.js | 48 + .../test/helpers/strings.js | 5 + .../test/helpers/time.js | 30 + .../test/helpers/txpool.js | 29 + .../test/metatx/ERC2771Context.test.js | 133 + .../test/metatx/ERC2771Forwarder.t.sol | 279 + .../test/metatx/ERC2771Forwarder.test.js | 384 + .../test/proxy/Clones.behaviour.js | 160 + .../test/proxy/Clones.t.sol | 91 + .../test/proxy/Clones.test.js | 175 + .../test/proxy/ERC1967/ERC1967Proxy.test.js | 23 + .../test/proxy/ERC1967/ERC1967Utils.test.js | 162 + .../test/proxy/Proxy.behaviour.js | 185 + .../test/proxy/beacon/BeaconProxy.test.js | 141 + .../proxy/beacon/UpgradeableBeacon.test.js | 55 + .../test/proxy/transparent/ProxyAdmin.test.js | 82 + .../TransparentUpgradeableProxy.behaviour.js | 357 + .../TransparentUpgradeableProxy.test.js | 28 + .../test/proxy/utils/Initializable.test.js | 216 + .../test/proxy/utils/UUPSUpgradeable.test.js | 120 + .../test/sanity.test.js | 27 + .../test/token/ERC1155/ERC1155.behavior.js | 763 + .../test/token/ERC1155/ERC1155.test.js | 213 + .../extensions/ERC1155Burnable.test.js | 66 + .../extensions/ERC1155Pausable.test.js | 105 + .../ERC1155/extensions/ERC1155Supply.test.js | 119 + .../extensions/ERC1155URIStorage.test.js | 70 + .../token/ERC1155/utils/ERC1155Holder.test.js | 56 + .../token/ERC1155/utils/ERC1155Utils.test.js | 299 + .../test/token/ERC20/ERC20.behavior.js | 269 + .../test/token/ERC20/ERC20.test.js | 199 + .../token/ERC20/extensions/ERC1363.test.js | 370 + .../ERC20/extensions/ERC20Burnable.test.js | 105 + .../ERC20/extensions/ERC20Capped.test.js | 55 + .../ERC20/extensions/ERC20FlashMint.test.js | 164 + .../ERC20/extensions/ERC20Pausable.test.js | 129 + .../ERC20/extensions/ERC20Permit.test.js | 109 + .../token/ERC20/extensions/ERC20Votes.test.js | 546 + .../ERC20/extensions/ERC20Wrapper.test.js | 203 + .../test/token/ERC20/extensions/ERC4626.t.sol | 41 + .../token/ERC20/extensions/ERC4626.test.js | 888 + .../draft-ERC20TemporaryApproval.test.js | 142 + .../test/token/ERC20/utils/SafeERC20.test.js | 427 + .../test/token/ERC721/ERC721.behavior.js | 972 + .../test/token/ERC721/ERC721.test.js | 23 + .../token/ERC721/ERC721Enumerable.test.js | 28 + .../ERC721/extensions/ERC721Burnable.test.js | 77 + .../ERC721/extensions/ERC721Consecutive.t.sol | 181 + .../extensions/ERC721Consecutive.test.js | 236 + .../ERC721/extensions/ERC721Pausable.test.js | 81 + .../ERC721/extensions/ERC721Royalty.test.js | 57 + .../extensions/ERC721URIStorage.test.js | 121 + .../ERC721/extensions/ERC721Votes.test.js | 194 + .../ERC721/extensions/ERC721Wrapper.test.js | 201 + .../token/ERC721/utils/ERC721Holder.test.js | 20 + .../token/ERC721/utils/ERC721Utils.test.js | 94 + .../test/token/common/ERC2981.behavior.js | 152 + .../test/utils/Address.test.js | 281 + .../test/utils/Arrays.t.sol | 31 + .../test/utils/Arrays.test.js | 223 + .../test/utils/Base64.t.sol | 34 + .../test/utils/Base64.test.js | 59 + .../test/utils/Bytes.test.js | 88 + .../test/utils/CAIP.test.js | 53 + .../test/utils/Context.behavior.js | 48 + .../test/utils/Context.test.js | 18 + .../test/utils/Create2.t.sol | 17 + .../test/utils/Create2.test.js | 190 + .../test/utils/Multicall.test.js | 72 + .../test/utils/Nonces.behavior.js | 189 + .../test/utils/Nonces.test.js | 16 + .../test/utils/NoncesKeyed.test.js | 17 + .../test/utils/Packing.t.sol | 993 + .../test/utils/Packing.test.js | 70 + .../test/utils/Panic.test.js | 37 + .../test/utils/Pausable.test.js | 90 + .../test/utils/ReentrancyGuard.test.js | 50 + .../test/utils/ShortStrings.t.sol | 109 + .../test/utils/ShortStrings.test.js | 64 + .../test/utils/SlotDerivation.t.sol | 248 + .../test/utils/SlotDerivation.test.js | 58 + .../test/utils/StorageSlot.test.js | 73 + .../test/utils/Strings.t.sol | 50 + .../test/utils/Strings.test.js | 342 + .../test/utils/TransientSlot.test.js | 59 + .../test/utils/cryptography/ECDSA.test.js | 211 + .../test/utils/cryptography/EIP712.test.js | 105 + .../utils/cryptography/MerkleProof.test.js | 213 + .../cryptography/MessageHashUtils.test.js | 68 + .../test/utils/cryptography/P256.t.sol | 44 + .../test/utils/cryptography/P256.test.js | 156 + .../test/utils/cryptography/RSA.helper.js | 17 + .../test/utils/cryptography/RSA.test.js | 102 + .../utils/cryptography/SigVer15_186-3.rsp | 3850 ++ .../cryptography/SignatureChecker.test.js | 61 + .../ecdsa_secp256r1_sha256_p1363_test.json | 3719 ++ .../test/utils/introspection/ERC165.test.js | 18 + .../utils/introspection/ERC165Checker.test.js | 245 + .../SupportsInterface.behavior.js | 145 + .../test/utils/math/Math.t.sol | 311 + .../test/utils/math/Math.test.js | 562 + .../test/utils/math/SafeCast.test.js | 159 + .../test/utils/math/SignedMath.t.sol | 80 + .../test/utils/math/SignedMath.test.js | 53 + .../test/utils/structs/BitMap.test.js | 149 + .../test/utils/structs/Checkpoints.t.sol | 332 + .../test/utils/structs/Checkpoints.test.js | 146 + .../test/utils/structs/CircularBuffer.test.js | 83 + .../utils/structs/DoubleEndedQueue.test.js | 102 + .../utils/structs/EnumerableMap.behavior.js | 151 + .../test/utils/structs/EnumerableMap.test.js | 65 + .../utils/structs/EnumerableSet.behavior.js | 116 + .../test/utils/structs/EnumerableSet.test.js | 61 + .../test/utils/structs/Heap.t.sol | 74 + .../test/utils/structs/Heap.test.js | 113 + .../test/utils/structs/MerkleTree.test.js | 100 + .../test/utils/types/Time.test.js | 135 + .../lib/sequence-v3/package.json | 13 + .../lib/sequence-v3/pnpm-lock.yaml | 157 + .../lib/sequence-v3/pnpm-workspace.yaml | 2 + .../lib/sequence-v3/script/Deploy.s.sol | 36 + .../lib/sequence-v3/script/DeployMocks.s.sol | 19 + .../lib/sequence-v3/src/Estimator.sol | 111 + .../lib/sequence-v3/src/Factory.sol | 28 + .../lib/sequence-v3/src/Guest.sol | 76 + .../lib/sequence-v3/src/Simulator.sol | 109 + .../lib/sequence-v3/src/Stage1Module.sol | 29 + .../lib/sequence-v3/src/Stage2Module.sol | 27 + .../lib/sequence-v3/src/Wallet.huff | 55 + .../lib/sequence-v3/src/Wallet.sol | 67 + .../src/extensions/passkeys/Passkeys.sol | 123 + .../src/extensions/recovery/Recovery.sol | 217 + .../src/extensions/sessions/SessionErrors.sol | 56 + .../extensions/sessions/SessionManager.sol | 133 + .../src/extensions/sessions/SessionSig.sol | 421 + .../explicit/ExplicitSessionManager.sol | 171 + .../explicit/IExplicitSessionManager.sol | 41 + .../sessions/explicit/Permission.sol | 112 + .../sessions/explicit/PermissionValidator.sol | 135 + .../sessions/implicit/Attestation.sol | 122 + .../implicit/ISignalsImplicitMode.sol | 26 + .../implicit/ImplicitSessionManager.sol | 83 + .../lib/sequence-v3/src/modules/Calls.sol | 124 + .../sequence-v3/src/modules/ERC4337v07.sol | 73 + .../lib/sequence-v3/src/modules/Hooks.sol | 124 + .../src/modules/Implementation.sol | 50 + .../lib/sequence-v3/src/modules/Nonce.sol | 48 + .../lib/sequence-v3/src/modules/Payload.sol | 278 + .../src/modules/ReentrancyGuard.sol | 38 + .../lib/sequence-v3/src/modules/Storage.sol | 37 + .../sequence-v3/src/modules/auth/BaseAuth.sol | 174 + .../sequence-v3/src/modules/auth/BaseSig.sol | 500 + .../sequence-v3/src/modules/auth/SelfAuth.sol | 19 + .../src/modules/auth/Stage1Auth.sol | 62 + .../src/modules/auth/Stage2Auth.sol | 45 + .../src/modules/interfaces/IAccount.sol | 65 + .../src/modules/interfaces/IAuth.sol | 17 + .../src/modules/interfaces/ICheckpointer.sol | 25 + .../interfaces/IDelegatedExtension.sol | 25 + .../modules/interfaces/IERC1155Receiver.sol | 38 + .../src/modules/interfaces/IERC1271.sol | 35 + .../modules/interfaces/IERC223Receiver.sol | 15 + .../modules/interfaces/IERC721Receiver.sol | 21 + .../modules/interfaces/IERC777Receiver.sol | 24 + .../src/modules/interfaces/IEntryPoint.sol | 10 + .../src/modules/interfaces/IPartialAuth.sol | 35 + .../src/modules/interfaces/ISapient.sol | 38 + .../lib/sequence-v3/src/utils/Base64.sol | 169 + .../lib/sequence-v3/src/utils/LibBytes.sol | 120 + .../lib/sequence-v3/src/utils/LibOptim.sol | 68 + .../lib/sequence-v3/src/utils/P256.sol | 153 + .../lib/sequence-v3/src/utils/WebAuthn.sol | 333 + .../lib/sequence-v3/test/Factory.t.sol | 32 + .../lib/sequence-v3/test/Guest.t.sol | 287 + .../lib/sequence-v3/test/Stage1Module.t.sol | 1305 + .../lib/sequence-v3/test/Wallet.t.sol | 110 + .../test/extensions/passkeys/Passkeys.t.sol | 540 + .../test/extensions/recovery/Recovery.t.sol | 595 + .../extensions/sessions/Attestation.t.sol | 51 + .../test/extensions/sessions/Permission.t.sol | 157 + .../extensions/sessions/SessionCalls.t.sol | 299 + .../extensions/sessions/SessionManager.t.sol | 855 + .../test/extensions/sessions/SessionSig.t.sol | 1020 + .../extensions/sessions/SessionTestBase.sol | 209 + .../explicit/ExplicitSessionManager.t.sol | 866 + .../explicit/PermissionValidator.t.sol | 323 + .../implicit/ImplicitSessionManager.t.sol | 221 + .../recovery/RecoveryDenialOfService.t.sol | 199 + .../sessions/ExtendedSessionTestBase.sol | 175 + .../sessions/SessionDenialOfService.t.sol | 191 + .../sessions/SessionLimitIncrementTest.t.sol | 76 + .../extensions/sessions/SessionSelfCall.t.sol | 72 + .../sessions/SessionSignatureAbuse.t.sol | 143 + .../sessions/SessionUsingERC4337.t.sol | 142 + .../sessions/SessionValueForwarding.t.sol | 295 + .../ERC4337v07/ERC4337Entrypoint.t.sol | 179 + .../lib/sequence-v3/test/mocks/AcceptAll.sol | 10 + .../lib/sequence-v3/test/mocks/CanReenter.sol | 11 + .../lib/sequence-v3/test/mocks/Emitter.sol | 39 + .../lib/sequence-v3/test/mocks/MockERC20.sol | 46 + .../test/mocks/MockPayableReceiver.sol | 8 + .../sequence-v3/test/mocks/ValueForwarder.sol | 14 + .../sequence-v3/test/modules/BaseSig.t.sol | 2550 ++ .../lib/sequence-v3/test/modules/Calls.t.sol | 457 + .../sequence-v3/test/modules/ERC4337v07.t.sol | 246 + .../lib/sequence-v3/test/modules/Hooks.t.sol | 174 + .../test/modules/Implementation.t.sol | 31 + .../lib/sequence-v3/test/modules/Nonce.t.sol | 50 + .../sequence-v3/test/modules/Payload.t.sol | 381 + .../lib/sequence-v3/test/utils/Base64.t.sol | 161 + .../lib/sequence-v3/test/utils/LibBytes.t.sol | 335 + .../sequence-v3/test/utils/PrimitivesRPC.sol | 581 + .../lib/sequence-v3/test/utils/TestUtils.sol | 129 + .../signals-implicit-mode/script/Deploy.s.sol | 18 + .../src/helper/SignalsImplicitMode.sol | 55 + .../src/registry/IImplicitProjectRegistry.sol | 70 + .../registry/IImplicitProjectValidation.sol | 25 + .../src/registry/ImplicitProjectRegistry.sol | 189 + .../test/ImplicitProjectRegistry.t.sol | 710 + .../test/SignalsImplicitMode.t.sol | 115 + .../signals-implicit-mode/test/TestHelper.sol | 61 + .../test/mock/SignalsImplicitModeMock.sol | 12 + .../packages/sequence-core-1.0.0/package.json | 60 + .../packages/services/README.md | 3 + .../packages/services/api/CHANGELOG.md | 2154 + .../packages/services/api/README.md | 3 + .../packages/services/api/package.json | 28 + .../packages/services/api/src/api.gen.ts | 4517 ++ .../packages/services/api/src/index.ts | 36 + .../packages/services/api/tsconfig.json | 10 + .../packages/services/builder/CHANGELOG.md | 155 + .../packages/services/builder/README.md | 3 + .../packages/services/builder/package.json | 28 + .../services/builder/src/builder.gen.ts | 714 + .../packages/services/builder/src/index.ts | 30 + .../packages/services/builder/tsconfig.json | 10 + .../packages/services/guard/CHANGELOG.md | 2942 ++ .../packages/services/guard/README.md | 3 + .../packages/services/guard/package.json | 35 + .../services/guard/src/client/guard.gen.ts | 1087 + .../packages/services/guard/src/index.ts | 6 + .../packages/services/guard/src/local.ts | 23 + .../packages/services/guard/src/sequence.ts | 56 + .../packages/services/guard/src/types.ts | 27 + .../services/guard/test/sequence.test.ts | 189 + .../packages/services/guard/tsconfig.json | 10 + .../services/identity-instrument/package.json | 32 + .../identity-instrument/src/challenge.ts | 221 + .../src/identity-instrument.gen.ts | 781 + .../services/identity-instrument/src/index.ts | 88 + .../test/challenge.test.ts | 197 + .../identity-instrument/tsconfig.json | 10 + .../identity-instrument/vitest.config.ts | 8 + .../packages/services/indexer/CHANGELOG.md | 1779 + .../packages/services/indexer/README.md | 3 + .../packages/services/indexer/package.json | 28 + .../packages/services/indexer/src/index.ts | 71 + .../services/indexer/src/indexer.gen.ts | 2353 + .../services/indexer/src/indexergw.gen.ts | 1523 + .../packages/services/indexer/tsconfig.json | 10 + .../services/marketplace/CHANGELOG.md | 238 + .../packages/services/marketplace/README.md | 3 + .../services/marketplace/package.json | 28 + .../services/marketplace/src/index.ts | 36 + .../marketplace/src/marketplace.gen.ts | 2483 + .../services/marketplace/tsconfig.json | 10 + .../packages/services/metadata/CHANGELOG.md | 1787 + .../packages/services/metadata/README.md | 3 + .../packages/services/metadata/package.json | 28 + .../packages/services/metadata/src/index.ts | 66 + .../services/metadata/src/metadata.gen.ts | 2818 ++ .../packages/services/metadata/tsconfig.json | 10 + .../packages/services/relayer/CHANGELOG.md | 3846 ++ .../packages/services/relayer/README.md | 3 + .../services/relayer/hardhat.config.js | 15 + .../packages/services/relayer/package.json | 33 + .../packages/services/relayer/src/index.ts | 1 + .../services/relayer/src/local-relayer.ts | 125 + .../services/relayer/src/provider-relayer.ts | 284 + .../services/relayer/src/rpc-relayer/index.ts | 1 + .../relayer/src/rpc-relayer/relayer.gen.ts | 2037 + .../packages/services/relayer/tsconfig.json | 10 + .../packages/utils/README.md | 4 + .../packages/utils/abi/CHANGELOG.md | 2085 + .../packages/utils/abi/README.md | 3 + .../packages/utils/abi/package.json | 28 + .../packages/utils/abi/src/index.ts | 22 + .../utils/abi/src/sale/erc1155Sale.ts | 352 + .../packages/utils/abi/src/sale/erc721Sale.ts | 352 + .../packages/utils/abi/src/tokens/erc1155.ts | 422 + .../utils/abi/src/tokens/erc1155Items.ts | 378 + .../packages/utils/abi/src/tokens/erc20.ts | 316 + .../packages/utils/abi/src/tokens/erc6909.ts | 404 + .../packages/utils/abi/src/tokens/erc721.ts | 441 + .../utils/abi/src/tokens/erc721Items.ts | 441 + .../packages/utils/abi/src/wallet/erc1271.ts | 26 + .../packages/utils/abi/src/wallet/erc5719.ts | 19 + .../packages/utils/abi/src/wallet/erc6492.ts | 61 + .../packages/utils/abi/src/wallet/factory.ts | 18 + .../packages/utils/abi/src/wallet/index.ts | 26 + .../src/wallet/libs/requireFreshSigners.ts | 15 + .../utils/abi/src/wallet/mainModule.ts | 158 + .../abi/src/wallet/mainModuleUpgradable.ts | 28 + .../utils/abi/src/wallet/moduleHooks.ts | 248 + .../utils/abi/src/wallet/sequenceUtils.ts | 516 + .../utils/abi/src/wallet/walletProxyHook.ts | 9 + .../packages/utils/abi/tsconfig.json | 10 + .../packages/wallet/core/package.json | 41 + .../packages/wallet/core/src/envelope.ts | 148 + .../packages/wallet/core/src/index.ts | 8 + .../wallet/core/src/preconditions/codec.ts | 193 + .../wallet/core/src/preconditions/index.ts | 3 + .../core/src/preconditions/selectors.ts | 41 + .../wallet/core/src/preconditions/types.ts | 201 + .../wallet/core/src/relayer/bundler.ts | 23 + .../wallet/core/src/relayer/bundlers/index.ts | 1 + .../core/src/relayer/bundlers/pimlico.ts | 177 + .../packages/wallet/core/src/relayer/index.ts | 7 + .../wallet/core/src/relayer/relayer.ts | 87 + .../wallet/core/src/relayer/standard/abi.ts | 13 + .../core/src/relayer/standard/eip6963.ts | 70 + .../wallet/core/src/relayer/standard/index.ts | 5 + .../wallet/core/src/relayer/standard/local.ts | 347 + .../core/src/relayer/standard/pk-relayer.ts | 133 + .../core/src/relayer/standard/rpc/index.ts | 375 + .../src/relayer/standard/rpc/relayer.gen.ts | 2037 + .../core/src/relayer/standard/sequence.ts | 95 + .../packages/wallet/core/src/signers/guard.ts | 110 + .../packages/wallet/core/src/signers/index.ts | 45 + .../wallet/core/src/signers/passkey.ts | 284 + .../wallet/core/src/signers/pk/encrypted.ts | 157 + .../wallet/core/src/signers/pk/index.ts | 77 + .../core/src/signers/session-manager.ts | 369 + .../core/src/signers/session/explicit.ts | 385 + .../core/src/signers/session/implicit.ts | 176 + .../wallet/core/src/signers/session/index.ts | 3 + .../core/src/signers/session/session.ts | 62 + .../packages/wallet/core/src/state/cached.ts | 235 + .../packages/wallet/core/src/state/debug.ts | 126 + .../packages/wallet/core/src/state/index.ts | 87 + .../wallet/core/src/state/local/index.ts | 441 + .../wallet/core/src/state/local/indexed-db.ts | 204 + .../wallet/core/src/state/local/memory.ts | 156 + .../wallet/core/src/state/remote/dev-http.ts | 253 + .../wallet/core/src/state/remote/index.ts | 1 + .../wallet/core/src/state/sequence/index.ts | 673 + .../core/src/state/sequence/sessions.gen.ts | 1021 + .../packages/wallet/core/src/state/utils.ts | 59 + .../packages/wallet/core/src/utils/index.ts | 1 + .../src/utils/session/permission-builder.ts | 337 + .../packages/wallet/core/src/wallet.ts | 609 + .../packages/wallet/core/test/constants.ts | 18 + .../wallet/core/test/envelope.test.ts | 617 + .../wallet/core/test/preconditions.test.ts | 283 + .../core/test/preconditions/codec.test.ts | 554 + .../core/test/preconditions/selectors.test.ts | 415 + .../core/test/preconditions/types.test.ts | 443 + .../wallet/core/test/relayer/bundler.test.ts | 306 + .../wallet/core/test/relayer/relayer.test.ts | 366 + .../wallet/core/test/session-manager.test.ts | 1097 + .../packages/wallet/core/test/setup.ts | 63 + .../wallet/core/test/signers-guard.test.ts | 298 + .../wallet/core/test/signers-index.test.ts | 96 + .../wallet/core/test/signers-passkey.test.ts | 666 + .../core/test/signers-pk-encrypted.test.ts | 425 + .../wallet/core/test/signers-pk.test.ts | 252 + .../test/signers-session-explicit.test.ts | 571 + .../test/signers-session-implicit.test.ts | 488 + .../wallet/core/test/state/cached.test.ts | 536 + .../wallet/core/test/state/debug.test.ts | 335 + .../core/test/state/local/memory.test.ts | 220 + .../wallet/core/test/state/utils.test.ts | 410 + .../utils/session/permission-builder.test.ts | 767 + .../packages/wallet/core/test/wallet.test.ts | 392 + .../packages/wallet/core/tsconfig.json | 10 + .../packages/wallet/core/vitest.config.ts | 9 + .../packages/wallet/dapp-client/README.md | 238 + .../wallet/dapp-client/eslint.config.mjs | 4 + .../packages/wallet/dapp-client/package.json | 38 + .../dapp-client/src/ChainSessionManager.ts | 991 + .../wallet/dapp-client/src/DappClient.ts | 801 + .../wallet/dapp-client/src/DappTransport.ts | 518 + .../packages/wallet/dapp-client/src/index.ts | 48 + .../wallet/dapp-client/src/types/index.ts | 218 + .../wallet/dapp-client/src/utils/constants.ts | 5 + .../wallet/dapp-client/src/utils/errors.ts | 62 + .../wallet/dapp-client/src/utils/index.ts | 186 + .../wallet/dapp-client/src/utils/storage.ts | 272 + .../packages/wallet/dapp-client/tsconfig.json | 10 + .../wallet/primitives-cli/eslint.config.mjs | 4 + .../wallet/primitives-cli/package.json | 36 + .../wallet/primitives-cli/src/index.ts | 27 + .../primitives-cli/src/subcommands/address.ts | 68 + .../primitives-cli/src/subcommands/config.ts | 221 + .../src/subcommands/devTools.ts | 269 + .../src/subcommands/passkeys.ts | 298 + .../primitives-cli/src/subcommands/payload.ts | 159 + .../src/subcommands/recovery.ts | 191 + .../primitives-cli/src/subcommands/server.ts | 403 + .../primitives-cli/src/subcommands/session.ts | 142 + .../src/subcommands/sessionExplicit.ts | 95 + .../src/subcommands/sessionImplicit.ts | 79 + .../src/subcommands/signature.ts | 223 + .../wallet/primitives-cli/src/utils.ts | 37 + .../wallet/primitives-cli/tsconfig.json | 10 + .../wallet/primitives/eslint.config.mjs | 4 + .../packages/wallet/primitives/package.json | 33 + .../packages/wallet/primitives/src/address.ts | 19 + .../wallet/primitives/src/attestation.ts | 124 + .../packages/wallet/primitives/src/config.ts | 619 + .../wallet/primitives/src/constants.ts | 65 + .../packages/wallet/primitives/src/context.ts | 77 + .../wallet/primitives/src/erc-6492.ts | 97 + .../wallet/primitives/src/extensions/index.ts | 28 + .../primitives/src/extensions/passkeys.ts | 283 + .../primitives/src/extensions/recovery.ts | 548 + .../wallet/primitives/src/generic-tree.ts | 55 + .../packages/wallet/primitives/src/index.ts | 16 + .../packages/wallet/primitives/src/network.ts | 1013 + .../packages/wallet/primitives/src/payload.ts | 951 + .../wallet/primitives/src/permission.ts | 285 + .../wallet/primitives/src/precondition.ts | 117 + .../wallet/primitives/src/session-config.ts | 681 + .../primitives/src/session-signature.ts | 199 + .../wallet/primitives/src/signature.ts | 1399 + .../packages/wallet/primitives/src/utils.ts | 109 + .../wallet/primitives/test/address.test.ts | 320 + .../primitives/test/attestation.test.ts | 419 + .../wallet/primitives/test/config.test.ts | 932 + .../wallet/primitives/test/erc-6492.test.ts | 485 + .../primitives/test/generic-tree.test.ts | 453 + .../wallet/primitives/test/passkeys.test.ts | 828 + .../wallet/primitives/test/payload.test.ts | 1075 + .../wallet/primitives/test/permission.test.ts | 822 + .../primitives/test/precondition.test.ts | 695 + .../wallet/primitives/test/recovery.test.ts | 925 + .../primitives/test/session-config.test.ts | 931 + .../primitives/test/session-signature.test.ts | 833 + .../wallet/primitives/test/signature.test.ts | 2183 + .../wallet/primitives/test/utils.test.ts | 541 + .../packages/wallet/primitives/tsconfig.json | 10 + .../wallet/primitives/vitest.config.ts | 9 + .../packages/wallet/wdk/.env.test | 5 + .../packages/wallet/wdk/package.json | 45 + .../wallet/wdk/src/dbs/auth-commitments.ts | 31 + .../packages/wallet/wdk/src/dbs/auth-keys.ts | 125 + .../packages/wallet/wdk/src/dbs/generic.ts | 196 + .../packages/wallet/wdk/src/dbs/index.ts | 16 + .../packages/wallet/wdk/src/dbs/messages.ts | 21 + .../wallet/wdk/src/dbs/passkey-credentials.ts | 68 + .../packages/wallet/wdk/src/dbs/recovery.ts | 20 + .../packages/wallet/wdk/src/dbs/signatures.ts | 20 + .../wallet/wdk/src/dbs/transactions.ts | 21 + .../packages/wallet/wdk/src/dbs/wallets.ts | 21 + .../wallet/wdk/src/identity/signer.ts | 78 + .../packages/wallet/wdk/src/index.ts | 2 + .../packages/wallet/wdk/src/sequence/cron.ts | 174 + .../wallet/wdk/src/sequence/devices.ts | 53 + .../wallet/wdk/src/sequence/errors.ts | 20 + .../wallet/wdk/src/sequence/guards.ts | 44 + .../src/sequence/handlers/authcode-pkce.ts | 71 + .../wdk/src/sequence/handlers/authcode.ts | 114 + .../wdk/src/sequence/handlers/devices.ts | 53 + .../wallet/wdk/src/sequence/handlers/guard.ts | 111 + .../wdk/src/sequence/handlers/handler.ts | 14 + .../wdk/src/sequence/handlers/identity.ts | 100 + .../wallet/wdk/src/sequence/handlers/index.ts | 6 + .../wdk/src/sequence/handlers/mnemonic.ts | 121 + .../wallet/wdk/src/sequence/handlers/otp.ts | 128 + .../wdk/src/sequence/handlers/passkeys.ts | 110 + .../wdk/src/sequence/handlers/recovery.ts | 88 + .../packages/wallet/wdk/src/sequence/index.ts | 25 + .../wallet/wdk/src/sequence/logger.ts | 11 + .../wallet/wdk/src/sequence/manager.ts | 551 + .../wallet/wdk/src/sequence/messages.ts | 249 + .../wallet/wdk/src/sequence/recovery.ts | 610 + .../wallet/wdk/src/sequence/sessions.ts | 441 + .../wallet/wdk/src/sequence/signatures.ts | 440 + .../wallet/wdk/src/sequence/signers.ts | 95 + .../wallet/wdk/src/sequence/transactions.ts | 661 + .../wallet/wdk/src/sequence/types/device.ts | 17 + .../wallet/wdk/src/sequence/types/index.ts | 31 + .../wdk/src/sequence/types/message-request.ts | 26 + .../wallet/wdk/src/sequence/types/module.ts | 7 + .../wallet/wdk/src/sequence/types/recovery.ts | 15 + .../src/sequence/types/signature-request.ts | 170 + .../wallet/wdk/src/sequence/types/signer.ts | 33 + .../src/sequence/types/transaction-request.ts | 87 + .../wallet/wdk/src/sequence/types/wallet.ts | 120 + .../wallet/wdk/src/sequence/wallets.ts | 1392 + .../wallet/wdk/test/authcode-pkce.test.ts | 363 + .../packages/wallet/wdk/test/authcode.test.ts | 764 + .../packages/wallet/wdk/test/constants.ts | 139 + .../packages/wallet/wdk/test/guard.test.ts | 318 + .../wallet/wdk/test/identity-auth-dbs.test.ts | 430 + .../wallet/wdk/test/identity-signer.test.ts | 527 + .../packages/wallet/wdk/test/messages.test.ts | 428 + .../packages/wallet/wdk/test/otp.test.ts | 750 + .../packages/wallet/wdk/test/passkeys.test.ts | 640 + .../packages/wallet/wdk/test/recovery.test.ts | 503 + .../packages/wallet/wdk/test/sessions.test.ts | 526 + .../packages/wallet/wdk/test/setup.ts | 86 + .../wallet/wdk/test/transactions.test.ts | 965 + .../packages/wallet/wdk/test/wallets.test.ts | 872 + .../packages/wallet/wdk/tsconfig.json | 10 + .../packages/wallet/wdk/vitest.config.ts | 21 + .../sequence-core-1.0.0/pnpm-workspace.yaml | 22 + .../sequence-core-1.0.0/repo/README.md | 4 + .../repo/eslint-config/README.md | 3 + .../repo/eslint-config/base.js | 52 + .../repo/eslint-config/next.js | 49 + .../repo/eslint-config/package.json | 24 + .../repo/eslint-config/react-internal.js | 39 + .../repo/typescript-config/base.json | 19 + .../repo/typescript-config/nextjs.json | 12 + .../repo/typescript-config/package.json | 9 + .../repo/typescript-config/react-library.json | 7 + .../repo/ui/eslint.config.mjs | 4 + .../sequence-core-1.0.0/repo/ui/package.json | 28 + .../repo/ui/src/button.tsx | 17 + .../sequence-core-1.0.0/repo/ui/src/card.tsx | 27 + .../sequence-core-1.0.0/repo/ui/src/code.tsx | 5 + .../sequence-core-1.0.0/repo/ui/tsconfig.json | 8 + .../repo/ui/turbo/generators/config.ts | 30 + .../turbo/generators/templates/component.hbs | 8 + .../packages/sequence-core-1.0.0/turbo.json | 36 + .../wallet-contracts/.eslintignore | 3 + .../wallet-contracts/.eslintrc.js | 38 + .../wallet-contracts/.gitattributes | 1 + .../actions/install-dependencies/action.yml | 36 + .../wallet-contracts/.github/workflows/ci.yml | 108 + .../wallet-contracts/.gitmodules | 6 + .../wallet-contracts/.prettierrc | 9 + .../wallet-contracts/.solcover.js | 3 + .../wallet-contracts/.solhint.json | 26 + .../0xsequence-wallet-contracts-3.0.1.tgz | Bin 0 -> 34322 bytes .../Counter/.github/workflows/test.yml | 38 + .../wallet-contracts/Counter/.gitmodules | 3 + .../wallet-contracts/Counter/README.md | 66 + .../Counter.s.sol/1/run-1763223074249.json | 47 + .../Counter.s.sol/1/run-1763223530987.json | 47 + .../broadcast/Counter.s.sol/1/run-latest.json | 47 + .../wallet-contracts/Counter/foundry.lock | 8 + .../wallet-contracts/Counter/foundry.toml | 6 + .../Counter/lib/forge-std/.gitattributes | 1 + .../Counter/lib/forge-std/.github/CODEOWNERS | 1 + .../lib/forge-std/.github/dependabot.yml | 6 + .../lib/forge-std/.github/workflows/ci.yml | 142 + .../lib/forge-std/.github/workflows/sync.yml | 36 + .../Counter/lib/forge-std/CONTRIBUTING.md | 193 + .../Counter/lib/forge-std/LICENSE-APACHE | 203 + .../Counter/lib/forge-std/LICENSE-MIT | 25 + .../Counter/lib/forge-std/README.md | 266 + .../lib/forge-std/RELEASE_CHECKLIST.md | 12 + .../Counter/lib/forge-std/foundry.toml | 27 + .../Counter/lib/forge-std/package.json | 16 + .../Counter/lib/forge-std/scripts/vm.py | 646 + .../Counter/lib/forge-std/src/Base.sol | 48 + .../Counter/lib/forge-std/src/Config.sol | 60 + .../Counter/lib/forge-std/src/LibVariable.sol | 477 + .../Counter/lib/forge-std/src/Script.sol | 28 + .../lib/forge-std/src/StdAssertions.sol | 764 + .../Counter/lib/forge-std/src/StdChains.sol | 287 + .../Counter/lib/forge-std/src/StdCheats.sol | 829 + .../Counter/lib/forge-std/src/StdConfig.sol | 612 + .../lib/forge-std/src/StdConstants.sol | 30 + .../Counter/lib/forge-std/src/StdError.sol | 15 + .../lib/forge-std/src/StdInvariant.sol | 122 + .../Counter/lib/forge-std/src/StdJson.sol | 283 + .../Counter/lib/forge-std/src/StdMath.sol | 43 + .../Counter/lib/forge-std/src/StdStorage.sol | 473 + .../Counter/lib/forge-std/src/StdStyle.sol | 333 + .../Counter/lib/forge-std/src/StdToml.sol | 283 + .../Counter/lib/forge-std/src/StdUtils.sol | 208 + .../Counter/lib/forge-std/src/Test.sol | 34 + .../Counter/lib/forge-std/src/Vm.sol | 2494 + .../Counter/lib/forge-std/src/console.sol | 1560 + .../Counter/lib/forge-std/src/console2.sol | 4 + .../lib/forge-std/src/interfaces/IERC1155.sol | 105 + .../lib/forge-std/src/interfaces/IERC165.sol | 12 + .../lib/forge-std/src/interfaces/IERC20.sol | 43 + .../lib/forge-std/src/interfaces/IERC4626.sol | 190 + .../lib/forge-std/src/interfaces/IERC6909.sol | 72 + .../lib/forge-std/src/interfaces/IERC721.sol | 164 + .../lib/forge-std/src/interfaces/IERC7540.sol | 150 + .../lib/forge-std/src/interfaces/IERC7575.sol | 241 + .../forge-std/src/interfaces/IMulticall3.sol | 73 + .../Counter/lib/forge-std/src/safeconsole.sol | 13937 ++++++ .../lib/forge-std/test/CommonBase.t.sol | 44 + .../Counter/lib/forge-std/test/Config.t.sol | 352 + .../lib/forge-std/test/LibVariable.t.sol | 434 + .../lib/forge-std/test/StdAssertions.t.sol | 141 + .../lib/forge-std/test/StdChains.t.sol | 227 + .../lib/forge-std/test/StdCheats.t.sol | 639 + .../lib/forge-std/test/StdConstants.t.sol | 38 + .../Counter/lib/forge-std/test/StdError.t.sol | 120 + .../Counter/lib/forge-std/test/StdJson.t.sol | 49 + .../Counter/lib/forge-std/test/StdMath.t.sol | 202 + .../lib/forge-std/test/StdStorage.t.sol | 488 + .../Counter/lib/forge-std/test/StdStyle.t.sol | 110 + .../Counter/lib/forge-std/test/StdToml.t.sol | 49 + .../Counter/lib/forge-std/test/StdUtils.t.sol | 342 + .../Counter/lib/forge-std/test/Vm.t.sol | 18 + .../test/compilation/CompilationScript.sol | 10 + .../compilation/CompilationScriptBase.sol | 10 + .../test/compilation/CompilationTest.sol | 10 + .../test/compilation/CompilationTestBase.sol | 10 + .../test/fixtures/broadcast.log.json | 187 + .../lib/forge-std/test/fixtures/config.toml | 81 + .../lib/forge-std/test/fixtures/test.json | 8 + .../lib/forge-std/test/fixtures/test.toml | 6 + .../Counter/script/Counter.s.sol | 19 + .../wallet-contracts/Counter/src/Counter.sol | 14 + .../Counter/test/Counter.t.sol | 24 + .../Counter/utils/JsonBindings.sol | 18 + .../wallet-contracts/LICENSE | 219 + .../wallet-contracts/README.md | 56 + .../audits/v1/Consensys_Diligence.md | 7 + .../v1/Quantstamp_Arcadeum_Report_Final.pdf | Bin 0 -> 399997 bytes .../v1/sequence_quantstamp_audit_feb_2021.pdf | Bin 0 -> 376935 bytes .../Sequence Wallet - Zellic Audit Report.pdf | Bin 0 -> 1669108 bytes ...-horizon-sequence-wallet-audit-2023-02.pdf | Bin 0 -> 1020223 bytes .../wallet-contracts/config/PROD.env.sample | 3 + .../wallet-contracts/contracts/Factory.sol | 23 + .../wallet-contracts/contracts/Wallet.sol | 60 + .../contracts/hooks/WalletProxyHook.sol | 12 + .../hooks/interfaces/IWalletProxy.sol | 12 + .../contracts/interfaces/IERC1271Wallet.sol | 26 + .../interfaces/receivers/IERC1155Receiver.sol | 9 + .../interfaces/receivers/IERC223Receiver.sol | 6 + .../interfaces/receivers/IERC721Receiver.sol | 6 + .../interfaces/receivers/IERC777Receiver.sol | 6 + .../contracts/interfaces/tokens/IERC1155.sol | 27 + .../contracts/interfaces/tokens/IERC20.sol | 14 + .../contracts/interfaces/tokens/IERC721.sol | 18 + .../contracts/mocks/AlwaysRevertMock.sol | 8 + .../contracts/mocks/CallReceiverMock.sol | 22 + .../contracts/mocks/DelegateCallMock.sol | 23 + .../contracts/mocks/ERC1155Mock.sol | 63 + .../contracts/mocks/ERC165CheckerMock.sol | 53 + .../contracts/mocks/ERC20Mock.sol | 51 + .../contracts/mocks/ERC721Mock.sol | 86 + .../contracts/mocks/GasBurnerMock.sol | 17 + .../contracts/mocks/HookCallerMock.sol | 55 + .../contracts/mocks/HookMock.sol | 8 + .../contracts/mocks/LibBytesImpl.sol | 20 + .../contracts/mocks/LibBytesPointerImpl.sol | 24 + .../contracts/mocks/LibStringImp.sol | 24 + .../contracts/mocks/ModuleMock.sol | 10 + .../contracts/modules/GuestModule.sol | 103 + .../contracts/modules/MainModule.sol | 49 + .../modules/MainModuleGasEstimation.sol | 104 + .../modules/MainModuleUpgradable.sol | 61 + .../modules/commons/Implementation.sol | 31 + .../contracts/modules/commons/ModuleAuth.sol | 166 + .../modules/commons/ModuleAuthConvenience.sol | 43 + .../modules/commons/ModuleAuthFixed.sol | 74 + .../modules/commons/ModuleAuthUpgradable.sol | 50 + .../contracts/modules/commons/ModuleCalls.sol | 131 + .../modules/commons/ModuleCreator.sol | 35 + .../modules/commons/ModuleERC165.sol | 17 + .../modules/commons/ModuleERC5719.sol | 18 + .../modules/commons/ModuleExtraAuth.sol | 75 + .../contracts/modules/commons/ModuleHooks.sol | 142 + .../contracts/modules/commons/ModuleIPFS.sol | 37 + .../contracts/modules/commons/ModuleNonce.sol | 66 + .../commons/ModuleOnlyDelegatecall.sol | 22 + .../modules/commons/ModuleSelfAuth.sol | 13 + .../modules/commons/ModuleStorage.sol | 22 + .../modules/commons/ModuleUpdate.sol | 49 + .../ModuleIgnoreAuthUpgradable.sol | 20 + .../gas-estimation/ModuleIgnoreNonceCalls.sol | 34 + .../commons/interfaces/IModuleAuth.sol | 46 + .../interfaces/IModuleAuthUpgradable.sol | 9 + .../commons/interfaces/IModuleCalls.sol | 37 + .../commons/interfaces/IModuleCreator.sol | 13 + .../commons/interfaces/IModuleHooks.sol | 31 + .../commons/interfaces/IModuleUpdate.sol | 21 + .../submodules/auth/SequenceBaseSig.sol | 255 + .../submodules/auth/SequenceChainedSig.sol | 112 + .../submodules/auth/SequenceDynamicSig.sol | 25 + .../submodules/auth/SequenceNoChainIdSig.sol | 14 + .../submodules/nonce/SubModuleNonce.sol | 33 + .../contracts/modules/utils/GasEstimator.sol | 15 + .../modules/utils/MultiCallUtils.sol | 105 + .../contracts/modules/utils/RequireUtils.sol | 112 + .../contracts/modules/utils/SequenceUtils.sol | 7 + .../contracts/trust/Trust.sol | 160 + .../contracts/trust/TrustFactory.sol | 33 + .../contracts/utils/LibAddress.sol | 17 + .../contracts/utils/LibBytes.sol | 75 + .../contracts/utils/LibBytesPointer.sol | 150 + .../contracts/utils/LibOptim.sol | 74 + .../contracts/utils/LibString.sol | 87 + .../contracts/utils/SignatureValidator.sol | 127 + .../wallet-contracts/docs/book.css | 13 + .../wallet-contracts/docs/book.toml | 13 + .../wallet-contracts/docs/solidity.min.js | 74 + .../wallet-contracts/docs/src/README.md | 56 + .../wallet-contracts/docs/src/SUMMARY.md | 92 + .../contracts/Factory.sol/contract.Factory.md | 32 + .../docs/src/contracts/README.md | 11 + .../contracts/Wallet.sol/library.Wallet.md | 58 + .../docs/src/contracts/hooks/README.md | 5 + .../contract.WalletProxyHook.md | 15 + .../interface.IWalletProxy.md | 14 + .../src/contracts/hooks/interfaces/README.md | 4 + .../interface.IERC1271Wallet.md | 57 + .../docs/src/contracts/interfaces/README.md | 6 + .../interface.IERC1155Receiver.md | 21 + .../interface.IERC223Receiver.md | 12 + .../interface.IERC721Receiver.md | 12 + .../interface.IERC777Receiver.md | 12 + .../contracts/interfaces/receivers/README.md | 7 + .../tokens/IERC1155.sol/interface.IERC1155.md | 83 + .../tokens/IERC20.sol/interface.IERC20.md | 60 + .../tokens/IERC721.sol/interface.IERC721.md | 87 + .../src/contracts/interfaces/tokens/README.md | 6 + .../contract.AlwaysRevertMock.md | 12 + .../contract.CallReceiverMock.md | 48 + .../contract.DelegateCallMock.md | 48 + .../ERC1155Mock.sol/contract.ERC1155Mock.md | 110 + .../contract.ERC165CheckerMock.md | 37 + .../mocks/ERC20Mock.sol/contract.ERC20Mock.md | 103 + .../ERC721Mock.sol/contract.ERC721Mock.md | 151 + .../contract.GasBurnerMock.md | 19 + .../contract.HookCallerMock.md | 49 + .../mocks/HookMock.sol/contract.HookMock.md | 12 + .../LibBytesImpl.sol/contract.LibBytesImpl.md | 26 + .../contract.LibBytesPointerImpl.md | 33 + .../LibStringImp.sol/contract.LibStringImp.md | 33 + .../ModuleMock.sol/contract.ModuleMock.md | 19 + .../docs/src/contracts/mocks/README.md | 17 + .../GuestModule.sol/contract.GuestModule.md | 124 + .../MainModule.sol/contract.MainModule.md | 57 + .../contract.MainModuleGasEstimation.md | 85 + .../contract.MainModuleUpgradable.md | 63 + .../docs/src/contracts/modules/README.md | 9 + .../contract.Implementation.md | 42 + .../ModuleAuth.sol/abstract.ModuleAuth.md | 203 + .../abstract.ModuleAuthConvenience.md | 53 + .../abstract.ModuleAuthFixed.md | 108 + .../abstract.ModuleAuthUpgradable.md | 75 + .../ModuleCalls.sol/abstract.ModuleCalls.md | 104 + .../contract.ModuleCreator.md | 57 + .../ModuleERC165.sol/abstract.ModuleERC165.md | 31 + .../contract.ModuleERC5719.md | 15 + .../abstract.ModuleExtraAuth.md | 92 + .../ModuleHooks.sol/contract.ModuleHooks.md | 202 + .../ModuleIPFS.sol/contract.ModuleIPFS.md | 52 + .../ModuleNonce.sol/contract.ModuleNonce.md | 96 + .../contract.ModuleOnlyDelegatecall.md | 36 + .../contract.ModuleSelfAuth.md | 19 + .../library.ModuleStorage.md | 33 + .../ModuleUpdate.sol/contract.ModuleUpdate.md | 70 + .../src/contracts/modules/commons/README.md | 23 + .../abstract.ModuleIgnoreAuthUpgradable.md | 32 + .../abstract.ModuleIgnoreNonceCalls.md | 26 + .../modules/commons/gas-estimation/README.md | 5 + .../IModuleAuth.sol/abstract.IModuleAuth.md | 101 + .../interface.IModuleAuthUpgradable.md | 14 + .../interface.IModuleCalls.md | 78 + .../interface.IModuleCreator.md | 33 + .../interface.IModuleHooks.md | 77 + .../abstract.IModuleUpdate.md | 46 + .../modules/commons/interfaces/README.md | 9 + .../modules/commons/submodules/README.md | 5 + .../modules/commons/submodules/auth/README.md | 7 + .../library.SequenceBaseSig.md | 225 + .../abstract.SequenceChainedSig.md | 91 + .../library.SequenceDynamicSig.md | 35 + .../library.SequenceNoChainIdSig.md | 28 + .../commons/submodules/nonce/README.md | 4 + .../library.SubModuleNonce.md | 51 + .../GasEstimator.sol/contract.GasEstimator.md | 14 + .../contract.MultiCallUtils.md | 133 + .../src/contracts/modules/utils/README.md | 7 + .../RequireUtils.sol/contract.RequireUtils.md | 149 + .../contract.SequenceUtils.md | 7 + .../docs/src/contracts/trust/README.md | 6 + .../trust/Trust.sol/contract.Trust.md | 186 + .../trust/Trust.sol/function.absDiff.md | 8 + .../TrustFactory.sol/contract.TrustFactory.md | 26 + .../LibAddress.sol/library.LibAddress.md | 23 + .../utils/LibBytes.sol/library.LibBytes.md | 114 + .../library.LibBytesPointer.md | 201 + .../utils/LibOptim.sol/library.LibOptim.md | 100 + .../utils/LibString.sol/library.LibString.md | 106 + .../docs/src/contracts/utils/README.md | 9 + .../library.SignatureValidator.md | 130 + .../wallet-contracts/foundry.lock | 8 + .../wallet-contracts/foundry.toml | 11 + .../foundry_test/base/AdvTest.sol | 205 + .../foundry_test/hooks/WalletProxyHook.t.sol | 37 + .../modules/commons/Implementation.t.sol | 66 + .../modules/commons/ModuleCalls.t.sol | 351 + .../modules/commons/ModuleERC5719.t.sol | 42 + .../modules/commons/ModuleExtraAuth.t.sol | 175 + .../modules/commons/ModuleIPFS.t.sol | 46 + .../modules/commons/ModuleStorage.t.sol | 84 + .../submodules/auth/SequenceBaseSig.t.sol | 325 + .../submodules/auth/SequenceChainedSig.t.sol | 276 + .../submodules/auth/SequenceDynamicSig.t.sol | 57 + .../auth/SequenceNoChainIdSig.t.sol | 51 + .../submodules/nonce/SubModuleNonce.t.sol | 16 + .../modules/utils/L2CompressorEncoder.sol | 393 + .../modules/utils/L2CompressorHuff.t.sol | 284 + .../utils/L2CompressorHuffReadExecute.sol | 143 + .../utils/L2CompressorHuffReadFlag.t.sol | 1018 + .../utils/L2CompressorHuffReadNonce.sol | 55 + .../utils/L2CompressorHuffReadTx.t.sol | 93 + .../utils/L2CompressorHuffReadTxs.t.sol | 123 + .../modules/utils/RequireUtils.t.sol | 158 + .../foundry_test/trust/Trust.t.sol | 867 + .../foundry_test/trust/TrustFactory.t.sol | 53 + .../foundry_test/utils/LibAddress.t.sol | 15 + .../foundry_test/utils/LibBytes.t.sol | 100 + .../foundry_test/utils/LibBytesPointer.t.sol | 152 + .../foundry_test/utils/LibOptim.t.sol | 63 + .../utils/SignatureValidator.t.sol | 199 + .../wallet-contracts/funding.json | 5 + .../wallet-contracts/hardhat.config.ts | 72 + .../lib/forge-std/.github/workflows/ci.yml | 92 + .../lib/forge-std/.github/workflows/sync.yml | 29 + .../lib/forge-std/.gitmodules | 3 + .../lib/forge-std/LICENSE-APACHE | 203 + .../lib/forge-std/LICENSE-MIT | 25 + .../wallet-contracts/lib/forge-std/README.md | 250 + .../lib/forge-std/foundry.toml | 21 + .../lib/ds-test/.github/workflows/build.yml | 41 + .../lib/forge-std/lib/ds-test/LICENSE | 674 + .../lib/forge-std/lib/ds-test/Makefile | 14 + .../lib/forge-std/lib/ds-test/default.nix | 4 + .../lib/forge-std/lib/ds-test/demo/demo.sol | 222 + .../lib/forge-std/lib/ds-test/package.json | 15 + .../lib/forge-std/lib/ds-test/src/test.sol | 592 + .../lib/forge-std/lib/ds-test/src/test.t.sol | 417 + .../lib/forge-std/package.json | 16 + .../lib/forge-std/src/Base.sol | 33 + .../lib/forge-std/src/Script.sol | 26 + .../lib/forge-std/src/StdAssertions.sol | 376 + .../lib/forge-std/src/StdChains.sol | 231 + .../lib/forge-std/src/StdCheats.sol | 639 + .../lib/forge-std/src/StdError.sol | 15 + .../lib/forge-std/src/StdInvariant.sol | 92 + .../lib/forge-std/src/StdJson.sol | 179 + .../lib/forge-std/src/StdMath.sol | 43 + .../lib/forge-std/src/StdStorage.sol | 327 + .../lib/forge-std/src/StdStyle.sol | 333 + .../lib/forge-std/src/StdUtils.sol | 192 + .../lib/forge-std/src/Test.sol | 32 + .../wallet-contracts/lib/forge-std/src/Vm.sol | 490 + .../lib/forge-std/src/console.sol | 1533 + .../lib/forge-std/src/console2.sol | 1546 + .../lib/forge-std/src/interfaces/IERC1155.sol | 105 + .../lib/forge-std/src/interfaces/IERC165.sol | 12 + .../lib/forge-std/src/interfaces/IERC20.sol | 43 + .../lib/forge-std/src/interfaces/IERC4626.sol | 190 + .../lib/forge-std/src/interfaces/IERC721.sol | 164 + .../forge-std/src/interfaces/IMulticall3.sol | 73 + .../lib/forge-std/test/StdAssertions.t.sol | 999 + .../lib/forge-std/test/StdChains.t.sol | 160 + .../lib/forge-std/test/StdCheats.t.sol | 418 + .../lib/forge-std/test/StdError.t.sol | 118 + .../lib/forge-std/test/StdMath.t.sol | 197 + .../lib/forge-std/test/StdStorage.t.sol | 283 + .../lib/forge-std/test/StdStyle.t.sol | 110 + .../lib/forge-std/test/StdUtils.t.sol | 297 + .../test/compilation/CompilationScript.sol | 10 + .../compilation/CompilationScriptBase.sol | 10 + .../test/compilation/CompilationTest.sol | 10 + .../test/compilation/CompilationTestBase.sol | 10 + .../test/fixtures/broadcast.log.json | 187 + .../lib/foundry-huff/.git-blame-ignore-revs | 2 + .../foundry-huff/.github/workflows/tests.yaml | 31 + .../lib/foundry-huff/.gitmodules | 6 + .../wallet-contracts/lib/foundry-huff/LICENSE | 201 + .../lib/foundry-huff/README.md | 167 + .../lib/foundry-huff/assets/Group 1.png | Bin 0 -> 23776 bytes .../lib/foundry-huff/assets/banner.jpg | Bin 0 -> 45536 bytes .../black_white_huff-removebg-preview.png | Bin 0 -> 5748 bytes .../foundry-huff/assets/black_white_huff.png | Bin 0 -> 8644 bytes .../lib/foundry-huff/assets/foundry.png | Bin 0 -> 14491 bytes .../assets/foundry_huff_banner.jpg | Bin 0 -> 45502 bytes .../assets/foundry_huff_banner.png | Bin 0 -> 23481 bytes .../lib/foundry-huff/assets/huff.png | Bin 0 -> 11820 bytes .../lib/foundry-huff/assets/inverted_huff.png | Bin 0 -> 14651 bytes .../assets/x-removebg-preview.png | Bin 0 -> 11985 bytes .../lib/foundry-huff/assets/x.jpg | Bin 0 -> 8013 bytes .../lib/foundry-huff/foundry.toml | 10 + .../lib/forge-std/.github/workflows/ci.yml | 134 + .../lib/forge-std/.github/workflows/sync.yml | 29 + .../foundry-huff/lib/forge-std/.gitmodules | 3 + .../foundry-huff/lib/forge-std/LICENSE-APACHE | 203 + .../foundry-huff/lib/forge-std/LICENSE-MIT | 25 + .../lib/foundry-huff/lib/forge-std/README.md | 250 + .../foundry-huff/lib/forge-std/foundry.toml | 21 + .../lib/ds-test/.github/workflows/build.yml | 41 + .../lib/forge-std/lib/ds-test/LICENSE | 674 + .../lib/forge-std/lib/ds-test/Makefile | 14 + .../lib/forge-std/lib/ds-test/default.nix | 4 + .../lib/forge-std/lib/ds-test/demo/demo.sol | 222 + .../lib/forge-std/lib/ds-test/package.json | 15 + .../lib/forge-std/lib/ds-test/src/test.sol | 592 + .../lib/forge-std/lib/ds-test/src/test.t.sol | 417 + .../foundry-huff/lib/forge-std/package.json | 16 + .../foundry-huff/lib/forge-std/src/Base.sol | 35 + .../foundry-huff/lib/forge-std/src/Script.sol | 27 + .../lib/forge-std/src/StdAssertions.sol | 376 + .../lib/forge-std/src/StdChains.sol | 234 + .../lib/forge-std/src/StdCheats.sol | 817 + .../lib/forge-std/src/StdError.sol | 15 + .../lib/forge-std/src/StdInvariant.sol | 92 + .../lib/forge-std/src/StdJson.sol | 179 + .../lib/forge-std/src/StdMath.sol | 43 + .../lib/forge-std/src/StdStorage.sol | 331 + .../lib/forge-std/src/StdStyle.sol | 333 + .../lib/forge-std/src/StdUtils.sol | 198 + .../foundry-huff/lib/forge-std/src/Test.sol | 33 + .../lib/foundry-huff/lib/forge-std/src/Vm.sol | 542 + .../lib/forge-std/src/console.sol | 1533 + .../lib/forge-std/src/console2.sol | 1558 + .../lib/forge-std/src/interfaces/IERC1155.sol | 105 + .../lib/forge-std/src/interfaces/IERC165.sol | 12 + .../lib/forge-std/src/interfaces/IERC20.sol | 43 + .../lib/forge-std/src/interfaces/IERC4626.sol | 190 + .../lib/forge-std/src/interfaces/IERC721.sol | 164 + .../forge-std/src/interfaces/IMulticall3.sol | 73 + .../lib/forge-std/src/safeconsole.sol | 13248 ++++++ .../lib/forge-std/test/StdAssertions.t.sol | 999 + .../lib/forge-std/test/StdChains.t.sol | 215 + .../lib/forge-std/test/StdCheats.t.sol | 610 + .../lib/forge-std/test/StdError.t.sol | 118 + .../lib/forge-std/test/StdMath.t.sol | 212 + .../lib/forge-std/test/StdStorage.t.sol | 293 + .../lib/forge-std/test/StdStyle.t.sol | 110 + .../lib/forge-std/test/StdUtils.t.sol | 342 + .../test/compilation/CompilationScript.sol | 10 + .../compilation/CompilationScriptBase.sol | 10 + .../test/compilation/CompilationTest.sol | 10 + .../test/compilation/CompilationTestBase.sol | 10 + .../test/fixtures/broadcast.log.json | 187 + .../lib/foundry-huff/scripts/binary_check.sh | 11 + .../lib/foundry-huff/scripts/file_writer.sh | 3 + .../lib/foundry-huff/scripts/rand_bytes.sh | 3 + .../foundry-huff/scripts/read_and_append.sh | 3 + .../lib/solidity-stringutils/.gitattributes | 1 + .../.github/workflows/ci.yml | 14 + .../lib/solidity-stringutils/.gitmodules | 3 + .../lib/solidity-stringutils/LICENSE | 201 + .../lib/solidity-stringutils/Makefile | 4 + .../lib/solidity-stringutils/README | 1 + .../lib/solidity-stringutils/README.md | 357 + .../lib/solidity-stringutils/dappfile | 8 + .../solidity-stringutils/lib/ds-test/LICENSE | 674 + .../solidity-stringutils/lib/ds-test/Makefile | 14 + .../lib/ds-test/default.nix | 4 + .../lib/ds-test/demo/demo.sol | 223 + .../lib/ds-test/src/test.sol | 434 + .../lib/solidity-stringutils/src/strings.sol | 727 + .../solidity-stringutils/src/strings.t.sol | 216 + .../lib/foundry-huff/remappings.txt | 2 + .../lib/foundry-huff/scripts/binary_check.sh | 11 + .../lib/foundry-huff/scripts/file_writer.sh | 3 + .../lib/foundry-huff/scripts/rand_bytes.sh | 3 + .../foundry-huff/scripts/read_and_append.sh | 3 + .../lib/foundry-huff/src/HuffConfig.sol | 247 + .../lib/foundry-huff/src/HuffDeployer.sol | 134 + .../src/depreciated/StatefulDeployer.sol | 73 + .../src/depreciated/StatefulDeployer.t.sol | 56 + .../foundry-huff/src/test/HuffConfig.t.sol | 55 + .../foundry-huff/src/test/HuffDeployer.t.sol | 276 + .../lib/foundry-huff/src/test/Logging.t.sol | 83 + .../src/test/contracts/ConstOverride.huff | 6 + .../src/test/contracts/Constructor.huff | 69 + .../test/contracts/ConstructorNeedsValue.huff | 16 + .../src/test/contracts/EVMVersionCheck.huff | 5 + .../src/test/contracts/LotsOfLogging.huff | 56 + .../src/test/contracts/NoConstructor.huff | 38 + .../src/test/contracts/Number.huff | 38 + .../src/test/contracts/RememberCreator.huff | 24 + .../src/test/interfaces/IConstructor.sol | 7 + .../src/test/interfaces/INumber.sol | 7 + .../src/test/interfaces/IRememberCreator.sol | 6 + .../wallet-contracts/networks/arbitrum.json | 22 + .../networks/arbitrumGoerli.json | 22 + .../networks/arbitrumNova.json | 22 + .../wallet-contracts/networks/avalanche.json | 22 + .../networks/avalancheFuji.json | 22 + .../wallet-contracts/networks/bnb.json | 22 + .../wallet-contracts/networks/bnbTestnet.json | 22 + .../wallet-contracts/networks/gnosis.json | 22 + .../wallet-contracts/networks/goerli.json | 22 + .../wallet-contracts/networks/hardhat.json | 22 + .../wallet-contracts/networks/mainnet.json | 22 + .../wallet-contracts/networks/mumbai.json | 22 + .../wallet-contracts/networks/optimism.json | 22 + .../wallet-contracts/networks/polygon.json | 26 + .../networks/polygonZkevm.json | 22 + .../wallet-contracts/package-lock.json | 38191 ++++++++++++++++ .../wallet-contracts/package.json | 105 + .../wallet-contracts/pnpm-lock.yaml | 13554 ++++++ .../wallet-contracts/remappings.txt | 3 + .../wallet-contracts/run_huff_tests.sh | 17 + .../wallet-contracts/soldeer.lock | 6 + .../wallet-contracts/src/Errors.huff | 158 + .../wallet-contracts/src/L2Compressor.huff | 140 + .../wallet-contracts/src/L2CompressorLib.huff | 2562 ++ ...jkqagwbukjfojatjegwtjmxhdL2Compressor.huff | 142 + ...vvfcuoxtlisicumgcpzqhgavjL2Compressor.huff | 142 + ...egfauooldcwyvlordhurwepivL2Compressor.huff | 142 + ...shkgzisywrbnkhcrodypkvbvyL2Compressor.huff | 142 + ...drtxibkzevmerruajxffksduvL2Compressor.huff | 142 + ...lnugcaogzpvcdfhvolsvzerleL2Compressor.huff | 142 + ...ovsnvnyyhadlushmcopgxtlcwL2Compressor.huff | 142 + ...sqtnysjlyfovitokyykvxttnoL2Compressor.huff | 142 + ...ufexucahwkkbkfdcmuiabvbfeL2Compressor.huff | 142 + ...gvfqaqtuxwpgejdnyqkualpwlL2Compressor.huff | 142 + ...orkxonmlujouewhlrvjjrmurcL2Compressor.huff | 142 + ...skwojupcsygtzovabokiotusaL2Compressor.huff | 142 + ...wzygdglttftvfnbgkuxhmtqwiL2Compressor.huff | 142 + ...aqrahclmuoszdisbtgmuppjvfL2Compressor.huff | 142 + ...kbktfjhzdpajytwhcpkhlmscqL2Compressor.huff | 142 + ...eweytjiloryhjilsqguaprwtwL2Compressor.huff | 142 + ...onlpbmziexnicojtlgsgfouyrL2Compressor.huff | 142 + ...zwlsndhjyagmukhxiugwadpxxL2Compressor.huff | 142 + ...kngjvjjjqfpzmxlycnvbslwevL2Compressor.huff | 142 + ...nijxlttsivcfgzleurbgpchhzL2Compressor.huff | 142 + ...fmyszewnycpzlqmcopsqccarqL2Compressor.huff | 142 + ...vbjyubdfmmdxzehdfcdiwufcrL2Compressor.huff | 142 + ...mhbdbiuueqxutuvcxicgrmnxwL2Compressor.huff | 142 + ...nxxrhkhfelgdrwmnbwwirribaL2Compressor.huff | 142 + ...yicdnumnesfhcjlgtqguwdpnpL2Compressor.huff | 142 + ...csyytsvygxsyhvyojjbqsghpbL2Compressor.huff | 142 + ...yvcmrjzhibkdksklxflvtfefdL2Compressor.huff | 142 + ...fcykqjxgggzptgdvokhmzcvamL2Compressor.huff | 142 + ...lozoqyyfvpcdqeanjxglmtzbbL2Compressor.huff | 142 + .../src/imps/L2CompressorImps.huff | 52 + .../src/imps/L2CompressorReadExecute.huff | 30 + .../src/imps/L2CompressorReadFlag.huff | 30 + .../src/imps/L2CompressorReadNonce.huff | 30 + .../src/imps/L2CompressorReadTx.huff | 30 + .../src/imps/L2CompressorReadTxs.huff | 30 + ...fvplniuqleqmglgpL2CompressorReadNonce.huff | 32 + ...brskpnttujfxlnsuqL2CompressorReadFlag.huff | 32 + ...kvygupcezykxnllxhooL2CompressorReadTx.huff | 32 + ...hmuynutuutdpetfmL2CompressorReadNonce.huff | 32 + ...ijkxkzjebeugweL2CompressorReadExecute.huff | 32 + ...vimfyeuyukrpkefkpjvL2CompressorReadTx.huff | 32 + ...xubslwqheqqdtpojdxL2CompressorReadTxs.huff | 32 + ...fpbluzvxgnvfnbjbvdL2CompressorReadTxs.huff | 32 + ...juvxauktfiveuhazL2CompressorReadNonce.huff | 32 + ...eablvdedlohtwcpgruiL2CompressorReadTx.huff | 32 + ...ujxdddmmbuqrzcvpqlL2CompressorReadTxs.huff | 32 + ...muiiddtfwsyytzwszL2CompressorReadFlag.huff | 32 + ...ecwtcwuiczrfadymzpwL2CompressorReadTx.huff | 32 + ...lfabzhyfjejoyhqoxvnL2CompressorReadTx.huff | 32 + ...licrbibyyssybguhL2CompressorReadNonce.huff | 32 + ...svglcrgoqbepkaL2CompressorReadExecute.huff | 32 + ...ksdozrardbmkofvggL2CompressorReadFlag.huff | 32 + ...zxedpzkrqkrxgpL2CompressorReadExecute.huff | 32 + ...ssijauhsotgyqtayygL2CompressorReadTxs.huff | 32 + ...dwrkmombuemzhicuirL2CompressorReadTxs.huff | 32 + ...tvptvgszvdeemgpomnL2CompressorReadTxs.huff | 32 + ...glrinqvkqirnywzkmmmL2CompressorReadTx.huff | 32 + ...sulrygitvkhredhzhL2CompressorReadFlag.huff | 32 + ...aalvdegpzaqhuqqhiasL2CompressorReadTx.huff | 32 + ...mdvycqormkvpykanxnL2CompressorReadTxs.huff | 32 + ...ucihkxihmonvdzfxL2CompressorReadNonce.huff | 32 + ...fcvecckcbuhhhpvpfL2CompressorReadFlag.huff | 32 + ...ftzbzzrxvcmizbL2CompressorReadExecute.huff | 32 + ...cwxtmeqbuwldxifmL2CompressorReadNonce.huff | 32 + ...jwbyxrediuokmghmftbL2CompressorReadTx.huff | 32 + ...rdpemqiejqiknsfiL2CompressorReadNonce.huff | 32 + ...foughzygdwrhxuzibL2CompressorReadFlag.huff | 32 + ...rixmvtxkffgwchL2CompressorReadExecute.huff | 32 + ...tqmujkoilcaudgL2CompressorReadExecute.huff | 32 + ...ycyuqniujobcpgjuysL2CompressorReadTxs.huff | 32 + ...ixyvzwfzordmogvuL2CompressorReadNonce.huff | 32 + ...yygzhjrvozrogmL2CompressorReadExecute.huff | 32 + ...epdhwqsahoduwcqrrpL2CompressorReadTxs.huff | 32 + ...izmyrwtgelqlacL2CompressorReadExecute.huff | 32 + ...dhdecpajexqefympmL2CompressorReadFlag.huff | 32 + ...xkesysithbtrbvqqL2CompressorReadNonce.huff | 32 + ...vwlvozjzwlctwrzrL2CompressorReadNonce.huff | 32 + ...rexbaruoucdulzvqvL2CompressorReadFlag.huff | 32 + ...zsmahiisgmgdjzfjxqL2CompressorReadTxs.huff | 32 + ...aqwygxkipfvshmgystL2CompressorReadTxs.huff | 32 + ...perstvmceseoukqtcL2CompressorReadFlag.huff | 32 + ...lvuclsezveuuexubagL2CompressorReadTxs.huff | 32 + ...pfceqpqhdfzbiiL2CompressorReadExecute.huff | 32 + ...pfucdlmsxiuwbhxrsL2CompressorReadFlag.huff | 32 + ...xcpetgqmymkladcanwtL2CompressorReadTx.huff | 32 + ...llmivwlrgrfhmdzslL2CompressorReadFlag.huff | 32 + ...rmebqsqsnoleofcgyciL2CompressorReadTx.huff | 32 + ...aqrlwcoejtxsysubcL2CompressorReadFlag.huff | 32 + ...saspukxeydggrhL2CompressorReadExecute.huff | 32 + ...qlpehxidlrhdvkcoyL2CompressorReadFlag.huff | 32 + ...bqyenjlfkzsbjkxcL2CompressorReadNonce.huff | 32 + ...rwmufefnibyzayqaaciL2CompressorReadTx.huff | 32 + ...suogqwefdorgsntvcxL2CompressorReadTxs.huff | 32 + ...ihfqfuruuvbxqbL2CompressorReadExecute.huff | 32 + ...medlqkqqhszmvuuxioL2CompressorReadTxs.huff | 32 + ...bouzrwkvkhpzncpjzsL2CompressorReadTxs.huff | 32 + ...kuiktwofhzwbszraL2CompressorReadNonce.huff | 32 + ...ntvdsgkeofzbhbhdsL2CompressorReadFlag.huff | 32 + ...obnextlfkyykzrdomL2CompressorReadFlag.huff | 32 + ...zdduewzkbcwlvsakcL2CompressorReadFlag.huff | 32 + ...fkhccrhufdhjjazeL2CompressorReadNonce.huff | 32 + ...htlarvljeqysguhoizaL2CompressorReadTx.huff | 32 + ...wrmogebamkqmhdvljmlL2CompressorReadTx.huff | 32 + ...dnlbnftvkuearfL2CompressorReadExecute.huff | 32 + ...stckycmjquytqlfsdxoL2CompressorReadTx.huff | 32 + ...rrpmypzdufaanmpuL2CompressorReadNonce.huff | 32 + ...asdtggpxqllpajsfgL2CompressorReadFlag.huff | 32 + ...tgrrlpmnzupwinL2CompressorReadExecute.huff | 32 + ...mbynuotwqkanwdlaqwpL2CompressorReadTx.huff | 32 + ...gzyejxobzrgvpizgfdL2CompressorReadTxs.huff | 32 + ...ihlkysfiliofczzxkhL2CompressorReadTxs.huff | 32 + ...eikmnrgvhavunciniubL2CompressorReadTx.huff | 32 + ...lvopyxfsbdteqegnyogL2CompressorReadTx.huff | 32 + ...mzpjfotpjfuqxtnqrznL2CompressorReadTx.huff | 32 + ...mayqquwflixlquuhfxhL2CompressorReadTx.huff | 32 + ...itanbofqxpeepnlpnL2CompressorReadFlag.huff | 32 + ...dekencowviukvlcrylcL2CompressorReadTx.huff | 32 + ...wbvymwfzttbygcbfmqL2CompressorReadTxs.huff | 32 + ...hrcqjmlolnoulkL2CompressorReadExecute.huff | 32 + ...ckjtrcwgaqmtqrL2CompressorReadExecute.huff | 32 + ...wzkubprcmgpexkL2CompressorReadExecute.huff | 32 + ...vfvlctpjeldqbrshL2CompressorReadNonce.huff | 32 + ...jpleorchotchzsecL2CompressorReadNonce.huff | 32 + ...wcvynodibgfqnidibL2CompressorReadFlag.huff | 32 + ...jvdzyjcjrsbhplpsL2CompressorReadNonce.huff | 32 + ...gxsfgldujuphcmuueL2CompressorReadFlag.huff | 32 + ...zffpwypehvvksjzbvnL2CompressorReadTxs.huff | 32 + ...klqlujjtzpxrejpmL2CompressorReadNonce.huff | 32 + ...sisgwnqqymvpjvskcL2CompressorReadFlag.huff | 32 + ...htgjgwawtaakhwL2CompressorReadExecute.huff | 32 + ...voiaurnusvgnrhusL2CompressorReadNonce.huff | 32 + ...wupwcjsnyherfswgsgcL2CompressorReadTx.huff | 32 + ...uaqyoulenyhrwfuvsiL2CompressorReadTxs.huff | 32 + ...prlkfulinnjttkL2CompressorReadExecute.huff | 32 + ...xerdftkvyxqwwiL2CompressorReadExecute.huff | 32 + ...hkmwlwmhlgvymnL2CompressorReadExecute.huff | 32 + ...vxsxrlsluymfdiL2CompressorReadExecute.huff | 32 + ...bwcqavoskmutltL2CompressorReadExecute.huff | 32 + ...gmtbremlhrxnejL2CompressorReadExecute.huff | 32 + ...bspndmkchcjaofllL2CompressorReadNonce.huff | 32 + ...dfbtyakjkbvehkjdbmgL2CompressorReadTx.huff | 32 + ...pekynjthxzellyhsxeL2CompressorReadTxs.huff | 32 + ...uggwhjnxbrgifehtxhfL2CompressorReadTx.huff | 32 + .../test/ChainedSignatures.spec.ts | 136 + .../wallet-contracts/test/ERC165.spec.ts | 73 + .../wallet-contracts/test/Factory.spec.ts | 65 + .../test/GasEstimation.spec.ts | 353 + .../wallet-contracts/test/GuestModule.spec.ts | 98 + .../wallet-contracts/test/LibBytes.spec.ts | 185 + .../wallet-contracts/test/LibString.spec.ts | 83 + .../wallet-contracts/test/MainModule.bench.ts | 198 + .../wallet-contracts/test/MainModule.spec.ts | 2247 + .../test/MerkleSignatures.spec.ts | 30 + .../test/MultiCallUtils.spec.ts | 282 + .../wallet-contracts/test/utils/contracts.ts | 87 + .../wallet-contracts/test/utils/imposter.ts | 43 + .../wallet-contracts/test/utils/index.ts | 118 + .../wallet-contracts/test/utils/sequence.ts | 613 + .../wallet-contracts/test/utils/wallet.ts | 329 + .../wallet-contracts/tsconfig.json | 37 + .../typings/chai-bignumber.d.ts | 16 + .../wallet-contracts/typings/chai-bn.ts | 19 + .../wallet-contracts/typings/truffle.d.ts | 12 + .../wallet-contracts/utils/JsonBindings.sol | 193 + .../wallet-contracts/utils/benchmarker.ts | 106 + .../wallet-contracts/utils/config-loader.ts | 159 + .../utils/deploy-contracts.ts | 207 + .../utils/workers/bench-worker.ts | 89 + 2195 files changed, 524627 insertions(+) create mode 100644 wagmi-project/packages/sequence-core-1.0.0/.changeset/README.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/.changeset/config.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/.github/CODEOWNERS create mode 100644 wagmi-project/packages/sequence-core-1.0.0/.github/ISSUE_TEMPLATE/bug_report.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/.github/ISSUE_TEMPLATE/custom.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/.github/ISSUE_TEMPLATE/feature_request.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/.github/actions/install-dependencies/action.yml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/.github/workflows/on_pr_pnpm-format-label.yml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/.github/workflows/pnpm-format.yml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/.github/workflows/publish-dists.yml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/.github/workflows/tests.yml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/.gitmodules create mode 100644 wagmi-project/packages/sequence-core-1.0.0/.prettierrc create mode 100644 wagmi-project/packages/sequence-core-1.0.0/.vscode/launch.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/.vscode/settings.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/LICENSE create mode 100644 wagmi-project/packages/sequence-core-1.0.0/README.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/corepack.tgz create mode 100644 wagmi-project/packages/sequence-core-1.0.0/extras/docs/README.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/extras/docs/app/favicon.ico create mode 100644 wagmi-project/packages/sequence-core-1.0.0/extras/docs/app/fonts/GeistMonoVF.woff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/extras/docs/app/fonts/GeistVF.woff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/extras/docs/app/globals.css create mode 100644 wagmi-project/packages/sequence-core-1.0.0/extras/docs/app/layout.tsx create mode 100644 wagmi-project/packages/sequence-core-1.0.0/extras/docs/app/page.module.css create mode 100644 wagmi-project/packages/sequence-core-1.0.0/extras/docs/app/page.tsx create mode 100644 wagmi-project/packages/sequence-core-1.0.0/extras/docs/eslint.config.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/extras/docs/next.config.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/extras/docs/package.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/extras/docs/public/file-text.svg create mode 100644 wagmi-project/packages/sequence-core-1.0.0/extras/docs/public/globe.svg create mode 100644 wagmi-project/packages/sequence-core-1.0.0/extras/docs/public/next.svg create mode 100644 wagmi-project/packages/sequence-core-1.0.0/extras/docs/public/turborepo-dark.svg create mode 100644 wagmi-project/packages/sequence-core-1.0.0/extras/docs/public/turborepo-light.svg create mode 100644 wagmi-project/packages/sequence-core-1.0.0/extras/docs/public/vercel.svg create mode 100644 wagmi-project/packages/sequence-core-1.0.0/extras/docs/public/window.svg create mode 100644 wagmi-project/packages/sequence-core-1.0.0/extras/docs/tsconfig.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/extras/web/README.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/extras/web/app/favicon.ico create mode 100644 wagmi-project/packages/sequence-core-1.0.0/extras/web/app/fonts/GeistMonoVF.woff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/extras/web/app/fonts/GeistVF.woff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/extras/web/app/globals.css create mode 100644 wagmi-project/packages/sequence-core-1.0.0/extras/web/app/layout.tsx create mode 100644 wagmi-project/packages/sequence-core-1.0.0/extras/web/app/page.module.css create mode 100644 wagmi-project/packages/sequence-core-1.0.0/extras/web/app/page.tsx create mode 100644 wagmi-project/packages/sequence-core-1.0.0/extras/web/eslint.config.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/extras/web/next.config.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/extras/web/package.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/extras/web/public/file-text.svg create mode 100644 wagmi-project/packages/sequence-core-1.0.0/extras/web/public/globe.svg create mode 100644 wagmi-project/packages/sequence-core-1.0.0/extras/web/public/next.svg create mode 100644 wagmi-project/packages/sequence-core-1.0.0/extras/web/public/turborepo-dark.svg create mode 100644 wagmi-project/packages/sequence-core-1.0.0/extras/web/public/turborepo-light.svg create mode 100644 wagmi-project/packages/sequence-core-1.0.0/extras/web/public/vercel.svg create mode 100644 wagmi-project/packages/sequence-core-1.0.0/extras/web/public/window.svg create mode 100644 wagmi-project/packages/sequence-core-1.0.0/extras/web/tsconfig.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/foundry.lock create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lefthook.yml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/.env.sample create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/.github/workflows/test.yml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/.gitmodules create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/README.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/foundry.toml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/forge-std/.gitattributes create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/forge-std/.github/CODEOWNERS create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/forge-std/.github/workflows/ci.yml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/forge-std/.github/workflows/sync.yml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/forge-std/CONTRIBUTING.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/forge-std/LICENSE-APACHE create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/forge-std/LICENSE-MIT create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/forge-std/README.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/forge-std/RELEASE_CHECKLIST.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/forge-std/foundry.toml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/forge-std/package.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/forge-std/scripts/vm.py create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/forge-std/src/Base.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/forge-std/src/Config.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/forge-std/src/LibVariable.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/forge-std/src/Script.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/forge-std/src/StdAssertions.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/forge-std/src/StdChains.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/forge-std/src/StdCheats.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/forge-std/src/StdConfig.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/forge-std/src/StdConstants.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/forge-std/src/StdError.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/forge-std/src/StdInvariant.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/forge-std/src/StdJson.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/forge-std/src/StdMath.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/forge-std/src/StdStorage.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/forge-std/src/StdStyle.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/forge-std/src/StdToml.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/forge-std/src/StdUtils.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/forge-std/src/Test.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/forge-std/src/Vm.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/forge-std/src/console.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/forge-std/src/console2.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/forge-std/src/interfaces/IERC1155.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/forge-std/src/interfaces/IERC165.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/forge-std/src/interfaces/IERC20.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/forge-std/src/interfaces/IERC4626.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/forge-std/src/interfaces/IERC6909.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/forge-std/src/interfaces/IERC721.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/forge-std/src/interfaces/IERC7540.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/forge-std/src/interfaces/IERC7575.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/forge-std/src/interfaces/IMulticall3.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/forge-std/src/safeconsole.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/forge-std/test/CommonBase.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/forge-std/test/Config.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/forge-std/test/LibVariable.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/forge-std/test/StdAssertions.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/forge-std/test/StdChains.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/forge-std/test/StdCheats.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/forge-std/test/StdConstants.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/forge-std/test/StdError.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/forge-std/test/StdJson.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/forge-std/test/StdMath.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/forge-std/test/StdStorage.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/forge-std/test/StdStyle.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/forge-std/test/StdToml.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/forge-std/test/StdUtils.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/forge-std/test/Vm.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/forge-std/test/compilation/CompilationScript.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/forge-std/test/compilation/CompilationScriptBase.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/forge-std/test/compilation/CompilationTest.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/forge-std/test/compilation/CompilationTestBase.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/forge-std/test/fixtures/broadcast.log.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/forge-std/test/fixtures/config.toml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/forge-std/test/fixtures/test.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/forge-std/test/fixtures/test.toml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/.env.sample create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/.github/workflows/tests.yml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/.gitmodules create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/.prettierignore create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/.prettierrc create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/LICENSE create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/README.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/build_proxy.sh create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/docs/CHAINED.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/docs/CONFIGURATIONS.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/docs/PAYLOAD.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/docs/SESSIONS.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/docs/SIGNATURE.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/foundry.toml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lefthook.yml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/.eslintrc.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/.github/workflows/build.yml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/.solcover.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/.solhint.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/.solhintignore create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/LICENSE create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/README.md create mode 100644 "wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/audits/EIP_4337_\342\200\223_Ethereum_Account_Abstraction_Incremental_Audit_Feb_2023.pdf" create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/contracts/core/BaseAccount.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/contracts/core/BasePaymaster.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/contracts/core/EntryPoint.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/contracts/core/EntryPointSimulations.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/contracts/core/Helpers.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/contracts/core/NonceManager.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/contracts/core/SenderCreator.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/contracts/core/StakeManager.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/contracts/core/UserOperationLib.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/contracts/interfaces/IAccount.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/contracts/interfaces/IAccountExecute.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/contracts/interfaces/IAggregator.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/contracts/interfaces/IEntryPoint.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/contracts/interfaces/IEntryPointSimulations.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/contracts/interfaces/INonceManager.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/contracts/interfaces/IPaymaster.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/contracts/interfaces/IStakeManager.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/contracts/interfaces/PackedUserOperation.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/contracts/package.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/contracts/samples/LegacyTokenPaymaster.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/contracts/samples/SimpleAccount.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/contracts/samples/SimpleAccountFactory.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/contracts/samples/TokenPaymaster.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/contracts/samples/VerifyingPaymaster.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/contracts/samples/bls/BLSAccount.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/contracts/samples/bls/BLSAccountFactory.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/contracts/samples/bls/BLSHelper.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/contracts/samples/bls/BLSSignatureAggregator.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/contracts/samples/bls/IBLSAccount.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/contracts/samples/bls/lib/BLSOpen.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/contracts/samples/bls/lib/hubble-contracts/contracts/libs/BLS.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/contracts/samples/bls/lib/hubble-contracts/contracts/libs/ModExp.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/contracts/samples/callback/TokenCallbackHandler.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/contracts/samples/utils/IOracle.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/contracts/samples/utils/OracleHelper.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/contracts/samples/utils/UniswapHelper.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/contracts/utils/Exec.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/deploy/1_deploy_entrypoint.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/deploy/2_deploy_SimpleAccountFactory.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/deployments/arbitrum/.chainId create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/deployments/arbitrum/EntryPoint.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/deployments/arbitrum/solcInputs/a4c52f0671aad8941c53d6ead2063803.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/deployments/gnosis/.chainId create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/deployments/gnosis/EntryPoint.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/deployments/gnosis/solcInputs/a4c52f0671aad8941c53d6ead2063803.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/deployments/goerli/.chainId create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/deployments/goerli/EntryPoint.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/deployments/goerli/solcInputs/a4c52f0671aad8941c53d6ead2063803.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/deployments/kovan/.chainId create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/deployments/kovan/EntryPoint.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/deployments/kovan/SimpleWallet.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/deployments/kovan/TestCounter.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/deployments/kovan/solcInputs/9255faacf3ae4e81db1326413027bfa0.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/deployments/mainnet/.chainId create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/deployments/mainnet/EntryPoint.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/deployments/mainnet/SimpleAccountFactory.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/deployments/mainnet/solcInputs/02113a2ed1850c3774563305ee607f11.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/deployments/mainnet/solcInputs/a4c52f0671aad8941c53d6ead2063803.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/deployments/mainnet/solcInputs/cfbebdf1101dd2bc0f310cb0b7d62cb7.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/deployments/matic/.chainId create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/deployments/matic/EntryPoint.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/deployments/matic/solcInputs/a4c52f0671aad8941c53d6ead2063803.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/deployments/matic/solcInputs/cfbebdf1101dd2bc0f310cb0b7d62cb7.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/deployments/mumbai/.chainId create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/deployments/mumbai/EntryPoint.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/deployments/mumbai/solcInputs/a4c52f0671aad8941c53d6ead2063803.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/deployments/optimism/.chainId create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/deployments/optimism/EntryPoint.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/deployments/optimism/solcInputs/a4c52f0671aad8941c53d6ead2063803.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/deployments/sepolia/.chainId create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/deployments/sepolia/EntryPoint.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/deployments/sepolia/solcInputs/a4c52f0671aad8941c53d6ead2063803.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/erc/ERCS/erc-4337.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/erc/ERCS/erc-7562.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/erc/assets/erc-4337/bundle-seq-pm.svg create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/erc/assets/erc-4337/bundle-seq.svg create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/erc/assets/erc-4337/image1.png create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/erc/assets/erc-4337/image2.png create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/gascalc/0-init-gas-checker.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/gascalc/1-simple-wallet.gas.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/gascalc/2-paymaster.gas.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/gascalc/3-huge-tx-gas.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/gascalc/4-paymaster-postop.gas.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/gascalc/5-token-paymaster.gas.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/gascalc/GasChecker.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/hardhat.config.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/package.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/reports/gas-checker.txt create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/scripts/check-gas-reports create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/scripts/docker-gascalc create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/scripts/docker-gascalc.yml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/scripts/gascalc create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/scripts/hh-wrapper create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/scripts/postpack-contracts-package.sh create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/scripts/prepack-contracts-package.sh create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/scripts/sample-script.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/scripts/solcErrors create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/src/AASigner.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/src/Create2Factory.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/src/Utils.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/src/runop.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/test/0-create2factory.test.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/test/UserOp.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/test/UserOperation.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/test/aa.init.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/test/chaiHelper.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/test/debugTx.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/test/entrypoint.test.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/test/entrypointsimulations.test.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/test/helpers.test.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/test/paymaster.test.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/test/samples/OracleHelper.test.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/test/samples/TokenPaymaster.test.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/test/simple-wallet.test.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/test/solidityTypes.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/test/testExecAccount.test.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/test/testutils.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/test/verifying_paymaster.test.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/test/y.bls.test.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/tsconfig.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/account-abstraction/yarn.lock create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/erc2470-libs/.gitattributes create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/erc2470-libs/.githooks/pre-commit create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/erc2470-libs/.github/workflows/test.yml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/erc2470-libs/.gitmodules create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/erc2470-libs/.solhint.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/erc2470-libs/README.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/erc2470-libs/foundry.toml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/erc2470-libs/lib/forge-std/.gitattributes create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/erc2470-libs/lib/forge-std/.github/workflows/ci.yml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/erc2470-libs/lib/forge-std/.github/workflows/sync.yml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/erc2470-libs/lib/forge-std/LICENSE-APACHE create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/erc2470-libs/lib/forge-std/LICENSE-MIT create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/erc2470-libs/lib/forge-std/README.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/erc2470-libs/lib/forge-std/foundry.toml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/erc2470-libs/lib/forge-std/package.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/erc2470-libs/lib/forge-std/scripts/vm.py create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/erc2470-libs/lib/forge-std/src/Base.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/erc2470-libs/lib/forge-std/src/Script.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/erc2470-libs/lib/forge-std/src/StdAssertions.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/erc2470-libs/lib/forge-std/src/StdChains.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/erc2470-libs/lib/forge-std/src/StdCheats.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/erc2470-libs/lib/forge-std/src/StdError.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/erc2470-libs/lib/forge-std/src/StdInvariant.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/erc2470-libs/lib/forge-std/src/StdJson.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/erc2470-libs/lib/forge-std/src/StdMath.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/erc2470-libs/lib/forge-std/src/StdStorage.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/erc2470-libs/lib/forge-std/src/StdStyle.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/erc2470-libs/lib/forge-std/src/StdToml.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/erc2470-libs/lib/forge-std/src/StdUtils.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/erc2470-libs/lib/forge-std/src/Test.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/erc2470-libs/lib/forge-std/src/Vm.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/erc2470-libs/lib/forge-std/src/console.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/erc2470-libs/lib/forge-std/src/console2.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/erc2470-libs/lib/forge-std/src/interfaces/IERC1155.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/erc2470-libs/lib/forge-std/src/interfaces/IERC165.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/erc2470-libs/lib/forge-std/src/interfaces/IERC20.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/erc2470-libs/lib/forge-std/src/interfaces/IERC4626.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/erc2470-libs/lib/forge-std/src/interfaces/IERC721.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/erc2470-libs/lib/forge-std/src/interfaces/IMulticall3.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/erc2470-libs/lib/forge-std/src/mocks/MockERC20.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/erc2470-libs/lib/forge-std/src/mocks/MockERC721.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/erc2470-libs/lib/forge-std/src/safeconsole.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/erc2470-libs/lib/forge-std/test/StdAssertions.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/erc2470-libs/lib/forge-std/test/StdChains.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/erc2470-libs/lib/forge-std/test/StdCheats.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/erc2470-libs/lib/forge-std/test/StdError.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/erc2470-libs/lib/forge-std/test/StdJson.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/erc2470-libs/lib/forge-std/test/StdMath.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/erc2470-libs/lib/forge-std/test/StdStorage.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/erc2470-libs/lib/forge-std/test/StdStyle.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/erc2470-libs/lib/forge-std/test/StdToml.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/erc2470-libs/lib/forge-std/test/StdUtils.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/erc2470-libs/lib/forge-std/test/Vm.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/erc2470-libs/lib/forge-std/test/compilation/CompilationScript.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/erc2470-libs/lib/forge-std/test/compilation/CompilationScriptBase.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/erc2470-libs/lib/forge-std/test/compilation/CompilationTest.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/erc2470-libs/lib/forge-std/test/compilation/CompilationTestBase.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/erc2470-libs/lib/forge-std/test/fixtures/broadcast.log.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/erc2470-libs/lib/forge-std/test/fixtures/test.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/erc2470-libs/lib/forge-std/test/fixtures/test.toml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/erc2470-libs/lib/forge-std/test/mocks/MockERC20.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/erc2470-libs/lib/forge-std/test/mocks/MockERC721.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/erc2470-libs/script/MockERC20Deployer.s.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/erc2470-libs/script/SingletonDeployer.s.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/erc2470-libs/src/ISingletonFactory.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/forge-std/.gitattributes create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/forge-std/.github/workflows/ci.yml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/forge-std/.github/workflows/sync.yml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/forge-std/CONTRIBUTING.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/forge-std/LICENSE-APACHE create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/forge-std/LICENSE-MIT create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/forge-std/README.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/forge-std/foundry.toml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/forge-std/package.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/forge-std/scripts/vm.py create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/forge-std/src/Base.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/forge-std/src/Script.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/forge-std/src/StdAssertions.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/forge-std/src/StdChains.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/forge-std/src/StdCheats.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/forge-std/src/StdConstants.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/forge-std/src/StdError.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/forge-std/src/StdInvariant.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/forge-std/src/StdJson.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/forge-std/src/StdMath.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/forge-std/src/StdStorage.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/forge-std/src/StdStyle.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/forge-std/src/StdToml.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/forge-std/src/StdUtils.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/forge-std/src/Test.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/forge-std/src/Vm.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/forge-std/src/console.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/forge-std/src/console2.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/forge-std/src/interfaces/IERC1155.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/forge-std/src/interfaces/IERC165.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/forge-std/src/interfaces/IERC20.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/forge-std/src/interfaces/IERC4626.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/forge-std/src/interfaces/IERC6909.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/forge-std/src/interfaces/IERC721.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/forge-std/src/interfaces/IERC7540.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/forge-std/src/interfaces/IERC7575.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/forge-std/src/interfaces/IMulticall3.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/forge-std/src/safeconsole.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/forge-std/test/CommonBase.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/forge-std/test/StdAssertions.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/forge-std/test/StdChains.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/forge-std/test/StdCheats.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/forge-std/test/StdConstants.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/forge-std/test/StdError.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/forge-std/test/StdJson.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/forge-std/test/StdMath.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/forge-std/test/StdStorage.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/forge-std/test/StdStyle.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/forge-std/test/StdToml.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/forge-std/test/StdUtils.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/forge-std/test/Vm.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/forge-std/test/compilation/CompilationScript.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/forge-std/test/compilation/CompilationScriptBase.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/forge-std/test/compilation/CompilationTest.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/forge-std/test/compilation/CompilationTestBase.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/forge-std/test/fixtures/broadcast.log.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/forge-std/test/fixtures/test.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/forge-std/test/fixtures/test.toml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/.changeset/config.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/.codecov.yml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/.editorconfig create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/.githooks/pre-push create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/.github/ISSUE_TEMPLATE/bug_report.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/.github/ISSUE_TEMPLATE/config.yml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/.github/ISSUE_TEMPLATE/feature_request.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/.github/PULL_REQUEST_TEMPLATE.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/.github/actions/gas-compare/action.yml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/.github/actions/setup/action.yml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/.github/actions/storage-layout/action.yml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/.github/workflows/actionlint.yml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/.github/workflows/changeset.yml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/.github/workflows/checks.yml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/.github/workflows/docs.yml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/.github/workflows/formal-verification.yml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/.github/workflows/release-cycle.yml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/.github/workflows/upgradeable.yml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/.gitmodules create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/.mocharc.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/.prettierrc create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/.solcover.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/CHANGELOG.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/CODE_OF_CONDUCT.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/CONTRIBUTING.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/FUNDING.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/GUIDELINES.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/LICENSE create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/README.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/RELEASING.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/SECURITY.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/audits/2017-03.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/audits/2018-10.pdf create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/audits/2022-10-Checkpoints.pdf create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/audits/2022-10-ERC4626.pdf create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/audits/2023-05-v4.9.pdf create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/audits/2023-10-v5.0.pdf create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/audits/2024-10-v5.1.pdf create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/audits/README.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/certora/Makefile create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/certora/README.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/certora/diff/access_manager_AccessManager.sol.patch create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/certora/harnesses/AccessControlDefaultAdminRulesHarness.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/certora/harnesses/AccessControlHarness.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/certora/harnesses/AccessManagedHarness.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/certora/harnesses/AccessManagerHarness.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/certora/harnesses/DoubleEndedQueueHarness.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/certora/harnesses/ERC20FlashMintHarness.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/certora/harnesses/ERC20PermitHarness.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/certora/harnesses/ERC20WrapperHarness.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/certora/harnesses/ERC3156FlashBorrowerHarness.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/certora/harnesses/ERC721Harness.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/certora/harnesses/ERC721ReceiverHarness.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/certora/harnesses/EnumerableMapHarness.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/certora/harnesses/EnumerableSetHarness.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/certora/harnesses/InitializableHarness.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/certora/harnesses/NoncesHarness.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/certora/harnesses/Ownable2StepHarness.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/certora/harnesses/OwnableHarness.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/certora/harnesses/PausableHarness.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/certora/harnesses/TimelockControllerHarness.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/certora/reports/2021-10.pdf create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/certora/reports/2022-03.pdf create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/certora/reports/2022-05.pdf create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/certora/run.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/certora/specs.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/certora/specs/AccessControl.spec create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/certora/specs/AccessControlDefaultAdminRules.spec create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/certora/specs/AccessManaged.spec create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/certora/specs/AccessManager.spec create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/certora/specs/DoubleEndedQueue.spec create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/certora/specs/ERC20.spec create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/certora/specs/ERC20FlashMint.spec create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/certora/specs/ERC20Wrapper.spec create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/certora/specs/ERC721.spec create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/certora/specs/EnumerableMap.spec create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/certora/specs/EnumerableSet.spec create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/certora/specs/Initializable.spec create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/certora/specs/Nonces.spec create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/certora/specs/Ownable.spec create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/certora/specs/Ownable2Step.spec create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/certora/specs/Pausable.spec create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/certora/specs/TimelockController.spec create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/certora/specs/helpers/helpers.spec create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/certora/specs/methods/IAccessControl.spec create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/certora/specs/methods/IAccessControlDefaultAdminRules.spec create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/certora/specs/methods/IAccessManaged.spec create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/certora/specs/methods/IAccessManager.spec create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/certora/specs/methods/IERC20.spec create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/certora/specs/methods/IERC2612.spec create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/certora/specs/methods/IERC3156FlashBorrower.spec create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/certora/specs/methods/IERC3156FlashLender.spec create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/certora/specs/methods/IERC5313.spec create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/certora/specs/methods/IERC721.spec create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/certora/specs/methods/IERC721Receiver.spec create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/certora/specs/methods/IOwnable.spec create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/certora/specs/methods/IOwnable2Step.spec create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/access/AccessControl.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/access/IAccessControl.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/access/Ownable.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/access/Ownable2Step.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/access/README.adoc create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/access/extensions/AccessControlDefaultAdminRules.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/access/extensions/AccessControlEnumerable.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/access/extensions/IAccessControlDefaultAdminRules.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/access/extensions/IAccessControlEnumerable.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/access/manager/AccessManaged.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/access/manager/AccessManager.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/access/manager/AuthorityUtils.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/access/manager/IAccessManaged.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/access/manager/IAccessManager.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/access/manager/IAuthority.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/account/README.adoc create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/account/utils/draft-ERC4337Utils.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/account/utils/draft-ERC7579Utils.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/finance/README.adoc create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/finance/VestingWallet.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/finance/VestingWalletCliff.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/governance/Governor.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/governance/IGovernor.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/governance/README.adoc create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/governance/TimelockController.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorCountingFractional.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorCountingOverridable.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorCountingSimple.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorPreventLateQuorum.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorSettings.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorStorage.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorTimelockAccess.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorTimelockCompound.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorTimelockControl.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorVotes.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorVotesQuorumFraction.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/governance/utils/IVotes.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/governance/utils/Votes.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/governance/utils/VotesExtended.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/interfaces/IERC1155.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/interfaces/IERC1155MetadataURI.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/interfaces/IERC1155Receiver.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/interfaces/IERC1271.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/interfaces/IERC1363.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/interfaces/IERC1363Receiver.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/interfaces/IERC1363Spender.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/interfaces/IERC165.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/interfaces/IERC1820Implementer.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/interfaces/IERC1820Registry.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/interfaces/IERC1967.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/interfaces/IERC20.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/interfaces/IERC20Metadata.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/interfaces/IERC2309.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/interfaces/IERC2612.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/interfaces/IERC2981.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/interfaces/IERC3156.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/interfaces/IERC3156FlashBorrower.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/interfaces/IERC3156FlashLender.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/interfaces/IERC4626.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/interfaces/IERC4906.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/interfaces/IERC5267.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/interfaces/IERC5313.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/interfaces/IERC5805.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/interfaces/IERC6372.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/interfaces/IERC721.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/interfaces/IERC721Enumerable.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/interfaces/IERC721Metadata.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/interfaces/IERC721Receiver.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/interfaces/IERC777.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/interfaces/IERC777Recipient.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/interfaces/IERC777Sender.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/interfaces/README.adoc create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/interfaces/draft-IERC1822.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/interfaces/draft-IERC4337.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/interfaces/draft-IERC6093.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/interfaces/draft-IERC7579.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/interfaces/draft-IERC7674.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/metatx/ERC2771Context.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/metatx/ERC2771Forwarder.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/metatx/README.adoc create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/AccessManagedTarget.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/AccessManagerMock.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/ArraysMock.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/AuthorityMock.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/Base64Dirty.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/BatchCaller.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/CallReceiverMock.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/ConstructorMock.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/ContextMock.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/DummyImplementation.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/EIP712Verifier.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/ERC1271WalletMock.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/ERC165/ERC165InterfacesSupported.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/ERC165/ERC165MaliciousData.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/ERC165/ERC165MissingData.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/ERC165/ERC165NotSupported.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/ERC165/ERC165ReturnBomb.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/ERC2771ContextMock.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/ERC3156FlashBorrowerMock.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/EtherReceiverMock.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/InitializableMock.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/MerkleProofCustomHashMock.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/MerkleTreeMock.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/MulticallHelper.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/MultipleInheritanceInitializableMocks.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/PausableMock.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/ReentrancyAttack.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/ReentrancyMock.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/ReentrancyTransientMock.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/RegressionImplementation.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/SingleInheritanceInitializableMocks.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/Stateless.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/StorageSlotMock.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/TimelockReentrant.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/TransientSlotMock.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/UpgradeableBeaconMock.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/VotesExtendedMock.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/VotesMock.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/account/utils/ERC7579UtilsMock.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/compound/CompTimelock.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/docs/ERC20WithAutoMinerReward.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/docs/ERC4626Fees.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/docs/MyNFT.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/docs/access-control/AccessControlERC20MintBase.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/docs/access-control/AccessControlERC20MintMissing.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/docs/access-control/AccessControlERC20MintOnlyRole.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/docs/access-control/AccessControlModified.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/docs/access-control/AccessControlNonRevokableAdmin.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/docs/access-control/AccessManagedERC20MintBase.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/docs/access-control/MyContractOwnable.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/docs/governance/MyGovernor.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/docs/governance/MyToken.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/docs/governance/MyTokenTimestampBased.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/docs/governance/MyTokenWrapped.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/docs/token/ERC1155/GameItems.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/docs/token/ERC1155/MyERC115HolderContract.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/docs/token/ERC20/GLDToken.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/docs/token/ERC721/GameItem.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/docs/utilities/Base64NFT.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/docs/utilities/Multicall.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/governance/GovernorCountingOverridableMock.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/governance/GovernorFractionalMock.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/governance/GovernorMock.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/governance/GovernorPreventLateQuorumMock.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/governance/GovernorStorageMock.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/governance/GovernorTimelockAccessMock.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/governance/GovernorTimelockCompoundMock.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/governance/GovernorTimelockControlMock.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/governance/GovernorVoteMock.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/governance/GovernorWithParamsMock.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/proxy/BadBeacon.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/proxy/ClashingImplementation.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/proxy/UUPSUpgradeableMock.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/token/ERC1155ReceiverMock.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/token/ERC1363ForceApproveMock.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/token/ERC1363NoReturnMock.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/token/ERC1363ReceiverMock.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/token/ERC1363ReturnFalseMock.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/token/ERC1363SpenderMock.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/token/ERC20ApprovalMock.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/token/ERC20DecimalsMock.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/token/ERC20ExcessDecimalsMock.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/token/ERC20FlashMintMock.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/token/ERC20ForceApproveMock.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/token/ERC20GetterHelper.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/token/ERC20Mock.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/token/ERC20MulticallMock.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/token/ERC20NoReturnMock.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/token/ERC20Reentrant.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/token/ERC20ReturnFalseMock.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/token/ERC20VotesAdditionalCheckpointsMock.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/token/ERC20VotesLegacyMock.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/token/ERC20VotesTimestampMock.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/token/ERC4626LimitsMock.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/token/ERC4626Mock.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/token/ERC4626OffsetMock.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/token/ERC4646FeesMock.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/token/ERC721ConsecutiveEnumerableMock.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/token/ERC721ConsecutiveMock.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/token/ERC721ReceiverMock.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/mocks/token/ERC721URIStorageMock.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/package.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/proxy/Clones.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/proxy/ERC1967/ERC1967Proxy.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/proxy/ERC1967/ERC1967Utils.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/proxy/Proxy.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/proxy/README.adoc create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/proxy/beacon/BeaconProxy.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/proxy/beacon/IBeacon.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/proxy/beacon/UpgradeableBeacon.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/proxy/transparent/ProxyAdmin.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/proxy/transparent/TransparentUpgradeableProxy.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/proxy/utils/Initializable.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/proxy/utils/UUPSUpgradeable.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/token/ERC1155/ERC1155.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/token/ERC1155/IERC1155.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/token/ERC1155/IERC1155Receiver.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/token/ERC1155/README.adoc create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/token/ERC1155/extensions/ERC1155Burnable.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/token/ERC1155/extensions/ERC1155Pausable.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/token/ERC1155/extensions/ERC1155Supply.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/token/ERC1155/extensions/ERC1155URIStorage.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/token/ERC1155/utils/ERC1155Holder.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/token/ERC1155/utils/ERC1155Utils.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/token/ERC20/README.adoc create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC1363.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Burnable.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Capped.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20FlashMint.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Pausable.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Permit.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Votes.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Wrapper.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC4626.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Permit.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/draft-ERC20TemporaryApproval.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/token/ERC20/utils/ERC1363Utils.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/token/ERC721/ERC721.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/token/ERC721/IERC721.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/token/ERC721/IERC721Receiver.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/token/ERC721/README.adoc create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721Burnable.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721Consecutive.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721Enumerable.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721Pausable.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721Royalty.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721URIStorage.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721Votes.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721Wrapper.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/IERC721Enumerable.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/IERC721Metadata.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/token/ERC721/utils/ERC721Holder.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/token/ERC721/utils/ERC721Utils.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/token/common/ERC2981.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/token/common/README.adoc create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/utils/Address.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/utils/Arrays.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/utils/Base64.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/utils/Bytes.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/utils/CAIP10.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/utils/CAIP2.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/utils/Comparators.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/utils/Context.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/utils/Create2.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/utils/Errors.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/utils/Multicall.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/utils/Nonces.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/utils/NoncesKeyed.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/utils/Packing.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/utils/Panic.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/utils/Pausable.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/utils/README.adoc create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/utils/ReentrancyGuard.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/utils/ReentrancyGuardTransient.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/utils/ShortStrings.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/utils/SlotDerivation.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/utils/StorageSlot.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/utils/Strings.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/utils/TransientSlot.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/utils/cryptography/ECDSA.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/utils/cryptography/EIP712.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/utils/cryptography/Hashes.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/utils/cryptography/MerkleProof.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/utils/cryptography/MessageHashUtils.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/utils/cryptography/P256.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/utils/cryptography/RSA.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/utils/cryptography/SignatureChecker.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/utils/introspection/ERC165.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/utils/introspection/ERC165Checker.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/utils/math/Math.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/utils/math/SafeCast.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/utils/math/SignedMath.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/utils/structs/BitMaps.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/utils/structs/Checkpoints.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/utils/structs/CircularBuffer.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/utils/structs/DoubleEndedQueue.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/utils/structs/EnumerableMap.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/utils/structs/EnumerableSet.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/utils/structs/Heap.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/utils/structs/MerkleTree.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/utils/types/Time.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/vendor/compound/ICompoundTimelock.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/contracts/vendor/compound/LICENSE create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/docs/README.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/docs/antora.yml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/docs/config.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/docs/modules/ROOT/images/access-control-multiple.svg create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/docs/modules/ROOT/images/access-manager-functions.svg create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/docs/modules/ROOT/images/access-manager.svg create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/docs/modules/ROOT/images/erc4626-attack-3a.png create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/docs/modules/ROOT/images/erc4626-attack-3b.png create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/docs/modules/ROOT/images/erc4626-attack-6.png create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/docs/modules/ROOT/images/erc4626-attack.png create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/docs/modules/ROOT/images/erc4626-deposit.png create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/docs/modules/ROOT/images/erc4626-mint.png create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/docs/modules/ROOT/images/erc4626-rate-linear.png create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/docs/modules/ROOT/images/erc4626-rate-loglog.png create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/docs/modules/ROOT/images/erc4626-rate-loglogext.png create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/docs/modules/ROOT/images/tally-exec.png create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/docs/modules/ROOT/images/tally-vote.png create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/docs/modules/ROOT/nav.adoc create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/docs/modules/ROOT/pages/access-control.adoc create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/docs/modules/ROOT/pages/backwards-compatibility.adoc create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/docs/modules/ROOT/pages/crowdsales.adoc create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/docs/modules/ROOT/pages/drafts.adoc create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/docs/modules/ROOT/pages/erc1155.adoc create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/docs/modules/ROOT/pages/erc20-supply.adoc create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/docs/modules/ROOT/pages/erc20.adoc create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/docs/modules/ROOT/pages/erc4626.adoc create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/docs/modules/ROOT/pages/erc721.adoc create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/docs/modules/ROOT/pages/extending-contracts.adoc create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/docs/modules/ROOT/pages/faq.adoc create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/docs/modules/ROOT/pages/governance.adoc create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/docs/modules/ROOT/pages/index.adoc create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/docs/modules/ROOT/pages/tokens.adoc create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/docs/modules/ROOT/pages/upgradeable.adoc create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/docs/modules/ROOT/pages/utilities.adoc create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/docs/modules/ROOT/pages/wizard.adoc create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/docs/templates/contract.hbs create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/docs/templates/helpers.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/docs/templates/page.hbs create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/docs/templates/properties.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/eslint.config.mjs create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/foundry.toml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/fv-requirements.txt create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/hardhat.config.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/hardhat/async-test-sanity.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/hardhat/env-artifacts.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/hardhat/ignore-unreachable-warnings.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/hardhat/remappings.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/hardhat/skip-foundry-tests.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/hardhat/task-test-get-files.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/lib/erc4626-tests/ERC4626.prop.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/lib/erc4626-tests/ERC4626.test.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/lib/erc4626-tests/LICENSE create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/lib/erc4626-tests/README.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/lib/forge-std/.gitattributes create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/lib/forge-std/.github/workflows/ci.yml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/lib/forge-std/.github/workflows/sync.yml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/lib/forge-std/LICENSE-APACHE create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/lib/forge-std/LICENSE-MIT create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/lib/forge-std/README.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/lib/forge-std/foundry.toml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/lib/forge-std/package.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/lib/forge-std/scripts/vm.py create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/lib/forge-std/src/Base.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/lib/forge-std/src/Script.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/lib/forge-std/src/StdAssertions.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/lib/forge-std/src/StdChains.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/lib/forge-std/src/StdCheats.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/lib/forge-std/src/StdError.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/lib/forge-std/src/StdInvariant.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/lib/forge-std/src/StdJson.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/lib/forge-std/src/StdMath.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/lib/forge-std/src/StdStorage.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/lib/forge-std/src/StdStyle.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/lib/forge-std/src/StdToml.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/lib/forge-std/src/StdUtils.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/lib/forge-std/src/Test.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/lib/forge-std/src/Vm.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/lib/forge-std/src/console.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/lib/forge-std/src/console2.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/lib/forge-std/src/interfaces/IERC1155.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/lib/forge-std/src/interfaces/IERC165.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/lib/forge-std/src/interfaces/IERC20.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/lib/forge-std/src/interfaces/IERC4626.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/lib/forge-std/src/interfaces/IERC721.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/lib/forge-std/src/interfaces/IMulticall3.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/lib/forge-std/src/mocks/MockERC20.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/lib/forge-std/src/mocks/MockERC721.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/lib/forge-std/src/safeconsole.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/lib/forge-std/test/StdAssertions.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/lib/forge-std/test/StdChains.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/lib/forge-std/test/StdCheats.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/lib/forge-std/test/StdError.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/lib/forge-std/test/StdJson.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/lib/forge-std/test/StdMath.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/lib/forge-std/test/StdStorage.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/lib/forge-std/test/StdStyle.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/lib/forge-std/test/StdToml.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/lib/forge-std/test/StdUtils.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/lib/forge-std/test/Vm.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/lib/forge-std/test/compilation/CompilationScript.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/lib/forge-std/test/compilation/CompilationScriptBase.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/lib/forge-std/test/compilation/CompilationTest.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/lib/forge-std/test/compilation/CompilationTestBase.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/lib/forge-std/test/fixtures/broadcast.log.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/lib/forge-std/test/fixtures/test.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/lib/forge-std/test/fixtures/test.toml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/lib/forge-std/test/mocks/MockERC20.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/lib/forge-std/test/mocks/MockERC721.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/lib/halmos-cheatcodes/LICENSE create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/lib/halmos-cheatcodes/README.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/lib/halmos-cheatcodes/src/SVM.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/lib/halmos-cheatcodes/src/SymTest.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/logo.svg create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/netlify.toml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/package-lock.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/package.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/remappings.txt create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/renovate.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/scripts/checks/compare-layout.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/scripts/checks/compareGasReports.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/scripts/checks/coverage.sh create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/scripts/checks/extract-layout.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/scripts/checks/generation.sh create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/scripts/checks/inheritance-ordering.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/scripts/checks/pragma-consistency.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/scripts/gen-nav.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/scripts/generate/format-lines.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/scripts/generate/helpers/sanitize.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/scripts/generate/run.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/scripts/generate/templates/Arrays.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/scripts/generate/templates/Arrays.opts.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/scripts/generate/templates/Checkpoints.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/scripts/generate/templates/Checkpoints.opts.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/scripts/generate/templates/Checkpoints.t.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/scripts/generate/templates/EnumerableMap.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/scripts/generate/templates/EnumerableMap.opts.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/scripts/generate/templates/EnumerableSet.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/scripts/generate/templates/EnumerableSet.opts.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/scripts/generate/templates/MerkleProof.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/scripts/generate/templates/MerkleProof.opts.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/scripts/generate/templates/Packing.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/scripts/generate/templates/Packing.opts.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/scripts/generate/templates/Packing.t.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/scripts/generate/templates/SafeCast.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/scripts/generate/templates/Slot.opts.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/scripts/generate/templates/SlotDerivation.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/scripts/generate/templates/SlotDerivation.t.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/scripts/generate/templates/StorageSlot.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/scripts/generate/templates/StorageSlotMock.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/scripts/generate/templates/TransientSlot.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/scripts/generate/templates/TransientSlotMock.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/scripts/generate/templates/conversion.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/scripts/git-user-config.sh create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/scripts/helpers.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/scripts/prepack.sh create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/scripts/prepare-docs.sh create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/scripts/prepare.sh create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/scripts/release/format-changelog.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/scripts/release/synchronize-versions.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/scripts/release/update-comment.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/scripts/release/version.sh create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/scripts/release/workflow/exit-prerelease.sh create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/scripts/release/workflow/github-release.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/scripts/release/workflow/integrity-check.sh create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/scripts/release/workflow/pack.sh create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/scripts/release/workflow/publish.sh create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/scripts/release/workflow/rerun.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/scripts/release/workflow/set-changesets-pr-title.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/scripts/release/workflow/start.sh create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/scripts/release/workflow/state.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/scripts/remove-ignored-artifacts.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/scripts/solhint-custom/index.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/scripts/solhint-custom/package.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/scripts/update-docs-branch.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/scripts/upgradeable/README.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/scripts/upgradeable/patch-apply.sh create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/scripts/upgradeable/patch-save.sh create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/scripts/upgradeable/transpile-onto.sh create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/scripts/upgradeable/transpile.sh create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/scripts/upgradeable/upgradeable.patch create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/slither.config.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/solhint.config.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/TESTING.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/access/AccessControl.behavior.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/access/AccessControl.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/access/Ownable.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/access/Ownable2Step.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/access/extensions/AccessControlDefaultAdminRules.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/access/extensions/AccessControlEnumerable.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/access/manager/AccessManaged.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/access/manager/AccessManager.behavior.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/access/manager/AccessManager.predicate.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/access/manager/AccessManager.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/access/manager/AuthorityUtils.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/account/utils/draft-ERC4337Utils.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/account/utils/draft-ERC7579Utils.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/account/utils/draft-ERC7579Utils.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/bin/EntryPoint070.abi create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/bin/EntryPoint070.bytecode create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/bin/SenderCreator070.abi create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/bin/SenderCreator070.bytecode create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/finance/VestingWallet.behavior.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/finance/VestingWallet.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/finance/VestingWalletCliff.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/governance/Governor.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/governance/Governor.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/governance/TimelockController.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/governance/extensions/GovernorCountingFractional.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/governance/extensions/GovernorCountingOverridable.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/governance/extensions/GovernorERC721.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/governance/extensions/GovernorPreventLateQuorum.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/governance/extensions/GovernorStorage.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/governance/extensions/GovernorTimelockAccess.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/governance/extensions/GovernorTimelockCompound.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/governance/extensions/GovernorTimelockControl.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/governance/extensions/GovernorVotesQuorumFraction.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/governance/extensions/GovernorWithParams.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/governance/utils/ERC6372.behavior.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/governance/utils/Votes.behavior.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/governance/utils/Votes.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/governance/utils/VotesExtended.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/helpers/access-manager.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/helpers/account.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/helpers/chains.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/helpers/constants.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/helpers/deploy.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/helpers/eip712-types.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/helpers/eip712.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/helpers/enums.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/helpers/erc4337-entrypoint.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/helpers/erc4337.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/helpers/erc7579.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/helpers/governance.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/helpers/iterate.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/helpers/math.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/helpers/methods.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/helpers/random.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/helpers/storage.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/helpers/strings.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/helpers/time.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/helpers/txpool.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/metatx/ERC2771Context.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/metatx/ERC2771Forwarder.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/metatx/ERC2771Forwarder.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/proxy/Clones.behaviour.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/proxy/Clones.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/proxy/Clones.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/proxy/ERC1967/ERC1967Proxy.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/proxy/ERC1967/ERC1967Utils.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/proxy/Proxy.behaviour.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/proxy/beacon/BeaconProxy.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/proxy/beacon/UpgradeableBeacon.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/proxy/transparent/ProxyAdmin.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/proxy/transparent/TransparentUpgradeableProxy.behaviour.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/proxy/transparent/TransparentUpgradeableProxy.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/proxy/utils/Initializable.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/proxy/utils/UUPSUpgradeable.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/sanity.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/token/ERC1155/ERC1155.behavior.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/token/ERC1155/ERC1155.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/token/ERC1155/extensions/ERC1155Burnable.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/token/ERC1155/extensions/ERC1155Pausable.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/token/ERC1155/extensions/ERC1155Supply.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/token/ERC1155/extensions/ERC1155URIStorage.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/token/ERC1155/utils/ERC1155Holder.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/token/ERC1155/utils/ERC1155Utils.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/token/ERC20/ERC20.behavior.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/token/ERC20/ERC20.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC1363.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20Burnable.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20Capped.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20FlashMint.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20Pausable.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20Permit.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20Votes.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20Wrapper.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC4626.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC4626.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/token/ERC20/extensions/draft-ERC20TemporaryApproval.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/token/ERC20/utils/SafeERC20.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/token/ERC721/ERC721.behavior.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/token/ERC721/ERC721.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/token/ERC721/ERC721Enumerable.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/token/ERC721/extensions/ERC721Burnable.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/token/ERC721/extensions/ERC721Consecutive.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/token/ERC721/extensions/ERC721Consecutive.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/token/ERC721/extensions/ERC721Pausable.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/token/ERC721/extensions/ERC721Royalty.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/token/ERC721/extensions/ERC721URIStorage.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/token/ERC721/extensions/ERC721Votes.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/token/ERC721/extensions/ERC721Wrapper.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/token/ERC721/utils/ERC721Holder.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/token/ERC721/utils/ERC721Utils.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/token/common/ERC2981.behavior.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/utils/Address.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/utils/Arrays.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/utils/Arrays.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/utils/Base64.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/utils/Base64.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/utils/Bytes.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/utils/CAIP.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/utils/Context.behavior.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/utils/Context.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/utils/Create2.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/utils/Create2.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/utils/Multicall.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/utils/Nonces.behavior.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/utils/Nonces.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/utils/NoncesKeyed.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/utils/Packing.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/utils/Packing.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/utils/Panic.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/utils/Pausable.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/utils/ReentrancyGuard.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/utils/ShortStrings.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/utils/ShortStrings.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/utils/SlotDerivation.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/utils/SlotDerivation.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/utils/StorageSlot.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/utils/Strings.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/utils/Strings.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/utils/TransientSlot.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/utils/cryptography/ECDSA.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/utils/cryptography/EIP712.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/utils/cryptography/MerkleProof.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/utils/cryptography/MessageHashUtils.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/utils/cryptography/P256.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/utils/cryptography/P256.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/utils/cryptography/RSA.helper.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/utils/cryptography/RSA.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/utils/cryptography/SigVer15_186-3.rsp create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/utils/cryptography/SignatureChecker.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/utils/cryptography/ecdsa_secp256r1_sha256_p1363_test.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/utils/introspection/ERC165.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/utils/introspection/ERC165Checker.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/utils/introspection/SupportsInterface.behavior.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/utils/math/Math.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/utils/math/Math.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/utils/math/SafeCast.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/utils/math/SignedMath.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/utils/math/SignedMath.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/utils/structs/BitMap.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/utils/structs/Checkpoints.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/utils/structs/Checkpoints.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/utils/structs/CircularBuffer.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/utils/structs/DoubleEndedQueue.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/utils/structs/EnumerableMap.behavior.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/utils/structs/EnumerableMap.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/utils/structs/EnumerableSet.behavior.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/utils/structs/EnumerableSet.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/utils/structs/Heap.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/utils/structs/Heap.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/utils/structs/MerkleTree.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/lib/openzeppelin-contracts/test/utils/types/Time.test.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/package.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/pnpm-lock.yaml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/pnpm-workspace.yaml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/script/Deploy.s.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/script/DeployMocks.s.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/src/Estimator.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/src/Factory.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/src/Guest.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/src/Simulator.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/src/Stage1Module.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/src/Stage2Module.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/src/Wallet.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/src/Wallet.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/src/extensions/passkeys/Passkeys.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/src/extensions/recovery/Recovery.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/src/extensions/sessions/SessionErrors.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/src/extensions/sessions/SessionManager.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/src/extensions/sessions/SessionSig.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/src/extensions/sessions/explicit/ExplicitSessionManager.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/src/extensions/sessions/explicit/IExplicitSessionManager.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/src/extensions/sessions/explicit/Permission.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/src/extensions/sessions/explicit/PermissionValidator.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/src/extensions/sessions/implicit/Attestation.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/src/extensions/sessions/implicit/ISignalsImplicitMode.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/src/extensions/sessions/implicit/ImplicitSessionManager.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/src/modules/Calls.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/src/modules/ERC4337v07.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/src/modules/Hooks.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/src/modules/Implementation.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/src/modules/Nonce.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/src/modules/Payload.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/src/modules/ReentrancyGuard.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/src/modules/Storage.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/src/modules/auth/BaseAuth.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/src/modules/auth/BaseSig.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/src/modules/auth/SelfAuth.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/src/modules/auth/Stage1Auth.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/src/modules/auth/Stage2Auth.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/src/modules/interfaces/IAccount.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/src/modules/interfaces/IAuth.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/src/modules/interfaces/ICheckpointer.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/src/modules/interfaces/IDelegatedExtension.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/src/modules/interfaces/IERC1155Receiver.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/src/modules/interfaces/IERC1271.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/src/modules/interfaces/IERC223Receiver.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/src/modules/interfaces/IERC721Receiver.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/src/modules/interfaces/IERC777Receiver.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/src/modules/interfaces/IEntryPoint.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/src/modules/interfaces/IPartialAuth.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/src/modules/interfaces/ISapient.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/src/utils/Base64.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/src/utils/LibBytes.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/src/utils/LibOptim.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/src/utils/P256.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/src/utils/WebAuthn.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/test/Factory.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/test/Guest.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/test/Stage1Module.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/test/Wallet.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/test/extensions/passkeys/Passkeys.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/test/extensions/recovery/Recovery.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/test/extensions/sessions/Attestation.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/test/extensions/sessions/Permission.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/test/extensions/sessions/SessionCalls.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/test/extensions/sessions/SessionManager.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/test/extensions/sessions/SessionSig.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/test/extensions/sessions/SessionTestBase.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/test/extensions/sessions/explicit/ExplicitSessionManager.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/test/extensions/sessions/explicit/PermissionValidator.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/test/extensions/sessions/implicit/ImplicitSessionManager.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/test/integrations/extensions/recovery/RecoveryDenialOfService.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/test/integrations/extensions/sessions/ExtendedSessionTestBase.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/test/integrations/extensions/sessions/SessionDenialOfService.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/test/integrations/extensions/sessions/SessionLimitIncrementTest.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/test/integrations/extensions/sessions/SessionSelfCall.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/test/integrations/extensions/sessions/SessionSignatureAbuse.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/test/integrations/extensions/sessions/SessionUsingERC4337.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/test/integrations/extensions/sessions/SessionValueForwarding.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/test/integrations/modules/ERC4337v07/ERC4337Entrypoint.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/test/mocks/AcceptAll.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/test/mocks/CanReenter.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/test/mocks/Emitter.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/test/mocks/MockERC20.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/test/mocks/MockPayableReceiver.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/test/mocks/ValueForwarder.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/test/modules/BaseSig.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/test/modules/Calls.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/test/modules/ERC4337v07.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/test/modules/Hooks.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/test/modules/Implementation.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/test/modules/Nonce.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/test/modules/Payload.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/test/utils/Base64.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/test/utils/LibBytes.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/test/utils/PrimitivesRPC.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/lib/sequence-v3/test/utils/TestUtils.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/script/Deploy.s.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/src/helper/SignalsImplicitMode.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/src/registry/IImplicitProjectRegistry.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/src/registry/IImplicitProjectValidation.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/src/registry/ImplicitProjectRegistry.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/test/ImplicitProjectRegistry.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/test/SignalsImplicitMode.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/test/TestHelper.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/lib/signals-implicit-mode/test/mock/SignalsImplicitModeMock.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/package.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/services/README.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/services/api/CHANGELOG.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/services/api/README.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/services/api/package.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/services/api/src/api.gen.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/services/api/src/index.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/services/api/tsconfig.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/services/builder/CHANGELOG.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/services/builder/README.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/services/builder/package.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/services/builder/src/builder.gen.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/services/builder/src/index.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/services/builder/tsconfig.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/services/guard/CHANGELOG.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/services/guard/README.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/services/guard/package.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/services/guard/src/client/guard.gen.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/services/guard/src/index.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/services/guard/src/local.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/services/guard/src/sequence.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/services/guard/src/types.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/services/guard/test/sequence.test.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/services/guard/tsconfig.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/services/identity-instrument/package.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/services/identity-instrument/src/challenge.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/services/identity-instrument/src/identity-instrument.gen.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/services/identity-instrument/src/index.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/services/identity-instrument/test/challenge.test.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/services/identity-instrument/tsconfig.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/services/identity-instrument/vitest.config.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/services/indexer/CHANGELOG.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/services/indexer/README.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/services/indexer/package.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/services/indexer/src/index.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/services/indexer/src/indexer.gen.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/services/indexer/src/indexergw.gen.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/services/indexer/tsconfig.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/services/marketplace/CHANGELOG.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/services/marketplace/README.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/services/marketplace/package.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/services/marketplace/src/index.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/services/marketplace/src/marketplace.gen.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/services/marketplace/tsconfig.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/services/metadata/CHANGELOG.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/services/metadata/README.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/services/metadata/package.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/services/metadata/src/index.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/services/metadata/src/metadata.gen.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/services/metadata/tsconfig.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/services/relayer/CHANGELOG.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/services/relayer/README.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/services/relayer/hardhat.config.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/services/relayer/package.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/services/relayer/src/index.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/services/relayer/src/local-relayer.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/services/relayer/src/provider-relayer.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/services/relayer/src/rpc-relayer/index.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/services/relayer/src/rpc-relayer/relayer.gen.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/services/relayer/tsconfig.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/utils/README.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/utils/abi/CHANGELOG.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/utils/abi/README.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/utils/abi/package.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/utils/abi/src/index.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/utils/abi/src/sale/erc1155Sale.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/utils/abi/src/sale/erc721Sale.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/utils/abi/src/tokens/erc1155.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/utils/abi/src/tokens/erc1155Items.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/utils/abi/src/tokens/erc20.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/utils/abi/src/tokens/erc6909.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/utils/abi/src/tokens/erc721.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/utils/abi/src/tokens/erc721Items.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/utils/abi/src/wallet/erc1271.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/utils/abi/src/wallet/erc5719.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/utils/abi/src/wallet/erc6492.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/utils/abi/src/wallet/factory.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/utils/abi/src/wallet/index.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/utils/abi/src/wallet/libs/requireFreshSigners.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/utils/abi/src/wallet/mainModule.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/utils/abi/src/wallet/mainModuleUpgradable.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/utils/abi/src/wallet/moduleHooks.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/utils/abi/src/wallet/sequenceUtils.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/utils/abi/src/wallet/walletProxyHook.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/utils/abi/tsconfig.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/core/package.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/core/src/envelope.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/core/src/index.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/core/src/preconditions/codec.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/core/src/preconditions/index.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/core/src/preconditions/selectors.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/core/src/preconditions/types.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/core/src/relayer/bundler.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/core/src/relayer/bundlers/index.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/core/src/relayer/bundlers/pimlico.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/core/src/relayer/index.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/core/src/relayer/relayer.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/core/src/relayer/standard/abi.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/core/src/relayer/standard/eip6963.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/core/src/relayer/standard/index.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/core/src/relayer/standard/local.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/core/src/relayer/standard/pk-relayer.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/core/src/relayer/standard/rpc/index.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/core/src/relayer/standard/rpc/relayer.gen.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/core/src/relayer/standard/sequence.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/core/src/signers/guard.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/core/src/signers/index.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/core/src/signers/passkey.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/core/src/signers/pk/encrypted.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/core/src/signers/pk/index.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/core/src/signers/session-manager.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/core/src/signers/session/explicit.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/core/src/signers/session/implicit.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/core/src/signers/session/index.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/core/src/signers/session/session.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/core/src/state/cached.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/core/src/state/debug.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/core/src/state/index.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/core/src/state/local/index.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/core/src/state/local/indexed-db.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/core/src/state/local/memory.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/core/src/state/remote/dev-http.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/core/src/state/remote/index.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/core/src/state/sequence/index.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/core/src/state/sequence/sessions.gen.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/core/src/state/utils.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/core/src/utils/index.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/core/src/utils/session/permission-builder.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/core/src/wallet.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/core/test/constants.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/core/test/envelope.test.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/core/test/preconditions.test.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/core/test/preconditions/codec.test.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/core/test/preconditions/selectors.test.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/core/test/preconditions/types.test.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/core/test/relayer/bundler.test.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/core/test/relayer/relayer.test.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/core/test/session-manager.test.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/core/test/setup.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/core/test/signers-guard.test.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/core/test/signers-index.test.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/core/test/signers-passkey.test.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/core/test/signers-pk-encrypted.test.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/core/test/signers-pk.test.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/core/test/signers-session-explicit.test.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/core/test/signers-session-implicit.test.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/core/test/state/cached.test.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/core/test/state/debug.test.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/core/test/state/local/memory.test.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/core/test/state/utils.test.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/core/test/utils/session/permission-builder.test.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/core/test/wallet.test.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/core/tsconfig.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/core/vitest.config.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/dapp-client/README.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/dapp-client/eslint.config.mjs create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/dapp-client/package.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/dapp-client/src/ChainSessionManager.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/dapp-client/src/DappClient.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/dapp-client/src/DappTransport.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/dapp-client/src/index.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/dapp-client/src/types/index.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/dapp-client/src/utils/constants.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/dapp-client/src/utils/errors.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/dapp-client/src/utils/index.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/dapp-client/src/utils/storage.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/dapp-client/tsconfig.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/primitives-cli/eslint.config.mjs create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/primitives-cli/package.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/primitives-cli/src/index.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/primitives-cli/src/subcommands/address.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/primitives-cli/src/subcommands/config.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/primitives-cli/src/subcommands/devTools.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/primitives-cli/src/subcommands/passkeys.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/primitives-cli/src/subcommands/payload.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/primitives-cli/src/subcommands/recovery.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/primitives-cli/src/subcommands/server.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/primitives-cli/src/subcommands/session.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/primitives-cli/src/subcommands/sessionExplicit.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/primitives-cli/src/subcommands/sessionImplicit.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/primitives-cli/src/subcommands/signature.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/primitives-cli/src/utils.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/primitives-cli/tsconfig.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/primitives/eslint.config.mjs create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/primitives/package.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/primitives/src/address.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/primitives/src/attestation.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/primitives/src/config.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/primitives/src/constants.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/primitives/src/context.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/primitives/src/erc-6492.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/primitives/src/extensions/index.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/primitives/src/extensions/passkeys.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/primitives/src/extensions/recovery.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/primitives/src/generic-tree.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/primitives/src/index.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/primitives/src/network.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/primitives/src/payload.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/primitives/src/permission.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/primitives/src/precondition.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/primitives/src/session-config.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/primitives/src/session-signature.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/primitives/src/signature.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/primitives/src/utils.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/primitives/test/address.test.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/primitives/test/attestation.test.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/primitives/test/config.test.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/primitives/test/erc-6492.test.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/primitives/test/generic-tree.test.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/primitives/test/passkeys.test.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/primitives/test/payload.test.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/primitives/test/permission.test.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/primitives/test/precondition.test.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/primitives/test/recovery.test.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/primitives/test/session-config.test.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/primitives/test/session-signature.test.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/primitives/test/signature.test.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/primitives/test/utils.test.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/primitives/tsconfig.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/primitives/vitest.config.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/wdk/.env.test create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/wdk/package.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/wdk/src/dbs/auth-commitments.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/wdk/src/dbs/auth-keys.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/wdk/src/dbs/generic.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/wdk/src/dbs/index.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/wdk/src/dbs/messages.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/wdk/src/dbs/passkey-credentials.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/wdk/src/dbs/recovery.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/wdk/src/dbs/signatures.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/wdk/src/dbs/transactions.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/wdk/src/dbs/wallets.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/wdk/src/identity/signer.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/wdk/src/index.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/wdk/src/sequence/cron.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/wdk/src/sequence/devices.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/wdk/src/sequence/errors.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/wdk/src/sequence/guards.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/wdk/src/sequence/handlers/authcode-pkce.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/wdk/src/sequence/handlers/authcode.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/wdk/src/sequence/handlers/devices.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/wdk/src/sequence/handlers/guard.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/wdk/src/sequence/handlers/handler.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/wdk/src/sequence/handlers/identity.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/wdk/src/sequence/handlers/index.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/wdk/src/sequence/handlers/mnemonic.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/wdk/src/sequence/handlers/otp.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/wdk/src/sequence/handlers/passkeys.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/wdk/src/sequence/handlers/recovery.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/wdk/src/sequence/index.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/wdk/src/sequence/logger.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/wdk/src/sequence/manager.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/wdk/src/sequence/messages.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/wdk/src/sequence/recovery.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/wdk/src/sequence/sessions.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/wdk/src/sequence/signatures.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/wdk/src/sequence/signers.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/wdk/src/sequence/transactions.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/wdk/src/sequence/types/device.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/wdk/src/sequence/types/index.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/wdk/src/sequence/types/message-request.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/wdk/src/sequence/types/module.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/wdk/src/sequence/types/recovery.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/wdk/src/sequence/types/signature-request.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/wdk/src/sequence/types/signer.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/wdk/src/sequence/types/transaction-request.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/wdk/src/sequence/types/wallet.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/wdk/src/sequence/wallets.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/wdk/test/authcode-pkce.test.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/wdk/test/authcode.test.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/wdk/test/constants.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/wdk/test/guard.test.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/wdk/test/identity-auth-dbs.test.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/wdk/test/identity-signer.test.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/wdk/test/messages.test.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/wdk/test/otp.test.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/wdk/test/passkeys.test.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/wdk/test/recovery.test.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/wdk/test/sessions.test.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/wdk/test/setup.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/wdk/test/transactions.test.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/wdk/test/wallets.test.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/wdk/tsconfig.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/packages/wallet/wdk/vitest.config.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/pnpm-workspace.yaml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/repo/README.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/repo/eslint-config/README.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/repo/eslint-config/base.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/repo/eslint-config/next.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/repo/eslint-config/package.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/repo/eslint-config/react-internal.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/repo/typescript-config/base.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/repo/typescript-config/nextjs.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/repo/typescript-config/package.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/repo/typescript-config/react-library.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/repo/ui/eslint.config.mjs create mode 100644 wagmi-project/packages/sequence-core-1.0.0/repo/ui/package.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/repo/ui/src/button.tsx create mode 100644 wagmi-project/packages/sequence-core-1.0.0/repo/ui/src/card.tsx create mode 100644 wagmi-project/packages/sequence-core-1.0.0/repo/ui/src/code.tsx create mode 100644 wagmi-project/packages/sequence-core-1.0.0/repo/ui/tsconfig.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/repo/ui/turbo/generators/config.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/repo/ui/turbo/generators/templates/component.hbs create mode 100644 wagmi-project/packages/sequence-core-1.0.0/turbo.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/.eslintignore create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/.eslintrc.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/.gitattributes create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/.github/actions/install-dependencies/action.yml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/.github/workflows/ci.yml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/.gitmodules create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/.prettierrc create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/.solcover.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/.solhint.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/0xsequence-wallet-contracts-3.0.1.tgz create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/.github/workflows/test.yml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/.gitmodules create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/README.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/broadcast/Counter.s.sol/1/run-1763223074249.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/broadcast/Counter.s.sol/1/run-1763223530987.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/broadcast/Counter.s.sol/1/run-latest.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/foundry.lock create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/foundry.toml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/lib/forge-std/.gitattributes create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/lib/forge-std/.github/CODEOWNERS create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/lib/forge-std/.github/dependabot.yml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/lib/forge-std/.github/workflows/ci.yml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/lib/forge-std/.github/workflows/sync.yml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/lib/forge-std/CONTRIBUTING.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/lib/forge-std/LICENSE-APACHE create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/lib/forge-std/LICENSE-MIT create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/lib/forge-std/README.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/lib/forge-std/RELEASE_CHECKLIST.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/lib/forge-std/foundry.toml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/lib/forge-std/package.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/lib/forge-std/scripts/vm.py create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/lib/forge-std/src/Base.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/lib/forge-std/src/Config.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/lib/forge-std/src/LibVariable.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/lib/forge-std/src/Script.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/lib/forge-std/src/StdAssertions.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/lib/forge-std/src/StdChains.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/lib/forge-std/src/StdCheats.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/lib/forge-std/src/StdConfig.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/lib/forge-std/src/StdConstants.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/lib/forge-std/src/StdError.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/lib/forge-std/src/StdInvariant.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/lib/forge-std/src/StdJson.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/lib/forge-std/src/StdMath.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/lib/forge-std/src/StdStorage.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/lib/forge-std/src/StdStyle.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/lib/forge-std/src/StdToml.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/lib/forge-std/src/StdUtils.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/lib/forge-std/src/Test.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/lib/forge-std/src/Vm.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/lib/forge-std/src/console.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/lib/forge-std/src/console2.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/lib/forge-std/src/interfaces/IERC1155.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/lib/forge-std/src/interfaces/IERC165.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/lib/forge-std/src/interfaces/IERC20.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/lib/forge-std/src/interfaces/IERC4626.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/lib/forge-std/src/interfaces/IERC6909.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/lib/forge-std/src/interfaces/IERC721.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/lib/forge-std/src/interfaces/IERC7540.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/lib/forge-std/src/interfaces/IERC7575.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/lib/forge-std/src/interfaces/IMulticall3.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/lib/forge-std/src/safeconsole.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/lib/forge-std/test/CommonBase.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/lib/forge-std/test/Config.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/lib/forge-std/test/LibVariable.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/lib/forge-std/test/StdAssertions.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/lib/forge-std/test/StdChains.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/lib/forge-std/test/StdCheats.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/lib/forge-std/test/StdConstants.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/lib/forge-std/test/StdError.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/lib/forge-std/test/StdJson.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/lib/forge-std/test/StdMath.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/lib/forge-std/test/StdStorage.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/lib/forge-std/test/StdStyle.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/lib/forge-std/test/StdToml.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/lib/forge-std/test/StdUtils.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/lib/forge-std/test/Vm.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/lib/forge-std/test/compilation/CompilationScript.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/lib/forge-std/test/compilation/CompilationScriptBase.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/lib/forge-std/test/compilation/CompilationTest.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/lib/forge-std/test/compilation/CompilationTestBase.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/lib/forge-std/test/fixtures/broadcast.log.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/lib/forge-std/test/fixtures/config.toml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/lib/forge-std/test/fixtures/test.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/lib/forge-std/test/fixtures/test.toml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/script/Counter.s.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/src/Counter.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/test/Counter.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/Counter/utils/JsonBindings.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/LICENSE create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/README.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/audits/v1/Consensys_Diligence.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/audits/v1/Quantstamp_Arcadeum_Report_Final.pdf create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/audits/v1/sequence_quantstamp_audit_feb_2021.pdf create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/audits/v2/Sequence Wallet - Zellic Audit Report.pdf create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/audits/v2/consensys-horizon-sequence-wallet-audit-2023-02.pdf create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/config/PROD.env.sample create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/contracts/Factory.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/contracts/Wallet.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/contracts/hooks/WalletProxyHook.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/contracts/hooks/interfaces/IWalletProxy.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/contracts/interfaces/IERC1271Wallet.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/contracts/interfaces/receivers/IERC1155Receiver.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/contracts/interfaces/receivers/IERC223Receiver.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/contracts/interfaces/receivers/IERC721Receiver.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/contracts/interfaces/receivers/IERC777Receiver.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/contracts/interfaces/tokens/IERC1155.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/contracts/interfaces/tokens/IERC20.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/contracts/interfaces/tokens/IERC721.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/contracts/mocks/AlwaysRevertMock.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/contracts/mocks/CallReceiverMock.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/contracts/mocks/DelegateCallMock.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/contracts/mocks/ERC1155Mock.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/contracts/mocks/ERC165CheckerMock.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/contracts/mocks/ERC20Mock.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/contracts/mocks/ERC721Mock.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/contracts/mocks/GasBurnerMock.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/contracts/mocks/HookCallerMock.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/contracts/mocks/HookMock.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/contracts/mocks/LibBytesImpl.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/contracts/mocks/LibBytesPointerImpl.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/contracts/mocks/LibStringImp.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/contracts/mocks/ModuleMock.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/contracts/modules/GuestModule.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/contracts/modules/MainModule.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/contracts/modules/MainModuleGasEstimation.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/contracts/modules/MainModuleUpgradable.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/contracts/modules/commons/Implementation.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/contracts/modules/commons/ModuleAuth.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/contracts/modules/commons/ModuleAuthConvenience.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/contracts/modules/commons/ModuleAuthFixed.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/contracts/modules/commons/ModuleAuthUpgradable.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/contracts/modules/commons/ModuleCalls.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/contracts/modules/commons/ModuleCreator.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/contracts/modules/commons/ModuleERC165.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/contracts/modules/commons/ModuleERC5719.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/contracts/modules/commons/ModuleExtraAuth.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/contracts/modules/commons/ModuleHooks.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/contracts/modules/commons/ModuleIPFS.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/contracts/modules/commons/ModuleNonce.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/contracts/modules/commons/ModuleOnlyDelegatecall.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/contracts/modules/commons/ModuleSelfAuth.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/contracts/modules/commons/ModuleStorage.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/contracts/modules/commons/ModuleUpdate.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/contracts/modules/commons/gas-estimation/ModuleIgnoreAuthUpgradable.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/contracts/modules/commons/gas-estimation/ModuleIgnoreNonceCalls.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/contracts/modules/commons/interfaces/IModuleAuth.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/contracts/modules/commons/interfaces/IModuleAuthUpgradable.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/contracts/modules/commons/interfaces/IModuleCalls.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/contracts/modules/commons/interfaces/IModuleCreator.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/contracts/modules/commons/interfaces/IModuleHooks.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/contracts/modules/commons/interfaces/IModuleUpdate.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/contracts/modules/commons/submodules/auth/SequenceDynamicSig.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/contracts/modules/commons/submodules/auth/SequenceNoChainIdSig.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/contracts/modules/commons/submodules/nonce/SubModuleNonce.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/contracts/modules/utils/GasEstimator.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/contracts/modules/utils/MultiCallUtils.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/contracts/modules/utils/RequireUtils.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/contracts/modules/utils/SequenceUtils.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/contracts/trust/Trust.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/contracts/trust/TrustFactory.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/contracts/utils/LibAddress.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/contracts/utils/LibBytes.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/contracts/utils/LibBytesPointer.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/contracts/utils/LibOptim.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/contracts/utils/LibString.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/contracts/utils/SignatureValidator.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/book.css create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/book.toml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/solidity.min.js create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/README.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/SUMMARY.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/Factory.sol/contract.Factory.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/README.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/Wallet.sol/library.Wallet.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/hooks/README.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/hooks/WalletProxyHook.sol/contract.WalletProxyHook.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/hooks/interfaces/IWalletProxy.sol/interface.IWalletProxy.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/hooks/interfaces/README.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/interfaces/IERC1271Wallet.sol/interface.IERC1271Wallet.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/interfaces/README.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/interfaces/receivers/IERC1155Receiver.sol/interface.IERC1155Receiver.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/interfaces/receivers/IERC223Receiver.sol/interface.IERC223Receiver.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/interfaces/receivers/IERC721Receiver.sol/interface.IERC721Receiver.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/interfaces/receivers/IERC777Receiver.sol/interface.IERC777Receiver.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/interfaces/receivers/README.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/interfaces/tokens/IERC1155.sol/interface.IERC1155.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/interfaces/tokens/IERC20.sol/interface.IERC20.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/interfaces/tokens/IERC721.sol/interface.IERC721.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/interfaces/tokens/README.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/mocks/AlwaysRevertMock.sol/contract.AlwaysRevertMock.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/mocks/CallReceiverMock.sol/contract.CallReceiverMock.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/mocks/DelegateCallMock.sol/contract.DelegateCallMock.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/mocks/ERC1155Mock.sol/contract.ERC1155Mock.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/mocks/ERC165CheckerMock.sol/contract.ERC165CheckerMock.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/mocks/ERC20Mock.sol/contract.ERC20Mock.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/mocks/ERC721Mock.sol/contract.ERC721Mock.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/mocks/GasBurnerMock.sol/contract.GasBurnerMock.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/mocks/HookCallerMock.sol/contract.HookCallerMock.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/mocks/HookMock.sol/contract.HookMock.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/mocks/LibBytesImpl.sol/contract.LibBytesImpl.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/mocks/LibBytesPointerImpl.sol/contract.LibBytesPointerImpl.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/mocks/LibStringImp.sol/contract.LibStringImp.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/mocks/ModuleMock.sol/contract.ModuleMock.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/mocks/README.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/modules/GuestModule.sol/contract.GuestModule.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/modules/MainModule.sol/contract.MainModule.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/modules/MainModuleGasEstimation.sol/contract.MainModuleGasEstimation.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/modules/MainModuleUpgradable.sol/contract.MainModuleUpgradable.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/modules/README.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/modules/commons/Implementation.sol/contract.Implementation.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/modules/commons/ModuleAuth.sol/abstract.ModuleAuth.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/modules/commons/ModuleAuthConvenience.sol/abstract.ModuleAuthConvenience.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/modules/commons/ModuleAuthFixed.sol/abstract.ModuleAuthFixed.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/modules/commons/ModuleAuthUpgradable.sol/abstract.ModuleAuthUpgradable.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/modules/commons/ModuleCalls.sol/abstract.ModuleCalls.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/modules/commons/ModuleCreator.sol/contract.ModuleCreator.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/modules/commons/ModuleERC165.sol/abstract.ModuleERC165.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/modules/commons/ModuleERC5719.sol/contract.ModuleERC5719.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/modules/commons/ModuleExtraAuth.sol/abstract.ModuleExtraAuth.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/modules/commons/ModuleHooks.sol/contract.ModuleHooks.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/modules/commons/ModuleIPFS.sol/contract.ModuleIPFS.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/modules/commons/ModuleNonce.sol/contract.ModuleNonce.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/modules/commons/ModuleOnlyDelegatecall.sol/contract.ModuleOnlyDelegatecall.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/modules/commons/ModuleSelfAuth.sol/contract.ModuleSelfAuth.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/modules/commons/ModuleStorage.sol/library.ModuleStorage.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/modules/commons/ModuleUpdate.sol/contract.ModuleUpdate.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/modules/commons/README.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/modules/commons/gas-estimation/ModuleIgnoreAuthUpgradable.sol/abstract.ModuleIgnoreAuthUpgradable.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/modules/commons/gas-estimation/ModuleIgnoreNonceCalls.sol/abstract.ModuleIgnoreNonceCalls.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/modules/commons/gas-estimation/README.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/modules/commons/interfaces/IModuleAuth.sol/abstract.IModuleAuth.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/modules/commons/interfaces/IModuleAuthUpgradable.sol/interface.IModuleAuthUpgradable.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/modules/commons/interfaces/IModuleCalls.sol/interface.IModuleCalls.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/modules/commons/interfaces/IModuleCreator.sol/interface.IModuleCreator.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/modules/commons/interfaces/IModuleHooks.sol/interface.IModuleHooks.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/modules/commons/interfaces/IModuleUpdate.sol/abstract.IModuleUpdate.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/modules/commons/interfaces/README.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/modules/commons/submodules/README.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/modules/commons/submodules/auth/README.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol/library.SequenceBaseSig.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol/abstract.SequenceChainedSig.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/modules/commons/submodules/auth/SequenceDynamicSig.sol/library.SequenceDynamicSig.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/modules/commons/submodules/auth/SequenceNoChainIdSig.sol/library.SequenceNoChainIdSig.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/modules/commons/submodules/nonce/README.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/modules/commons/submodules/nonce/SubModuleNonce.sol/library.SubModuleNonce.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/modules/utils/GasEstimator.sol/contract.GasEstimator.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/modules/utils/MultiCallUtils.sol/contract.MultiCallUtils.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/modules/utils/README.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/modules/utils/RequireUtils.sol/contract.RequireUtils.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/modules/utils/SequenceUtils.sol/contract.SequenceUtils.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/trust/README.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/trust/Trust.sol/contract.Trust.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/trust/Trust.sol/function.absDiff.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/trust/TrustFactory.sol/contract.TrustFactory.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/utils/LibAddress.sol/library.LibAddress.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/utils/LibBytes.sol/library.LibBytes.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/utils/LibBytesPointer.sol/library.LibBytesPointer.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/utils/LibOptim.sol/library.LibOptim.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/utils/LibString.sol/library.LibString.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/utils/README.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/docs/src/contracts/utils/SignatureValidator.sol/library.SignatureValidator.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/foundry.lock create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/foundry.toml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/foundry_test/base/AdvTest.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/foundry_test/hooks/WalletProxyHook.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/foundry_test/modules/commons/Implementation.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/foundry_test/modules/commons/ModuleCalls.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/foundry_test/modules/commons/ModuleERC5719.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/foundry_test/modules/commons/ModuleExtraAuth.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/foundry_test/modules/commons/ModuleIPFS.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/foundry_test/modules/commons/ModuleStorage.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/foundry_test/modules/commons/submodules/auth/SequenceBaseSig.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/foundry_test/modules/commons/submodules/auth/SequenceChainedSig.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/foundry_test/modules/commons/submodules/auth/SequenceDynamicSig.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/foundry_test/modules/commons/submodules/auth/SequenceNoChainIdSig.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/foundry_test/modules/commons/submodules/nonce/SubModuleNonce.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/foundry_test/modules/utils/L2CompressorEncoder.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/foundry_test/modules/utils/L2CompressorHuff.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/foundry_test/modules/utils/L2CompressorHuffReadExecute.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/foundry_test/modules/utils/L2CompressorHuffReadFlag.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/foundry_test/modules/utils/L2CompressorHuffReadNonce.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/foundry_test/modules/utils/L2CompressorHuffReadTx.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/foundry_test/modules/utils/L2CompressorHuffReadTxs.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/foundry_test/modules/utils/RequireUtils.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/foundry_test/trust/Trust.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/foundry_test/trust/TrustFactory.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/foundry_test/utils/LibAddress.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/foundry_test/utils/LibBytes.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/foundry_test/utils/LibBytesPointer.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/foundry_test/utils/LibOptim.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/foundry_test/utils/SignatureValidator.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/funding.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/hardhat.config.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/forge-std/.github/workflows/ci.yml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/forge-std/.github/workflows/sync.yml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/forge-std/.gitmodules create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/forge-std/LICENSE-APACHE create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/forge-std/LICENSE-MIT create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/forge-std/README.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/forge-std/foundry.toml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/forge-std/lib/ds-test/.github/workflows/build.yml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/forge-std/lib/ds-test/LICENSE create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/forge-std/lib/ds-test/Makefile create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/forge-std/lib/ds-test/default.nix create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/forge-std/lib/ds-test/demo/demo.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/forge-std/lib/ds-test/package.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/forge-std/lib/ds-test/src/test.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/forge-std/lib/ds-test/src/test.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/forge-std/package.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/forge-std/src/Base.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/forge-std/src/Script.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/forge-std/src/StdAssertions.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/forge-std/src/StdChains.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/forge-std/src/StdCheats.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/forge-std/src/StdError.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/forge-std/src/StdInvariant.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/forge-std/src/StdJson.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/forge-std/src/StdMath.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/forge-std/src/StdStorage.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/forge-std/src/StdStyle.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/forge-std/src/StdUtils.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/forge-std/src/Test.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/forge-std/src/Vm.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/forge-std/src/console.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/forge-std/src/console2.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/forge-std/src/interfaces/IERC1155.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/forge-std/src/interfaces/IERC165.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/forge-std/src/interfaces/IERC20.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/forge-std/src/interfaces/IERC4626.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/forge-std/src/interfaces/IERC721.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/forge-std/src/interfaces/IMulticall3.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/forge-std/test/StdAssertions.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/forge-std/test/StdChains.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/forge-std/test/StdCheats.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/forge-std/test/StdError.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/forge-std/test/StdMath.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/forge-std/test/StdStorage.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/forge-std/test/StdStyle.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/forge-std/test/StdUtils.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/forge-std/test/compilation/CompilationScript.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/forge-std/test/compilation/CompilationScriptBase.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/forge-std/test/compilation/CompilationTest.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/forge-std/test/compilation/CompilationTestBase.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/forge-std/test/fixtures/broadcast.log.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/.git-blame-ignore-revs create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/.github/workflows/tests.yaml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/.gitmodules create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/LICENSE create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/README.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/assets/Group 1.png create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/assets/banner.jpg create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/assets/black_white_huff-removebg-preview.png create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/assets/black_white_huff.png create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/assets/foundry.png create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/assets/foundry_huff_banner.jpg create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/assets/foundry_huff_banner.png create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/assets/huff.png create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/assets/inverted_huff.png create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/assets/x-removebg-preview.png create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/assets/x.jpg create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/foundry.toml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/lib/forge-std/.github/workflows/ci.yml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/lib/forge-std/.github/workflows/sync.yml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/lib/forge-std/.gitmodules create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/lib/forge-std/LICENSE-APACHE create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/lib/forge-std/LICENSE-MIT create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/lib/forge-std/README.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/lib/forge-std/foundry.toml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/lib/forge-std/lib/ds-test/.github/workflows/build.yml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/lib/forge-std/lib/ds-test/LICENSE create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/lib/forge-std/lib/ds-test/Makefile create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/lib/forge-std/lib/ds-test/default.nix create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/lib/forge-std/lib/ds-test/demo/demo.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/lib/forge-std/lib/ds-test/package.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/lib/forge-std/lib/ds-test/src/test.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/lib/forge-std/lib/ds-test/src/test.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/lib/forge-std/package.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/lib/forge-std/src/Base.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/lib/forge-std/src/Script.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/lib/forge-std/src/StdAssertions.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/lib/forge-std/src/StdChains.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/lib/forge-std/src/StdCheats.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/lib/forge-std/src/StdError.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/lib/forge-std/src/StdInvariant.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/lib/forge-std/src/StdJson.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/lib/forge-std/src/StdMath.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/lib/forge-std/src/StdStorage.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/lib/forge-std/src/StdStyle.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/lib/forge-std/src/StdUtils.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/lib/forge-std/src/Test.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/lib/forge-std/src/Vm.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/lib/forge-std/src/console.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/lib/forge-std/src/console2.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/lib/forge-std/src/interfaces/IERC1155.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/lib/forge-std/src/interfaces/IERC165.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/lib/forge-std/src/interfaces/IERC20.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/lib/forge-std/src/interfaces/IERC4626.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/lib/forge-std/src/interfaces/IERC721.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/lib/forge-std/src/interfaces/IMulticall3.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/lib/forge-std/src/safeconsole.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/lib/forge-std/test/StdAssertions.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/lib/forge-std/test/StdChains.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/lib/forge-std/test/StdCheats.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/lib/forge-std/test/StdError.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/lib/forge-std/test/StdMath.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/lib/forge-std/test/StdStorage.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/lib/forge-std/test/StdStyle.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/lib/forge-std/test/StdUtils.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/lib/forge-std/test/compilation/CompilationScript.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/lib/forge-std/test/compilation/CompilationScriptBase.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/lib/forge-std/test/compilation/CompilationTest.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/lib/forge-std/test/compilation/CompilationTestBase.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/lib/forge-std/test/fixtures/broadcast.log.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/lib/foundry-huff/scripts/binary_check.sh create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/lib/foundry-huff/scripts/file_writer.sh create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/lib/foundry-huff/scripts/rand_bytes.sh create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/lib/foundry-huff/scripts/read_and_append.sh create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/lib/solidity-stringutils/.gitattributes create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/lib/solidity-stringutils/.github/workflows/ci.yml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/lib/solidity-stringutils/.gitmodules create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/lib/solidity-stringutils/LICENSE create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/lib/solidity-stringutils/Makefile create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/lib/solidity-stringutils/README create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/lib/solidity-stringutils/README.md create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/lib/solidity-stringutils/dappfile create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/lib/solidity-stringutils/lib/ds-test/LICENSE create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/lib/solidity-stringutils/lib/ds-test/Makefile create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/lib/solidity-stringutils/lib/ds-test/default.nix create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/lib/solidity-stringutils/lib/ds-test/demo/demo.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/lib/solidity-stringutils/lib/ds-test/src/test.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/lib/solidity-stringutils/src/strings.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/lib/solidity-stringutils/src/strings.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/remappings.txt create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/scripts/binary_check.sh create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/scripts/file_writer.sh create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/scripts/rand_bytes.sh create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/scripts/read_and_append.sh create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/src/HuffConfig.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/src/HuffDeployer.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/src/depreciated/StatefulDeployer.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/src/depreciated/StatefulDeployer.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/src/test/HuffConfig.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/src/test/HuffDeployer.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/src/test/Logging.t.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/src/test/contracts/ConstOverride.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/src/test/contracts/Constructor.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/src/test/contracts/ConstructorNeedsValue.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/src/test/contracts/EVMVersionCheck.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/src/test/contracts/LotsOfLogging.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/src/test/contracts/NoConstructor.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/src/test/contracts/Number.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/src/test/contracts/RememberCreator.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/src/test/interfaces/IConstructor.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/src/test/interfaces/INumber.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/lib/foundry-huff/src/test/interfaces/IRememberCreator.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/networks/arbitrum.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/networks/arbitrumGoerli.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/networks/arbitrumNova.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/networks/avalanche.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/networks/avalancheFuji.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/networks/bnb.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/networks/bnbTestnet.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/networks/gnosis.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/networks/goerli.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/networks/hardhat.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/networks/mainnet.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/networks/mumbai.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/networks/optimism.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/networks/polygon.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/networks/polygonZkevm.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/package-lock.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/package.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/pnpm-lock.yaml create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/remappings.txt create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/run_huff_tests.sh create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/soldeer.lock create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/Errors.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/L2Compressor.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/L2CompressorLib.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/__TEMP__csfnkjajkqagwbukjfojatjegwtjmxhdL2Compressor.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/__TEMP__cvwewezvvfcuoxtlisicumgcpzqhgavjL2Compressor.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/__TEMP__cvyihdgegfauooldcwyvlordhurwepivL2Compressor.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/__TEMP__dpdvzwushkgzisywrbnkhcrodypkvbvyL2Compressor.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/__TEMP__ecomtgzdrtxibkzevmerruajxffksduvL2Compressor.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/__TEMP__iacuotklnugcaogzpvcdfhvolsvzerleL2Compressor.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/__TEMP__jcmwhtnovsnvnyyhadlushmcopgxtlcwL2Compressor.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/__TEMP__jdfvnyqsqtnysjlyfovitokyykvxttnoL2Compressor.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/__TEMP__jyyzvebufexucahwkkbkfdcmuiabvbfeL2Compressor.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/__TEMP__kbisarygvfqaqtuxwpgejdnyqkualpwlL2Compressor.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/__TEMP__lszmdtforkxonmlujouewhlrvjjrmurcL2Compressor.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/__TEMP__mgltnswskwojupcsygtzovabokiotusaL2Compressor.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/__TEMP__mzwfsngwzygdglttftvfnbgkuxhmtqwiL2Compressor.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/__TEMP__nxqmasuaqrahclmuoszdisbtgmuppjvfL2Compressor.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/__TEMP__pgmagdckbktfjhzdpajytwhcpkhlmscqL2Compressor.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/__TEMP__pwbfbdaeweytjiloryhjilsqguaprwtwL2Compressor.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/__TEMP__pxqvpgsonlpbmziexnicojtlgsgfouyrL2Compressor.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/__TEMP__qcagqkszwlsndhjyagmukhxiugwadpxxL2Compressor.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/__TEMP__qymdioekngjvjjjqfpzmxlycnvbslwevL2Compressor.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/__TEMP__rpzdmcdnijxlttsivcfgzleurbgpchhzL2Compressor.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/__TEMP__rulclzzfmyszewnycpzlqmcopsqccarqL2Compressor.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/__TEMP__uexsnlcvbjyubdfmmdxzehdfcdiwufcrL2Compressor.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/__TEMP__ughbfnqmhbdbiuueqxutuvcxicgrmnxwL2Compressor.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/__TEMP__uzsvtiqnxxrhkhfelgdrwmnbwwirribaL2Compressor.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/__TEMP__vffsqkjyicdnumnesfhcjlgtqguwdpnpL2Compressor.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/__TEMP__vtbpzpccsyytsvygxsyhvyojjbqsghpbL2Compressor.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/__TEMP__xhuychsyvcmrjzhibkdksklxflvtfefdL2Compressor.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/__TEMP__ylxrpbrfcykqjxgggzptgdvokhmzcvamL2Compressor.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/__TEMP__zkzjzrglozoqyyfvpcdqeanjxglmtzbbL2Compressor.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/L2CompressorImps.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/L2CompressorReadExecute.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/L2CompressorReadFlag.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/L2CompressorReadNonce.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/L2CompressorReadTx.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/L2CompressorReadTxs.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__aayxscdgqfgqckqcfvplniuqleqmglgpL2CompressorReadNonce.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__agjsoduxivwxbunbrskpnttujfxlnsuqL2CompressorReadFlag.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__aozfhsjnhfgdhkvygupcezykxnllxhooL2CompressorReadTx.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__auoqqxuvhsugblxkhmuynutuutdpetfmL2CompressorReadNonce.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__bgiysfzlfrqnqopegdijkxkzjebeugweL2CompressorReadExecute.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__bhcstacsnwaeevimfyeuyukrpkefkpjvL2CompressorReadTx.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__bjodacjzehrzeexubslwqheqqdtpojdxL2CompressorReadTxs.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__bqzqrnjvdcsevkfpbluzvxgnvfnbjbvdL2CompressorReadTxs.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__bxxjqefyxrrctwjijuvxauktfiveuhazL2CompressorReadNonce.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__cczbajsfeehqceablvdedlohtwcpgruiL2CompressorReadTx.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__ceqwybpkmvqejmujxdddmmbuqrzcvpqlL2CompressorReadTxs.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__cinzltxsvuofyvnmuiiddtfwsyytzwszL2CompressorReadFlag.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__ckntqzzuqphqsecwtcwuiczrfadymzpwL2CompressorReadTx.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__ctxqvslrdaagplfabzhyfjejoyhqoxvnL2CompressorReadTx.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__cxyftrlslztbljuqlicrbibyyssybguhL2CompressorReadNonce.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__cyxkjqcsonpojbyksbsvglcrgoqbepkaL2CompressorReadExecute.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__deeivxbssjzviqkksdozrardbmkofvggL2CompressorReadFlag.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__dexeqmbbqijqudvjnczxedpzkrqkrxgpL2CompressorReadExecute.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__ebpduriemctxazssijauhsotgyqtayygL2CompressorReadTxs.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__edfwesooemxojadwrkmombuemzhicuirL2CompressorReadTxs.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__eicqyirjstlxuotvptvgszvdeemgpomnL2CompressorReadTxs.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__eiovqvzojbuhtglrinqvkqirnywzkmmmL2CompressorReadTx.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__elmwrfrphdzesjosulrygitvkhredhzhL2CompressorReadFlag.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__eqatcxksiizfyaalvdegpzaqhuqqhiasL2CompressorReadTx.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__etsleznlprfdbomdvycqormkvpykanxnL2CompressorReadTxs.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__ezolvnoridtqgdaoucihkxihmonvdzfxL2CompressorReadNonce.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__fjxkkzopmkrdujlfcvecckcbuhhhpvpfL2CompressorReadFlag.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__fnqywxkjihwbqdurhcftzbzzrxvcmizbL2CompressorReadExecute.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__fophszhswirxqqcvcwxtmeqbuwldxifmL2CompressorReadNonce.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__fvrcmlbliwfwkjwbyxrediuokmghmftbL2CompressorReadTx.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__fzlawzzpwhflvpxtrdpemqiejqiknsfiL2CompressorReadNonce.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__gllqgrsektwpyxkfoughzygdwrhxuzibL2CompressorReadFlag.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__gmuxapiaoacldjbqqarixmvtxkffgwchL2CompressorReadExecute.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__gnbrxkaxjdmimbyepztqmujkoilcaudgL2CompressorReadExecute.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__grtgxrlusabnzjycyuqniujobcpgjuysL2CompressorReadTxs.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__guymonsuywmugusjixyvzwfzordmogvuL2CompressorReadNonce.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__gvmiqpcdvchroaxhcnyygzhjrvozrogmL2CompressorReadExecute.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__hahsuwlfvumxsoepdhwqsahoduwcqrrpL2CompressorReadTxs.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__hbzqhssjozyiqufyamizmyrwtgelqlacL2CompressorReadExecute.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__hfunbeczbrqifdmdhdecpajexqefympmL2CompressorReadFlag.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__htawaymiowrkxyrnxkesysithbtrbvqqL2CompressorReadNonce.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__hwddxmqkngntwieovwlvozjzwlctwrzrL2CompressorReadNonce.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__iepjlcxcjkjplwmrexbaruoucdulzvqvL2CompressorReadFlag.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__igcaczanzcfoaizsmahiisgmgdjzfjxqL2CompressorReadTxs.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__irlchgckchrpalaqwygxkipfvshmgystL2CompressorReadTxs.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__ixvgjbblpufenoaperstvmceseoukqtcL2CompressorReadFlag.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__jehdemzdnzfibjlvuclsezveuuexubagL2CompressorReadTxs.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__jgpbsiwsniszmajdqepfceqpqhdfzbiiL2CompressorReadExecute.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__jowmzjwgdpwndoapfucdlmsxiuwbhxrsL2CompressorReadFlag.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__jujqtnlfowbvuxcpetgqmymkladcanwtL2CompressorReadTx.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__jvyndfqmdiikuahllmivwlrgrfhmdzslL2CompressorReadFlag.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__kqlasykhhfirrrmebqsqsnoleofcgyciL2CompressorReadTx.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__krffnjyglejvywvaqrlwcoejtxsysubcL2CompressorReadFlag.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__lcamxsrkjvabmusmojsaspukxeydggrhL2CompressorReadExecute.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__lhhzpskainxqfqaqlpehxidlrhdvkcoyL2CompressorReadFlag.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__lqfhpuhoyykhenkubqyenjlfkzsbjkxcL2CompressorReadNonce.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__lvxixehkgptearwmufefnibyzayqaaciL2CompressorReadTx.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__lyxapewhygradusuogqwefdorgsntvcxL2CompressorReadTxs.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__mfzlovayqwfmitftdbihfqfuruuvbxqbL2CompressorReadExecute.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__mimqucgooefgrgmedlqkqqhszmvuuxioL2CompressorReadTxs.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__mlmvtiltzqbjdwbouzrwkvkhpzncpjzsL2CompressorReadTxs.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__mscgrvpcuajxspktkuiktwofhzwbszraL2CompressorReadNonce.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__mscqnapvfrrvforntvdsgkeofzbhbhdsL2CompressorReadFlag.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__nikafqmlyyfgnksobnextlfkyykzrdomL2CompressorReadFlag.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__nmkhnrsondojimozdduewzkbcwlvsakcL2CompressorReadFlag.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__nwvyiqgthdyhbeqefkhccrhufdhjjazeL2CompressorReadNonce.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__obfmnrpwkqhjnhtlarvljeqysguhoizaL2CompressorReadTx.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__osezdxhuqmvwkwrmogebamkqmhdvljmlL2CompressorReadTx.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__pabiechkuxsxbofnkwdnlbnftvkuearfL2CompressorReadExecute.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__paowmqtaesjuestckycmjquytqlfsdxoL2CompressorReadTx.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__pbsqieaiicgyhrvarrpmypzdufaanmpuL2CompressorReadNonce.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__pdhdqmtavohyssvasdtggpxqllpajsfgL2CompressorReadFlag.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__petemgomrtnkvriaaltgrrlpmnzupwinL2CompressorReadExecute.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__prsagizbgnvlqmbynuotwqkanwdlaqwpL2CompressorReadTx.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__pwmrquntendpgjgzyejxobzrgvpizgfdL2CompressorReadTxs.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__qcnbdgafrzidybihlkysfiliofczzxkhL2CompressorReadTxs.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__qmgpovlxptxlyeikmnrgvhavunciniubL2CompressorReadTx.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__qotscdrriksxilvopyxfsbdteqegnyogL2CompressorReadTx.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__qpcuafrrwylbrmzpjfotpjfuqxtnqrznL2CompressorReadTx.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__qrusinhmosfcvmayqquwflixlquuhfxhL2CompressorReadTx.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__raqvmbdtosqccjiitanbofqxpeepnlpnL2CompressorReadFlag.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__ruqfgeoaamevndekencowviukvlcrylcL2CompressorReadTx.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__sccswirfbmatrvwbvymwfzttbygcbfmqL2CompressorReadTxs.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__sgfhxhvokcpqraldrihrcqjmlolnoulkL2CompressorReadExecute.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__smnsryuyuhbbunwequckjtrcwgaqmtqrL2CompressorReadExecute.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__stxwzpcueqdwmcsxvxwzkubprcmgpexkL2CompressorReadExecute.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__syiwghttzfntbuucvfvlctpjeldqbrshL2CompressorReadNonce.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__tadxtxolhcweyyokjpleorchotchzsecL2CompressorReadNonce.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__tlpzvbklzufubgnwcvynodibgfqnidibL2CompressorReadFlag.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__uobsemubvemlejzpjvdzyjcjrsbhplpsL2CompressorReadNonce.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__uudbvubkefushlwgxsfgldujuphcmuueL2CompressorReadFlag.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__uyprsxxzmvxmqqzffpwypehvvksjzbvnL2CompressorReadTxs.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__vmmtlehczdflhfwnklqlujjtzpxrejpmL2CompressorReadNonce.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__voqybenghboelsmsisgwnqqymvpjvskcL2CompressorReadFlag.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__vtdvfmunyolkgcpjpzhtgjgwawtaakhwL2CompressorReadExecute.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__vtynudukibsyoxexvoiaurnusvgnrhusL2CompressorReadNonce.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__vvictwvevvjztwupwcjsnyherfswgsgcL2CompressorReadTx.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__vzqupagxqpkbexuaqyoulenyhrwfuvsiL2CompressorReadTxs.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__wcgjgrxjyjenenrnolprlkfulinnjttkL2CompressorReadExecute.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__weeyfqxkqtokrkcwbrxerdftkvyxqwwiL2CompressorReadExecute.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__xbuxrypubsjveaucjyhkmwlwmhlgvymnL2CompressorReadExecute.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__xeqwdqdlujruiiyywivxsxrlsluymfdiL2CompressorReadExecute.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__xprohfjolmgvmuxskobwcqavoskmutltL2CompressorReadExecute.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__yhfcljsbzcghwkonkegmtbremlhrxnejL2CompressorReadExecute.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__yphredkigvzhxnjzbspndmkchcjaofllL2CompressorReadNonce.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__zfeyxnkrahdyldfbtyakjkbvehkjdbmgL2CompressorReadTx.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__zmblbdmtdrpbbopekynjthxzellyhsxeL2CompressorReadTxs.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/src/imps/__TEMP__zvcrygcudiscauggwhjnxbrgifehtxhfL2CompressorReadTx.huff create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/test/ChainedSignatures.spec.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/test/ERC165.spec.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/test/Factory.spec.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/test/GasEstimation.spec.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/test/GuestModule.spec.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/test/LibBytes.spec.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/test/LibString.spec.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/test/MainModule.bench.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/test/MainModule.spec.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/test/MerkleSignatures.spec.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/test/MultiCallUtils.spec.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/test/utils/contracts.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/test/utils/imposter.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/test/utils/index.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/test/utils/sequence.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/test/utils/wallet.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/tsconfig.json create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/typings/chai-bignumber.d.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/typings/chai-bn.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/typings/truffle.d.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/utils/JsonBindings.sol create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/utils/benchmarker.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/utils/config-loader.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/utils/deploy-contracts.ts create mode 100644 wagmi-project/packages/sequence-core-1.0.0/wallet-contracts/utils/workers/bench-worker.ts diff --git a/wagmi-project/packages/sequence-core-1.0.0/.changeset/README.md b/wagmi-project/packages/sequence-core-1.0.0/.changeset/README.md new file mode 100644 index 000000000..e5b6d8d6a --- /dev/null +++ b/wagmi-project/packages/sequence-core-1.0.0/.changeset/README.md @@ -0,0 +1,8 @@ +# Changesets + +Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works +with multi-package repos, or single-package repos to help you version and publish your code. You can +find the full documentation for it [in our repository](https://github.com/changesets/changesets) + +We have a quick list of common questions to get you started engaging with this project in +[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md) diff --git a/wagmi-project/packages/sequence-core-1.0.0/.changeset/config.json b/wagmi-project/packages/sequence-core-1.0.0/.changeset/config.json new file mode 100644 index 000000000..6b372552c --- /dev/null +++ b/wagmi-project/packages/sequence-core-1.0.0/.changeset/config.json @@ -0,0 +1,11 @@ +{ + "$schema": "https://unpkg.com/@changesets/config@3.0.5/schema.json", + "changelog": "@changesets/cli/changelog", + "commit": false, + "fixed": [], + "linked": [], + "access": "restricted", + "baseBranch": "main", + "updateInternalDependencies": "patch", + "ignore": [] +} diff --git a/wagmi-project/packages/sequence-core-1.0.0/.github/CODEOWNERS b/wagmi-project/packages/sequence-core-1.0.0/.github/CODEOWNERS new file mode 100644 index 000000000..7f34c7a88 --- /dev/null +++ b/wagmi-project/packages/sequence-core-1.0.0/.github/CODEOWNERS @@ -0,0 +1 @@ +* @0xsequence/disable-codeowners-notifications @0xsequence/core diff --git a/wagmi-project/packages/sequence-core-1.0.0/.github/ISSUE_TEMPLATE/bug_report.md b/wagmi-project/packages/sequence-core-1.0.0/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 000000000..b5c68e55b --- /dev/null +++ b/wagmi-project/packages/sequence-core-1.0.0/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,40 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: '' +assignees: '' +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: + +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Desktop (please complete the following information):** + +- OS: [e.g. iOS] +- Browser [e.g. chrome, safari] +- Version [e.g. 22] + +**Smartphone (please complete the following information):** + +- Device: [e.g. iPhone6] +- OS: [e.g. iOS8.1] +- Browser [e.g. stock browser, safari] +- Version [e.g. 22] + +**Additional context** +Add any other context about the problem here. diff --git a/wagmi-project/packages/sequence-core-1.0.0/.github/ISSUE_TEMPLATE/custom.md b/wagmi-project/packages/sequence-core-1.0.0/.github/ISSUE_TEMPLATE/custom.md new file mode 100644 index 000000000..96a47352a --- /dev/null +++ b/wagmi-project/packages/sequence-core-1.0.0/.github/ISSUE_TEMPLATE/custom.md @@ -0,0 +1,7 @@ +--- +name: Custom issue template +about: Describe this issue template's purpose here. +title: '' +labels: '' +assignees: '' +--- diff --git a/wagmi-project/packages/sequence-core-1.0.0/.github/ISSUE_TEMPLATE/feature_request.md b/wagmi-project/packages/sequence-core-1.0.0/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 000000000..2f28cead0 --- /dev/null +++ b/wagmi-project/packages/sequence-core-1.0.0/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,19 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: '' +assignees: '' +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. diff --git a/wagmi-project/packages/sequence-core-1.0.0/.github/actions/install-dependencies/action.yml b/wagmi-project/packages/sequence-core-1.0.0/.github/actions/install-dependencies/action.yml new file mode 100644 index 000000000..ca81d1a40 --- /dev/null +++ b/wagmi-project/packages/sequence-core-1.0.0/.github/actions/install-dependencies/action.yml @@ -0,0 +1,39 @@ +name: Setup Node and PNPM dependencies + +runs: + using: 'composite' + + steps: + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: 20 + + - name: Setup PNPM + uses: pnpm/action-setup@v3 + with: + version: 10 + run_install: false + + - name: Get pnpm store directory + id: pnpm-cache + shell: bash + run: | + echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT + + - name: Setup pnpm cache + uses: actions/cache@v4 + with: + path: | + ${{ steps.pnpm-cache.outputs.STORE_PATH }} + node_modules + packages/*/node_modules + ~/.cache/puppeteer + key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} + restore-keys: | + ${{ runner.os }}-pnpm-store- + + - name: Install dependencies + shell: bash + run: pnpm install --frozen-lockfile + if: ${{ steps.pnpm-cache.outputs.cache-hit != 'true' }} diff --git a/wagmi-project/packages/sequence-core-1.0.0/.github/workflows/on_pr_pnpm-format-label.yml b/wagmi-project/packages/sequence-core-1.0.0/.github/workflows/on_pr_pnpm-format-label.yml new file mode 100644 index 000000000..84fb27cb3 --- /dev/null +++ b/wagmi-project/packages/sequence-core-1.0.0/.github/workflows/on_pr_pnpm-format-label.yml @@ -0,0 +1,23 @@ +name: pnpm-format-label + +on: + pull_request: + types: [labeled] + +jobs: + proto: + if: ${{ github.event.label.name == 'pnpm format' }} + uses: ./.github/workflows/pnpm-format.yml + secrets: inherit + + rm: + if: ${{ github.event.label.name == 'pnpm format' }} + runs-on: ubuntu-latest + steps: + - name: Remove the label + run: | + LABEL=$(echo "${{ github.event.label.name }}" | sed 's/ /%20/g') + curl -X DELETE \ + -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \ + -H "Accept: application/vnd.github.v3+json" \ + https://api.github.com/repos/${{ github.repository }}/issues/${{ github.event.pull_request.number }}/labels/$LABEL diff --git a/wagmi-project/packages/sequence-core-1.0.0/.github/workflows/pnpm-format.yml b/wagmi-project/packages/sequence-core-1.0.0/.github/workflows/pnpm-format.yml new file mode 100644 index 000000000..1be36e1a6 --- /dev/null +++ b/wagmi-project/packages/sequence-core-1.0.0/.github/workflows/pnpm-format.yml @@ -0,0 +1,27 @@ +name: pnpm format + +on: + workflow_call: + +jobs: + run: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ github.head_ref }} + fetch-depth: 20 + + - uses: ./.github/actions/install-dependencies + + - run: pnpm format + + - name: Commit back + uses: 0xsequence/actions/git-commit@v0.0.4 + env: + API_TOKEN_GITHUB: ${{ secrets.GH_TOKEN_GIT_COMMIT }} + with: + files: './' + branch: ${{ github.head_ref }} + commit_message: '[AUTOMATED] pnpm format' diff --git a/wagmi-project/packages/sequence-core-1.0.0/.github/workflows/publish-dists.yml b/wagmi-project/packages/sequence-core-1.0.0/.github/workflows/publish-dists.yml new file mode 100644 index 000000000..fd4bb7905 --- /dev/null +++ b/wagmi-project/packages/sequence-core-1.0.0/.github/workflows/publish-dists.yml @@ -0,0 +1,88 @@ +name: Publish Dists for Packages + +on: + workflow_dispatch: + push: + branches: + - master + +jobs: + build-and-push: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - uses: ./.github/actions/install-dependencies + + - name: Build package + run: pnpm run build + + - name: Prepare dist branch + run: | + PACKAGES=("services/guard" "services/identity-instrument" "services/relayer" "wallet/core" "wallet/primitives" "wallet/wdk" "wallet/dapp-client") + + for PACKAGE in "${PACKAGES[@]}"; do + BRANCH="dists/$PACKAGE" + PKG_DIR="packages/$PACKAGE" + + echo "📦 Publishing $PACKAGE to $BRANCH" + + mkdir -p /tmp/$PACKAGE + shopt -s dotglob + cp -r $PKG_DIR/* /tmp/$PACKAGE || true + + cd /tmp/$PACKAGE + git init + git checkout -b $BRANCH + + git config user.name "github-actions" + git config user.email "actions@github.com" + + echo "🔧 Rewriting workspace: deps in package.json..." + node -e ' + const fs = require("fs"); + const path = require("path"); + const pkgPath = path.resolve("package.json"); + const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8")); + const repo = "github:0xsequence/sequence.js"; + + const versions = { + "@0xsequence/guard": `${repo}#dists/services/guard`, + "@0xsequence/identity-instrument": `${repo}#dists/services/identity-instrument`, + "@0xsequence/relayer": `${repo}#dists/services/relayer`, + "@0xsequence/wallet-core": `${repo}#dists/wallet/core`, + "@0xsequence/wallet-primitives": `${repo}#dists/wallet/primitives`, + "@0xsequence/wallet-wdk": `${repo}#dists/wallet/wdk`, + }; + + const rewrite = (deps = {}) => { + for (const k in deps) { + if (deps[k].startsWith("workspace:")) { + const version = versions[k]; + + if (!version) { + console.warn(`No version found for ${k}, skipping...`); + continue; + } + + deps[k] = version; + console.log(`→ ${k} → ${deps[k]}`); + } + } + }; + + rewrite(pkg.dependencies); + fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2)); + ' + + git add . + git commit -m "Build: publish $PACKAGE dist" + + git remote add origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git + git push -f origin HEAD:$BRANCH + + cd - + done diff --git a/wagmi-project/packages/sequence-core-1.0.0/.github/workflows/tests.yml b/wagmi-project/packages/sequence-core-1.0.0/.github/workflows/tests.yml new file mode 100644 index 000000000..62fc357db --- /dev/null +++ b/wagmi-project/packages/sequence-core-1.0.0/.github/workflows/tests.yml @@ -0,0 +1,63 @@ +on: [push] + +name: tests + +jobs: + install: + name: Install dependencies + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: ./.github/actions/install-dependencies + + build: + name: Run build + runs-on: ubuntu-latest + needs: [install] + steps: + - uses: actions/checkout@v4 + - uses: ./.github/actions/install-dependencies + - run: pnpm clean + - run: pnpm build + + tests: + name: Run all tests + runs-on: ubuntu-latest + needs: [install] + steps: + - uses: actions/checkout@v4 + - uses: ./.github/actions/install-dependencies + - name: Install Foundry + uses: foundry-rs/foundry-toolchain@v1 + with: + version: nightly + - name: Start Anvil in background + run: anvil --fork-url https://nodes.sequence.app/arbitrum & + - run: pnpm test + + # NOTE: if you'd like to see example of how to run + # tests per package in parallel, see 'v2' branch + # .github/workflows/tests.yml + + # coverage: + # name: Run coverage + # runs-on: ubuntu-latest + # needs: [install] + # steps: + # - uses: actions/checkout@v4 + # - uses: actions/setup-node@v4 + # with: + # node-version: 20 + # - uses: actions/cache@v4 + # id: pnpm-cache + # with: + # path: | + # node_modules + # */*/node_modules + # key: ${{ runner.os }}-install-${{ hashFiles('**/package.json', '**/pnpm.lock') }} + # - run: pnpm dev && (pnpm coverage || true) + # - uses: codecov/codecov-action@v1 + # with: + # fail_ci_if_error: true + # verbose: true + # directory: ./coverage diff --git a/wagmi-project/packages/sequence-core-1.0.0/.gitmodules b/wagmi-project/packages/sequence-core-1.0.0/.gitmodules new file mode 100644 index 000000000..6131d7399 --- /dev/null +++ b/wagmi-project/packages/sequence-core-1.0.0/.gitmodules @@ -0,0 +1,3 @@ +[submodule "lib/signals-implicit-mode"] + path = lib/signals-implicit-mode + url = https://github.com/0xsequence/signals-implicit-mode diff --git a/wagmi-project/packages/sequence-core-1.0.0/.prettierrc b/wagmi-project/packages/sequence-core-1.0.0/.prettierrc new file mode 100644 index 000000000..cbe842acd --- /dev/null +++ b/wagmi-project/packages/sequence-core-1.0.0/.prettierrc @@ -0,0 +1,5 @@ +{ + "printWidth": 120, + "semi": false, + "singleQuote": true +} diff --git a/wagmi-project/packages/sequence-core-1.0.0/.vscode/launch.json b/wagmi-project/packages/sequence-core-1.0.0/.vscode/launch.json new file mode 100644 index 000000000..dc22920a8 --- /dev/null +++ b/wagmi-project/packages/sequence-core-1.0.0/.vscode/launch.json @@ -0,0 +1,28 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Launch primitives-cli server", + "type": "node", + "request": "launch", + "program": "${workspaceFolder}/packages/wallet/primitives-cli/dist/index.js", + "args": ["server"], + "runtimeArgs": ["--enable-source-maps"], + "cwd": "${workspaceFolder}", + "console": "integratedTerminal", + "sourceMaps": true, + "outFiles": [ + "${workspaceFolder}/packages/wallet/primitives-cli/dist/**/*.js", + "${workspaceFolder}/packages/wallet/core/dist/**/*.js", + "${workspaceFolder}/packages/wallet/primitives/dist/**/*.js", + "${workspaceFolder}/packages/wallet/wdk/dist/**/*.js" + ], + "sourceMapPathOverrides": { + "../packages/wallet/primitives-cli/src/*": "${workspaceFolder}/packages/wallet/primitives-cli/src/*", + "../packages/wallet/core/src/*": "${workspaceFolder}/packages/wallet/core/src/*", + "../packages/wallet/primitives/src/*": "${workspaceFolder}/packages/wallet/primitives/src/*", + "../packages/wallet/wdk/src/*": "${workspaceFolder}/packages/wallet/wdk/src/*" + } + } + ] +} diff --git a/wagmi-project/packages/sequence-core-1.0.0/.vscode/settings.json b/wagmi-project/packages/sequence-core-1.0.0/.vscode/settings.json new file mode 100644 index 000000000..44a73ec3a --- /dev/null +++ b/wagmi-project/packages/sequence-core-1.0.0/.vscode/settings.json @@ -0,0 +1,7 @@ +{ + "eslint.workingDirectories": [ + { + "mode": "auto" + } + ] +} diff --git a/wagmi-project/packages/sequence-core-1.0.0/LICENSE b/wagmi-project/packages/sequence-core-1.0.0/LICENSE new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/wagmi-project/packages/sequence-core-1.0.0/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/wagmi-project/packages/sequence-core-1.0.0/README.md b/wagmi-project/packages/sequence-core-1.0.0/README.md new file mode 100644 index 000000000..4c663ccf8 --- /dev/null +++ b/wagmi-project/packages/sequence-core-1.0.0/README.md @@ -0,0 +1,39 @@ +## sequence.js v3 core libraries and SDK + +**NOTE: please see [v2](https://github.com/0xsequence/sequence.js/tree/v2) branch for sequence.js 2.x.x** + +--- + +Sequence v3 core libraries and [wallet-contracts-v3](https://github.com/0xsequence/wallet-contracts-v3) SDK. + +## Packages + +- `@0xsequence/wallet-primitives`: stateless low-level utilities specifically for interacting directly with sequence wallet's smart contracts +- `@0xsequence/wallet-core`: higher level utilities for creating and using sequence wallets +- `@0xsequence/wallet-wdk`: all-in-one wallet development kit for building a sequence wallet product + +## Development + +### Getting Started + +1. Install dependencies: + `pnpm install` + +2. Build all packages: + `pnpm build` + +### Development Workflow + +- Run development mode across all packages: + `pnpm dev` + +- Run tests: + `pnpm test` + + > **Note:** Tests require [anvil](https://github.com/foundry-rs/foundry/tree/master/anvil) and [forge](https://github.com/foundry-rs/foundry) to be installed. You can run a local anvil instance using `pnpm run test:anvil`. + +- Linting and formatting is enforced via git hooks + +## License + +Apache-2.0 diff --git a/wagmi-project/packages/sequence-core-1.0.0/corepack.tgz b/wagmi-project/packages/sequence-core-1.0.0/corepack.tgz new file mode 100644 index 0000000000000000000000000000000000000000..afa76b295c7db9783722ef00487b4fa4ddd20901 GIT binary patch literal 4311947 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