diff --git a/.changeset/nine-colts-clap.md b/.changeset/nine-colts-clap.md
new file mode 100644
index 0000000000..7bd8afc229
--- /dev/null
+++ b/.changeset/nine-colts-clap.md
@@ -0,0 +1,6 @@
+---
+"wagmi": minor
+"@wagmi/core": minor
+---
+
+Added experimental EIP-5792 Actions & Hooks.
diff --git a/.github/workflows/verify.yml b/.github/workflows/verify.yml
index 9c18433eda..ffd47b0cdf 100644
--- a/.github/workflows/verify.yml
+++ b/.github/workflows/verify.yml
@@ -63,7 +63,7 @@ jobs:
strategy:
matrix:
typescript-version: ['5.0.4', '5.1.6', '5.2.2', 'latest']
- viem-version: ['2.8.4', 'latest']
+ viem-version: ['2.9.31', 'latest']
steps:
- name: Clone repository
diff --git a/.gitignore b/.gitignore
index 48b7235821..0b914097b1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -22,10 +22,12 @@ 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
diff --git a/docs/.vitepress/sidebar.ts b/docs/.vitepress/sidebar.ts
index 52144d7e96..aa41113d36 100644
--- a/docs/.vitepress/sidebar.ts
+++ b/docs/.vitepress/sidebar.ts
@@ -344,6 +344,31 @@ export function getSidebar() {
},
],
},
+ {
+ text: 'Experimental',
+ items: [
+ {
+ text: 'useCallsStatus',
+ link: '/react/api/hooks/useCallsStatus',
+ },
+ {
+ text: 'useCapabilities',
+ link: '/react/api/hooks/useCapabilities',
+ },
+ {
+ text: 'useSendCalls',
+ link: '/react/api/hooks/useSendCalls',
+ },
+ {
+ text: 'useShowCallsStatus',
+ link: '/react/api/hooks/useShowCallsStatus',
+ },
+ {
+ text: 'useWriteContracts',
+ link: '/react/api/hooks/useWriteContracts',
+ },
+ ],
+ },
],
'/core': [
{
@@ -687,6 +712,31 @@ export function getSidebar() {
},
],
},
+ {
+ text: 'Experimental',
+ items: [
+ {
+ text: 'getCallsStatus',
+ link: '/core/api/actions/getCallsStatus',
+ },
+ {
+ text: 'getCapabilities',
+ link: '/core/api/actions/getCapabilities',
+ },
+ {
+ text: 'sendCalls',
+ link: '/core/api/actions/sendCalls',
+ },
+ {
+ text: 'showCallsStatus',
+ link: '/core/api/actions/showCallsStatus',
+ },
+ {
+ text: 'writeContracts',
+ link: '/core/api/actions/writeContracts',
+ },
+ ],
+ },
],
'/cli': [
{
diff --git a/docs/core/api/actions/getCallsStatus.md b/docs/core/api/actions/getCallsStatus.md
new file mode 100644
index 0000000000..e94cfb668f
--- /dev/null
+++ b/docs/core/api/actions/getCallsStatus.md
@@ -0,0 +1,101 @@
+
+
+# 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)
+
+::: warning
+This is an experimental action that is not supported in most wallets. It is recommended to have a fallback mechanism if using this in production.
+:::
+
+## Import
+
+```ts
+import { getCallsStatus } from '@wagmi/core/experimental'
+```
+
+## Usage
+
+::: code-group
+```ts [index.ts]
+import { getCallsStatus } from '@wagmi/core/experimental'
+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/experimental'
+```
+
+### connector
+
+`Connector | undefined`
+
+Connector to get call statuses with.
+
+::: code-group
+```ts [index.ts]
+import { getConnections, getCallsStatus } from '@wagmi/core/experimental'
+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/experimental'
+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/experimental'
+```
+
+`bigint`
+
+Most recent block number seen.
+
+## Error
+
+```ts
+import { type GetCallsStatusErrorType } from '@wagmi/core/experimental'
+```
+
+
+
+## Viem
+
+- [`getCallsStatus`](https://viem.sh/experimental/eip5792/getCallsStatus)
diff --git a/docs/core/api/actions/getCapabilities.md b/docs/core/api/actions/getCapabilities.md
new file mode 100644
index 0000000000..6fe8cd99e9
--- /dev/null
+++ b/docs/core/api/actions/getCapabilities.md
@@ -0,0 +1,98 @@
+
+
+# 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)
+
+::: warning
+This is an experimental action that is not supported in most wallets. It is recommended to have a fallback mechanism if using this in production.
+:::
+
+## Import
+
+```ts
+import { getCapabilities } from '@wagmi/core/experimental'
+```
+
+## Usage
+
+::: code-group
+```ts [index.ts]
+import { getCapabilities } from '@wagmi/core/experimental'
+import { config } from './config'
+
+const capabilities = await getCapabilities(config)
+```
+<<< @/snippets/core/config.ts[config.ts]
+:::
+
+## Parameters
+
+```ts
+import { type GetCapabilitiesParameters } from '@wagmi/core/experimental'
+```
+
+### account
+
+`Account | Address | undefined`
+
+Fetch capabilities for the provided account.
+
+::: code-group
+```ts [index.ts]
+import { getCapabilities } from '@wagmi/core/experimental'
+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/experimental'
+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/experimental'
+```
+
+`bigint`
+
+Most recent block number seen.
+
+## Error
+
+```ts
+import { type GetCapabilitiesErrorType } from '@wagmi/core/experimental'
+```
+
+
+
+## Viem
+
+- [`getCapabilities`](https://viem.sh/experimental/eip5792/getCapabilities)
diff --git a/docs/core/api/actions/sendCalls.md b/docs/core/api/actions/sendCalls.md
new file mode 100644
index 0000000000..92332bd99d
--- /dev/null
+++ b/docs/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)
+
+::: warning
+This is an experimental action that is not supported in most wallets. It is recommended to have a fallback mechanism if using this in production.
+:::
+
+## Import
+
+```ts
+import { sendCalls } from '@wagmi/core/experimental'
+```
+
+## Usage
+
+::: code-group
+```ts [index.ts]
+import { parseEther } from 'viem'
+import { sendCalls } from '@wagmi/core/experimental'
+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/experimental'
+```
+
+### account
+
+`Account | Address | undefined`
+
+Account to execute the calls.
+
+::: code-group
+```ts [index.ts]
+import { parseEther } from 'viem'
+import { sendCalls } from '@wagmi/core/experimental'
+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/experimental'
+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/experimental'
+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/experimental'
+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/experimental'
+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/experimental'
+```
+
+`bigint`
+
+Most recent block number seen.
+
+## Error
+
+```ts
+import { type SendCallsErrorType } from '@wagmi/core/experimental'
+```
+
+
+
+## Viem
+
+- [`sendCalls`](https://viem.sh/experimental/eip5792/sendCalls)
diff --git a/docs/core/api/actions/showCallsStatus.md b/docs/core/api/actions/showCallsStatus.md
new file mode 100644
index 0000000000..dba02841ff
--- /dev/null
+++ b/docs/core/api/actions/showCallsStatus.md
@@ -0,0 +1,101 @@
+
+
+# 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)
+
+::: warning
+This is an experimental action that is not supported in most wallets. It is recommended to have a fallback mechanism if using this in production.
+:::
+
+## Import
+
+```ts
+import { showCallsStatus } from '@wagmi/core/experimental'
+```
+
+## Usage
+
+::: code-group
+```ts [index.ts]
+import { showCallsStatus } from '@wagmi/core/experimental'
+import { config } from './config'
+
+await showCallsStatus(config, {
+ id: '0x1234567890abcdef',
+})
+```
+<<< @/snippets/core/config.ts[config.ts]
+:::
+
+## Parameters
+
+```ts
+import { type ShowCallsStatusParameters } from '@wagmi/core/experimental'
+```
+
+### connector
+
+`Connector | undefined`
+
+Connector to show call statuses with.
+
+::: code-group
+```ts [index.ts]
+import { getConnections, showCallsStatus } from '@wagmi/core/experimental'
+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/experimental'
+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/experimental'
+```
+
+`bigint`
+
+Most recent block number seen.
+
+## Error
+
+```ts
+import { type ShowCallsStatusErrorType } from '@wagmi/core/experimental'
+```
+
+
+
+## Viem
+
+- [`showCallsStatus`](https://viem.sh/experimental/eip5792/showCallsStatus)
diff --git a/docs/core/api/actions/writeContracts.md b/docs/core/api/actions/writeContracts.md
new file mode 100644
index 0000000000..c782330707
--- /dev/null
+++ b/docs/core/api/actions/writeContracts.md
@@ -0,0 +1,319 @@
+
+
+# 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)
+
+::: warning
+This is an experimental action that is not supported in most wallets. It is recommended to have a fallback mechanism if using this in production.
+:::
+
+## 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/docs/react/api/hooks/useCallsStatus.md b/docs/react/api/hooks/useCallsStatus.md
new file mode 100644
index 0000000000..2d4acb7f63
--- /dev/null
+++ b/docs/react/api/hooks/useCallsStatus.md
@@ -0,0 +1,145 @@
+---
+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`](/core/api/actions/useSendCalls).
+
+::: warning
+This is an experimental action that is not supported in most wallets. It is recommended to have a fallback mechanism if using this in production.
+:::
+
+## Import
+
+```ts
+import { useCallsStatus } from 'wagmi/experimental'
+```
+
+## Usage
+
+::: code-group
+```tsx [index.tsx]
+import { useCallsStatus } from 'wagmi/experimental'
+
+function App() {
+ const result = useCallsStatus({
+ id: '0x...', // [!code focus]
+ })
+}
+```
+<<< @/snippets/react/config.ts[config.ts]
+:::
+
+## Parameters
+
+```ts
+import { type UseCallsStatusParameters } from 'wagmi/experimental'
+```
+
+### config
+
+`Config | undefined`
+
+[`Config`](/react/api/createConfig#config) to use instead of retrieving from the from nearest [`WagmiProvider`](/react/api/WagmiProvider).
+
+::: code-group
+```tsx [index.tsx]
+import { useCallsStatus } from 'wagmi/experimental'
+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/experimental'
+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/experimental'
+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/experimental'
+```
+
+
+
+
+
+## Action
+
+- [`getCallsStatus`](https://viem.sh/experimental/eip5792/getCallsStatus)
\ No newline at end of file
diff --git a/docs/react/api/hooks/useCapabilities.md b/docs/react/api/hooks/useCapabilities.md
new file mode 100644
index 0000000000..e478cf000a
--- /dev/null
+++ b/docs/react/api/hooks/useCapabilities.md
@@ -0,0 +1,142 @@
+---
+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)
+
+::: warning
+This is an experimental Hook that is not supported in most wallets. It is recommended to have a fallback mechanism if using this in production.
+:::
+
+## Import
+
+```ts
+import { useCapabilities } from 'wagmi/experimental'
+```
+
+## Usage
+
+::: code-group
+```tsx [index.tsx]
+import { useCapabilities } from 'wagmi/experimental'
+
+function App() {
+ const result = useCapabilities()
+}
+```
+<<< @/snippets/react/config.ts[config.ts]
+:::
+
+## Parameters
+
+```ts
+import { type UseCapabilitiesParameters } from 'wagmi/experimental'
+```
+
+### 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 from nearest [`WagmiProvider`](/react/api/WagmiProvider).
+
+::: code-group
+```tsx [index.tsx]
+import { useCapabilities } from 'wagmi/experimental'
+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/experimental'
+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/experimental'
+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/experimental'
+```
+
+
+
+
+
+## Action
+
+- [`getCapabilities`](https://viem.sh/experimental/eip5792/getCapabilities)
\ No newline at end of file
diff --git a/docs/react/api/hooks/useSendCalls.md b/docs/react/api/hooks/useSendCalls.md
new file mode 100644
index 0000000000..a85d13fea7
--- /dev/null
+++ b/docs/react/api/hooks/useSendCalls.md
@@ -0,0 +1,107 @@
+---
+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)
+
+::: warning
+This is an experimental Hook that is not supported in most wallets. It is recommended to have a fallback mechanism if using this in production.
+:::
+
+## Import
+
+```ts
+import { useSendCalls } from 'wagmi/experimental'
+```
+
+## Usage
+
+::: code-group
+```tsx [index.tsx]
+import { useSendCalls } from 'wagmi/experimental'
+import { parseEther } from 'viem'
+
+function App() {
+ const { sendCalls } = useSendCalls()
+
+ return (
+
+ )
+}
+```
+<<< @/snippets/react/config.ts[config.ts]
+:::
+
+## Parameters
+
+```ts
+import { type UseSendCallsParameters } from 'wagmi/experimental'
+```
+
+### config
+
+`Config | undefined`
+
+[`Config`](/react/api/createConfig#config) to use instead of retrieving from the from nearest [`WagmiProvider`](/react/api/WagmiProvider).
+
+::: code-group
+```tsx [index.tsx]
+import { useSendCalls } from 'wagmi/experimental'
+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/experimental'
+```
+
+
+
+
+
+## Action
+
+- [`sendCalls`](/core/api/actions/sendCalls)
diff --git a/docs/react/api/hooks/useShowCallsStatus.md b/docs/react/api/hooks/useShowCallsStatus.md
new file mode 100644
index 0000000000..ee45927e29
--- /dev/null
+++ b/docs/react/api/hooks/useShowCallsStatus.md
@@ -0,0 +1,98 @@
+---
+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)
+
+::: warning
+This is an experimental action that is not supported in most wallets. It is recommended to have a fallback mechanism if using this in production.
+:::
+
+## Import
+
+```ts
+import { useShowCallsStatus } from 'wagmi/experimental'
+```
+
+## Usage
+
+::: code-group
+```tsx [index.tsx]
+import { useShowCallsStatus } from 'wagmi/experimental'
+import { parseEther } from 'viem'
+
+function App() {
+ const { showCallsStatus } = useShowCallsStatus()
+
+ return (
+
+ )
+}
+```
+<<< @/snippets/react/config.ts[config.ts]
+:::
+
+## Parameters
+
+```ts
+import { type UseShowCallsStatusParameters } from 'wagmi/experimental'
+```
+
+### config
+
+`Config | undefined`
+
+[`Config`](/react/api/createConfig#config) to use instead of retrieving from the from nearest [`WagmiProvider`](/react/api/WagmiProvider).
+
+::: code-group
+```tsx [index.tsx]
+import { useShowCallsStatus } from 'wagmi/experimental'
+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/experimental'
+```
+
+
+
+
+
+## Action
+
+- [`showCallsStatus`](/core/api/actions/showCallsStatus)
diff --git a/docs/react/api/hooks/useWriteContracts.md b/docs/react/api/hooks/useWriteContracts.md
new file mode 100644
index 0000000000..21f79e3dad
--- /dev/null
+++ b/docs/react/api/hooks/useWriteContracts.md
@@ -0,0 +1,123 @@
+---
+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)
+
+::: warning
+This is an experimental Hook that is not supported in most wallets. It is recommended to have a fallback mechanism if using this in production.
+:::
+
+## 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 from 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/package.json b/package.json
index b2ff62dbb5..38e63ed592 100644
--- a/package.json
+++ b/package.json
@@ -52,7 +52,7 @@
"sherif": "^0.8.1",
"simple-git-hooks": "^2.9.0",
"typescript": "5.4.2",
- "viem": "2.8.4",
+ "viem": "2.9.31",
"vitest": "^0.34.5"
},
"packageManager": "pnpm@8.10.5",
@@ -95,14 +95,14 @@
"ignoreDependencies": ["@walletconnect/modal"]
},
"packages/core": {
- "entry": "src/exports/{actions,chains,codegen,index,internal,query}.ts!",
+ "entry": "src/exports/{actions,chains,codegen,experimental,index,internal,query}.ts!",
"ignoreDependencies": ["@tanstack/query-core"]
},
"packages/create-wagmi": {
"entry": "src/cli.ts!"
},
"packages/react": {
- "entry": "src/exports/{actions,chains,codegen,connectors,index,query}.ts!"
+ "entry": "src/exports/{actions,chains,codegen,connectors,experimental,index,query}.ts!"
},
"packages/test": {
"entry": [
diff --git a/packages/core/package.json b/packages/core/package.json
index 47def7cac3..d4f63556c9 100644
--- a/packages/core/package.json
+++ b/packages/core/package.json
@@ -11,7 +11,7 @@
"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",
- "clean": "rm -rf dist tsconfig.tsbuildinfo actions chains codegen internal query",
+ "clean": "rm -rf dist tsconfig.tsbuildinfo actions chains codegen experimental internal query",
"test:build": "publint --strict",
"typecheck": "tsc --noEmit"
},
@@ -23,6 +23,7 @@
"!src/**/*.test-d.ts",
"/actions",
"/chains",
+ "/experimental",
"/internal",
"/query"
],
@@ -48,6 +49,10 @@
"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"
@@ -60,21 +65,12 @@
},
"typesVersions": {
"*": {
- "actions": [
- "./dist/types/exports/actions.d.ts"
- ],
- "chains": [
- "./dist/types/exports/chains.d.ts"
- ],
- "codegen": [
- "./dist/types/exports/codegen.d.ts"
- ],
- "internal": [
- "./dist/types/exports/internal.d.ts"
- ],
- "query": [
- "./dist/types/exports/query.d.ts"
- ]
+ "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": {
@@ -98,17 +94,7 @@
"devDependencies": {
"@tanstack/query-core": ">=5.0.0"
},
- "contributors": [
- "awkweb.eth ",
- "jxom.eth "
- ],
+ "contributors": ["awkweb.eth ", "jxom.eth "],
"funding": "https://github.com/sponsors/wevm",
- "keywords": [
- "wagmi",
- "eth",
- "ethereum",
- "dapps",
- "wallet",
- "web3"
- ]
-}
\ No newline at end of file
+ "keywords": ["wagmi", "eth", "ethereum", "dapps", "wallet", "web3"]
+}
diff --git a/packages/core/src/actions/call.test.ts b/packages/core/src/actions/call.test.ts
index 3e088095bd..25d6357cf1 100644
--- a/packages/core/src/actions/call.test.ts
+++ b/packages/core/src/actions/call.test.ts
@@ -74,7 +74,7 @@ test('nonce too low', async () => {
nonce: 0
Details: nonce too low
- Version: viem@2.8.4"
+ Version: viem@2.9.31"
`)
})
@@ -103,7 +103,7 @@ test('insufficient funds', async () => {
value: 100000 ETH
Details: Insufficient funds for gas * price + value
- Version: viem@2.8.4"
+ Version: viem@2.9.31"
`)
})
@@ -126,7 +126,7 @@ test('maxFeePerGas less than maxPriorityFeePerGas', async () => {
maxFeePerGas: 20 gwei
maxPriorityFeePerGas: 22 gwei
- Version: viem@2.8.4"
+ Version: viem@2.9.31"
`)
})
@@ -146,7 +146,7 @@ test('contract revert (contract error)', async () => {
data: 0xa0712d6800000000000000000000000000000000000000000000000000000000000001a4
Details: execution reverted: revert: Token ID is taken
- Version: viem@2.8.4"
+ Version: viem@2.9.31"
`)
})
@@ -166,6 +166,6 @@ test('contract revert (insufficient params)', async () => {
data: 0xa0712d68
Details: execution reverted
- Version: viem@2.8.4"
+ Version: viem@2.9.31"
`)
})
diff --git a/packages/core/src/actions/connect.test.ts b/packages/core/src/actions/connect.test.ts
index e0f51b2d62..ab77ea9d74 100644
--- a/packages/core/src/actions/connect.test.ts
+++ b/packages/core/src/actions/connect.test.ts
@@ -57,7 +57,7 @@ test('behavior: user rejected request', async () => {
[UserRejectedRequestError: User rejected the request.
Details: Failed to connect.
- Version: viem@2.8.4]
+ Version: viem@2.9.31]
`)
})
diff --git a/packages/core/src/actions/getToken.test.ts b/packages/core/src/actions/getToken.test.ts
index 9e437f20ff..97834d47ed 100644
--- a/packages/core/src/actions/getToken.test.ts
+++ b/packages/core/src/actions/getToken.test.ts
@@ -79,6 +79,6 @@ test('behavior: bogus token', async () => {
function: decimals()
Docs: https://viem.sh/docs/contract/multicall
- Version: viem@2.8.4"
+ Version: viem@2.9.31"
`)
})
diff --git a/packages/core/src/actions/prepareTransactionRequest.test.ts b/packages/core/src/actions/prepareTransactionRequest.test.ts
index aeb9c2ca30..a62b964bd4 100644
--- a/packages/core/src/actions/prepareTransactionRequest.test.ts
+++ b/packages/core/src/actions/prepareTransactionRequest.test.ts
@@ -88,6 +88,7 @@ test('behavior: local account', async () => {
{
"account": {
"address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
+ "experimental_signAuthMessage": [Function],
"publicKey": "0x048318535b54105d4a7aae60c08fc45f9687181b4fdfc625bd1a753fa7397fed753547f11ca8696646f2f3acb08e31016afac23e630c5d11f59f61fef57b0d2aa5",
"signMessage": [Function],
"signTransaction": [Function],
diff --git a/packages/core/src/actions/readContracts.test.ts b/packages/core/src/actions/readContracts.test.ts
index ca3b898b86..34038084c5 100644
--- a/packages/core/src/actions/readContracts.test.ts
+++ b/packages/core/src/actions/readContracts.test.ts
@@ -397,7 +397,7 @@ test('throws if allowFailure=false & a contract method fails', async () => {
args: (0xA0Cf798816D4b9b9866b5330EEa46a18382f251e, 69420)
Docs: https://viem.sh/docs/contract/readContract
- Version: viem@2.8.4"
+ Version: viem@2.9.31"
`,
)
})
@@ -450,7 +450,7 @@ test('allowFailure=true & a contract method fails', async () => {
args: (0xA0Cf798816D4b9b9866b5330EEa46a18382f251e, 69420)
Docs: https://viem.sh/docs/contract/readContract
- Version: viem@2.8.4],
+ Version: viem@2.9.31],
"result": undefined,
"status": "failure",
},
@@ -464,7 +464,7 @@ test('allowFailure=true & a contract method fails', async () => {
args: (0xA0Cf798816D4b9b9866b5330EEa46a18382f251e, 69421)
Docs: https://viem.sh/docs/contract/readContract
- Version: viem@2.8.4],
+ Version: viem@2.9.31],
"result": undefined,
"status": "failure",
},
@@ -502,7 +502,7 @@ test('throws if allowFailure=false & encoding contract function data fails', asy
args: (1e+31)
Docs: https://viem.sh/docs/contract/readContract
- Version: viem@2.8.4"
+ Version: viem@2.9.31"
`,
)
})
@@ -561,7 +561,7 @@ test('allowFailure=true & encoding contract function data fails', async () => {
args: (1e+31)
Docs: https://viem.sh/docs/contract/readContract
- Version: viem@2.8.4],
+ Version: viem@2.9.31],
"result": undefined,
"status": "failure",
},
@@ -579,7 +579,7 @@ test('allowFailure=true & encoding contract function data fails', async () => {
args: (1e+31)
Docs: https://viem.sh/docs/contract/readContract
- Version: viem@2.8.4],
+ Version: viem@2.9.31],
"result": undefined,
"status": "failure",
},
@@ -617,7 +617,7 @@ test('should throw if allowFailure=false & a contract has no response', async ()
args: (0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC)
Docs: https://viem.sh/docs/contract/readContract
- Version: viem@2.8.4"
+ Version: viem@2.9.31"
`,
)
})
@@ -669,7 +669,7 @@ test('allowFailure=true & a contract has no response', async () => {
args: (0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC)
Docs: https://viem.sh/docs/contract/readContract
- Version: viem@2.8.4],
+ Version: viem@2.9.31],
"result": undefined,
"status": "failure",
},
diff --git a/packages/core/src/actions/sendTransaction.test.ts b/packages/core/src/actions/sendTransaction.test.ts
index ccd25105a9..3309ed363b 100644
--- a/packages/core/src/actions/sendTransaction.test.ts
+++ b/packages/core/src/actions/sendTransaction.test.ts
@@ -77,7 +77,7 @@ test('behavior: value exceeds balance', async () => {
value: 99999 ETH
Details: Insufficient funds for gas * price + value
- Version: viem@2.8.4"
+ Version: viem@2.9.31"
`)
await disconnect(config, { connector })
})
diff --git a/packages/core/src/actions/sendTransaction.ts b/packages/core/src/actions/sendTransaction.ts
index 1ae61db29f..218fd69572 100644
--- a/packages/core/src/actions/sendTransaction.ts
+++ b/packages/core/src/actions/sendTransaction.ts
@@ -82,7 +82,7 @@ export async function sendTransaction<
if (!('data' in parameters) || !parameters.data) return undefined
// Skip gas estimation if connector supports simulation.
- if (activeConnector?.supportsSimulation) return undefined
+ if ((connector ?? activeConnector)?.supportsSimulation) return undefined
// Skip gas estimation if `null` is provided.
if (gas_ === null) return undefined
diff --git a/packages/core/src/actions/signMessage.test.ts b/packages/core/src/actions/signMessage.test.ts
index 4be837a32c..f5d4917161 100644
--- a/packages/core/src/actions/signMessage.test.ts
+++ b/packages/core/src/actions/signMessage.test.ts
@@ -51,7 +51,7 @@ test('behavior: user rejected request', async () => {
[UserRejectedRequestError: User rejected the request.
Details: Failed to sign message.
- Version: viem@2.8.4]
+ Version: viem@2.9.31]
`)
await disconnect(config, { connector: connector_ })
})
diff --git a/packages/core/src/actions/signTypedData.test.ts b/packages/core/src/actions/signTypedData.test.ts
index d67f053c8c..6519be6901 100644
--- a/packages/core/src/actions/signTypedData.test.ts
+++ b/packages/core/src/actions/signTypedData.test.ts
@@ -47,7 +47,7 @@ test('behavior: user rejected request', async () => {
[UserRejectedRequestError: User rejected the request.
Details: Failed to sign typed data.
- Version: viem@2.8.4]
+ Version: viem@2.9.31]
`)
await disconnect(config, { connector: connector_ })
})
diff --git a/packages/core/src/actions/switchChain.test.ts b/packages/core/src/actions/switchChain.test.ts
index a2f2f0edd7..3e61852e36 100644
--- a/packages/core/src/actions/switchChain.test.ts
+++ b/packages/core/src/actions/switchChain.test.ts
@@ -43,7 +43,7 @@ test('behavior: user rejected request', async () => {
[UserRejectedRequestError: User rejected the request.
Details: Failed to switch chain.
- Version: viem@2.8.4]
+ Version: viem@2.9.31]
`)
await disconnect(config, { connector: connector_ })
})
diff --git a/packages/core/src/connectors/mock.ts b/packages/core/src/connectors/mock.ts
index df4df88879..067a0764cd 100644
--- a/packages/core/src/connectors/mock.ts
+++ b/packages/core/src/connectors/mock.ts
@@ -6,11 +6,14 @@ import {
SwitchChainError,
type Transport,
UserRejectedRequestError,
+ type WalletCallReceipt,
type WalletRpcSchema,
custom,
fromHex,
getAddress,
+ keccak256,
numberToHex,
+ stringToHex,
} from 'viem'
import { rpc } from 'viem/utils'
@@ -35,6 +38,7 @@ export type MockParameters = {
mock.type = 'mock' as const
export function mock(parameters: MockParameters) {
+ const transactionCache = new Map()
const features = parameters.features ?? {}
type Provider = ReturnType<
@@ -70,7 +74,10 @@ export function mock(parameters: MockParameters) {
connected = true
- return { accounts, chainId: currentChainId }
+ return {
+ accounts: accounts.map((x) => getAddress(x)),
+ chainId: currentChainId,
+ }
},
async disconnect() {
connected = false
@@ -151,6 +158,86 @@ export function mock(parameters: MockParameters) {
return
}
+ 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 null
+ 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
+ }),
+ )
+ if (receipts.some((x) => !x))
+ return { status: 'PENDING', receipts: [] }
+ return { status: 'CONFIRMED', receipts }
+ }
+
+ if (method === 'wallet_showCallsStatus') return
+
// other methods
if (method === 'personal_sign') {
if (features.signMessageError) {
diff --git a/packages/core/src/experimental/actions/getCallsStatus.test.ts b/packages/core/src/experimental/actions/getCallsStatus.test.ts
new file mode 100644
index 0000000000..b20886d530
--- /dev/null
+++ b/packages/core/src/experimental/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 '../../actions/connect.js'
+import { disconnect } from '../../actions/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('CONFIRMED')
+ expect(
+ receipts?.map((x) => ({ ...x, blockHash: undefined })),
+ ).toMatchInlineSnapshot(
+ `
+ [
+ {
+ "blockHash": undefined,
+ "blockNumber": 19258214n,
+ "gasUsed": 21064n,
+ "logs": [],
+ "status": "success",
+ "transactionHash": "0xa81a893ca5596aa105fc10206b9a8bd63df8bd526d8c0594496330f956515b4b",
+ },
+ {
+ "blockHash": undefined,
+ "blockNumber": 19258214n,
+ "gasUsed": 21000n,
+ "logs": [],
+ "status": "success",
+ "transactionHash": "0x63624bbfc73f8bd7629ecb4e00ba521a9967ea9e9098ac17ae5bf500c904da1a",
+ },
+ {
+ "blockHash": undefined,
+ "blockNumber": 19258214n,
+ "gasUsed": 21000n,
+ "logs": [],
+ "status": "success",
+ "transactionHash": "0xc3df1b2f2c76723846a964c0c4d6d11ba423df036e0e636d298416e0f94bda29",
+ },
+ ]
+ `,
+ )
+ await disconnect(config, { connector })
+})
diff --git a/packages/core/src/experimental/actions/getCallsStatus.ts b/packages/core/src/experimental/actions/getCallsStatus.ts
new file mode 100644
index 0000000000..d1fa1de00c
--- /dev/null
+++ b/packages/core/src/experimental/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/experimental'
+
+import { getConnectorClient } from '../../actions/getConnectorClient.js'
+import { type Config } from '../../createConfig.js'
+import type { ConnectorParameter } from '../../types/properties.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/packages/core/src/experimental/actions/getCapabilities.test.ts b/packages/core/src/experimental/actions/getCapabilities.test.ts
new file mode 100644
index 0000000000..2946e27a5c
--- /dev/null
+++ b/packages/core/src/experimental/actions/getCapabilities.test.ts
@@ -0,0 +1,64 @@
+import { accounts, config } from '@wagmi/test'
+import { expect, test } from 'vitest'
+
+import { connect } from '../../actions/connect.js'
+import { disconnect } from '../../actions/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/packages/core/src/experimental/actions/getCapabilities.ts b/packages/core/src/experimental/actions/getCapabilities.ts
new file mode 100644
index 0000000000..b27c6ef745
--- /dev/null
+++ b/packages/core/src/experimental/actions/getCapabilities.ts
@@ -0,0 +1,28 @@
+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/experimental'
+
+import { getConnectorClient } from '../../actions/getConnectorClient.js'
+import { type Config } from '../../createConfig.js'
+import type { ConnectorParameter } from '../../types/properties.js'
+
+export type GetCapabilitiesParameters =
+ viem_GetCapabilitiesParameters & ConnectorParameter
+
+export type GetCapabilitiesReturnType = viem_GetCapabilitiesReturnType
+
+export type GetCapabilitiesErrorType = viem_GetCapabilitiesErrorType
+
+/** https://wagmi.sh/core/api/actions/getCapabilities */
+export async function getCapabilities(
+ config: config,
+ parameters: GetCapabilitiesParameters = {},
+): Promise {
+ const { account, connector } = parameters
+ const client = await getConnectorClient(config, { account, connector })
+ return viem_getCapabilities(client as any, { account: account as Account })
+}
diff --git a/packages/core/src/experimental/actions/sendCalls.test.ts b/packages/core/src/experimental/actions/sendCalls.test.ts
new file mode 100644
index 0000000000..589bce6adf
--- /dev/null
+++ b/packages/core/src/experimental/actions/sendCalls.test.ts
@@ -0,0 +1,88 @@
+import { accounts, config } from '@wagmi/test'
+import { parseEther } from 'viem'
+import { expect, test } from 'vitest'
+
+import { connect } from '../../actions/connect.js'
+import { disconnect } from '../../actions/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(
+ '"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(`
+ "Connector not connected.
+
+ Version: @wagmi/core@x.y.z"
+ `)
+})
+
+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(`
+ "Account \\"0xA0Cf798816D4b9b9866b5330EEa46a18382f251e\\" not found for connector \\"Mock Connector\\".
+
+ Version: @wagmi/core@x.y.z"
+ `)
+ await disconnect(config, { connector })
+})
diff --git a/packages/core/src/experimental/actions/sendCalls.ts b/packages/core/src/experimental/actions/sendCalls.ts
new file mode 100644
index 0000000000..369300083e
--- /dev/null
+++ b/packages/core/src/experimental/actions/sendCalls.ts
@@ -0,0 +1,68 @@
+import { type Account, type 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/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 Evaluate } from '../../types/utils.js'
+
+export type SendCallsParameters<
+ config extends Config = Config,
+ chainId extends config['chains'][number]['id'] = config['chains'][number]['id'],
+ ///
+ chains extends readonly Chain[] = SelectChains,
+> = {
+ [key in keyof chains]: Evaluate<
+ Omit, '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<
+ 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),
+ ...(account ? { account } : {}),
+ calls,
+ chain: chainId ? { id: chainId } : undefined,
+ })
+}
diff --git a/packages/core/src/experimental/actions/showCallsStatus.test.ts b/packages/core/src/experimental/actions/showCallsStatus.test.ts
new file mode 100644
index 0000000000..d397886e05
--- /dev/null
+++ b/packages/core/src/experimental/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 '../../actions/connect.js'
+import { disconnect } from '../../actions/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/packages/core/src/experimental/actions/showCallsStatus.ts b/packages/core/src/experimental/actions/showCallsStatus.ts
new file mode 100644
index 0000000000..23be4f4ebd
--- /dev/null
+++ b/packages/core/src/experimental/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/experimental'
+
+import { getConnectorClient } from '../../actions/getConnectorClient.js'
+import { type Config } from '../../createConfig.js'
+import type { ConnectorParameter } from '../../types/properties.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/packages/core/src/experimental/actions/writeContracts.test.ts b/packages/core/src/experimental/actions/writeContracts.test.ts
new file mode 100644
index 0000000000..42df43c452
--- /dev/null
+++ b/packages/core/src/experimental/actions/writeContracts.test.ts
@@ -0,0 +1,95 @@
+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(
+ '"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(`
+ "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(`
+ "Account \\"0xA0Cf798816D4b9b9866b5330EEa46a18382f251e\\" not found for connector \\"Mock Connector\\".
+
+ Version: @wagmi/core@x.y.z"
+ `)
+ await disconnect(config, { connector })
+})
diff --git a/packages/core/src/experimental/actions/writeContracts.ts b/packages/core/src/experimental/actions/writeContracts.ts
new file mode 100644
index 0000000000..f1c63e1ba3
--- /dev/null
+++ b/packages/core/src/experimental/actions/writeContracts.ts
@@ -0,0 +1,77 @@
+import { type Account, type Chain, type 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 Evaluate } 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]: Evaluate<
+ 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/packages/core/src/experimental/query/getCallsStatus.test.ts b/packages/core/src/experimental/query/getCallsStatus.test.ts
new file mode 100644
index 0000000000..fe834ecc79
--- /dev/null
+++ b/packages/core/src/experimental/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/packages/core/src/experimental/query/getCallsStatus.ts b/packages/core/src/experimental/query/getCallsStatus.ts
new file mode 100644
index 0000000000..1f8619b4ba
--- /dev/null
+++ b/packages/core/src/experimental/query/getCallsStatus.ts
@@ -0,0 +1,50 @@
+import { type QueryOptions } from '@tanstack/query-core'
+
+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 { Evaluate } from '../../types/utils.js'
+import {
+ type GetCallsStatusErrorType,
+ type GetCallsStatusParameters,
+ type GetCallsStatusReturnType,
+ getCallsStatus,
+} from '../actions/getCallsStatus.js'
+
+export type GetCallsStatusOptions = Evaluate<
+ 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/packages/core/src/experimental/query/getCapabilities.test.ts b/packages/core/src/experimental/query/getCapabilities.test.ts
new file mode 100644
index 0000000000..942eb37e04
--- /dev/null
+++ b/packages/core/src/experimental/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/packages/core/src/experimental/query/getCapabilities.ts b/packages/core/src/experimental/query/getCapabilities.ts
new file mode 100644
index 0000000000..24946e65a0
--- /dev/null
+++ b/packages/core/src/experimental/query/getCapabilities.ts
@@ -0,0 +1,50 @@
+import { type QueryOptions } from '@tanstack/query-core'
+
+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 { Evaluate, ExactPartial } from '../../types/utils.js'
+import {
+ type GetCapabilitiesErrorType,
+ type GetCapabilitiesParameters,
+ type GetCapabilitiesReturnType,
+ getCapabilities,
+} from '../actions/getCapabilities.js'
+
+export type GetCapabilitiesOptions = Evaluate<
+ ExactPartial & ScopeKeyParameter
+>
+
+export function getCapabilitiesQueryOptions(
+ 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 = GetCapabilitiesReturnType
+
+export type GetCapabilitiesData = GetCapabilitiesQueryFnData
+
+export function getCapabilitiesQueryKey(options: GetCapabilitiesOptions = {}) {
+ return ['capabilities', filterQueryOptions(options)] as const
+}
+
+export type GetCapabilitiesQueryKey = ReturnType
diff --git a/packages/core/src/experimental/query/sendCalls.test.ts b/packages/core/src/experimental/query/sendCalls.test.ts
new file mode 100644
index 0000000000..9892aa43e3
--- /dev/null
+++ b/packages/core/src/experimental/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/packages/core/src/experimental/query/sendCalls.ts b/packages/core/src/experimental/query/sendCalls.ts
new file mode 100644
index 0000000000..7949c3b3e7
--- /dev/null
+++ b/packages/core/src/experimental/query/sendCalls.ts
@@ -0,0 +1,64 @@
+import type { MutateOptions, MutationOptions } from '@tanstack/query-core'
+
+import { type Config } from '../../createConfig.js'
+import { type Evaluate } from '../../types/utils.js'
+import {
+ type SendCallsErrorType,
+ type SendCallsParameters,
+ type SendCallsReturnType,
+ sendCalls,
+} from '../actions/sendCalls.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 = Evaluate
+
+export type SendCallsVariables<
+ config extends Config,
+ chainId extends config['chains'][number]['id'],
+> = SendCallsParameters
+
+export type SendCallsMutate = <
+ chainId extends config['chains'][number]['id'],
+>(
+ variables: SendCallsVariables,
+ options?:
+ | Evaluate<
+ MutateOptions<
+ SendCallsData,
+ SendCallsErrorType,
+ Evaluate>,
+ context
+ >
+ >
+ | undefined,
+) => void
+
+export type SendCallsMutateAsync = <
+ chainId extends config['chains'][number]['id'],
+>(
+ variables: SendCallsVariables,
+ options?:
+ | Evaluate<
+ MutateOptions<
+ SendCallsData,
+ SendCallsErrorType,
+ Evaluate>,
+ context
+ >
+ >
+ | undefined,
+) => Promise
diff --git a/packages/core/src/experimental/query/showCallsStatus.test.ts b/packages/core/src/experimental/query/showCallsStatus.test.ts
new file mode 100644
index 0000000000..ad26ab6171
--- /dev/null
+++ b/packages/core/src/experimental/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/packages/core/src/experimental/query/showCallsStatus.ts b/packages/core/src/experimental/query/showCallsStatus.ts
new file mode 100644
index 0000000000..4cc704a910
--- /dev/null
+++ b/packages/core/src/experimental/query/showCallsStatus.ts
@@ -0,0 +1,57 @@
+import type { MutateOptions, MutationOptions } from '@tanstack/query-core'
+
+import { type Config } from '../../createConfig.js'
+import { type Evaluate } from '../../types/utils.js'
+import {
+ type ShowCallsStatusErrorType,
+ type ShowCallsStatusParameters,
+ type ShowCallsStatusReturnType,
+ showCallsStatus,
+} from '../actions/showCallsStatus.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 = Evaluate
+
+export type ShowCallsStatusVariables = ShowCallsStatusParameters
+
+export type ShowCallsStatusMutate = (
+ variables: ShowCallsStatusVariables,
+ options?:
+ | Evaluate<
+ MutateOptions<
+ ShowCallsStatusData,
+ ShowCallsStatusErrorType,
+ Evaluate,
+ context
+ >
+ >
+ | undefined,
+) => void
+
+export type ShowCallsStatusMutateAsync = (
+ variables: ShowCallsStatusVariables,
+ options?:
+ | Evaluate<
+ MutateOptions<
+ ShowCallsStatusData,
+ ShowCallsStatusErrorType,
+ Evaluate,
+ context
+ >
+ >
+ | undefined,
+) => Promise
diff --git a/packages/core/src/experimental/query/writeContracts.test.ts b/packages/core/src/experimental/query/writeContracts.test.ts
new file mode 100644
index 0000000000..5f4a1f28dd
--- /dev/null
+++ b/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/packages/core/src/experimental/query/writeContracts.ts b/packages/core/src/experimental/query/writeContracts.ts
new file mode 100644
index 0000000000..dfc9187ff8
--- /dev/null
+++ b/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 Evaluate } 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 = Evaluate
+
+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?:
+ | Evaluate<
+ MutateOptions<
+ WriteContractsData,
+ WriteContractsErrorType,
+ Evaluate>,
+ context
+ >
+ >
+ | undefined,
+) => void
+
+export type WriteContractsMutateAsync<
+ contracts extends readonly unknown[],
+ config extends Config,
+ context = unknown,
+> = (
+ variables: WriteContractsVariables,
+ options?:
+ | Evaluate<
+ MutateOptions<
+ WriteContractsData,
+ WriteContractsErrorType,
+ Evaluate>,
+ context
+ >
+ >
+ | undefined,
+) => Promise
diff --git a/packages/core/src/exports/experimental.ts b/packages/core/src/exports/experimental.ts
new file mode 100644
index 0000000000..b552083378
--- /dev/null
+++ b/packages/core/src/exports/experimental.ts
@@ -0,0 +1,84 @@
+////////////////////////////////////////////////////////////////////////////////
+// Actions
+////////////////////////////////////////////////////////////////////////////////
+
+export {
+ type GetCallsStatusErrorType,
+ type GetCallsStatusParameters,
+ type GetCallsStatusReturnType,
+ getCallsStatus,
+} from '../experimental/actions/getCallsStatus.js'
+
+export {
+ type GetCapabilitiesErrorType,
+ type GetCapabilitiesParameters,
+ type GetCapabilitiesReturnType,
+ getCapabilities,
+} from '../experimental/actions/getCapabilities.js'
+
+export {
+ type SendCallsErrorType,
+ type SendCallsParameters,
+ type SendCallsReturnType,
+ sendCalls,
+} from '../experimental/actions/sendCalls.js'
+
+export {
+ type ShowCallsStatusErrorType,
+ type ShowCallsStatusParameters,
+ type ShowCallsStatusReturnType,
+ showCallsStatus,
+} from '../experimental/actions/showCallsStatus.js'
+
+export {
+ type WriteContractsErrorType,
+ type WriteContractsParameters,
+ type WriteContractsReturnType,
+ writeContracts,
+} from '../experimental/actions/writeContracts.js'
+
+////////////////////////////////////////////////////////////////////////////////
+// Tanstack Query
+////////////////////////////////////////////////////////////////////////////////
+
+export {
+ type GetCallsStatusData,
+ type GetCallsStatusOptions,
+ type GetCallsStatusQueryFnData,
+ type GetCallsStatusQueryKey,
+ getCallsStatusQueryOptions,
+ getCallsStatusQueryKey,
+} from '../experimental/query/getCallsStatus.js'
+
+export {
+ type GetCapabilitiesData,
+ type GetCapabilitiesOptions,
+ type GetCapabilitiesQueryFnData,
+ type GetCapabilitiesQueryKey,
+ getCapabilitiesQueryOptions,
+ getCapabilitiesQueryKey,
+} from '../experimental/query/getCapabilities.js'
+
+export {
+ type SendCallsData,
+ type SendCallsMutate,
+ type SendCallsMutateAsync,
+ type SendCallsVariables,
+ sendCallsMutationOptions,
+} from '../experimental/query/sendCalls.js'
+
+export {
+ type ShowCallsStatusData,
+ type ShowCallsStatusMutate,
+ type ShowCallsStatusMutateAsync,
+ type ShowCallsStatusVariables,
+ showCallsStatusMutationOptions,
+} from '../experimental/query/showCallsStatus.js'
+
+export {
+ type WriteContractsData,
+ type WriteContractsMutate,
+ type WriteContractsMutateAsync,
+ type WriteContractsVariables,
+ writeContractsMutationOptions,
+} from '../experimental/query/writeContracts.js'
diff --git a/packages/core/src/query/prepareTransactionRequest.test.ts b/packages/core/src/query/prepareTransactionRequest.test.ts
index 2bb0e23af1..6d81391c4f 100644
--- a/packages/core/src/query/prepareTransactionRequest.test.ts
+++ b/packages/core/src/query/prepareTransactionRequest.test.ts
@@ -44,6 +44,7 @@ test('parameters: account', () => {
{
"account": {
"address": "0x14791697260E4c9A71f18484C9f997B308e59325",
+ "experimental_signAuthMessage": [Function],
"publicKey": "0x046655feed4d214c261e0a6b554395596f1f1476a77d999560e5a8df9b8a1a3515217e88dd05e938efdd71b2cce322bf01da96cd42087b236e8f5043157a9c068e",
"signMessage": [Function],
"signTransaction": [Function],
diff --git a/packages/react/package.json b/packages/react/package.json
index 8156802f72..226d9e2cb5 100644
--- a/packages/react/package.json
+++ b/packages/react/package.json
@@ -11,7 +11,7 @@
"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",
- "clean": "rm -rf dist tsconfig.tsbuildinfo actions chains codegen connectors query",
+ "clean": "rm -rf dist tsconfig.tsbuildinfo actions chains codegen connectors experimental query",
"test:build": "publint --strict",
"typecheck": "tsc --noEmit"
},
@@ -25,6 +25,7 @@
"/chains",
"/codegen",
"/connectors",
+ "/experimental",
"/query"
],
"sideEffects": false,
@@ -53,6 +54,10 @@
"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"
@@ -61,21 +66,12 @@
},
"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"
- ],
- "query": [
- "./dist/types/exports/query.d.ts"
- ]
+ "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": {
@@ -103,10 +99,7 @@
"react": ">=18",
"react-dom": ">=18"
},
- "contributors": [
- "awkweb.eth ",
- "jxom.eth "
- ],
+ "contributors": ["awkweb.eth ", "jxom.eth "],
"funding": "https://github.com/sponsors/wevm",
"keywords": [
"wagmi",
@@ -118,4 +111,4 @@
"wallet",
"web3"
]
-}
\ No newline at end of file
+}
diff --git a/packages/react/src/experimental/hooks/useCallsStatus.test.ts b/packages/react/src/experimental/hooks/useCallsStatus.test.ts
new file mode 100644
index 0000000000..98c202ee77
--- /dev/null
+++ b/packages/react/src/experimental/hooks/useCallsStatus.test.ts
@@ -0,0 +1,92 @@
+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! }),
+ )
+ await waitFor(() => expect(result_2.current.isSuccess).toBeTruthy())
+
+ expect(result_2.current.data).toMatchInlineSnapshot(
+ `
+ {
+ "receipts": [],
+ "status": "PENDING",
+ }
+ `,
+ )
+
+ await testClient.mainnet.mine({ blocks: 1 })
+
+ const { result: result_3 } = renderHook(() =>
+ useCallsStatus({ id: result.current.data! }),
+ )
+ await waitFor(() => expect(result_3.current.isSuccess).toBeTruthy())
+
+ expect(result_3.current.data).toMatchInlineSnapshot(
+ `
+ {
+ "receipts": [
+ {
+ "blockHash": "0x759f30616acde00a66d2bd83cc0bd011662ff0ca945d599554818fa0f9fdd0d2",
+ "blockNumber": 19258214n,
+ "gasUsed": 21064n,
+ "logs": [],
+ "status": "success",
+ "transactionHash": "0xa81a893ca5596aa105fc10206b9a8bd63df8bd526d8c0594496330f956515b4b",
+ },
+ {
+ "blockHash": "0x759f30616acde00a66d2bd83cc0bd011662ff0ca945d599554818fa0f9fdd0d2",
+ "blockNumber": 19258214n,
+ "gasUsed": 21000n,
+ "logs": [],
+ "status": "success",
+ "transactionHash": "0x63624bbfc73f8bd7629ecb4e00ba521a9967ea9e9098ac17ae5bf500c904da1a",
+ },
+ {
+ "blockHash": "0x759f30616acde00a66d2bd83cc0bd011662ff0ca945d599554818fa0f9fdd0d2",
+ "blockNumber": 19258214n,
+ "gasUsed": 21000n,
+ "logs": [],
+ "status": "success",
+ "transactionHash": "0xc3df1b2f2c76723846a964c0c4d6d11ba423df036e0e636d298416e0f94bda29",
+ },
+ ],
+ "status": "CONFIRMED",
+ }
+ `,
+ )
+
+ await disconnect(config, { connector })
+})
diff --git a/packages/react/src/experimental/hooks/useCallsStatus.ts b/packages/react/src/experimental/hooks/useCallsStatus.ts
new file mode 100644
index 0000000000..f9ce545753
--- /dev/null
+++ b/packages/react/src/experimental/hooks/useCallsStatus.ts
@@ -0,0 +1,49 @@
+'use client'
+
+import { type Config, type ResolvedRegister } from '@wagmi/core'
+import {
+ type GetCallsStatusData,
+ type GetCallsStatusErrorType,
+ type GetCallsStatusOptions,
+ type GetCallsStatusQueryFnData,
+ type GetCallsStatusQueryKey,
+ getCallsStatusQueryOptions,
+} from '@wagmi/core/experimental'
+import { type Evaluate } from '@wagmi/core/internal'
+
+import { useConfig } from '../../hooks/useConfig.js'
+import type { ConfigParameter, QueryParameter } from '../../types/properties.js'
+import { type UseQueryReturnType, useQuery } from '../../utils/query.js'
+
+export type UseCallsStatusParameters<
+ config extends Config = Config,
+ selectData = GetCallsStatusData,
+> = Evaluate<
+ 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/packages/react/src/experimental/hooks/useCapabilities.test.ts b/packages/react/src/experimental/hooks/useCapabilities.test.ts
new file mode 100644
index 0000000000..007b7172ce
--- /dev/null
+++ b/packages/react/src/experimental/hooks/useCapabilities.test.ts
@@ -0,0 +1,171 @@
+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())
+
+ expect(result.current).toMatchInlineSnapshot(`
+ {
+ "data": undefined,
+ "dataUpdatedAt": 0,
+ "error": [ConnectorNotConnectedError: Connector not connected.
+
+ Version: @wagmi/core@2.8.1],
+ "errorUpdateCount": 2,
+ "errorUpdatedAt": 1675209600000,
+ "failureCount": 1,
+ "failureReason": [ConnectorNotConnectedError: Connector not connected.
+
+ Version: @wagmi/core@2.8.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/packages/react/src/experimental/hooks/useCapabilities.ts b/packages/react/src/experimental/hooks/useCapabilities.ts
new file mode 100644
index 0000000000..2ee25935c7
--- /dev/null
+++ b/packages/react/src/experimental/hooks/useCapabilities.ts
@@ -0,0 +1,54 @@
+'use client'
+
+import { type Config, type ResolvedRegister } from '@wagmi/core'
+import {
+ type GetCapabilitiesData,
+ type GetCapabilitiesErrorType,
+ type GetCapabilitiesOptions,
+ type GetCapabilitiesQueryFnData,
+ type GetCapabilitiesQueryKey,
+ getCapabilitiesQueryOptions,
+} from '@wagmi/core/experimental'
+import { type Evaluate } from '@wagmi/core/internal'
+
+import { useAccount } from '../../hooks/useAccount.js'
+import { useConfig } from '../../hooks/useConfig.js'
+import type { ConfigParameter, QueryParameter } from '../../types/properties.js'
+import { type UseQueryReturnType, useQuery } from '../../utils/query.js'
+
+export type UseCapabilitiesParameters<
+ config extends Config = Config,
+ selectData = GetCapabilitiesData,
+> = Evaluate<
+ GetCapabilitiesOptions &
+ ConfigParameter &
+ QueryParameter<
+ GetCapabilitiesQueryFnData,
+ GetCapabilitiesErrorType,
+ selectData,
+ GetCapabilitiesQueryKey
+ >
+>
+
+export type UseCapabilitiesReturnType =
+ UseQueryReturnType
+
+/** https://wagmi.sh/react/api/hooks/useCapabilities */
+export function useCapabilities<
+ config extends Config = ResolvedRegister['config'],
+ 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/packages/react/src/experimental/hooks/useSendCalls.test.ts b/packages/react/src/experimental/hooks/useSendCalls.test.ts
new file mode 100644
index 0000000000..55771537dc
--- /dev/null
+++ b/packages/react/src/experimental/hooks/useSendCalls.test.ts
@@ -0,0 +1,40 @@
+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(
+ '"0x5dedb5a4ff8968db37459b52b83cbdc92b01c9c709c9cff26e345ef5cf27f92e"',
+ )
+
+ await disconnect(config, { connector })
+})
diff --git a/packages/react/src/experimental/hooks/useSendCalls.ts b/packages/react/src/experimental/hooks/useSendCalls.ts
new file mode 100644
index 0000000000..1953aea3cd
--- /dev/null
+++ b/packages/react/src/experimental/hooks/useSendCalls.ts
@@ -0,0 +1,76 @@
+'use client'
+
+import { useMutation } from '@tanstack/react-query'
+import type { Config, ResolvedRegister } from '@wagmi/core'
+import {
+ type SendCallsData,
+ type SendCallsErrorType,
+ type SendCallsMutate,
+ type SendCallsMutateAsync,
+ type SendCallsVariables,
+ sendCallsMutationOptions,
+} from '@wagmi/core/experimental'
+import type { Evaluate } from '@wagmi/core/internal'
+
+import { useConfig } from '../../hooks/useConfig.js'
+import type { ConfigParameter } from '../../types/properties.js'
+import type {
+ UseMutationParameters,
+ UseMutationReturnType,
+} from '../../utils/query.js'
+
+export type UseSendCallsParameters<
+ config extends Config = Config,
+ context = unknown,
+> = Evaluate<
+ ConfigParameter & {
+ mutation?:
+ | UseMutationParameters<
+ SendCallsData,
+ SendCallsErrorType,
+ SendCallsVariables,
+ context
+ >
+ | undefined
+ }
+>
+
+export type UseSendCallsReturnType<
+ config extends Config = Config,
+ context = unknown,
+> = Evaluate<
+ 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/packages/react/src/experimental/hooks/useShowCallsStatus.ts b/packages/react/src/experimental/hooks/useShowCallsStatus.ts
new file mode 100644
index 0000000000..774f3840bb
--- /dev/null
+++ b/packages/react/src/experimental/hooks/useShowCallsStatus.ts
@@ -0,0 +1,73 @@
+'use client'
+
+import { useMutation } from '@tanstack/react-query'
+import type { Config, ResolvedRegister } from '@wagmi/core'
+import {
+ type ShowCallsStatusData,
+ type ShowCallsStatusErrorType,
+ type ShowCallsStatusMutate,
+ type ShowCallsStatusMutateAsync,
+ type ShowCallsStatusVariables,
+ showCallsStatusMutationOptions,
+} from '@wagmi/core/experimental'
+import type { Evaluate } from '@wagmi/core/internal'
+
+import { useConfig } from '../../hooks/useConfig.js'
+import type { ConfigParameter } from '../../types/properties.js'
+import type {
+ UseMutationParameters,
+ UseMutationReturnType,
+} from '../../utils/query.js'
+
+export type UseShowCallsStatusParameters<
+ config extends Config = Config,
+ context = unknown,
+> = Evaluate<
+ ConfigParameter & {
+ mutation?:
+ | UseMutationParameters<
+ ShowCallsStatusData,
+ ShowCallsStatusErrorType,
+ ShowCallsStatusVariables,
+ context
+ >
+ | undefined
+ }
+>
+
+export type UseShowCallsStatusReturnType = Evaluate<
+ 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/packages/react/src/experimental/hooks/useWriteContracts.test.ts b/packages/react/src/experimental/hooks/useWriteContracts.test.ts
new file mode 100644
index 0000000000..1522bfb5cb
--- /dev/null
+++ b/packages/react/src/experimental/hooks/useWriteContracts.test.ts
@@ -0,0 +1,41 @@
+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(
+ '"0x8913636bd97cf4bcc0a6343c730905a27ead0f7480ff82190072e916439eb212"',
+ )
+
+ await disconnect(config, { connector })
+})
diff --git a/packages/react/src/experimental/hooks/useWriteContracts.ts b/packages/react/src/experimental/hooks/useWriteContracts.ts
new file mode 100644
index 0000000000..d64dc5875b
--- /dev/null
+++ b/packages/react/src/experimental/hooks/useWriteContracts.ts
@@ -0,0 +1,84 @@
+'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 { Evaluate } 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,
+> = Evaluate<
+ 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,
+> = Evaluate<
+ 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/packages/react/src/exports/experimental.ts b/packages/react/src/exports/experimental.ts
new file mode 100644
index 0000000000..2051235bcd
--- /dev/null
+++ b/packages/react/src/exports/experimental.ts
@@ -0,0 +1,33 @@
+////////////////////////////////////////////////////////////////////////////////
+// Hooks
+////////////////////////////////////////////////////////////////////////////////
+
+export {
+ type UseCallsStatusParameters,
+ type UseCallsStatusReturnType,
+ useCallsStatus,
+} from '../experimental/hooks/useCallsStatus.js'
+
+export {
+ type UseCapabilitiesParameters,
+ type UseCapabilitiesReturnType,
+ useCapabilities,
+} from '../experimental/hooks/useCapabilities.js'
+
+export {
+ type UseSendCallsParameters,
+ type UseSendCallsReturnType,
+ useSendCalls,
+} from '../experimental/hooks/useSendCalls.js'
+
+export {
+ type UseShowCallsStatusParameters,
+ type UseShowCallsStatusReturnType,
+ useShowCallsStatus,
+} from '../experimental/hooks/useShowCallsStatus.js'
+
+export {
+ type UseWriteContractsParameters,
+ type UseWriteContractsReturnType,
+ useWriteContracts,
+} from '../experimental/hooks/useWriteContracts.js'
diff --git a/packages/test/src/utils.ts b/packages/test/src/utils.ts
index 9b26c5750a..fe430fe911 100644
--- a/packages/test/src/utils.ts
+++ b/packages/test/src/utils.ts
@@ -1,4 +1,4 @@
-import { pool } from './constants.js'
+const pool = Number(process.env.VITEST_POOL_ID ?? 1)
export function getRpcUrls({ port }: { port: number }) {
return {
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 15a3e8d388..c8095ca1bb 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -63,8 +63,8 @@ importers:
specifier: 5.4.2
version: 5.4.2
viem:
- specifier: 2.8.4
- version: 2.8.4(typescript@5.4.2)
+ specifier: 2.9.31
+ version: 2.9.31(typescript@5.4.2)
vitest:
specifier: ^0.34.5
version: 0.34.5(@vitest/ui@0.34.5)(happy-dom@12.2.1)(jsdom@20.0.3)
@@ -11494,8 +11494,8 @@ packages:
- zod
dev: false
- /viem@2.8.4(typescript@5.4.2):
- resolution: {integrity: sha512-zBC8+YNKzo+XeUsCyXdrFzimH9Ei/nRfUKldPmVRoR/lR56/sqkDPyfCE1yvzwwmA9AJ9m9m2HtSPgl9NiTReA==}
+ /viem@2.9.31(typescript@5.4.2):
+ resolution: {integrity: sha512-8aJ8Dm/591Czwb/nRayo0z8Ls5KxqC4QYE33fmHwhx2tDUWC/hHcPZqjLRSTWFtAfi0aZKvP7BeB6UZ3ZkTRhQ==}
peerDependencies:
typescript: '>=5.0.4'
peerDependenciesMeta: