FRE-600: Fix code review blockers

- Consolidated duplicate UndoManagers to single instance
- Fixed connection promise to only resolve on 'connected' status
- Fixed WebSocketProvider import (WebsocketProvider)
- Added proper doc.destroy() cleanup
- Renamed isPresenceInitialized property to avoid conflict

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
2026-04-25 00:08:01 -04:00
parent 65b552bb08
commit 7c684a42cc
48450 changed files with 5679671 additions and 383 deletions

185
node_modules/viem/actions/ens/getEnsAddress.ts generated vendored Normal file
View File

@@ -0,0 +1,185 @@
import type { Address } from 'abitype'
import type { Client } from '../../clients/createClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import {
addressResolverAbi,
universalResolverResolveAbi,
} from '../../constants/abis.js'
import type { ErrorType } from '../../errors/utils.js'
import type { Chain } from '../../types/chain.js'
import type { Prettify } from '../../types/utils.js'
import {
type DecodeFunctionResultErrorType,
decodeFunctionResult,
} from '../../utils/abi/decodeFunctionResult.js'
import {
type EncodeFunctionDataErrorType,
encodeFunctionData,
} from '../../utils/abi/encodeFunctionData.js'
import {
type GetChainContractAddressErrorType,
getChainContractAddress,
} from '../../utils/chain/getChainContractAddress.js'
import { type TrimErrorType, trim } from '../../utils/data/trim.js'
import { type ToHexErrorType, toHex } from '../../utils/encoding/toHex.js'
import { isNullUniversalResolverError } from '../../utils/ens/errors.js'
import { localBatchGatewayUrl } from '../../utils/ens/localBatchGatewayRequest.js'
import { type NamehashErrorType, namehash } from '../../utils/ens/namehash.js'
import {
type PacketToBytesErrorType,
packetToBytes,
} from '../../utils/ens/packetToBytes.js'
import { getAction } from '../../utils/getAction.js'
import {
type ReadContractParameters,
readContract,
} from '../public/readContract.js'
export type GetEnsAddressParameters = Prettify<
Pick<ReadContractParameters, 'blockNumber' | 'blockTag'> & {
/**
* ENSIP-9 compliant coinType (chain) to get ENS address for.
*
* To get the `coinType` for a chain id, use the `toCoinType` function:
* ```ts
* import { toCoinType } from 'viem'
* import { base } from 'viem/chains'
*
* const coinType = toCoinType(base.id)
* ```
*
* @default 60n
*/
coinType?: bigint | undefined
/**
* Universal Resolver gateway URLs to use for resolving CCIP-read requests.
*/
gatewayUrls?: string[] | undefined
/**
* Name to get the address for.
*/
name: string
/**
* Whether or not to throw errors propagated from the ENS Universal Resolver Contract.
*/
strict?: boolean | undefined
/**
* Address of ENS Universal Resolver Contract.
*/
universalResolverAddress?: Address | undefined
}
>
export type GetEnsAddressReturnType = Address | null
export type GetEnsAddressErrorType =
| GetChainContractAddressErrorType
| EncodeFunctionDataErrorType
| NamehashErrorType
| ToHexErrorType
| PacketToBytesErrorType
| DecodeFunctionResultErrorType
| TrimErrorType
| ErrorType
/**
* Gets address for ENS name.
*
* - Docs: https://viem.sh/docs/ens/actions/getEnsAddress
* - Examples: https://stackblitz.com/github/wevm/viem/tree/main/examples/ens
*
* Calls `resolve(bytes, bytes)` on ENS Universal Resolver Contract.
*
* Since ENS names prohibit certain forbidden characters (e.g. underscore) and have other validation rules, you likely want to [normalize ENS names](https://docs.ens.domains/contract-api-reference/name-processing#normalising-names) with [UTS-46 normalization](https://unicode.org/reports/tr46) before passing them to `getEnsAddress`. You can use the built-in [`normalize`](https://viem.sh/docs/ens/utilities/normalize) function for this.
*
* @param client - Client to use
* @param parameters - {@link GetEnsAddressParameters}
* @returns Address for ENS name or `null` if not found. {@link GetEnsAddressReturnType}
*
* @example
* import { createPublicClient, http } from 'viem'
* import { mainnet } from 'viem/chains'
* import { getEnsAddress, normalize } from 'viem/ens'
*
* const client = createPublicClient({
* chain: mainnet,
* transport: http(),
* })
* const ensAddress = await getEnsAddress(client, {
* name: normalize('wevm.eth'),
* })
* // '0xd2135CfB216b74109775236E36d4b433F1DF507B'
*/
export async function getEnsAddress<chain extends Chain | undefined>(
client: Client<Transport, chain>,
parameters: GetEnsAddressParameters,
): Promise<GetEnsAddressReturnType> {
const { blockNumber, blockTag, coinType, name, gatewayUrls, strict } =
parameters
const { chain } = client
const universalResolverAddress = (() => {
if (parameters.universalResolverAddress)
return parameters.universalResolverAddress
if (!chain)
throw new Error(
'client chain not configured. universalResolverAddress is required.',
)
return getChainContractAddress({
blockNumber,
chain,
contract: 'ensUniversalResolver',
})
})()
const tlds = chain?.ensTlds
if (tlds && !tlds.some((tld) => name.endsWith(tld))) return null
const args = (() => {
if (coinType != null) return [namehash(name), BigInt(coinType)] as const
return [namehash(name)] as const
})()
try {
const functionData = encodeFunctionData({
abi: addressResolverAbi,
functionName: 'addr',
args,
})
const readContractParameters = {
address: universalResolverAddress,
abi: universalResolverResolveAbi,
functionName: 'resolveWithGateways',
args: [
toHex(packetToBytes(name)),
functionData,
gatewayUrls ?? [localBatchGatewayUrl],
],
blockNumber,
blockTag,
} as const
const readContractAction = getAction(client, readContract, 'readContract')
const res = await readContractAction(readContractParameters)
if (res[0] === '0x') return null
const address = decodeFunctionResult({
abi: addressResolverAbi,
args,
functionName: 'addr',
data: res[0],
})
if (address === '0x') return null
if (trim(address) === '0x00') return null
return address
} catch (err) {
if (strict) throw err
if (isNullUniversalResolverError(err)) return null
throw err
}
}

95
node_modules/viem/actions/ens/getEnsAvatar.ts generated vendored Normal file
View File

@@ -0,0 +1,95 @@
import type { Client } from '../../clients/createClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { ErrorType } from '../../errors/utils.js'
import type { Chain } from '../../types/chain.js'
import type { AssetGatewayUrls } from '../../types/ens.js'
import type { Prettify } from '../../types/utils.js'
import {
type ParseAvatarRecordErrorType,
parseAvatarRecord,
} from '../../utils/ens/avatar/parseAvatarRecord.js'
import { getAction } from '../../utils/getAction.js'
import {
type GetEnsTextErrorType,
type GetEnsTextParameters,
getEnsText,
} from './getEnsText.js'
export type GetEnsAvatarParameters = Prettify<
Omit<GetEnsTextParameters, 'key'> & {
/** Gateway urls to resolve IPFS and/or Arweave assets. */
assetGatewayUrls?: AssetGatewayUrls | undefined
}
>
export type GetEnsAvatarReturnType = string | null
export type GetEnsAvatarErrorType =
| GetEnsTextErrorType
| ParseAvatarRecordErrorType
| ErrorType
/**
* Gets the avatar of an ENS name.
*
* - Docs: https://viem.sh/docs/ens/actions/getEnsAvatar
* - Examples: https://stackblitz.com/github/wevm/viem/tree/main/examples/ens
*
* Calls [`getEnsText`](https://viem.sh/docs/ens/actions/getEnsText) with `key` set to `'avatar'`.
*
* Since ENS names prohibit certain forbidden characters (e.g. underscore) and have other validation rules, you likely want to [normalize ENS names](https://docs.ens.domains/contract-api-reference/name-processing#normalising-names) with [UTS-46 normalization](https://unicode.org/reports/tr46) before passing them to `getEnsAddress`. You can use the built-in [`normalize`](https://viem.sh/docs/ens/utilities/normalize) function for this.
*
* @param client - Client to use
* @param parameters - {@link GetEnsAvatarParameters}
* @returns Avatar URI or `null` if not found. {@link GetEnsAvatarReturnType}
*
* @example
* import { createPublicClient, http } from 'viem'
* import { mainnet } from 'viem/chains'
* import { getEnsAvatar, normalize } from 'viem/ens'
*
* const client = createPublicClient({
* chain: mainnet,
* transport: http(),
* })
* const ensAvatar = await getEnsAvatar(client, {
* name: normalize('wevm.eth'),
* })
* // 'https://ipfs.io/ipfs/Qma8mnp6xV3J2cRNf3mTth5C8nV11CAnceVinc3y8jSbio'
*/
export async function getEnsAvatar<chain extends Chain | undefined>(
client: Client<Transport, chain>,
{
blockNumber,
blockTag,
assetGatewayUrls,
name,
gatewayUrls,
strict,
universalResolverAddress,
}: GetEnsAvatarParameters,
): Promise<GetEnsAvatarReturnType> {
const record = await getAction(
client,
getEnsText,
'getEnsText',
)({
blockNumber,
blockTag,
key: 'avatar',
name,
universalResolverAddress,
gatewayUrls,
strict,
})
if (!record) return null
try {
return await parseAvatarRecord(client, {
record,
gatewayUrls: assetGatewayUrls,
})
} catch {
return null
}
}

140
node_modules/viem/actions/ens/getEnsName.ts generated vendored Normal file
View File

@@ -0,0 +1,140 @@
import type { Address } from 'abitype'
import type { Client } from '../../clients/createClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import { universalResolverReverseAbi } from '../../constants/abis.js'
import type { ErrorType } from '../../errors/utils.js'
import type { Chain } from '../../types/chain.js'
import type { Prettify } from '../../types/utils.js'
import {
type GetChainContractAddressErrorType,
getChainContractAddress,
} from '../../utils/chain/getChainContractAddress.js'
import { isNullUniversalResolverError } from '../../utils/ens/errors.js'
import { localBatchGatewayUrl } from '../../utils/ens/localBatchGatewayRequest.js'
import type { PacketToBytesErrorType } from '../../utils/ens/packetToBytes.js'
import { getAction } from '../../utils/getAction.js'
import {
type ReadContractErrorType,
type ReadContractParameters,
readContract,
} from '../public/readContract.js'
export type GetEnsNameParameters = Prettify<
Pick<ReadContractParameters, 'blockNumber' | 'blockTag'> & {
/**
* Address to get ENS name for.
*/
address: Address
/**
* ENSIP-9 compliant coinType (chain) to get ENS name for.
*
* To get the `coinType` for a chain id, use the `toCoinType` function:
* ```ts
* import { toCoinType } from 'viem'
* import { base } from 'viem/chains'
*
* const coinType = toCoinType(base.id)
* ```
*
* @default 60n
*/
coinType?: bigint | undefined
/**
* Universal Resolver gateway URLs to use for resolving CCIP-read requests.
*/
gatewayUrls?: string[] | undefined
/**
* Whether or not to throw errors propagated from the ENS Universal Resolver Contract.
*/
strict?: boolean | undefined
/**
* Address of ENS Universal Resolver Contract.
*/
universalResolverAddress?: Address | undefined
}
>
export type GetEnsNameReturnType = string | null
export type GetEnsNameErrorType =
| GetChainContractAddressErrorType
| ReadContractErrorType
| PacketToBytesErrorType
| ErrorType
/**
* Gets primary name for specified address.
*
* - Docs: https://viem.sh/docs/ens/actions/getEnsName
* - Examples: https://stackblitz.com/github/wevm/viem/tree/main/examples/ens
*
* Calls `reverse(bytes)` on ENS Universal Resolver Contract to "reverse resolve" the address to the primary ENS name.
*
* @param client - Client to use
* @param parameters - {@link GetEnsNameParameters}
* @returns Name or `null` if not found. {@link GetEnsNameReturnType}
*
* @example
* import { createPublicClient, http } from 'viem'
* import { mainnet } from 'viem/chains'
* import { getEnsName } from 'viem/ens'
*
* const client = createPublicClient({
* chain: mainnet,
* transport: http(),
* })
* const ensName = await getEnsName(client, {
* address: '0xd2135CfB216b74109775236E36d4b433F1DF507B',
* })
* // 'wevm.eth'
*/
export async function getEnsName<chain extends Chain | undefined>(
client: Client<Transport, chain>,
parameters: GetEnsNameParameters,
): Promise<GetEnsNameReturnType> {
const {
address,
blockNumber,
blockTag,
coinType = 60n,
gatewayUrls,
strict,
} = parameters
const { chain } = client
const universalResolverAddress = (() => {
if (parameters.universalResolverAddress)
return parameters.universalResolverAddress
if (!chain)
throw new Error(
'client chain not configured. universalResolverAddress is required.',
)
return getChainContractAddress({
blockNumber,
chain,
contract: 'ensUniversalResolver',
})
})()
try {
const readContractParameters = {
address: universalResolverAddress,
abi: universalResolverReverseAbi,
args: [address, coinType, gatewayUrls ?? [localBatchGatewayUrl]],
functionName: 'reverseWithGateways',
blockNumber,
blockTag,
} as const
const readContractAction = getAction(client, readContract, 'readContract')
const [name] = await readContractAction(readContractParameters)
return name || null
} catch (err) {
if (strict) throw err
if (isNullUniversalResolverError(err)) return null
throw err
}
}

120
node_modules/viem/actions/ens/getEnsResolver.ts generated vendored Normal file
View File

@@ -0,0 +1,120 @@
import type { Address } from 'abitype'
import type { Client } from '../../clients/createClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { ErrorType } from '../../errors/utils.js'
import type { Chain } from '../../types/chain.js'
import type { Prettify } from '../../types/utils.js'
import {
type GetChainContractAddressErrorType,
getChainContractAddress,
} from '../../utils/chain/getChainContractAddress.js'
import { type ToHexErrorType, toHex } from '../../utils/encoding/toHex.js'
import {
type PacketToBytesErrorType,
packetToBytes,
} from '../../utils/ens/packetToBytes.js'
import { getAction } from '../../utils/getAction.js'
import {
type ReadContractParameters,
readContract,
} from '../public/readContract.js'
export type GetEnsResolverParameters = Prettify<
Pick<ReadContractParameters, 'blockNumber' | 'blockTag'> & {
/** Name to get the address for. */
name: string
/** Address of ENS Universal Resolver Contract. */
universalResolverAddress?: Address | undefined
}
>
export type GetEnsResolverReturnType = Address
export type GetEnsResolverErrorType =
| GetChainContractAddressErrorType
| ToHexErrorType
| PacketToBytesErrorType
| ErrorType
/**
* Gets resolver for ENS name.
*
* - Docs: https://viem.sh/docs/ens/actions/getEnsResolver
* - Examples: https://stackblitz.com/github/wevm/viem/tree/main/examples/ens
*
* Calls `findResolver(bytes)` on ENS Universal Resolver Contract to retrieve the resolver of an ENS name.
*
* Since ENS names prohibit certain forbidden characters (e.g. underscore) and have other validation rules, you likely want to [normalize ENS names](https://docs.ens.domains/contract-api-reference/name-processing#normalising-names) with [UTS-46 normalization](https://unicode.org/reports/tr46) before passing them to `getEnsAddress`. You can use the built-in [`normalize`](https://viem.sh/docs/ens/utilities/normalize) function for this.
*
* @param client - Client to use
* @param parameters - {@link GetEnsResolverParameters}
* @returns Address for ENS resolver. {@link GetEnsResolverReturnType}
*
* @example
* import { createPublicClient, http } from 'viem'
* import { mainnet } from 'viem/chains'
* import { getEnsResolver, normalize } from 'viem/ens'
*
* const client = createPublicClient({
* chain: mainnet,
* transport: http(),
* })
* const resolverAddress = await getEnsResolver(client, {
* name: normalize('wevm.eth'),
* })
* // '0x4976fb03C32e5B8cfe2b6cCB31c09Ba78EBaBa41'
*/
export async function getEnsResolver<chain extends Chain | undefined>(
client: Client<Transport, chain>,
parameters: GetEnsResolverParameters,
): Promise<GetEnsResolverReturnType> {
const { blockNumber, blockTag, name } = parameters
const { chain } = client
const universalResolverAddress = (() => {
if (parameters.universalResolverAddress)
return parameters.universalResolverAddress
if (!chain)
throw new Error(
'client chain not configured. universalResolverAddress is required.',
)
return getChainContractAddress({
blockNumber,
chain,
contract: 'ensUniversalResolver',
})
})()
const tlds = chain?.ensTlds
if (tlds && !tlds.some((tld) => name.endsWith(tld)))
throw new Error(
`${name} is not a valid ENS TLD (${tlds?.join(', ')}) for chain "${chain.name}" (id: ${chain.id}).`,
)
const [resolverAddress] = await getAction(
client,
readContract,
'readContract',
)({
address: universalResolverAddress,
abi: [
{
inputs: [{ type: 'bytes' }],
name: 'findResolver',
outputs: [
{ type: 'address' },
{ type: 'bytes32' },
{ type: 'uint256' },
],
stateMutability: 'view',
type: 'function',
},
],
functionName: 'findResolver',
args: [toHex(packetToBytes(name))],
blockNumber,
blockTag,
})
return resolverAddress
}

153
node_modules/viem/actions/ens/getEnsText.ts generated vendored Normal file
View File

@@ -0,0 +1,153 @@
import type { Address } from 'abitype'
import type { Client } from '../../clients/createClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import {
textResolverAbi,
universalResolverResolveAbi,
} from '../../constants/abis.js'
import type { Chain } from '../../types/chain.js'
import type { Prettify } from '../../types/utils.js'
import {
type DecodeFunctionResultErrorType,
decodeFunctionResult,
} from '../../utils/abi/decodeFunctionResult.js'
import {
type EncodeFunctionDataErrorType,
encodeFunctionData,
} from '../../utils/abi/encodeFunctionData.js'
import {
type GetChainContractAddressErrorType,
getChainContractAddress,
} from '../../utils/chain/getChainContractAddress.js'
import { type ToHexErrorType, toHex } from '../../utils/encoding/toHex.js'
import { isNullUniversalResolverError } from '../../utils/ens/errors.js'
import { localBatchGatewayUrl } from '../../utils/ens/localBatchGatewayRequest.js'
import { type NamehashErrorType, namehash } from '../../utils/ens/namehash.js'
import {
type PacketToBytesErrorType,
packetToBytes,
} from '../../utils/ens/packetToBytes.js'
import { getAction } from '../../utils/getAction.js'
import {
type ReadContractErrorType,
type ReadContractParameters,
readContract,
} from '../public/readContract.js'
export type GetEnsTextParameters = Prettify<
Pick<ReadContractParameters, 'blockNumber' | 'blockTag'> & {
/** ENS name to get Text for. */
name: string
/** Universal Resolver gateway URLs to use for resolving CCIP-read requests. */
gatewayUrls?: string[] | undefined
/** Text record to retrieve. */
key: string
/** Whether or not to throw errors propagated from the ENS Universal Resolver Contract. */
strict?: boolean | undefined
/** Address of ENS Universal Resolver Contract. */
universalResolverAddress?: Address | undefined
}
>
export type GetEnsTextReturnType = string | null
export type GetEnsTextErrorType =
| GetChainContractAddressErrorType
| ReadContractErrorType
| ToHexErrorType
| PacketToBytesErrorType
| EncodeFunctionDataErrorType
| NamehashErrorType
| DecodeFunctionResultErrorType
/**
* Gets a text record for specified ENS name.
*
* - Docs: https://viem.sh/docs/ens/actions/getEnsResolver
* - Examples: https://stackblitz.com/github/wevm/viem/tree/main/examples/ens
*
* Calls `resolve(bytes, bytes)` on ENS Universal Resolver Contract.
*
* Since ENS names prohibit certain forbidden characters (e.g. underscore) and have other validation rules, you likely want to [normalize ENS names](https://docs.ens.domains/contract-api-reference/name-processing#normalising-names) with [UTS-46 normalization](https://unicode.org/reports/tr46) before passing them to `getEnsAddress`. You can use the built-in [`normalize`](https://viem.sh/docs/ens/utilities/normalize) function for this.
*
* @param client - Client to use
* @param parameters - {@link GetEnsTextParameters}
* @returns Address for ENS resolver. {@link GetEnsTextReturnType}
*
* @example
* import { createPublicClient, http } from 'viem'
* import { mainnet } from 'viem/chains'
* import { getEnsText, normalize } from 'viem/ens'
*
* const client = createPublicClient({
* chain: mainnet,
* transport: http(),
* })
* const twitterRecord = await getEnsText(client, {
* name: normalize('wevm.eth'),
* key: 'com.twitter',
* })
* // 'wevm_dev'
*/
export async function getEnsText<chain extends Chain | undefined>(
client: Client<Transport, chain>,
parameters: GetEnsTextParameters,
): Promise<GetEnsTextReturnType> {
const { blockNumber, blockTag, key, name, gatewayUrls, strict } = parameters
const { chain } = client
const universalResolverAddress = (() => {
if (parameters.universalResolverAddress)
return parameters.universalResolverAddress
if (!chain)
throw new Error(
'client chain not configured. universalResolverAddress is required.',
)
return getChainContractAddress({
blockNumber,
chain,
contract: 'ensUniversalResolver',
})
})()
const tlds = chain?.ensTlds
if (tlds && !tlds.some((tld) => name.endsWith(tld))) return null
try {
const readContractParameters = {
address: universalResolverAddress,
abi: universalResolverResolveAbi,
args: [
toHex(packetToBytes(name)),
encodeFunctionData({
abi: textResolverAbi,
functionName: 'text',
args: [namehash(name), key],
}),
gatewayUrls ?? [localBatchGatewayUrl],
],
functionName: 'resolveWithGateways',
blockNumber,
blockTag,
} as const
const readContractAction = getAction(client, readContract, 'readContract')
const res = await readContractAction(readContractParameters)
if (res[0] === '0x') return null
const record = decodeFunctionResult({
abi: textResolverAbi,
functionName: 'text',
data: res[0],
})
return record === '' ? null : record
} catch (err) {
if (strict) throw err
if (isNullUniversalResolverError(err)) return null
throw err
}
}

1172
node_modules/viem/actions/getContract.ts generated vendored Normal file

File diff suppressed because it is too large Load Diff

623
node_modules/viem/actions/index.ts generated vendored Normal file
View File

@@ -0,0 +1,623 @@
// biome-ignore lint/performance/noBarrelFile: entrypoint module
export {
type GetEnsAddressErrorType,
type GetEnsAddressParameters,
type GetEnsAddressReturnType,
getEnsAddress,
} from './ens/getEnsAddress.js'
export {
type GetEnsAvatarErrorType,
type GetEnsAvatarParameters,
type GetEnsAvatarReturnType,
getEnsAvatar,
} from './ens/getEnsAvatar.js'
export {
type GetEnsNameErrorType,
type GetEnsNameParameters,
type GetEnsNameReturnType,
getEnsName,
} from './ens/getEnsName.js'
export {
type GetEnsResolverErrorType,
type GetEnsResolverParameters,
type GetEnsResolverReturnType,
getEnsResolver,
} from './ens/getEnsResolver.js'
export {
type GetEnsTextErrorType,
type GetEnsTextParameters,
type GetEnsTextReturnType,
getEnsText,
} from './ens/getEnsText.js'
export {
type CallErrorType,
type CallParameters,
type CallReturnType,
call,
} from './public/call.js'
export {
type CreateAccessListErrorType,
type CreateAccessListParameters,
type CreateAccessListReturnType,
createAccessList,
} from './public/createAccessList.js'
export {
type CreateBlockFilterErrorType,
type CreateBlockFilterReturnType,
createBlockFilter,
} from './public/createBlockFilter.js'
export {
type CreateContractEventFilterErrorType,
type CreateContractEventFilterParameters,
type CreateContractEventFilterReturnType,
createContractEventFilter,
} from './public/createContractEventFilter.js'
export {
type CreateEventFilterErrorType,
type CreateEventFilterParameters,
type CreateEventFilterReturnType,
createEventFilter,
} from './public/createEventFilter.js'
export {
type CreatePendingTransactionFilterErrorType,
type CreatePendingTransactionFilterReturnType,
createPendingTransactionFilter,
} from './public/createPendingTransactionFilter.js'
export {
type EstimateContractGasErrorType,
type EstimateContractGasParameters,
type EstimateContractGasReturnType,
estimateContractGas,
} from './public/estimateContractGas.js'
export {
type EstimateFeesPerGasErrorType,
type EstimateFeesPerGasParameters,
type EstimateFeesPerGasReturnType,
estimateFeesPerGas,
} from './public/estimateFeesPerGas.js'
export {
type EstimateGasErrorType,
type EstimateGasParameters,
type EstimateGasReturnType,
estimateGas,
} from './public/estimateGas.js'
export {
type EstimateMaxPriorityFeePerGasErrorType,
type EstimateMaxPriorityFeePerGasParameters,
type EstimateMaxPriorityFeePerGasReturnType,
estimateMaxPriorityFeePerGas,
} from './public/estimateMaxPriorityFeePerGas.js'
export {
type FillTransactionErrorType,
type FillTransactionParameters,
type FillTransactionReturnType,
fillTransaction,
} from './public/fillTransaction.js'
export {
type GetBalanceErrorType,
type GetBalanceParameters,
type GetBalanceReturnType,
getBalance,
} from './public/getBalance.js'
export {
type GetBlobBaseFeeErrorType,
type GetBlobBaseFeeReturnType,
getBlobBaseFee,
} from './public/getBlobBaseFee.js'
export {
type GetBlockErrorType,
type GetBlockParameters,
type GetBlockReturnType,
getBlock,
} from './public/getBlock.js'
export {
type GetBlockNumberErrorType,
type GetBlockNumberParameters,
type GetBlockNumberReturnType,
getBlockNumber,
} from './public/getBlockNumber.js'
export {
type GetBlockTransactionCountErrorType,
type GetBlockTransactionCountParameters,
type GetBlockTransactionCountReturnType,
getBlockTransactionCount,
} from './public/getBlockTransactionCount.js'
export {
type GetChainIdErrorType,
type GetChainIdReturnType,
getChainId,
} from './public/getChainId.js'
export {
/** @deprecated Use `GetCodeErrorType` instead */
type GetCodeErrorType as GetBytecodeErrorType,
type GetCodeErrorType,
/** @deprecated Use `GetCodeParameters` instead */
type GetCodeParameters as GetBytecodeParameters,
type GetCodeParameters,
/** @deprecated Use `GetCodeReturnType` instead */
type GetCodeReturnType as GetBytecodeReturnType,
type GetCodeReturnType,
/** @deprecated Use `getCode` instead */
getCode as getBytecode,
getCode,
} from './public/getCode.js'
export {
type GetContractEventsErrorType,
type GetContractEventsParameters,
type GetContractEventsReturnType,
getContractEvents,
} from './public/getContractEvents.js'
export {
type GetDelegationErrorType,
type GetDelegationParameters,
type GetDelegationReturnType,
getDelegation,
} from './public/getDelegation.js'
export {
type GetEip712DomainErrorType,
type GetEip712DomainParameters,
type GetEip712DomainReturnType,
getEip712Domain,
} from './public/getEip712Domain.js'
export {
type GetFeeHistoryErrorType,
type GetFeeHistoryParameters,
type GetFeeHistoryReturnType,
getFeeHistory,
} from './public/getFeeHistory.js'
export {
type GetFilterChangesErrorType,
type GetFilterChangesParameters,
type GetFilterChangesReturnType,
getFilterChanges,
} from './public/getFilterChanges.js'
export {
type GetFilterLogsErrorType,
type GetFilterLogsParameters,
type GetFilterLogsReturnType,
getFilterLogs,
} from './public/getFilterLogs.js'
export {
type GetGasPriceErrorType,
type GetGasPriceReturnType,
getGasPrice,
} from './public/getGasPrice.js'
export {
type GetLogsErrorType,
type GetLogsParameters,
type GetLogsReturnType,
getLogs,
} from './public/getLogs.js'
export {
type GetProofErrorType,
type GetProofParameters,
type GetProofReturnType,
getProof,
} from './public/getProof.js'
export {
type GetStorageAtErrorType,
type GetStorageAtParameters,
type GetStorageAtReturnType,
getStorageAt,
} from './public/getStorageAt.js'
export {
type GetTransactionErrorType,
type GetTransactionParameters,
type GetTransactionReturnType,
getTransaction,
} from './public/getTransaction.js'
export {
type GetTransactionConfirmationsErrorType,
type GetTransactionConfirmationsParameters,
type GetTransactionConfirmationsReturnType,
getTransactionConfirmations,
} from './public/getTransactionConfirmations.js'
export {
type GetTransactionCountErrorType,
type GetTransactionCountParameters,
type GetTransactionCountReturnType,
getTransactionCount,
} from './public/getTransactionCount.js'
export {
type GetTransactionReceiptErrorType,
type GetTransactionReceiptParameters,
type GetTransactionReceiptReturnType,
getTransactionReceipt,
} from './public/getTransactionReceipt.js'
export {
type MulticallErrorType,
type MulticallParameters,
type MulticallReturnType,
multicall,
} from './public/multicall.js'
export {
type ReadContractErrorType,
type ReadContractParameters,
type ReadContractReturnType,
readContract,
} from './public/readContract.js'
export {
type SimulateBlocksErrorType,
/** @deprecated Use `SimulateBlocksErrorType` instead */
type SimulateBlocksErrorType as SimulateErrorType,
type SimulateBlocksParameters,
/** @deprecated Use `SimulateBlocksParameters` instead */
type SimulateBlocksParameters as SimulateParameters,
type SimulateBlocksReturnType,
/** @deprecated Use `SimulateBlocksReturnType` instead */
type SimulateBlocksReturnType as SimulateReturnType,
simulateBlocks,
/** @deprecated Use `simulateBlocks` instead */
simulateBlocks as simulate,
} from './public/simulateBlocks.js'
export {
type SimulateCallsErrorType,
type SimulateCallsParameters,
type SimulateCallsReturnType,
simulateCalls,
} from './public/simulateCalls.js'
export {
type SimulateContractErrorType,
type SimulateContractParameters,
type SimulateContractReturnType,
simulateContract,
} from './public/simulateContract.js'
export {
type UninstallFilterErrorType,
type UninstallFilterParameters,
type UninstallFilterReturnType,
uninstallFilter,
} from './public/uninstallFilter.js'
export {
type VerifyHashErrorType,
type VerifyHashParameters,
type VerifyHashReturnType,
verifyHash,
} from './public/verifyHash.js'
export {
type VerifyMessageErrorType,
type VerifyMessageParameters,
type VerifyMessageReturnType,
verifyMessage,
} from './public/verifyMessage.js'
export {
type VerifyTypedDataErrorType,
type VerifyTypedDataParameters,
type VerifyTypedDataReturnType,
verifyTypedData,
} from './public/verifyTypedData.js'
export {
type ReplacementReason,
type ReplacementReturnType,
type WaitForTransactionReceiptErrorType,
type WaitForTransactionReceiptParameters,
type WaitForTransactionReceiptReturnType,
waitForTransactionReceipt,
} from './public/waitForTransactionReceipt.js'
export {
type OnBlockNumberFn,
type OnBlockNumberParameter,
type WatchBlockNumberErrorType,
type WatchBlockNumberParameters,
type WatchBlockNumberReturnType,
watchBlockNumber,
} from './public/watchBlockNumber.js'
export {
type OnBlock,
type OnBlockParameter,
type WatchBlocksErrorType,
type WatchBlocksParameters,
type WatchBlocksReturnType,
watchBlocks,
} from './public/watchBlocks.js'
export {
type WatchContractEventErrorType,
type WatchContractEventParameters,
type WatchContractEventReturnType,
watchContractEvent,
} from './public/watchContractEvent.js'
export {
type WatchEventOnLogsFn,
type WatchEventOnLogsParameter,
type WatchEventParameters,
type WatchEventReturnType,
watchEvent,
} from './public/watchEvent.js'
export {
type OnTransactionsFn,
type OnTransactionsParameter,
type WatchPendingTransactionsErrorType,
type WatchPendingTransactionsParameters,
type WatchPendingTransactionsReturnType,
watchPendingTransactions,
} from './public/watchPendingTransactions.js'
export {
type DropTransactionParameters,
dropTransaction,
} from './test/dropTransaction.js'
export {
type DumpStateErrorType,
type DumpStateReturnType,
dumpState,
} from './test/dumpState.js'
export {
type GetAutomineErrorType,
type GetAutomineReturnType,
getAutomine,
} from './test/getAutomine.js'
export {
type GetTxpoolContentErrorType,
type GetTxpoolContentReturnType,
getTxpoolContent,
} from './test/getTxpoolContent.js'
export {
type GetTxpoolStatusErrorType,
type GetTxpoolStatusReturnType,
getTxpoolStatus,
} from './test/getTxpoolStatus.js'
export {
type ImpersonateAccountErrorType,
type ImpersonateAccountParameters,
impersonateAccount,
} from './test/impersonateAccount.js'
export {
type IncreaseTimeErrorType,
type IncreaseTimeParameters,
increaseTime,
} from './test/increaseTime.js'
export {
type InspectTxpoolErrorType,
type InspectTxpoolReturnType,
inspectTxpool,
} from './test/inspectTxpool.js'
export {
type LoadStateErrorType,
type LoadStateParameters,
type LoadStateReturnType,
loadState,
} from './test/loadState.js'
export {
type MineErrorType,
type MineParameters,
mine,
} from './test/mine.js'
export {
type RemoveBlockTimestampIntervalErrorType,
removeBlockTimestampInterval,
} from './test/removeBlockTimestampInterval.js'
export {
type ResetErrorType,
type ResetParameters,
reset,
} from './test/reset.js'
export {
type RevertErrorType,
type RevertParameters,
revert,
} from './test/revert.js'
export {
type SendUnsignedTransactionErrorType,
type SendUnsignedTransactionParameters,
type SendUnsignedTransactionReturnType,
sendUnsignedTransaction,
} from './test/sendUnsignedTransaction.js'
export { type SetAutomineErrorType, setAutomine } from './test/setAutomine.js'
export {
type SetBalanceErrorType,
type SetBalanceParameters,
setBalance,
} from './test/setBalance.js'
export {
type SetBlockGasLimitErrorType,
type SetBlockGasLimitParameters,
setBlockGasLimit,
} from './test/setBlockGasLimit.js'
export {
type SetBlockTimestampIntervalErrorType,
type SetBlockTimestampIntervalParameters,
setBlockTimestampInterval,
} from './test/setBlockTimestampInterval.js'
export {
type SetCodeErrorType,
type SetCodeParameters,
setCode,
} from './test/setCode.js'
export {
type SetCoinbaseErrorType,
type SetCoinbaseParameters,
setCoinbase,
} from './test/setCoinbase.js'
export {
type SetIntervalMiningErrorType,
type SetIntervalMiningParameters,
setIntervalMining,
} from './test/setIntervalMining.js'
export {
type SetLoggingEnabledErrorType,
setLoggingEnabled,
} from './test/setLoggingEnabled.js'
export {
type SetMinGasPriceErrorType,
type SetMinGasPriceParameters,
setMinGasPrice,
} from './test/setMinGasPrice.js'
export {
type SetNextBlockBaseFeePerGasErrorType,
type SetNextBlockBaseFeePerGasParameters,
setNextBlockBaseFeePerGas,
} from './test/setNextBlockBaseFeePerGas.js'
export {
type SetNextBlockTimestampErrorType,
type SetNextBlockTimestampParameters,
setNextBlockTimestamp,
} from './test/setNextBlockTimestamp.js'
export {
type SetNonceErrorType,
type SetNonceParameters,
setNonce,
} from './test/setNonce.js'
export { type SetRpcUrlErrorType, setRpcUrl } from './test/setRpcUrl.js'
export {
type SetStorageAtErrorType,
type SetStorageAtParameters,
setStorageAt,
} from './test/setStorageAt.js'
export { type SnapshotErrorType, snapshot } from './test/snapshot.js'
export {
type StopImpersonatingAccountErrorType,
type StopImpersonatingAccountParameters,
stopImpersonatingAccount,
} from './test/stopImpersonatingAccount.js'
export {
type AddChainErrorType,
type AddChainParameters,
addChain,
} from './wallet/addChain.js'
export {
type DeployContractErrorType,
type DeployContractParameters,
type DeployContractReturnType,
deployContract,
} from './wallet/deployContract.js'
export {
type GetAddressesErrorType,
type GetAddressesReturnType,
getAddresses,
} from './wallet/getAddresses.js'
export {
type GetCallsStatusErrorType,
type GetCallsStatusParameters,
type GetCallsStatusReturnType,
getCallsStatus,
} from './wallet/getCallsStatus.js'
export {
type GetCapabilitiesErrorType,
type GetCapabilitiesParameters,
type GetCapabilitiesReturnType,
getCapabilities,
} from './wallet/getCapabilities.js'
export {
type GetPermissionsErrorType,
type GetPermissionsReturnType,
getPermissions,
} from './wallet/getPermissions.js'
export {
type PrepareAuthorizationErrorType,
type PrepareAuthorizationParameters,
type PrepareAuthorizationReturnType,
prepareAuthorization,
} from './wallet/prepareAuthorization.js'
export {
defaultParameters as defaultPrepareTransactionRequestParameters,
type PrepareTransactionRequestErrorType,
type PrepareTransactionRequestParameters,
type PrepareTransactionRequestReturnType,
prepareTransactionRequest,
} from './wallet/prepareTransactionRequest.js'
export {
type RequestAddressesErrorType,
type RequestAddressesReturnType,
requestAddresses,
} from './wallet/requestAddresses.js'
export {
type RequestPermissionsErrorType,
type RequestPermissionsParameters,
type RequestPermissionsReturnType,
requestPermissions,
} from './wallet/requestPermissions.js'
export {
type SendCallsErrorType,
type SendCallsParameters,
type SendCallsReturnType,
sendCalls,
} from './wallet/sendCalls.js'
export {
type SendCallsSyncErrorType,
type SendCallsSyncParameters,
type SendCallsSyncReturnType,
sendCallsSync,
} from './wallet/sendCallsSync.js'
export {
type SendRawTransactionErrorType,
type SendRawTransactionParameters,
type SendRawTransactionReturnType,
sendRawTransaction,
} from './wallet/sendRawTransaction.js'
export {
type SendRawTransactionSyncErrorType,
type SendRawTransactionSyncParameters,
type SendRawTransactionSyncReturnType,
sendRawTransactionSync,
} from './wallet/sendRawTransactionSync.js'
export {
type SendTransactionErrorType,
type SendTransactionParameters,
type SendTransactionReturnType,
sendTransaction,
} from './wallet/sendTransaction.js'
export {
type SendTransactionSyncErrorType,
type SendTransactionSyncParameters,
type SendTransactionSyncReturnType,
sendTransactionSync,
} from './wallet/sendTransactionSync.js'
export {
type ShowCallsStatusErrorType,
type ShowCallsStatusParameters,
type ShowCallsStatusReturnType,
showCallsStatus,
} from './wallet/showCallsStatus.js'
export {
type SignAuthorizationErrorType,
type SignAuthorizationParameters,
type SignAuthorizationReturnType,
signAuthorization,
} from './wallet/signAuthorization.js'
export {
type SignMessageErrorType,
type SignMessageParameters,
type SignMessageReturnType,
signMessage,
} from './wallet/signMessage.js'
export {
type SignTransactionErrorType,
type SignTransactionParameters,
type SignTransactionReturnType,
signTransaction,
} from './wallet/signTransaction.js'
export {
type SignTypedDataErrorType,
type SignTypedDataParameters,
type SignTypedDataReturnType,
signTypedData,
} from './wallet/signTypedData.js'
export {
type SwitchChainErrorType,
type SwitchChainParameters,
switchChain,
} from './wallet/switchChain.js'
export {
type WaitForCallsStatusErrorType,
type WaitForCallsStatusParameters,
type WaitForCallsStatusReturnType,
type WaitForCallsStatusTimeoutErrorType,
waitForCallsStatus,
} from './wallet/waitForCallsStatus.js'
export {
type WatchAssetErrorType,
type WatchAssetParameters,
type WatchAssetReturnType,
watchAsset,
} from './wallet/watchAsset.js'
export {
type WriteContractErrorType,
type WriteContractParameters,
type WriteContractReturnType,
writeContract,
} from './wallet/writeContract.js'
export {
type WriteContractSyncErrorType,
type WriteContractSyncParameters,
type WriteContractSyncReturnType,
writeContractSync,
} from './wallet/writeContractSync.js'

6
node_modules/viem/actions/package.json generated vendored Normal file
View File

@@ -0,0 +1,6 @@
{
"type": "module",
"types": "../_types/actions/index.d.ts",
"module": "../_esm/actions/index.js",
"main": "../_cjs/actions/index.js"
}

480
node_modules/viem/actions/public/call.ts generated vendored Normal file
View File

@@ -0,0 +1,480 @@
import { type Address, parseAbi } from 'abitype'
import * as BlockOverrides from 'ox/BlockOverrides'
import type { Account } from '../../accounts/types.js'
import {
type ParseAccountErrorType,
parseAccount,
} from '../../accounts/utils/parseAccount.js'
import type { Client } from '../../clients/createClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import { multicall3Abi } from '../../constants/abis.js'
import { aggregate3Signature } from '../../constants/contract.js'
import {
deploylessCallViaBytecodeBytecode,
deploylessCallViaFactoryBytecode,
multicall3Bytecode,
} from '../../constants/contracts.js'
import { BaseError } from '../../errors/base.js'
import {
ChainDoesNotSupportContract,
ClientChainNotConfiguredError,
} from '../../errors/chain.js'
import {
CounterfactualDeploymentFailedError,
RawContractError,
type RawContractErrorType,
} from '../../errors/contract.js'
import type { ErrorType } from '../../errors/utils.js'
import type { BlockTag } from '../../types/block.js'
import type { Chain } from '../../types/chain.js'
import type { Hex } from '../../types/misc.js'
import type { RpcTransactionRequest } from '../../types/rpc.js'
import type { StateOverride } from '../../types/stateOverride.js'
import type { TransactionRequest } from '../../types/transaction.js'
import type { ExactPartial, UnionOmit } from '../../types/utils.js'
import {
type DecodeFunctionResultErrorType,
decodeFunctionResult,
} from '../../utils/abi/decodeFunctionResult.js'
import {
type EncodeDeployDataErrorType,
encodeDeployData,
} from '../../utils/abi/encodeDeployData.js'
import {
type EncodeFunctionDataErrorType,
encodeFunctionData,
} from '../../utils/abi/encodeFunctionData.js'
import type { RequestErrorType } from '../../utils/buildRequest.js'
import {
type GetChainContractAddressErrorType,
getChainContractAddress,
} from '../../utils/chain/getChainContractAddress.js'
import {
type NumberToHexErrorType,
numberToHex,
} from '../../utils/encoding/toHex.js'
import {
type GetCallErrorReturnType,
getCallError,
} from '../../utils/errors/getCallError.js'
import { extract } from '../../utils/formatters/extract.js'
import {
type FormatTransactionRequestErrorType,
type FormattedTransactionRequest,
formatTransactionRequest,
} from '../../utils/formatters/transactionRequest.js'
import {
type CreateBatchSchedulerErrorType,
createBatchScheduler,
} from '../../utils/promise/createBatchScheduler.js'
import {
type SerializeStateOverrideErrorType,
serializeStateOverride,
} from '../../utils/stateOverride.js'
import type {
AssertRequestErrorType,
AssertRequestParameters,
} from '../../utils/transaction/assertRequest.js'
import { assertRequest } from '../../utils/transaction/assertRequest.js'
export type CallParameters<
chain extends Chain | undefined = Chain | undefined,
> = UnionOmit<FormattedCall<chain>, 'from'> & {
/** Account attached to the call (msg.sender). */
account?: Account | Address | undefined
/** Whether or not to enable multicall batching on this call. */
batch?: boolean | undefined
/** Block overrides for the call. */
blockOverrides?: BlockOverrides.BlockOverrides | undefined
/** Bytecode to perform the call on. */
code?: Hex | undefined
/** Contract deployment factory address (ie. Create2 factory, Smart Account factory, etc). */
factory?: Address | undefined
/** Calldata to execute on the factory to deploy the contract. */
factoryData?: Hex | undefined
/** State overrides for the call. */
stateOverride?: StateOverride | undefined
} & (
| {
/** The balance of the account at a block number. */
blockNumber?: bigint | undefined
blockTag?: undefined
}
| {
blockNumber?: undefined
/**
* The balance of the account at a block tag.
* @default 'latest'
*/
blockTag?: BlockTag | undefined
}
)
type FormattedCall<chain extends Chain | undefined = Chain | undefined> =
FormattedTransactionRequest<chain>
export type CallReturnType = { data: Hex | undefined }
export type CallErrorType = GetCallErrorReturnType<
| ParseAccountErrorType
| SerializeStateOverrideErrorType
| AssertRequestErrorType
| NumberToHexErrorType
| FormatTransactionRequestErrorType
| ScheduleMulticallErrorType
| RequestErrorType
| ToDeploylessCallViaBytecodeDataErrorType
| ToDeploylessCallViaFactoryDataErrorType
>
/**
* Executes a new message call immediately without submitting a transaction to the network.
*
* - Docs: https://viem.sh/docs/actions/public/call
* - JSON-RPC Methods: [`eth_call`](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_call)
*
* @param client - Client to use
* @param parameters - {@link CallParameters}
* @returns The call data. {@link CallReturnType}
*
* @example
* import { createPublicClient, http } from 'viem'
* import { mainnet } from 'viem/chains'
* import { call } from 'viem/public'
*
* const client = createPublicClient({
* chain: mainnet,
* transport: http(),
* })
* const data = await call(client, {
* account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266',
* data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
* to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
* })
*/
export async function call<chain extends Chain | undefined>(
client: Client<Transport, chain>,
args: CallParameters<chain>,
): Promise<CallReturnType> {
const {
account: account_ = client.account,
authorizationList,
batch = Boolean(client.batch?.multicall),
blockNumber,
blockTag = client.experimental_blockTag ?? 'latest',
accessList,
blobs,
blockOverrides,
code,
data: data_,
factory,
factoryData,
gas,
gasPrice,
maxFeePerBlobGas,
maxFeePerGas,
maxPriorityFeePerGas,
nonce,
to,
value,
stateOverride,
...rest
} = args
const account = account_ ? parseAccount(account_) : undefined
if (code && (factory || factoryData))
throw new BaseError(
'Cannot provide both `code` & `factory`/`factoryData` as parameters.',
)
if (code && to)
throw new BaseError('Cannot provide both `code` & `to` as parameters.')
// Check if the call is deployless via bytecode.
const deploylessCallViaBytecode = code && data_
// Check if the call is deployless via a factory.
const deploylessCallViaFactory = factory && factoryData && to && data_
const deploylessCall = deploylessCallViaBytecode || deploylessCallViaFactory
const data = (() => {
if (deploylessCallViaBytecode)
return toDeploylessCallViaBytecodeData({
code,
data: data_,
})
if (deploylessCallViaFactory)
return toDeploylessCallViaFactoryData({
data: data_,
factory,
factoryData,
to,
})
return data_
})()
try {
assertRequest(args as AssertRequestParameters)
const blockNumberHex =
typeof blockNumber === 'bigint' ? numberToHex(blockNumber) : undefined
const block = blockNumberHex || blockTag
const rpcBlockOverrides = blockOverrides
? BlockOverrides.toRpc(blockOverrides)
: undefined
const rpcStateOverride = serializeStateOverride(stateOverride)
const chainFormat = client.chain?.formatters?.transactionRequest?.format
const format = chainFormat || formatTransactionRequest
const request = format(
{
// Pick out extra data that might exist on the chain's transaction request type.
...extract(rest, { format: chainFormat }),
accessList,
account,
authorizationList,
blobs,
data,
gas,
gasPrice,
maxFeePerBlobGas,
maxFeePerGas,
maxPriorityFeePerGas,
nonce,
to: deploylessCall ? undefined : to,
value,
} as TransactionRequest,
'call',
) as TransactionRequest
if (
batch &&
shouldPerformMulticall({ request }) &&
!rpcStateOverride &&
!rpcBlockOverrides
) {
try {
return await scheduleMulticall(client, {
...request,
blockNumber,
blockTag,
} as unknown as ScheduleMulticallParameters<chain>)
} catch (err) {
if (
!(err instanceof ClientChainNotConfiguredError) &&
!(err instanceof ChainDoesNotSupportContract)
)
throw err
}
}
const params = (() => {
const base = [
request as ExactPartial<RpcTransactionRequest>,
block,
] as const
if (rpcStateOverride && rpcBlockOverrides)
return [...base, rpcStateOverride, rpcBlockOverrides] as const
if (rpcStateOverride) return [...base, rpcStateOverride] as const
if (rpcBlockOverrides) return [...base, {}, rpcBlockOverrides] as const
return base
})()
const response = await client.request({
method: 'eth_call',
params,
})
if (response === '0x') return { data: undefined }
return { data: response }
} catch (err) {
const data = getRevertErrorData(err)
// Check for CCIP-Read offchain lookup signature.
const { offchainLookup, offchainLookupSignature } = await import(
'../../utils/ccip.js'
)
if (
client.ccipRead !== false &&
data?.slice(0, 10) === offchainLookupSignature &&
to
)
return { data: await offchainLookup(client, { data, to }) }
// Check for counterfactual deployment error.
if (deploylessCall && data?.slice(0, 10) === '0x101bb98d')
throw new CounterfactualDeploymentFailedError({ factory })
throw getCallError(err as ErrorType, {
...args,
account,
chain: client.chain,
})
}
}
// We only want to perform a scheduled multicall if:
// - The request has calldata,
// - The request has a target address,
// - The target address is not already the aggregate3 signature,
// - The request has no other properties (`nonce`, `gas`, etc cannot be sent with a multicall).
function shouldPerformMulticall({ request }: { request: TransactionRequest }) {
const { data, to, ...request_ } = request
if (!data) return false
if (data.startsWith(aggregate3Signature)) return false
if (!to) return false
if (
Object.values(request_).filter((x) => typeof x !== 'undefined').length > 0
)
return false
return true
}
type ScheduleMulticallParameters<chain extends Chain | undefined> = Pick<
CallParameters<chain>,
'blockNumber' | 'blockTag'
> & {
data: Hex
multicallAddress?: Address | undefined
to: Address
}
type ScheduleMulticallErrorType =
| GetChainContractAddressErrorType
| NumberToHexErrorType
| CreateBatchSchedulerErrorType
| EncodeFunctionDataErrorType
| DecodeFunctionResultErrorType
| RawContractErrorType
| ErrorType
async function scheduleMulticall<chain extends Chain | undefined>(
client: Client<Transport>,
args: ScheduleMulticallParameters<chain>,
) {
const {
batchSize = 1024,
deployless = false,
wait = 0,
} = typeof client.batch?.multicall === 'object' ? client.batch.multicall : {}
const {
blockNumber,
blockTag = client.experimental_blockTag ?? 'latest',
data,
to,
} = args
const multicallAddress = (() => {
if (deployless) return null
if (args.multicallAddress) return args.multicallAddress
if (client.chain) {
return getChainContractAddress({
blockNumber,
chain: client.chain,
contract: 'multicall3',
})
}
throw new ClientChainNotConfiguredError()
})()
const blockNumberHex =
typeof blockNumber === 'bigint' ? numberToHex(blockNumber) : undefined
const block = blockNumberHex || blockTag
const { schedule } = createBatchScheduler({
id: `${client.uid}.${block}`,
wait,
shouldSplitBatch(args) {
const size = args.reduce((size, { data }) => size + (data.length - 2), 0)
return size > batchSize * 2
},
fn: async (
requests: {
data: Hex
to: Address
}[],
) => {
const calls = requests.map((request) => ({
allowFailure: true,
callData: request.data,
target: request.to,
}))
const calldata = encodeFunctionData({
abi: multicall3Abi,
args: [calls],
functionName: 'aggregate3',
})
const data = await client.request({
method: 'eth_call',
params: [
{
...(multicallAddress === null
? {
data: toDeploylessCallViaBytecodeData({
code: multicall3Bytecode,
data: calldata,
}),
}
: { to: multicallAddress, data: calldata }),
},
block,
],
})
return decodeFunctionResult({
abi: multicall3Abi,
args: [calls],
functionName: 'aggregate3',
data: data || '0x',
})
},
})
const [{ returnData, success }] = await schedule({ data, to })
if (!success) throw new RawContractError({ data: returnData })
if (returnData === '0x') return { data: undefined }
return { data: returnData }
}
type ToDeploylessCallViaBytecodeDataErrorType =
| EncodeDeployDataErrorType
| ErrorType
function toDeploylessCallViaBytecodeData(parameters: { code: Hex; data: Hex }) {
const { code, data } = parameters
return encodeDeployData({
abi: parseAbi(['constructor(bytes, bytes)']),
bytecode: deploylessCallViaBytecodeBytecode,
args: [code, data],
})
}
type ToDeploylessCallViaFactoryDataErrorType =
| EncodeDeployDataErrorType
| ErrorType
function toDeploylessCallViaFactoryData(parameters: {
data: Hex
factory: Address
factoryData: Hex
to: Address
}) {
const { data, factory, factoryData, to } = parameters
return encodeDeployData({
abi: parseAbi(['constructor(address, bytes, address, bytes)']),
bytecode: deploylessCallViaFactoryBytecode,
args: [to, data, factory, factoryData],
})
}
/** @internal */
export type GetRevertErrorDataErrorType = ErrorType
/** @internal */
export function getRevertErrorData(err: unknown) {
if (!(err instanceof BaseError)) return undefined
const error = err.walk() as RawContractError
return typeof error?.data === 'object' ? error.data?.data : error.data
}

163
node_modules/viem/actions/public/createAccessList.ts generated vendored Normal file
View File

@@ -0,0 +1,163 @@
import type { Address } from 'abitype'
import type { Account } from '../../accounts/types.js'
import {
type ParseAccountErrorType,
parseAccount,
} from '../../accounts/utils/parseAccount.js'
import type { Client } from '../../clients/createClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { ErrorType } from '../../errors/utils.js'
import type { BlockTag } from '../../types/block.js'
import type { Chain } from '../../types/chain.js'
import type { RpcTransactionRequest } from '../../types/rpc.js'
import type { AccessList, TransactionRequest } from '../../types/transaction.js'
import type { ExactPartial, Prettify, UnionOmit } from '../../types/utils.js'
import type { RequestErrorType } from '../../utils/buildRequest.js'
import {
type NumberToHexErrorType,
numberToHex,
} from '../../utils/encoding/toHex.js'
import {
type GetCallErrorReturnType,
getCallError,
} from '../../utils/errors/getCallError.js'
import { extract } from '../../utils/formatters/extract.js'
import {
type FormatTransactionRequestErrorType,
type FormattedTransactionRequest,
formatTransactionRequest,
} from '../../utils/formatters/transactionRequest.js'
import type {
AssertRequestErrorType,
AssertRequestParameters,
} from '../../utils/transaction/assertRequest.js'
import { assertRequest } from '../../utils/transaction/assertRequest.js'
export type CreateAccessListParameters<
chain extends Chain | undefined = Chain | undefined,
> = UnionOmit<
FormattedTransactionRequest<chain>,
'from' | 'nonce' | 'accessList'
> & {
/** Account attached to the call (msg.sender). */
account?: Account | Address | undefined
} & (
| {
/** The balance of the account at a block number. */
blockNumber?: bigint | undefined
blockTag?: undefined
}
| {
blockNumber?: undefined
/**
* The balance of the account at a block tag.
* @default 'latest'
*/
blockTag?: BlockTag | undefined
}
)
export type CreateAccessListReturnType = Prettify<{
accessList: AccessList
gasUsed: bigint
}>
export type CreateAccessListErrorType = GetCallErrorReturnType<
| ParseAccountErrorType
| AssertRequestErrorType
| NumberToHexErrorType
| FormatTransactionRequestErrorType
| RequestErrorType
>
/**
* Creates an EIP-2930 access list.
*
* - Docs: https://viem.sh/docs/actions/public/createAccessList
* - JSON-RPC Methods: `eth_createAccessList`
*
* @param client - Client to use
* @param parameters - {@link CreateAccessListParameters}
* @returns The access list. {@link CreateAccessListReturnType}
*
* @example
* import { createPublicClient, http } from 'viem'
* import { mainnet } from 'viem/chains'
* import { createAccessList } from 'viem/public'
*
* const client = createPublicClient({
* chain: mainnet,
* transport: http(),
* })
* const data = await createAccessList(client, {
* account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266',
* data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
* to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
* })
*/
export async function createAccessList<chain extends Chain | undefined>(
client: Client<Transport, chain>,
args: CreateAccessListParameters<chain>,
): Promise<CreateAccessListReturnType> {
const {
account: account_ = client.account,
blockNumber,
blockTag = 'latest',
blobs,
data,
gas,
gasPrice,
maxFeePerBlobGas,
maxFeePerGas,
maxPriorityFeePerGas,
to,
value,
...rest
} = args
const account = account_ ? parseAccount(account_) : undefined
try {
assertRequest(args as AssertRequestParameters)
const blockNumberHex =
typeof blockNumber === 'bigint' ? numberToHex(blockNumber) : undefined
const block = blockNumberHex || blockTag
const chainFormat = client.chain?.formatters?.transactionRequest?.format
const format = chainFormat || formatTransactionRequest
const request = format(
{
// Pick out extra data that might exist on the chain's transaction request type.
...extract(rest, { format: chainFormat }),
account,
blobs,
data,
gas,
gasPrice,
maxFeePerBlobGas,
maxFeePerGas,
maxPriorityFeePerGas,
to,
value,
} as TransactionRequest,
'createAccessList',
) as TransactionRequest
const response = await client.request({
method: 'eth_createAccessList',
params: [request as ExactPartial<RpcTransactionRequest>, block],
})
return {
accessList: response.accessList,
gasUsed: BigInt(response.gasUsed),
}
} catch (err) {
throw getCallError(err as ErrorType, {
...args,
account,
chain: client.chain,
})
}
}

44
node_modules/viem/actions/public/createBlockFilter.ts generated vendored Normal file
View File

@@ -0,0 +1,44 @@
import type { Client } from '../../clients/createClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { ErrorType } from '../../errors/utils.js'
import type { Chain } from '../../types/chain.js'
import type { Filter } from '../../types/filter.js'
import type { RequestErrorType } from '../../utils/buildRequest.js'
import { createFilterRequestScope } from '../../utils/filters/createFilterRequestScope.js'
export type CreateBlockFilterReturnType = Filter<'block'>
export type CreateBlockFilterErrorType = RequestErrorType | ErrorType
/**
* Creates a [`Filter`](https://viem.sh/docs/glossary/types#filter) to listen for new block hashes that can be used with [`getFilterChanges`](https://viem.sh/docs/actions/public/getFilterChanges).
*
* - Docs: https://viem.sh/docs/actions/public/createBlockFilter
* - JSON-RPC Methods: [`eth_newBlockFilter`](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_newBlockFilter)
*
* @param client - Client to use
* @returns [`Filter`](https://viem.sh/docs/glossary/types#filter). {@link CreateBlockFilterReturnType}
*
* @example
* import { createPublicClient, http } from 'viem'
* import { mainnet } from 'viem/chains'
* import { createBlockFilter } from 'viem/public'
*
* const client = createPublicClient({
* chain: mainnet,
* transport: http(),
* })
* const filter = await createBlockFilter(client)
* // { id: "0x345a6572337856574a76364e457a4366", type: 'block' }
*/
export async function createBlockFilter<chain extends Chain | undefined>(
client: Client<Transport, chain>,
): Promise<CreateBlockFilterReturnType> {
const getRequest = createFilterRequestScope(client, {
method: 'eth_newBlockFilter',
})
const id = await client.request({
method: 'eth_newBlockFilter',
})
return { id, request: getRequest(id), type: 'block' }
}

View File

@@ -0,0 +1,171 @@
import type { Abi, Address } from 'abitype'
import type { Client } from '../../clients/createClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { ErrorType } from '../../errors/utils.js'
import type { BlockNumber, BlockTag } from '../../types/block.js'
import type { Chain } from '../../types/chain.js'
import type {
ContractEventName,
MaybeExtractEventArgsFromAbi,
} from '../../types/contract.js'
import type { Filter } from '../../types/filter.js'
import type { Hex } from '../../types/misc.js'
import {
type EncodeEventTopicsErrorType,
type EncodeEventTopicsParameters,
encodeEventTopics,
} from '../../utils/abi/encodeEventTopics.js'
import type { RequestErrorType } from '../../utils/buildRequest.js'
import {
type NumberToHexErrorType,
numberToHex,
} from '../../utils/encoding/toHex.js'
import { createFilterRequestScope } from '../../utils/filters/createFilterRequestScope.js'
export type CreateContractEventFilterParameters<
abi extends Abi | readonly unknown[] = Abi,
eventName extends ContractEventName<abi> | undefined = undefined,
args extends
| MaybeExtractEventArgsFromAbi<abi, eventName>
| undefined = undefined,
strict extends boolean | undefined = undefined,
fromBlock extends BlockNumber | BlockTag | undefined = undefined,
toBlock extends BlockNumber | BlockTag | undefined = undefined,
> = {
address?: Address | Address[] | undefined
abi: abi
eventName?: eventName | ContractEventName<abi> | undefined
fromBlock?: fromBlock | BlockNumber | BlockTag | undefined
/**
* Whether or not the logs must match the indexed/non-indexed arguments in the event ABI item.
* @default false
*/
strict?: strict | boolean | undefined
toBlock?: toBlock | BlockNumber | BlockTag | undefined
} & (undefined extends eventName
? {
args?: undefined
}
: MaybeExtractEventArgsFromAbi<abi, eventName> extends infer eventFilterArgs
? {
args?:
| eventFilterArgs
| (args extends eventFilterArgs ? args : never)
| undefined
}
: {
args?: undefined
})
export type CreateContractEventFilterReturnType<
abi extends Abi | readonly unknown[] = Abi,
eventName extends ContractEventName<abi> | undefined = undefined,
args extends
| MaybeExtractEventArgsFromAbi<abi, eventName>
| undefined = undefined,
strict extends boolean | undefined = undefined,
fromBlock extends BlockNumber | BlockTag | undefined = undefined,
toBlock extends BlockNumber | BlockTag | undefined = undefined,
> = Filter<'event', abi, eventName, args, strict, fromBlock, toBlock>
export type CreateContractEventFilterErrorType =
| EncodeEventTopicsErrorType
| RequestErrorType
| NumberToHexErrorType
| ErrorType
/**
* Creates a Filter to retrieve event logs that can be used with [`getFilterChanges`](https://viem.sh/docs/actions/public/getFilterChanges) or [`getFilterLogs`](https://viem.sh/docs/actions/public/getFilterLogs).
*
* - Docs: https://viem.sh/docs/contract/createContractEventFilter
*
* @param client - Client to use
* @param parameters - {@link CreateContractEventFilterParameters}
* @returns [`Filter`](https://viem.sh/docs/glossary/types#filter). {@link CreateContractEventFilterReturnType}
*
* @example
* import { createPublicClient, http, parseAbi } from 'viem'
* import { mainnet } from 'viem/chains'
* import { createContractEventFilter } from 'viem/contract'
*
* const client = createPublicClient({
* chain: mainnet,
* transport: http(),
* })
* const filter = await createContractEventFilter(client, {
* abi: parseAbi(['event Transfer(address indexed, address indexed, uint256)']),
* })
*/
export async function createContractEventFilter<
chain extends Chain | undefined,
const abi extends Abi | readonly unknown[],
eventName extends ContractEventName<abi> | undefined,
args extends MaybeExtractEventArgsFromAbi<abi, eventName> | undefined,
strict extends boolean | undefined = undefined,
fromBlock extends BlockNumber | BlockTag | undefined = undefined,
toBlock extends BlockNumber | BlockTag | undefined = undefined,
>(
client: Client<Transport, chain>,
parameters: CreateContractEventFilterParameters<
abi,
eventName,
args,
strict,
fromBlock,
toBlock
>,
): Promise<
CreateContractEventFilterReturnType<
abi,
eventName,
args,
strict,
fromBlock,
toBlock
>
> {
const { address, abi, args, eventName, fromBlock, strict, toBlock } =
parameters as CreateContractEventFilterParameters
const getRequest = createFilterRequestScope(client, {
method: 'eth_newFilter',
})
const topics = eventName
? encodeEventTopics({
abi,
args,
eventName,
} as unknown as EncodeEventTopicsParameters)
: undefined
const id: Hex = await client.request({
method: 'eth_newFilter',
params: [
{
address,
fromBlock:
typeof fromBlock === 'bigint' ? numberToHex(fromBlock) : fromBlock,
toBlock: typeof toBlock === 'bigint' ? numberToHex(toBlock) : toBlock,
topics,
},
],
})
return {
abi,
args,
eventName,
id,
request: getRequest(id),
strict: Boolean(strict),
type: 'event',
} as unknown as CreateContractEventFilterReturnType<
abi,
eventName,
args,
strict,
fromBlock,
toBlock
>
}

237
node_modules/viem/actions/public/createEventFilter.ts generated vendored Normal file
View File

@@ -0,0 +1,237 @@
import type { AbiEvent, Address } from 'abitype'
import type { Client } from '../../clients/createClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { ErrorType } from '../../errors/utils.js'
import type { BlockNumber, BlockTag } from '../../types/block.js'
import type { Chain } from '../../types/chain.js'
import type {
MaybeAbiEventName,
MaybeExtractEventArgsFromAbi,
} from '../../types/contract.js'
import type { Filter } from '../../types/filter.js'
import type { Hex, LogTopic } from '../../types/misc.js'
import type { Prettify } from '../../types/utils.js'
import {
type EncodeEventTopicsErrorType,
type EncodeEventTopicsParameters,
encodeEventTopics,
} from '../../utils/abi/encodeEventTopics.js'
import type { RequestErrorType } from '../../utils/buildRequest.js'
import {
type NumberToHexErrorType,
numberToHex,
} from '../../utils/encoding/toHex.js'
import { createFilterRequestScope } from '../../utils/filters/createFilterRequestScope.js'
export type CreateEventFilterParameters<
abiEvent extends AbiEvent | undefined = undefined,
abiEvents extends
| readonly AbiEvent[]
| readonly unknown[]
| undefined = abiEvent extends AbiEvent ? [abiEvent] : undefined,
strict extends boolean | undefined = undefined,
fromBlock extends BlockNumber | BlockTag | undefined = undefined,
toBlock extends BlockNumber | BlockTag | undefined = undefined,
//
_eventName extends string | undefined = MaybeAbiEventName<abiEvent>,
_args extends
| MaybeExtractEventArgsFromAbi<abiEvents, _eventName>
| undefined = undefined,
> = {
address?: Address | Address[] | undefined
fromBlock?: fromBlock | BlockNumber | BlockTag | undefined
toBlock?: toBlock | BlockNumber | BlockTag | undefined
} & (MaybeExtractEventArgsFromAbi<
abiEvents,
_eventName
> extends infer eventFilterArgs
?
| {
args:
| eventFilterArgs
| (_args extends eventFilterArgs ? _args : never)
event: abiEvent
events?: undefined
/**
* Whether or not the logs must match the indexed/non-indexed arguments on `event`.
* @default false
*/
strict?: strict | undefined
}
| {
args?: undefined
event?: abiEvent | undefined
events?: undefined
/**
* Whether or not the logs must match the indexed/non-indexed arguments on `event`.
* @default false
*/
strict?: strict | undefined
}
| {
args?: undefined
event?: undefined
events: abiEvents | undefined
/**
* Whether or not the logs must match the indexed/non-indexed arguments on `event`.
* @default false
*/
strict?: strict | undefined
}
| {
args?: undefined
event?: undefined
events?: undefined
strict?: undefined
}
: {
args?: undefined
event?: undefined
events?: undefined
strict?: undefined
})
export type CreateEventFilterReturnType<
abiEvent extends AbiEvent | undefined = undefined,
abiEvents extends
| readonly AbiEvent[]
| readonly unknown[]
| undefined = abiEvent extends AbiEvent ? [abiEvent] : undefined,
strict extends boolean | undefined = undefined,
fromBlock extends BlockNumber | BlockTag | undefined = undefined,
toBlock extends BlockNumber | BlockTag | undefined = undefined,
_eventName extends string | undefined = MaybeAbiEventName<abiEvent>,
_args extends
| MaybeExtractEventArgsFromAbi<abiEvents, _eventName>
| undefined = undefined,
> = Prettify<
Filter<'event', abiEvents, _eventName, _args, strict, fromBlock, toBlock>
>
export type CreateEventFilterErrorType =
| EncodeEventTopicsErrorType
| RequestErrorType
| NumberToHexErrorType
| ErrorType
/**
* Creates a [`Filter`](https://viem.sh/docs/glossary/types#filter) to listen for new events that can be used with [`getFilterChanges`](https://viem.sh/docs/actions/public/getFilterChanges).
*
* - Docs: https://viem.sh/docs/actions/public/createEventFilter
* - JSON-RPC Methods: [`eth_newFilter`](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_newfilter)
*
* @param client - Client to use
* @param parameters - {@link CreateEventFilterParameters}
* @returns [`Filter`](https://viem.sh/docs/glossary/types#filter). {@link CreateEventFilterReturnType}
*
* @example
* import { createPublicClient, http } from 'viem'
* import { mainnet } from 'viem/chains'
* import { createEventFilter } from 'viem/public'
*
* const client = createPublicClient({
* chain: mainnet,
* transport: http(),
* })
* const filter = await createEventFilter(client, {
* address: '0xfba3912ca04dd458c843e2ee08967fc04f3579c2',
* })
*/
export async function createEventFilter<
chain extends Chain | undefined,
const abiEvent extends AbiEvent | undefined = undefined,
const abiEvents extends
| readonly AbiEvent[]
| readonly unknown[]
| undefined = abiEvent extends AbiEvent ? [abiEvent] : undefined,
strict extends boolean | undefined = undefined,
fromBlock extends BlockNumber<bigint> | BlockTag | undefined = undefined,
toBlock extends BlockNumber<bigint> | BlockTag | undefined = undefined,
_eventName extends string | undefined = MaybeAbiEventName<abiEvent>,
_args extends
| MaybeExtractEventArgsFromAbi<abiEvents, _eventName>
| undefined = undefined,
>(
client: Client<Transport, chain>,
{
address,
args,
event,
events: events_,
fromBlock,
strict,
toBlock,
}: CreateEventFilterParameters<
abiEvent,
abiEvents,
strict,
fromBlock,
toBlock,
_eventName,
_args
> = {} as any,
): Promise<
CreateEventFilterReturnType<
abiEvent,
abiEvents,
strict,
fromBlock,
toBlock,
_eventName,
_args
>
> {
const events = events_ ?? (event ? [event] : undefined)
const getRequest = createFilterRequestScope(client, {
method: 'eth_newFilter',
})
let topics: LogTopic[] = []
if (events) {
const encoded = (events as AbiEvent[]).flatMap((event) =>
encodeEventTopics({
abi: [event],
eventName: (event as AbiEvent).name,
args,
} as EncodeEventTopicsParameters),
)
// TODO: Clean up type casting
topics = [encoded as LogTopic]
if (event) topics = topics[0] as LogTopic[]
}
const id: Hex = await client.request({
method: 'eth_newFilter',
params: [
{
address,
fromBlock:
typeof fromBlock === 'bigint' ? numberToHex(fromBlock) : fromBlock,
toBlock: typeof toBlock === 'bigint' ? numberToHex(toBlock) : toBlock,
...(topics.length ? { topics } : {}),
},
],
})
return {
abi: events,
args,
eventName: event ? (event as AbiEvent).name : undefined,
fromBlock,
id,
request: getRequest(id),
strict: Boolean(strict),
toBlock,
type: 'event',
} as unknown as CreateEventFilterReturnType<
abiEvent,
abiEvents,
strict,
fromBlock,
toBlock,
_eventName,
_args
>
}

View File

@@ -0,0 +1,49 @@
import type { Client } from '../../clients/createClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { ErrorType } from '../../errors/utils.js'
import type { Chain } from '../../types/chain.js'
import type { Filter } from '../../types/filter.js'
import type { RequestErrorType } from '../../utils/buildRequest.js'
import { createFilterRequestScope } from '../../utils/filters/createFilterRequestScope.js'
export type CreatePendingTransactionFilterReturnType = Filter<'transaction'>
export type CreatePendingTransactionFilterErrorType =
| RequestErrorType
| ErrorType
/**
* Creates a Filter to listen for new pending transaction hashes that can be used with [`getFilterChanges`](https://viem.sh/docs/actions/public/getFilterChanges).
*
* - Docs: https://viem.sh/docs/actions/public/createPendingTransactionFilter
* - JSON-RPC Methods: [`eth_newPendingTransactionFilter`](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_newpendingtransactionfilter)
*
* @param client - Client to use
* @returns [`Filter`](https://viem.sh/docs/glossary/types#filter). {@link CreateBlockFilterReturnType}
*
* @example
* import { createPublicClient, http } from 'viem'
* import { mainnet } from 'viem/chains'
* import { createPendingTransactionFilter } from 'viem/public'
*
* const client = createPublicClient({
* chain: mainnet,
* transport: http(),
* })
* const filter = await createPendingTransactionFilter(client)
* // { id: "0x345a6572337856574a76364e457a4366", type: 'transaction' }
*/
export async function createPendingTransactionFilter<
transport extends Transport,
chain extends Chain | undefined,
>(
client: Client<transport, chain>,
): Promise<CreatePendingTransactionFilterReturnType> {
const getRequest = createFilterRequestScope(client, {
method: 'eth_newPendingTransactionFilter',
})
const id = await client.request({
method: 'eth_newPendingTransactionFilter',
})
return { id, request: getRequest(id), type: 'transaction' }
}

147
node_modules/viem/actions/public/estimateContractGas.ts generated vendored Normal file
View File

@@ -0,0 +1,147 @@
import type { Abi } from 'abitype'
import type { Account } from '../../accounts/types.js'
import {
type ParseAccountErrorType,
parseAccount,
} from '../../accounts/utils/parseAccount.js'
import type { Client } from '../../clients/createClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { BaseError } from '../../errors/base.js'
import type { Chain } from '../../types/chain.js'
import type {
ContractFunctionArgs,
ContractFunctionName,
ContractFunctionParameters,
GetValue,
} from '../../types/contract.js'
import type { Hex } from '../../types/misc.js'
import type { UnionOmit } from '../../types/utils.js'
import {
type EncodeFunctionDataErrorType,
type EncodeFunctionDataParameters,
encodeFunctionData,
} from '../../utils/abi/encodeFunctionData.js'
import {
type GetContractErrorReturnType,
getContractError,
} from '../../utils/errors/getContractError.js'
import { getAction } from '../../utils/getAction.js'
import {
type EstimateGasErrorType,
type EstimateGasParameters,
estimateGas,
} from './estimateGas.js'
export type EstimateContractGasParameters<
abi extends Abi | readonly unknown[] = Abi,
functionName extends ContractFunctionName<
abi,
'nonpayable' | 'payable'
> = ContractFunctionName<abi, 'nonpayable' | 'payable'>,
args extends ContractFunctionArgs<
abi,
'nonpayable' | 'payable',
functionName
> = ContractFunctionArgs<abi, 'nonpayable' | 'payable', functionName>,
chain extends Chain | undefined = Chain | undefined,
> = ContractFunctionParameters<
abi,
'nonpayable' | 'payable',
functionName,
args
> &
UnionOmit<EstimateGasParameters<chain>, 'data' | 'to' | 'value'> &
GetValue<
abi,
functionName,
EstimateGasParameters<chain> extends EstimateGasParameters
? EstimateGasParameters<chain>['value']
: EstimateGasParameters['value']
> & {
/** Data to append to the end of the calldata. Useful for adding a ["domain" tag](https://opensea.notion.site/opensea/Seaport-Order-Attributions-ec2d69bf455041a5baa490941aad307f). */
dataSuffix?: Hex | undefined
}
export type EstimateContractGasReturnType = bigint
export type EstimateContractGasErrorType = GetContractErrorReturnType<
EncodeFunctionDataErrorType | EstimateGasErrorType | ParseAccountErrorType
>
/**
* Estimates the gas required to successfully execute a contract write function call.
*
* - Docs: https://viem.sh/docs/contract/estimateContractGas
*
* Internally, uses a [Public Client](https://viem.sh/docs/clients/public) to call the [`estimateGas` action](https://viem.sh/docs/actions/public/estimateGas) with [ABI-encoded `data`](https://viem.sh/docs/contract/encodeFunctionData).
*
* @param client - Client to use
* @param parameters - {@link EstimateContractGasParameters}
* @returns The gas estimate (in wei). {@link EstimateContractGasReturnType}
*
* @example
* import { createPublicClient, http, parseAbi } from 'viem'
* import { mainnet } from 'viem/chains'
* import { estimateContractGas } from 'viem/contract'
*
* const client = createPublicClient({
* chain: mainnet,
* transport: http(),
* })
* const gas = await estimateContractGas(client, {
* address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
* abi: parseAbi(['function mint() public']),
* functionName: 'mint',
* account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266',
* })
*/
export async function estimateContractGas<
const abi extends Abi | readonly unknown[],
functionName extends ContractFunctionName<abi, 'nonpayable' | 'payable'>,
args extends ContractFunctionArgs<abi, 'pure' | 'view', functionName>,
chain extends Chain | undefined,
account extends Account | undefined = undefined,
>(
client: Client<Transport, chain, account>,
parameters: EstimateContractGasParameters<abi, functionName, args, chain>,
): Promise<EstimateContractGasReturnType> {
const {
abi,
address,
args,
functionName,
dataSuffix = typeof client.dataSuffix === 'string'
? client.dataSuffix
: client.dataSuffix?.value,
...request
} = parameters as EstimateContractGasParameters
const data = encodeFunctionData({
abi,
args,
functionName,
} as EncodeFunctionDataParameters)
try {
const gas = await getAction(
client,
estimateGas,
'estimateGas',
)({
data: `${data}${dataSuffix ? dataSuffix.replace('0x', '') : ''}`,
to: address,
...request,
} as unknown as EstimateGasParameters)
return gas
} catch (error) {
const account = request.account ? parseAccount(request.account) : undefined
throw getContractError(error as BaseError, {
abi,
address,
args,
docsPath: '/docs/contract/estimateContractGas',
functionName,
sender: account?.address,
})
}
}

178
node_modules/viem/actions/public/estimateFeesPerGas.ts generated vendored Normal file
View File

@@ -0,0 +1,178 @@
import type { Client } from '../../clients/createClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import {
BaseFeeScalarError,
type BaseFeeScalarErrorType,
Eip1559FeesNotSupportedError,
type Eip1559FeesNotSupportedErrorType,
} from '../../errors/fee.js'
import type { ErrorType } from '../../errors/utils.js'
import type { Account } from '../../types/account.js'
import type { Block } from '../../types/block.js'
import type {
Chain,
ChainEstimateFeesPerGasFnParameters,
ChainFeesFnParameters,
GetChainParameter,
} from '../../types/chain.js'
import type {
FeeValuesEIP1559,
FeeValuesLegacy,
FeeValuesType,
} from '../../types/fee.js'
import { getAction } from '../../utils/getAction.js'
import type { PrepareTransactionRequestParameters } from '../wallet/prepareTransactionRequest.js'
import {
type EstimateMaxPriorityFeePerGasErrorType,
internal_estimateMaxPriorityFeePerGas,
} from './estimateMaxPriorityFeePerGas.js'
import { getBlock } from './getBlock.js'
import { type GetGasPriceErrorType, getGasPrice } from './getGasPrice.js'
export type EstimateFeesPerGasParameters<
chain extends Chain | undefined = Chain | undefined,
chainOverride extends Chain | undefined = Chain | undefined,
type extends FeeValuesType = FeeValuesType,
> = {
/**
* The type of fee values to return.
*
* - `legacy`: Returns the legacy gas price.
* - `eip1559`: Returns the max fee per gas and max priority fee per gas.
*
* @default 'eip1559'
*/
type?: type | FeeValuesType | undefined
} & GetChainParameter<chain, chainOverride>
export type EstimateFeesPerGasReturnType<
type extends FeeValuesType = FeeValuesType,
> =
| (type extends 'legacy' ? FeeValuesLegacy : never)
| (type extends 'eip1559' ? FeeValuesEIP1559 : never)
export type EstimateFeesPerGasErrorType =
| BaseFeeScalarErrorType
| EstimateMaxPriorityFeePerGasErrorType
| GetGasPriceErrorType
| Eip1559FeesNotSupportedErrorType
| ErrorType
/**
* Returns an estimate for the fees per gas (in wei) for a
* transaction to be likely included in the next block.
* Defaults to [`chain.fees.estimateFeesPerGas`](/docs/clients/chains#fees-estimatefeespergas) if set.
*
* - Docs: https://viem.sh/docs/actions/public/estimateFeesPerGas
*
* @param client - Client to use
* @param parameters - {@link EstimateFeesPerGasParameters}
* @returns An estimate (in wei) for the fees per gas. {@link EstimateFeesPerGasReturnType}
*
* @example
* import { createPublicClient, http } from 'viem'
* import { mainnet } from 'viem/chains'
* import { estimateFeesPerGas } from 'viem/actions'
*
* const client = createPublicClient({
* chain: mainnet,
* transport: http(),
* })
* const maxPriorityFeePerGas = await estimateFeesPerGas(client)
* // { maxFeePerGas: ..., maxPriorityFeePerGas: ... }
*/
export async function estimateFeesPerGas<
chain extends Chain | undefined,
chainOverride extends Chain | undefined,
type extends FeeValuesType = 'eip1559',
>(
client: Client<Transport, chain>,
args?: EstimateFeesPerGasParameters<chain, chainOverride, type> | undefined,
): Promise<EstimateFeesPerGasReturnType<type>> {
return internal_estimateFeesPerGas(client, args as any)
}
export async function internal_estimateFeesPerGas<
chain extends Chain | undefined,
chainOverride extends Chain | undefined,
type extends FeeValuesType = 'eip1559',
>(
client: Client<Transport, chain>,
args: EstimateFeesPerGasParameters<chain, chainOverride, type> & {
block?: Block | undefined
request?: PrepareTransactionRequestParameters<Chain, Account> | undefined
},
): Promise<EstimateFeesPerGasReturnType<type>> {
const {
block: block_,
chain = client.chain,
request,
type = 'eip1559',
} = args || {}
const baseFeeMultiplier = await (async () => {
if (typeof chain?.fees?.baseFeeMultiplier === 'function')
return chain.fees.baseFeeMultiplier({
block: block_ as Block,
client,
request,
} as ChainFeesFnParameters)
return chain?.fees?.baseFeeMultiplier ?? 1.2
})()
if (baseFeeMultiplier < 1) throw new BaseFeeScalarError()
const decimals = baseFeeMultiplier.toString().split('.')[1]?.length ?? 0
const denominator = 10 ** decimals
const multiply = (base: bigint) =>
(base * BigInt(Math.ceil(baseFeeMultiplier * denominator))) /
BigInt(denominator)
const block = block_
? block_
: await getAction(client, getBlock, 'getBlock')({})
if (typeof chain?.fees?.estimateFeesPerGas === 'function') {
const fees = (await chain.fees.estimateFeesPerGas({
block: block_ as Block,
client,
multiply,
request,
type,
} as ChainEstimateFeesPerGasFnParameters)) as unknown as EstimateFeesPerGasReturnType<type>
if (fees !== null) return fees
}
if (type === 'eip1559') {
if (typeof block.baseFeePerGas !== 'bigint')
throw new Eip1559FeesNotSupportedError()
const maxPriorityFeePerGas =
typeof request?.maxPriorityFeePerGas === 'bigint'
? request.maxPriorityFeePerGas
: await internal_estimateMaxPriorityFeePerGas(
client as Client<Transport, Chain>,
{
block: block as Block,
chain,
request,
},
)
const baseFeePerGas = multiply(block.baseFeePerGas)
const maxFeePerGas =
request?.maxFeePerGas ?? baseFeePerGas + maxPriorityFeePerGas
return {
maxFeePerGas,
maxPriorityFeePerGas,
} as EstimateFeesPerGasReturnType<type>
}
const gasPrice =
request?.gasPrice ??
multiply(await getAction(client, getGasPrice, 'getGasPrice')({}))
return {
gasPrice,
} as EstimateFeesPerGasReturnType<type>
}

229
node_modules/viem/actions/public/estimateGas.ts generated vendored Normal file
View File

@@ -0,0 +1,229 @@
import type { Address } from 'abitype'
import type { Account } from '../../accounts/types.js'
import {
type ParseAccountErrorType,
parseAccount,
} from '../../accounts/utils/parseAccount.js'
import type { Client } from '../../clients/createClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import { BaseError } from '../../errors/base.js'
import type { BlockTag } from '../../types/block.js'
import type { Chain } from '../../types/chain.js'
import type { StateOverride } from '../../types/stateOverride.js'
import type { TransactionRequest } from '../../types/transaction.js'
import type { UnionOmit } from '../../types/utils.js'
import {
type RecoverAuthorizationAddressErrorType,
recoverAuthorizationAddress,
} from '../../utils/authorization/recoverAuthorizationAddress.js'
import type { RequestErrorType } from '../../utils/buildRequest.js'
import {
type NumberToHexErrorType,
numberToHex,
} from '../../utils/encoding/toHex.js'
import {
type GetEstimateGasErrorReturnType,
getEstimateGasError,
} from '../../utils/errors/getEstimateGasError.js'
import { extract } from '../../utils/formatters/extract.js'
import {
type FormattedTransactionRequest,
formatTransactionRequest,
} from '../../utils/formatters/transactionRequest.js'
import { serializeStateOverride } from '../../utils/stateOverride.js'
import {
type AssertRequestErrorType,
type AssertRequestParameters,
assertRequest,
} from '../../utils/transaction/assertRequest.js'
import {
type PrepareTransactionRequestParameters,
type PrepareTransactionRequestParameterType,
prepareTransactionRequest,
} from '../wallet/prepareTransactionRequest.js'
export type EstimateGasParameters<
chain extends Chain | undefined = Chain | undefined,
> = UnionOmit<FormattedEstimateGas<chain>, 'from'> & {
account?: Account | Address | undefined
prepare?:
| boolean
| readonly PrepareTransactionRequestParameterType[]
| undefined
stateOverride?: StateOverride | undefined
} & (
| {
/** The balance of the account at a block number. */
blockNumber?: bigint | undefined
blockTag?: undefined
}
| {
blockNumber?: undefined
/**
* The balance of the account at a block tag.
* @default 'latest'
*/
blockTag?: BlockTag | undefined
}
)
type FormattedEstimateGas<chain extends Chain | undefined = Chain | undefined> =
FormattedTransactionRequest<chain>
export type EstimateGasReturnType = bigint
export type EstimateGasErrorType = GetEstimateGasErrorReturnType<
| ParseAccountErrorType
| NumberToHexErrorType
| RequestErrorType
| RecoverAuthorizationAddressErrorType
| AssertRequestErrorType
>
/**
* Estimates the gas necessary to complete a transaction without submitting it to the network.
*
* - Docs: https://viem.sh/docs/actions/public/estimateGas
* - JSON-RPC Methods: [`eth_estimateGas`](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_estimategas)
*
* @param client - Client to use
* @param parameters - {@link EstimateGasParameters}
* @returns The gas estimate (in gas units). {@link EstimateGasReturnType}
*
* @example
* import { createPublicClient, http, parseEther } from 'viem'
* import { mainnet } from 'viem/chains'
* import { estimateGas } from 'viem/public'
*
* const client = createPublicClient({
* chain: mainnet,
* transport: http(),
* })
* const gasEstimate = await estimateGas(client, {
* account: '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e',
* to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
* value: parseEther('1'),
* })
*/
export async function estimateGas<
chain extends Chain | undefined,
account extends Account | undefined = undefined,
>(
client: Client<Transport, chain, account>,
args: EstimateGasParameters<chain>,
): Promise<EstimateGasReturnType> {
const { account: account_ = client.account, prepare = true } = args
const account = account_ ? parseAccount(account_) : undefined
const parameters = (() => {
if (Array.isArray(prepare)) return prepare
// Some RPC Providers do not compute versioned hashes from blobs. We will need
// to compute them.
if (account?.type !== 'local') return ['blobVersionedHashes']
return undefined
})()
try {
const to = await (async () => {
// If `to` exists on the parameters, use that.
if (args.to) return args.to
// If no `to` exists, and we are sending a EIP-7702 transaction, use the
// address of the first authorization in the list.
if (args.authorizationList && args.authorizationList.length > 0)
return await recoverAuthorizationAddress({
authorization: args.authorizationList[0],
}).catch(() => {
throw new BaseError(
'`to` is required. Could not infer from `authorizationList`',
)
})
// Otherwise, we are sending a deployment transaction.
return undefined
})()
const {
accessList,
authorizationList,
blobs,
blobVersionedHashes,
blockNumber,
blockTag,
data,
gas,
gasPrice,
maxFeePerBlobGas,
maxFeePerGas,
maxPriorityFeePerGas,
nonce,
value,
stateOverride,
...rest
} = prepare
? ((await prepareTransactionRequest(client, {
...args,
parameters,
to,
} as PrepareTransactionRequestParameters)) as EstimateGasParameters)
: args
// If we get `gas` back from the prepared transaction request, which is
// different from the `gas` we provided, it was likely filled by other means
// during request preparation (e.g. `eth_fillTransaction` or `chain.transactionRequest.prepare`).
// (e.g. `eth_fillTransaction` or `chain.transactionRequest.prepare`).
if (gas && args.gas !== gas) return gas
const blockNumberHex =
typeof blockNumber === 'bigint' ? numberToHex(blockNumber) : undefined
const block = blockNumberHex || blockTag
const rpcStateOverride = serializeStateOverride(stateOverride)
assertRequest(args as AssertRequestParameters)
const chainFormat = client.chain?.formatters?.transactionRequest?.format
const format = chainFormat || formatTransactionRequest
const request = format(
{
// Pick out extra data that might exist on the chain's transaction request type.
...extract(rest, { format: chainFormat }),
account,
accessList,
authorizationList,
blobs,
blobVersionedHashes,
data,
gasPrice,
maxFeePerBlobGas,
maxFeePerGas,
maxPriorityFeePerGas,
nonce,
to,
value,
} as TransactionRequest,
'estimateGas',
)
return BigInt(
await client.request({
method: 'eth_estimateGas',
params: rpcStateOverride
? [
request,
block ?? client.experimental_blockTag ?? 'latest',
rpcStateOverride,
]
: block
? [request, block]
: [request],
}),
)
} catch (err) {
throw getEstimateGasError(err as BaseError, {
...args,
account,
chain: client.chain,
})
}
}

View File

@@ -0,0 +1,134 @@
import type { Client } from '../../clients/createClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import {
Eip1559FeesNotSupportedError,
type Eip1559FeesNotSupportedErrorType,
} from '../../errors/fee.js'
import type { ErrorType } from '../../errors/utils.js'
import type { Account } from '../../types/account.js'
import type { Block } from '../../types/block.js'
import type {
Chain,
ChainFeesFnParameters,
GetChainParameter,
} from '../../types/chain.js'
import type { RequestErrorType } from '../../utils/buildRequest.js'
import {
type HexToBigIntErrorType,
hexToBigInt,
} from '../../utils/encoding/fromHex.js'
import { getAction } from '../../utils/getAction.js'
import type { PrepareTransactionRequestParameters } from '../wallet/prepareTransactionRequest.js'
import { type GetBlockErrorType, getBlock } from './getBlock.js'
import { type GetGasPriceErrorType, getGasPrice } from './getGasPrice.js'
export type EstimateMaxPriorityFeePerGasParameters<
chain extends Chain | undefined = Chain | undefined,
chainOverride extends Chain | undefined = Chain | undefined,
> = GetChainParameter<chain, chainOverride>
export type EstimateMaxPriorityFeePerGasReturnType = bigint
export type EstimateMaxPriorityFeePerGasErrorType =
| GetBlockErrorType
| HexToBigIntErrorType
| RequestErrorType
| GetBlockErrorType
| GetGasPriceErrorType
| Eip1559FeesNotSupportedErrorType
| ErrorType
/**
* Returns an estimate for the max priority fee per gas (in wei) for a
* transaction to be likely included in the next block.
* Defaults to [`chain.fees.defaultPriorityFee`](/docs/clients/chains#fees-defaultpriorityfee) if set.
*
* - Docs: https://viem.sh/docs/actions/public/estimateMaxPriorityFeePerGas
*
* @param client - Client to use
* @returns An estimate (in wei) for the max priority fee per gas. {@link EstimateMaxPriorityFeePerGasReturnType}
*
* @example
* import { createPublicClient, http } from 'viem'
* import { mainnet } from 'viem/chains'
* import { estimateMaxPriorityFeePerGas } from 'viem/actions'
*
* const client = createPublicClient({
* chain: mainnet,
* transport: http(),
* })
* const maxPriorityFeePerGas = await estimateMaxPriorityFeePerGas(client)
* // 10000000n
*/
export async function estimateMaxPriorityFeePerGas<
chain extends Chain | undefined,
chainOverride extends Chain | undefined,
>(
client: Client<Transport, chain>,
args?:
| EstimateMaxPriorityFeePerGasParameters<chain, chainOverride>
| undefined,
): Promise<EstimateMaxPriorityFeePerGasReturnType> {
return internal_estimateMaxPriorityFeePerGas(client, args as any)
}
export async function internal_estimateMaxPriorityFeePerGas<
chain extends Chain | undefined,
chainOverride extends Chain | undefined,
>(
client: Client<Transport, chain>,
args: EstimateMaxPriorityFeePerGasParameters<chain, chainOverride> & {
block?: Block | undefined
request?:
| PrepareTransactionRequestParameters<
chain,
Account | undefined,
chainOverride
>
| undefined
},
): Promise<EstimateMaxPriorityFeePerGasReturnType> {
const { block: block_, chain = client.chain, request } = args || {}
try {
const maxPriorityFeePerGas =
chain?.fees?.maxPriorityFeePerGas ?? chain?.fees?.defaultPriorityFee
if (typeof maxPriorityFeePerGas === 'function') {
const block =
block_ || (await getAction(client, getBlock, 'getBlock')({}))
const maxPriorityFeePerGas_ = await maxPriorityFeePerGas({
block,
client,
request,
} as ChainFeesFnParameters)
if (maxPriorityFeePerGas_ === null) throw new Error()
return maxPriorityFeePerGas_
}
if (typeof maxPriorityFeePerGas !== 'undefined') return maxPriorityFeePerGas
const maxPriorityFeePerGasHex = await client.request({
method: 'eth_maxPriorityFeePerGas',
})
return hexToBigInt(maxPriorityFeePerGasHex)
} catch {
// If the RPC Provider does not support `eth_maxPriorityFeePerGas`
// fall back to calculating it manually via `gasPrice - baseFeePerGas`.
// See: https://github.com/ethereum/pm/issues/328#:~:text=eth_maxPriorityFeePerGas%20after%20London%20will%20effectively%20return%20eth_gasPrice%20%2D%20baseFee
const [block, gasPrice] = await Promise.all([
block_
? Promise.resolve(block_)
: getAction(client, getBlock, 'getBlock')({}),
getAction(client, getGasPrice, 'getGasPrice')({}),
])
if (typeof block.baseFeePerGas !== 'bigint')
throw new Eip1559FeesNotSupportedError()
const maxPriorityFeePerGas = gasPrice - block.baseFeePerGas
if (maxPriorityFeePerGas < 0n) return 0n
return maxPriorityFeePerGas
}
}

258
node_modules/viem/actions/public/fillTransaction.ts generated vendored Normal file
View File

@@ -0,0 +1,258 @@
import type { Address } from 'abitype'
import { parseAccount } from '../../accounts/utils/parseAccount.js'
import type { Client } from '../../clients/createClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { BaseError } from '../../errors/base.js'
import { BaseFeeScalarError } from '../../errors/fee.js'
import type { ErrorType } from '../../errors/utils.js'
import type { Account, GetAccountParameter } from '../../types/account.js'
import type { ExtractCapabilities } from '../../types/capabilities.js'
import type {
Chain,
ChainFeesFnParameters,
DeriveChain,
GetChainParameter,
} from '../../types/chain.js'
import type { Hex } from '../../types/misc.js'
import type { TransactionRequest } from '../../types/transaction.js'
import type { UnionOmit } from '../../types/utils.js'
import {
type GetTransactionErrorReturnType,
getTransactionError,
} from '../../utils/errors/getTransactionError.js'
import { extract } from '../../utils/formatters/extract.js'
import {
type FormattedTransaction,
formatTransaction,
} from '../../utils/formatters/transaction.js'
import {
type FormattedTransactionRequest,
formatTransactionRequest,
} from '../../utils/formatters/transactionRequest.js'
import { getAction } from '../../utils/getAction.js'
import type { NonceManager } from '../../utils/nonceManager.js'
import { assertRequest } from '../../utils/transaction/assertRequest.js'
import { getBlock } from './getBlock.js'
import { getChainId as getChainId_ } from './getChainId.js'
export type FillTransactionParameters<
chain extends Chain | undefined = Chain | undefined,
account extends Account | undefined = Account | undefined,
chainOverride extends Chain | undefined = Chain | undefined,
accountOverride extends Account | Address | undefined =
| Account
| Address
| undefined,
///
_derivedChain extends Chain | undefined = DeriveChain<chain, chainOverride>,
> = UnionOmit<FormattedTransactionRequest<_derivedChain>, 'from'> &
GetAccountParameter<account, accountOverride, false, true> &
GetChainParameter<chain, chainOverride> & {
/**
* Nonce manager to use for the transaction request.
*/
nonceManager?: NonceManager | undefined
}
export type FillTransactionReturnType<
chain extends Chain | undefined = Chain | undefined,
chainOverride extends Chain | undefined = Chain | undefined,
///
_derivedChain extends Chain | undefined = DeriveChain<chain, chainOverride>,
> = {
capabilities?:
| ExtractCapabilities<'fillTransaction', 'ReturnType'>
| undefined
raw: Hex
transaction: FormattedTransaction<_derivedChain>
}
export type FillTransactionErrorType =
| GetTransactionErrorReturnType<ErrorType>
| ErrorType
/**
* Fills a transaction request with the necessary fields to be signed over.
*
* - Docs: https://viem.sh/docs/actions/public/fillTransaction
*
* @param client - Client to use
* @param parameters - {@link FillTransactionParameters}
* @returns The filled transaction. {@link FillTransactionReturnType}
*
* @example
* import { createPublicClient, http } from 'viem'
* import { mainnet } from 'viem/chains'
* import { fillTransaction } from 'viem/public'
*
* const client = createPublicClient({
* chain: mainnet,
* transport: http(),
* })
* const result = await fillTransaction(client, {
* account: '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e',
* to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
* value: parseEther('1'),
* })
*/
export async function fillTransaction<
chain extends Chain | undefined,
account extends Account | undefined,
chainOverride extends Chain | undefined = undefined,
accountOverride extends Account | Address | undefined = undefined,
>(
client: Client<Transport, chain, account>,
parameters: FillTransactionParameters<
chain,
account,
chainOverride,
accountOverride
>,
): Promise<FillTransactionReturnType<chain, chainOverride>> {
const {
account = client.account,
accessList,
authorizationList,
chain = client.chain,
blobVersionedHashes,
blobs,
data,
gas,
gasPrice,
maxFeePerBlobGas,
maxFeePerGas,
maxPriorityFeePerGas,
nonce: nonce_,
nonceManager,
to,
type,
value,
...rest
} = parameters
const nonce = await (async () => {
if (!account) return nonce_
if (!nonceManager) return nonce_
if (typeof nonce_ !== 'undefined') return nonce_
const account_ = parseAccount(account)
const chainId = chain
? chain.id
: await getAction(client, getChainId_, 'getChainId')({})
return await nonceManager.consume({
address: account_.address,
chainId,
client,
})
})()
assertRequest(parameters)
const chainFormat = chain?.formatters?.transactionRequest?.format
const format = chainFormat || formatTransactionRequest
const request = format(
{
// Pick out extra data that might exist on the chain's transaction request type.
...extract(rest, { format: chainFormat }),
account: account ? parseAccount(account) : undefined,
accessList,
authorizationList,
blobs,
blobVersionedHashes,
data,
gas,
gasPrice,
maxFeePerBlobGas,
maxFeePerGas,
maxPriorityFeePerGas,
nonce,
to,
type,
value,
} as TransactionRequest,
'fillTransaction',
)
try {
const response = await client.request({
method: 'eth_fillTransaction',
params: [request],
})
const format = chain?.formatters?.transaction?.format || formatTransaction
const transaction = format(response.tx)
// Remove unnecessary fields.
delete transaction.blockHash
delete transaction.blockNumber
delete transaction.r
delete transaction.s
delete transaction.transactionIndex
delete transaction.v
delete transaction.yParity
// Rewrite fields.
transaction.data = transaction.input
// Preference supplied fees (some nodes do not take these preferences).
if (transaction.gas) transaction.gas = parameters.gas ?? transaction.gas
if (transaction.gasPrice)
transaction.gasPrice = parameters.gasPrice ?? transaction.gasPrice
if (transaction.maxFeePerBlobGas)
transaction.maxFeePerBlobGas =
parameters.maxFeePerBlobGas ?? transaction.maxFeePerBlobGas
if (transaction.maxFeePerGas)
transaction.maxFeePerGas =
parameters.maxFeePerGas ?? transaction.maxFeePerGas
if (transaction.maxPriorityFeePerGas)
transaction.maxPriorityFeePerGas =
parameters.maxPriorityFeePerGas ?? transaction.maxPriorityFeePerGas
if (typeof transaction.nonce !== 'undefined')
transaction.nonce = parameters.nonce ?? transaction.nonce
// Build fee multiplier function.
const feeMultiplier = await (async () => {
if (typeof chain?.fees?.baseFeeMultiplier === 'function') {
const block = await getAction(client, getBlock, 'getBlock')({})
return chain.fees.baseFeeMultiplier({
block,
client,
request: parameters,
} as ChainFeesFnParameters)
}
return chain?.fees?.baseFeeMultiplier ?? 1.2
})()
if (feeMultiplier < 1) throw new BaseFeeScalarError()
const decimals = feeMultiplier.toString().split('.')[1]?.length ?? 0
const denominator = 10 ** decimals
const multiplyFee = (base: bigint) =>
(base * BigInt(Math.ceil(feeMultiplier * denominator))) /
BigInt(denominator)
// Apply fee multiplier.
if (!transaction.feePayerSignature) {
if (transaction.maxFeePerGas && !parameters.maxFeePerGas)
transaction.maxFeePerGas = multiplyFee(transaction.maxFeePerGas)
if (transaction.gasPrice && !parameters.gasPrice)
transaction.gasPrice = multiplyFee(transaction.gasPrice)
}
return {
raw: response.raw,
transaction: {
from: request.from,
...transaction,
},
...(response.capabilities ? { capabilities: response.capabilities } : {}),
}
} catch (err) {
throw getTransactionError(
err as BaseError,
{
...parameters,
chain: client.chain,
} as never,
)
}
}

121
node_modules/viem/actions/public/getBalance.ts generated vendored Normal file
View File

@@ -0,0 +1,121 @@
import type { Address } from 'abitype'
import type { Client } from '../../clients/createClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import { multicall3Abi } from '../../constants/abis.js'
import type { ErrorType } from '../../errors/utils.js'
import type { BlockTag } from '../../types/block.js'
import type { Chain } from '../../types/chain.js'
import { decodeFunctionResult } from '../../utils/abi/decodeFunctionResult.js'
import { encodeFunctionData } from '../../utils/abi/encodeFunctionData.js'
import type { RequestErrorType } from '../../utils/buildRequest.js'
import {
type NumberToHexErrorType,
numberToHex,
} from '../../utils/encoding/toHex.js'
import { getAction } from '../../utils/getAction.js'
import { type CallParameters, call } from './call.js'
export type GetBalanceParameters = {
/** The address of the account. */
address: Address
} & (
| {
/** The balance of the account at a block number. */
blockNumber?: bigint | undefined
blockTag?: undefined
}
| {
blockNumber?: undefined
/** The balance of the account at a block tag. */
blockTag?: BlockTag | undefined
}
)
export type GetBalanceReturnType = bigint
export type GetBalanceErrorType =
| NumberToHexErrorType
| RequestErrorType
| ErrorType
/**
* Returns the balance of an address in wei.
*
* - Docs: https://viem.sh/docs/actions/public/getBalance
* - JSON-RPC Methods: [`eth_getBalance`](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getbalance)
*
* You can convert the balance to ether units with [`formatEther`](https://viem.sh/docs/utilities/formatEther).
*
* ```ts
* const balance = await getBalance(client, {
* address: '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e',
* blockTag: 'safe'
* })
* const balanceAsEther = formatEther(balance)
* // "6.942"
* ```
*
* @param client - Client to use
* @param parameters - {@link GetBalanceParameters}
* @returns The balance of the address in wei. {@link GetBalanceReturnType}
*
* @example
* import { createPublicClient, http } from 'viem'
* import { mainnet } from 'viem/chains'
* import { getBalance } from 'viem/public'
*
* const client = createPublicClient({
* chain: mainnet,
* transport: http(),
* })
* const balance = await getBalance(client, {
* address: '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e',
* })
* // 10000000000000000000000n (wei)
*/
export async function getBalance<chain extends Chain | undefined>(
client: Client<Transport, chain>,
{
address,
blockNumber,
blockTag = client.experimental_blockTag ?? 'latest',
}: GetBalanceParameters,
): Promise<GetBalanceReturnType> {
if (client.batch?.multicall && client.chain?.contracts?.multicall3) {
const multicall3Address = client.chain.contracts.multicall3.address
const calldata = encodeFunctionData({
abi: multicall3Abi,
functionName: 'getEthBalance',
args: [address],
})
const { data } = await getAction(
client,
call,
'call',
)({
to: multicall3Address,
data: calldata,
blockNumber,
blockTag,
} as unknown as CallParameters<chain>)
return decodeFunctionResult({
abi: multicall3Abi,
functionName: 'getEthBalance',
args: [address],
data: data || '0x',
})
}
const blockNumberHex =
typeof blockNumber === 'bigint' ? numberToHex(blockNumber) : undefined
const balance = await client.request({
method: 'eth_getBalance',
params: [address, blockNumberHex || blockTag],
})
return BigInt(balance)
}

42
node_modules/viem/actions/public/getBlobBaseFee.ts generated vendored Normal file
View File

@@ -0,0 +1,42 @@
import type { Account } from '../../accounts/types.js'
import type { Client } from '../../clients/createClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { ErrorType } from '../../errors/utils.js'
import type { Chain } from '../../types/chain.js'
import type { RequestErrorType } from '../../utils/buildRequest.js'
export type GetBlobBaseFeeReturnType = bigint
export type GetBlobBaseFeeErrorType = RequestErrorType | ErrorType
/**
* Returns the base fee per blob gas in wei.
*
* - Docs: https://viem.sh/docs/actions/public/getBlobBaseFee
* - JSON-RPC Methods: [`eth_blobBaseFee`](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_blobBaseFee)
*
* @param client - Client to use
* @returns The blob base fee (in wei). {@link GetBlobBaseFeeReturnType}
*
* @example
* import { createPublicClient, http } from 'viem'
* import { mainnet } from 'viem/chains'
* import { getBlobBaseFee } from 'viem/public'
*
* const client = createPublicClient({
* chain: mainnet,
* transport: http(),
* })
* const blobBaseFee = await getBlobBaseFee(client)
*/
export async function getBlobBaseFee<
chain extends Chain | undefined,
account extends Account | undefined,
>(
client: Client<Transport, chain, account>,
): Promise<GetBlobBaseFeeReturnType> {
const baseFee = await client.request({
method: 'eth_blobBaseFee',
})
return BigInt(baseFee)
}

132
node_modules/viem/actions/public/getBlock.ts generated vendored Normal file
View File

@@ -0,0 +1,132 @@
import type { Account } from '../../accounts/types.js'
import type { Client } from '../../clients/createClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import {
BlockNotFoundError,
type BlockNotFoundErrorType,
} from '../../errors/block.js'
import type { ErrorType } from '../../errors/utils.js'
import type { BlockTag } from '../../types/block.js'
import type { Chain } from '../../types/chain.js'
import type { Hash } from '../../types/misc.js'
import type { RpcBlock } from '../../types/rpc.js'
import type { Prettify } from '../../types/utils.js'
import type { RequestErrorType } from '../../utils/buildRequest.js'
import {
type NumberToHexErrorType,
numberToHex,
} from '../../utils/encoding/toHex.js'
import {
type FormattedBlock,
formatBlock,
} from '../../utils/formatters/block.js'
export type GetBlockParameters<
includeTransactions extends boolean = false,
blockTag extends BlockTag = 'latest',
> = {
/** Whether or not to include transaction data in the response. */
includeTransactions?: includeTransactions | undefined
} & (
| {
/** Hash of the block. */
blockHash?: Hash | undefined
blockNumber?: undefined
blockTag?: undefined
}
| {
blockHash?: undefined
/** The block number. */
blockNumber?: bigint | undefined
blockTag?: undefined
}
| {
blockHash?: undefined
blockNumber?: undefined
/**
* The block tag.
* @default 'latest'
*/
blockTag?: blockTag | BlockTag | undefined
}
)
export type GetBlockReturnType<
chain extends Chain | undefined = undefined,
includeTransactions extends boolean = false,
blockTag extends BlockTag = 'latest',
> = Prettify<FormattedBlock<chain, includeTransactions, blockTag>>
export type GetBlockErrorType =
| BlockNotFoundErrorType
| NumberToHexErrorType
| RequestErrorType
| ErrorType
/**
* Returns information about a block at a block number, hash, or tag.
*
* - Docs: https://viem.sh/docs/actions/public/getBlock
* - Examples: https://stackblitz.com/github/wevm/viem/tree/main/examples/blocks_fetching-blocks
* - JSON-RPC Methods:
* - Calls [`eth_getBlockByNumber`](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getblockbynumber) for `blockNumber` & `blockTag`.
* - Calls [`eth_getBlockByHash`](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getblockbyhash) for `blockHash`.
*
* @param client - Client to use
* @param parameters - {@link GetBlockParameters}
* @returns Information about the block. {@link GetBlockReturnType}
*
* @example
* import { createPublicClient, http } from 'viem'
* import { mainnet } from 'viem/chains'
* import { getBlock } from 'viem/public'
*
* const client = createPublicClient({
* chain: mainnet,
* transport: http(),
* })
* const block = await getBlock(client)
*/
export async function getBlock<
chain extends Chain | undefined,
account extends Account | undefined,
includeTransactions extends boolean = false,
blockTag extends BlockTag = 'latest',
>(
client: Client<Transport, chain, account>,
{
blockHash,
blockNumber,
blockTag = client.experimental_blockTag ?? 'latest',
includeTransactions: includeTransactions_,
}: GetBlockParameters<includeTransactions, blockTag> = {},
): Promise<GetBlockReturnType<chain, includeTransactions, blockTag>> {
const includeTransactions = includeTransactions_ ?? false
const blockNumberHex =
blockNumber !== undefined ? numberToHex(blockNumber) : undefined
let block: RpcBlock | null = null
if (blockHash) {
block = await client.request(
{
method: 'eth_getBlockByHash',
params: [blockHash, includeTransactions],
},
{ dedupe: true },
)
} else {
block = await client.request(
{
method: 'eth_getBlockByNumber',
params: [blockNumberHex || blockTag, includeTransactions],
},
{ dedupe: Boolean(blockNumberHex) },
)
}
if (!block) throw new BlockNotFoundError({ blockHash, blockNumber })
const format = client.chain?.formatters?.block?.format || formatBlock
return format(block, 'getBlock')
}

66
node_modules/viem/actions/public/getBlockNumber.ts generated vendored Normal file
View File

@@ -0,0 +1,66 @@
import type { Client } from '../../clients/createClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { ErrorType } from '../../errors/utils.js'
import type { Chain } from '../../types/chain.js'
import type { RequestErrorType } from '../../utils/buildRequest.js'
import {
type GetCacheErrorType,
getCache,
withCache,
} from '../../utils/promise/withCache.js'
export type GetBlockNumberParameters = {
/** Time (in ms) that cached block number will remain in memory. */
cacheTime?: number | undefined
}
export type GetBlockNumberReturnType = bigint
export type GetBlockNumberErrorType = RequestErrorType | ErrorType
const cacheKey = (id: string) => `blockNumber.${id}`
/** @internal */
export type GetBlockNumberCacheErrorType = GetCacheErrorType | ErrorType
/** @internal */
export function getBlockNumberCache(id: string) {
return getCache(cacheKey(id))
}
/**
* Returns the number of the most recent block seen.
*
* - Docs: https://viem.sh/docs/actions/public/getBlockNumber
* - Examples: https://stackblitz.com/github/wevm/viem/tree/main/examples/blocks_fetching-blocks
* - JSON-RPC Methods: [`eth_blockNumber`](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_blocknumber)
*
* @param client - Client to use
* @param parameters - {@link GetBlockNumberParameters}
* @returns The number of the block. {@link GetBlockNumberReturnType}
*
* @example
* import { createPublicClient, http } from 'viem'
* import { mainnet } from 'viem/chains'
* import { getBlockNumber } from 'viem/public'
*
* const client = createPublicClient({
* chain: mainnet,
* transport: http(),
* })
* const blockNumber = await getBlockNumber(client)
* // 69420n
*/
export async function getBlockNumber<chain extends Chain | undefined>(
client: Client<Transport, chain>,
{ cacheTime = client.cacheTime }: GetBlockNumberParameters = {},
): Promise<GetBlockNumberReturnType> {
const blockNumberHex = await withCache(
() =>
client.request({
method: 'eth_blockNumber',
}),
{ cacheKey: cacheKey(client.uid), cacheTime },
)
return BigInt(blockNumberHex)
}

View File

@@ -0,0 +1,100 @@
import type { Client } from '../../clients/createClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { ErrorType } from '../../errors/utils.js'
import type { BlockTag } from '../../types/block.js'
import type { Chain } from '../../types/chain.js'
import type { Hash } from '../../types/misc.js'
import type { Quantity } from '../../types/rpc.js'
import type { RequestErrorType } from '../../utils/buildRequest.js'
import {
type HexToNumberErrorType,
hexToNumber,
} from '../../utils/encoding/fromHex.js'
import {
type NumberToHexErrorType,
numberToHex,
} from '../../utils/encoding/toHex.js'
export type GetBlockTransactionCountParameters =
| {
/** Hash of the block. */
blockHash?: Hash | undefined
blockNumber?: undefined
blockTag?: undefined
}
| {
blockHash?: undefined
/** The block number. */
blockNumber?: bigint | undefined
blockTag?: undefined
}
| {
blockHash?: undefined
blockNumber?: undefined
/** The block tag. Defaults to 'latest'. */
blockTag?: BlockTag | undefined
}
export type GetBlockTransactionCountReturnType = number
export type GetBlockTransactionCountErrorType =
| NumberToHexErrorType
| HexToNumberErrorType
| RequestErrorType
| ErrorType
/**
* Returns the number of Transactions at a block number, hash, or tag.
*
* - Docs: https://viem.sh/docs/actions/public/getBlockTransactionCount
* - JSON-RPC Methods:
* - Calls [`eth_getBlockTransactionCountByNumber`](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getblocktransactioncountbynumber) for `blockNumber` & `blockTag`.
* - Calls [`eth_getBlockTransactionCountByHash`](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getblocktransactioncountbyhash) for `blockHash`.
*
* @param client - Client to use
* @param parameters - {@link GetBlockTransactionCountParameters}
* @returns The block transaction count. {@link GetBlockTransactionCountReturnType}
*
* @example
* import { createPublicClient, http } from 'viem'
* import { mainnet } from 'viem/chains'
* import { getBlockTransactionCount } from 'viem/public'
*
* const client = createPublicClient({
* chain: mainnet,
* transport: http(),
* })
* const count = await getBlockTransactionCount(client)
*/
export async function getBlockTransactionCount<chain extends Chain | undefined>(
client: Client<Transport, chain>,
{
blockHash,
blockNumber,
blockTag = 'latest',
}: GetBlockTransactionCountParameters = {},
): Promise<GetBlockTransactionCountReturnType> {
const blockNumberHex =
blockNumber !== undefined ? numberToHex(blockNumber) : undefined
let count: Quantity
if (blockHash) {
count = await client.request(
{
method: 'eth_getBlockTransactionCountByHash',
params: [blockHash],
},
{ dedupe: true },
)
} else {
count = await client.request(
{
method: 'eth_getBlockTransactionCountByNumber',
params: [blockNumberHex || blockTag],
},
{ dedupe: Boolean(blockNumberHex) },
)
}
return hexToNumber(count)
}

51
node_modules/viem/actions/public/getChainId.ts generated vendored Normal file
View File

@@ -0,0 +1,51 @@
import type { Account } from '../../accounts/types.js'
import type { Client } from '../../clients/createClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { ErrorType } from '../../errors/utils.js'
import type { Chain } from '../../types/chain.js'
import type { RequestErrorType } from '../../utils/buildRequest.js'
import {
type HexToNumberErrorType,
hexToNumber,
} from '../../utils/encoding/fromHex.js'
export type GetChainIdReturnType = number
export type GetChainIdErrorType =
| HexToNumberErrorType
| RequestErrorType
| ErrorType
/**
* Returns the chain ID associated with the current network.
*
* - Docs: https://viem.sh/docs/actions/public/getChainId
* - JSON-RPC Methods: [`eth_chainId`](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_chainid)
*
* @param client - Client to use
* @returns The current chain ID. {@link GetChainIdReturnType}
*
* @example
* import { createPublicClient, http } from 'viem'
* import { mainnet } from 'viem/chains'
* import { getChainId } from 'viem/public'
*
* const client = createPublicClient({
* chain: mainnet,
* transport: http(),
* })
* const chainId = await getChainId(client)
* // 1
*/
export async function getChainId<
chain extends Chain | undefined,
account extends Account | undefined,
>(client: Client<Transport, chain, account>): Promise<GetChainIdReturnType> {
const chainIdHex = await client.request(
{
method: 'eth_chainId',
},
{ dedupe: true },
)
return hexToNumber(chainIdHex)
}

73
node_modules/viem/actions/public/getCode.ts generated vendored Normal file
View File

@@ -0,0 +1,73 @@
import type { Address } from 'abitype'
import type { Client } from '../../clients/createClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { ErrorType } from '../../errors/utils.js'
import type { BlockTag } from '../../types/block.js'
import type { Chain } from '../../types/chain.js'
import type { Hex } from '../../types/misc.js'
import type { RequestErrorType } from '../../utils/buildRequest.js'
import {
type NumberToHexErrorType,
numberToHex,
} from '../../utils/encoding/toHex.js'
export type GetCodeParameters = {
address: Address
} & (
| {
blockNumber?: undefined
blockTag?: BlockTag | undefined
}
| {
blockNumber?: bigint | undefined
blockTag?: undefined
}
)
export type GetCodeReturnType = Hex | undefined
export type GetCodeErrorType =
| NumberToHexErrorType
| RequestErrorType
| ErrorType
/**
* Retrieves the bytecode at an address.
*
* - Docs: https://viem.sh/docs/contract/getCode
* - JSON-RPC Methods: [`eth_getCode`](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getcode)
*
* @param client - Client to use
* @param parameters - {@link GetCodeParameters}
* @returns The contract's bytecode. {@link GetCodeReturnType}
*
* @example
* import { createPublicClient, http } from 'viem'
* import { mainnet } from 'viem/chains'
* import { getCode } from 'viem/contract'
*
* const client = createPublicClient({
* chain: mainnet,
* transport: http(),
* })
* const code = await getCode(client, {
* address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
* })
*/
export async function getCode<chain extends Chain | undefined>(
client: Client<Transport, chain>,
{ address, blockNumber, blockTag = 'latest' }: GetCodeParameters,
): Promise<GetCodeReturnType> {
const blockNumberHex =
blockNumber !== undefined ? numberToHex(blockNumber) : undefined
const hex = await client.request(
{
method: 'eth_getCode',
params: [address, blockNumberHex || blockTag],
},
{ dedupe: Boolean(blockNumberHex) },
)
if (hex === '0x') return undefined
return hex
}

170
node_modules/viem/actions/public/getContractEvents.ts generated vendored Normal file
View File

@@ -0,0 +1,170 @@
import type { Abi, Address } from 'abitype'
import type { Client } from '../../clients/createClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { ErrorType } from '../../errors/utils.js'
import type { BlockNumber, BlockTag } from '../../types/block.js'
import type { Chain } from '../../types/chain.js'
import type {
ContractEventArgs,
ContractEventName,
} from '../../types/contract.js'
import type { Log } from '../../types/log.js'
import type { Hash } from '../../types/misc.js'
import {
type GetAbiItemErrorType,
type GetAbiItemParameters,
getAbiItem,
} from '../../utils/abi/getAbiItem.js'
import { getAction } from '../../utils/getAction.js'
import {
type GetLogsErrorType,
type GetLogsParameters,
getLogs,
} from './getLogs.js'
export type GetContractEventsParameters<
abi extends Abi | readonly unknown[] = Abi,
eventName extends ContractEventName<abi> | undefined =
| ContractEventName<abi>
| undefined,
strict extends boolean | undefined = undefined,
fromBlock extends BlockNumber | BlockTag | undefined = undefined,
toBlock extends BlockNumber | BlockTag | undefined = undefined,
> = {
/** The address of the contract. */
address?: Address | Address[] | undefined
/** Contract ABI. */
abi: abi
args?:
| ContractEventArgs<
abi,
eventName extends ContractEventName<abi>
? eventName
: ContractEventName<abi>
>
| undefined
/** Contract event. */
eventName?: eventName | ContractEventName<abi> | undefined
/**
* Whether or not the logs must match the indexed/non-indexed arguments on `event`.
* @default false
*/
strict?: strict | boolean | undefined
} & (
| {
/** Block number or tag after which to include logs */
fromBlock?: fromBlock | BlockNumber | BlockTag | undefined
/** Block number or tag before which to include logs */
toBlock?: toBlock | BlockNumber | BlockTag | undefined
blockHash?: undefined
}
| {
fromBlock?: undefined
toBlock?: undefined
/** Hash of block to include logs from */
blockHash?: Hash | undefined
}
)
export type GetContractEventsReturnType<
abi extends Abi | readonly unknown[] = readonly unknown[],
eventName extends ContractEventName<abi> | undefined =
| ContractEventName<abi>
| undefined,
strict extends boolean | undefined = undefined,
fromBlock extends BlockNumber | BlockTag | undefined = undefined,
toBlock extends BlockNumber | BlockTag | undefined = undefined,
///
isPending extends boolean =
| (fromBlock extends 'pending' ? true : false)
| (toBlock extends 'pending' ? true : false),
> = Log<bigint, number, isPending, undefined, strict, abi, eventName>[]
export type GetContractEventsErrorType =
| GetAbiItemErrorType
| GetLogsErrorType
| ErrorType
/**
* Returns a list of event logs emitted by a contract.
*
* - Docs: https://viem.sh/docs/contract/getContractEvents#getcontractevents
* - JSON-RPC Methods: [`eth_getLogs`](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getlogs)
*
* @param client - Client to use
* @param parameters - {@link GetContractEventsParameters}
* @returns A list of event logs. {@link GetContractEventsReturnType}
*
* @example
* import { createClient, http } from 'viem'
* import { mainnet } from 'viem/chains'
* import { getContractEvents } from 'viem/public'
* import { wagmiAbi } from './abi'
*
* const client = createClient({
* chain: mainnet,
* transport: http(),
* })
* const logs = await getContractEvents(client, {
* address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
* abi: wagmiAbi,
* eventName: 'Transfer'
* })
*/
export async function getContractEvents<
chain extends Chain | undefined,
const abi extends Abi | readonly unknown[],
eventName extends ContractEventName<abi> | undefined = undefined,
strict extends boolean | undefined = undefined,
fromBlock extends BlockNumber | BlockTag | undefined = undefined,
toBlock extends BlockNumber | BlockTag | undefined = undefined,
>(
client: Client<Transport, chain>,
parameters: GetContractEventsParameters<
abi,
eventName,
strict,
fromBlock,
toBlock
>,
): Promise<
GetContractEventsReturnType<abi, eventName, strict, fromBlock, toBlock>
> {
const {
abi,
address,
args,
blockHash,
eventName,
fromBlock,
toBlock,
strict,
} = parameters
const event = eventName
? getAbiItem({ abi, name: eventName } as GetAbiItemParameters)
: undefined
const events = !event
? (abi as Abi).filter((x) => x.type === 'event')
: undefined
return getAction(
client,
getLogs,
'getLogs',
)({
address,
args,
blockHash,
event,
events,
fromBlock,
toBlock,
strict,
} as {} as GetLogsParameters) as unknown as GetContractEventsReturnType<
abi,
eventName,
strict,
fromBlock,
toBlock
>
}

80
node_modules/viem/actions/public/getDelegation.ts generated vendored Normal file
View File

@@ -0,0 +1,80 @@
import type { Address } from 'abitype'
import type { Client } from '../../clients/createClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { ErrorType } from '../../errors/utils.js'
import type { BlockTag } from '../../types/block.js'
import type { Chain } from '../../types/chain.js'
import {
type GetAddressErrorType,
getAddress,
} from '../../utils/address/getAddress.js'
import { type SizeErrorType, size } from '../../utils/data/size.js'
import { type SliceErrorType, slice } from '../../utils/data/slice.js'
import { type GetCodeErrorType, getCode } from './getCode.js'
export type GetDelegationParameters = {
/** The address to check for delegation. */
address: Address
} & (
| {
blockNumber?: undefined
blockTag?: BlockTag | undefined
}
| {
blockNumber?: bigint | undefined
blockTag?: undefined
}
)
export type GetDelegationReturnType = Address | undefined
export type GetDelegationErrorType =
| GetAddressErrorType
| GetCodeErrorType
| SliceErrorType
| SizeErrorType
| ErrorType
/**
* Returns the address that an account has delegated to via EIP-7702.
*
* - Docs: https://viem.sh/docs/actions/public/getDelegation
*
* @param client - Client to use
* @param parameters - {@link GetDelegationParameters}
* @returns The delegated address, or undefined if not delegated. {@link GetDelegationReturnType}
*
* @example
* import { createPublicClient, http } from 'viem'
* import { mainnet } from 'viem/chains'
* import { getDelegation } from 'viem/actions'
*
* const client = createPublicClient({
* chain: mainnet,
* transport: http(),
* })
* const delegation = await getDelegation(client, {
* address: '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e',
* })
*/
export async function getDelegation<chain extends Chain | undefined>(
client: Client<Transport, chain>,
{ address, blockNumber, blockTag = 'latest' }: GetDelegationParameters,
): Promise<GetDelegationReturnType> {
const code = await getCode(client, {
address,
...(blockNumber !== undefined ? { blockNumber } : { blockTag }),
} as GetDelegationParameters)
if (!code) return undefined
// EIP-7702 delegation designator: 0xef0100 prefix (3 bytes) + address (20 bytes) = 23 bytes
if (size(code) !== 23) return undefined
// Check for EIP-7702 delegation designator prefix
if (!code.startsWith('0xef0100')) return undefined
// Extract the delegated address (bytes 3-23) and checksum it
return getAddress(slice(code, 3, 23))
}

134
node_modules/viem/actions/public/getEip712Domain.ts generated vendored Normal file
View File

@@ -0,0 +1,134 @@
import type { Address, TypedDataDomain } from 'abitype'
import type { Client } from '../../clients/createClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import {
Eip712DomainNotFoundError,
type Eip712DomainNotFoundErrorType,
} from '../../errors/eip712.js'
import type { ErrorType } from '../../errors/utils.js'
import type { Hex } from '../../types/misc.js'
import type { RequiredBy } from '../../types/utils.js'
import { getAction } from '../../utils/getAction.js'
import {
type ReadContractErrorType,
type ReadContractParameters,
readContract,
} from './readContract.js'
export type GetEip712DomainParameters = {
address: Address
} & Pick<ReadContractParameters, 'factory' | 'factoryData'>
export type GetEip712DomainReturnType = {
domain: RequiredBy<
TypedDataDomain,
'chainId' | 'name' | 'verifyingContract' | 'salt' | 'version'
>
fields: Hex
extensions: readonly bigint[]
}
export type GetEip712DomainErrorType =
| Eip712DomainNotFoundErrorType
| ReadContractErrorType
| ErrorType
/**
* Reads the EIP-712 domain from a contract, based on the ERC-5267 specification.
*
* @param client - A {@link Client} instance.
* @param parameters - The parameters of the action. {@link GetEip712DomainParameters}
* @returns The EIP-712 domain, fields, and extensions. {@link GetEip712DomainReturnType}
*
* @example
* ```ts
* import { createPublicClient, http, getEip712Domain } from 'viem'
* import { mainnet } from 'viem/chains'
*
* const client = createPublicClient({
* chain: mainnet,
* transport: http(),
* })
*
* const domain = await getEip712Domain(client, {
* address: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
* })
* // {
* // domain: {
* // name: 'ExampleContract',
* // version: '1',
* // chainId: 1,
* // verifyingContract: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
* // },
* // fields: '0x0f',
* // extensions: [],
* // }
* ```
*/
export async function getEip712Domain(
client: Client<Transport>,
parameters: GetEip712DomainParameters,
): Promise<GetEip712DomainReturnType> {
const { address, factory, factoryData } = parameters
try {
const [
fields,
name,
version,
chainId,
verifyingContract,
salt,
extensions,
] = await getAction(
client,
readContract,
'readContract',
)({
abi,
address,
functionName: 'eip712Domain',
factory,
factoryData,
})
return {
domain: {
name,
version,
chainId: Number(chainId),
verifyingContract,
salt,
},
extensions,
fields,
}
} catch (e) {
const error = e as ReadContractErrorType
if (
error.name === 'ContractFunctionExecutionError' &&
error.cause.name === 'ContractFunctionZeroDataError'
) {
throw new Eip712DomainNotFoundError({ address })
}
throw error
}
}
const abi = [
{
inputs: [],
name: 'eip712Domain',
outputs: [
{ name: 'fields', type: 'bytes1' },
{ name: 'name', type: 'string' },
{ name: 'version', type: 'string' },
{ name: 'chainId', type: 'uint256' },
{ name: 'verifyingContract', type: 'address' },
{ name: 'salt', type: 'bytes32' },
{ name: 'extensions', type: 'uint256[]' },
],
stateMutability: 'view',
type: 'function',
},
] as const

94
node_modules/viem/actions/public/getFeeHistory.ts generated vendored Normal file
View File

@@ -0,0 +1,94 @@
import type { Client } from '../../clients/createClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { BlockTag } from '../../types/block.js'
import type { Chain } from '../../types/chain.js'
import type { FeeHistory } from '../../types/fee.js'
import type { RequestErrorType } from '../../utils/buildRequest.js'
import {
type NumberToHexErrorType,
numberToHex,
} from '../../utils/encoding/toHex.js'
import {
type FormatFeeHistoryErrorType,
formatFeeHistory,
} from '../../utils/formatters/feeHistory.js'
export type GetFeeHistoryParameters = {
/**
* Number of blocks in the requested range. Between 1 and 1024 blocks can be requested in a single query. Less than requested may be returned if not all blocks are available.
*/
blockCount: number
/**
* A monotonically increasing list of percentile values to sample from each block's effective priority fees per gas in ascending order, weighted by gas used.
*/
rewardPercentiles: number[]
} & (
| {
blockNumber?: undefined
/**
* Highest number block of the requested range.
* @default 'latest'
*/
blockTag?: BlockTag | undefined
}
| {
/** Highest number block of the requested range. */
blockNumber?: bigint | undefined
blockTag?: undefined
}
)
export type GetFeeHistoryReturnType = FeeHistory
export type GetFeeHistoryErrorType =
| NumberToHexErrorType
| RequestErrorType
| FormatFeeHistoryErrorType
/**
* Returns a collection of historical gas information.
*
* - Docs: https://viem.sh/docs/actions/public/getFeeHistory
* - JSON-RPC Methods: [`eth_feeHistory`](https://docs.alchemy.com/reference/eth-feehistory)
*
* @param client - Client to use
* @param parameters - {@link GetFeeHistoryParameters}
* @returns The gas estimate (in wei). {@link GetFeeHistoryReturnType}
*
* @example
* import { createPublicClient, http } from 'viem'
* import { mainnet } from 'viem/chains'
* import { getFeeHistory } from 'viem/public'
*
* const client = createPublicClient({
* chain: mainnet,
* transport: http(),
* })
* const feeHistory = await getFeeHistory(client, {
* blockCount: 4,
* rewardPercentiles: [25, 75],
* })
*/
export async function getFeeHistory<chain extends Chain | undefined>(
client: Client<Transport, chain>,
{
blockCount,
blockNumber,
blockTag = 'latest',
rewardPercentiles,
}: GetFeeHistoryParameters,
): Promise<GetFeeHistoryReturnType> {
const blockNumberHex =
typeof blockNumber === 'bigint' ? numberToHex(blockNumber) : undefined
const feeHistory = await client.request(
{
method: 'eth_feeHistory',
params: [
numberToHex(blockCount),
blockNumberHex || blockTag,
rewardPercentiles,
],
},
{ dedupe: Boolean(blockNumberHex) },
)
return formatFeeHistory(feeHistory)
}

208
node_modules/viem/actions/public/getFilterChanges.ts generated vendored Normal file
View File

@@ -0,0 +1,208 @@
import type { Abi, AbiEvent, ExtractAbiEvent } from 'abitype'
import type { Client } from '../../clients/createClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { ErrorType } from '../../errors/utils.js'
import type { RpcLog } from '../../index.js'
import type { BlockNumber, BlockTag } from '../../types/block.js'
import type { Chain } from '../../types/chain.js'
import type { Filter, FilterType } from '../../types/filter.js'
import type { Log } from '../../types/log.js'
import type { Hash } from '../../types/misc.js'
import type { DecodeEventLogErrorType } from '../../utils/abi/decodeEventLog.js'
import { parseEventLogs } from '../../utils/abi/parseEventLogs.js'
import type { RequestErrorType } from '../../utils/buildRequest.js'
import {
type FormatLogErrorType,
formatLog,
} from '../../utils/formatters/log.js'
export type GetFilterChangesParameters<
filterType extends FilterType = FilterType,
abi extends Abi | readonly unknown[] | undefined = undefined,
eventName extends string | undefined = undefined,
strict extends boolean | undefined = undefined,
fromBlock extends BlockNumber | BlockTag | undefined = undefined,
toBlock extends BlockNumber | BlockTag | undefined = undefined,
> = {
filter: Filter<filterType, abi, eventName, any, strict, fromBlock, toBlock>
}
export type GetFilterChangesReturnType<
filterType extends FilterType = FilterType,
abi extends Abi | readonly unknown[] | undefined = undefined,
eventName extends string | undefined = undefined,
strict extends boolean | undefined = undefined,
fromBlock extends BlockNumber | BlockTag | undefined = undefined,
toBlock extends BlockNumber | BlockTag | undefined = undefined,
_AbiEvent extends AbiEvent | undefined = abi extends Abi
? eventName extends string
? ExtractAbiEvent<abi, eventName>
: undefined
: undefined,
_Pending extends boolean =
| (fromBlock extends 'pending' ? true : false)
| (toBlock extends 'pending' ? true : false),
> = filterType extends 'event'
? Log<bigint, number, _Pending, _AbiEvent, strict, abi, eventName>[]
: Hash[]
export type GetFilterChangesErrorType =
| RequestErrorType
| DecodeEventLogErrorType
| FormatLogErrorType
| ErrorType
/**
* Returns a list of logs or hashes based on a [Filter](/docs/glossary/terms#filter) since the last time it was called.
*
* - Docs: https://viem.sh/docs/actions/public/getFilterChanges
* - JSON-RPC Methods: [`eth_getFilterChanges`](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getfilterchanges)
*
* A Filter can be created from the following actions:
*
* - [`createBlockFilter`](https://viem.sh/docs/actions/public/createBlockFilter)
* - [`createContractEventFilter`](https://viem.sh/docs/contract/createContractEventFilter)
* - [`createEventFilter`](https://viem.sh/docs/actions/public/createEventFilter)
* - [`createPendingTransactionFilter`](https://viem.sh/docs/actions/public/createPendingTransactionFilter)
*
* Depending on the type of filter, the return value will be different:
*
* - If the filter was created with `createContractEventFilter` or `createEventFilter`, it returns a list of logs.
* - If the filter was created with `createPendingTransactionFilter`, it returns a list of transaction hashes.
* - If the filter was created with `createBlockFilter`, it returns a list of block hashes.
*
* @param client - Client to use
* @param parameters - {@link GetFilterChangesParameters}
* @returns Logs or hashes. {@link GetFilterChangesReturnType}
*
* @example
* // Blocks
* import { createPublicClient, http } from 'viem'
* import { mainnet } from 'viem/chains'
* import { createBlockFilter, getFilterChanges } from 'viem/public'
*
* const client = createPublicClient({
* chain: mainnet,
* transport: http(),
* })
* const filter = await createBlockFilter(client)
* const hashes = await getFilterChanges(client, { filter })
*
* @example
* // Contract Events
* import { createPublicClient, http, parseAbi } from 'viem'
* import { mainnet } from 'viem/chains'
* import { createContractEventFilter, getFilterChanges } from 'viem/public'
*
* const client = createPublicClient({
* chain: mainnet,
* transport: http(),
* })
* const filter = await createContractEventFilter(client, {
* address: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
* abi: parseAbi(['event Transfer(address indexed, address indexed, uint256)']),
* eventName: 'Transfer',
* })
* const logs = await getFilterChanges(client, { filter })
*
* @example
* // Raw Events
* import { createPublicClient, http, parseAbiItem } from 'viem'
* import { mainnet } from 'viem/chains'
* import { createEventFilter, getFilterChanges } from 'viem/public'
*
* const client = createPublicClient({
* chain: mainnet,
* transport: http(),
* })
* const filter = await createEventFilter(client, {
* address: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
* event: parseAbiItem('event Transfer(address indexed, address indexed, uint256)'),
* })
* const logs = await getFilterChanges(client, { filter })
*
* @example
* // Transactions
* import { createPublicClient, http } from 'viem'
* import { mainnet } from 'viem/chains'
* import { createPendingTransactionFilter, getFilterChanges } from 'viem/public'
*
* const client = createPublicClient({
* chain: mainnet,
* transport: http(),
* })
* const filter = await createPendingTransactionFilter(client)
* const hashes = await getFilterChanges(client, { filter })
*/
export async function getFilterChanges<
transport extends Transport,
chain extends Chain | undefined,
filterType extends FilterType,
const abi extends Abi | readonly unknown[] | undefined,
eventName extends string | undefined,
strict extends boolean | undefined = undefined,
fromBlock extends BlockNumber | BlockTag | undefined = undefined,
toBlock extends BlockNumber | BlockTag | undefined = undefined,
>(
_client: Client<transport, chain>,
{
filter,
}: GetFilterChangesParameters<
filterType,
abi,
eventName,
strict,
fromBlock,
toBlock
>,
): Promise<
GetFilterChangesReturnType<
filterType,
abi,
eventName,
strict,
fromBlock,
toBlock
>
> {
const strict = 'strict' in filter && filter.strict
const logs = await filter.request({
method: 'eth_getFilterChanges',
params: [filter.id],
})
if (typeof logs[0] === 'string')
return logs as GetFilterChangesReturnType<
filterType,
abi,
eventName,
strict,
fromBlock,
toBlock
>
const formattedLogs = logs.map((log) => formatLog(log as RpcLog))
if (!('abi' in filter) || !filter.abi)
return formattedLogs as GetFilterChangesReturnType<
filterType,
abi,
eventName,
strict,
fromBlock,
toBlock
>
return parseEventLogs({
abi: filter.abi,
logs: formattedLogs,
strict,
}) as unknown as GetFilterChangesReturnType<
filterType,
abi,
eventName,
strict,
fromBlock,
toBlock
>
}

119
node_modules/viem/actions/public/getFilterLogs.ts generated vendored Normal file
View File

@@ -0,0 +1,119 @@
import type { Abi, AbiEvent, ExtractAbiEvent } from 'abitype'
import type { Client } from '../../clients/createClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { ErrorType } from '../../errors/utils.js'
import type { BlockNumber, BlockTag } from '../../types/block.js'
import type { Chain } from '../../types/chain.js'
import type { Filter } from '../../types/filter.js'
import type { Log } from '../../types/log.js'
import type { DecodeEventLogErrorType } from '../../utils/abi/decodeEventLog.js'
import { parseEventLogs } from '../../utils/abi/parseEventLogs.js'
import type { RequestErrorType } from '../../utils/buildRequest.js'
import {
type FormatLogErrorType,
formatLog,
} from '../../utils/formatters/log.js'
export type GetFilterLogsParameters<
abi extends Abi | readonly unknown[] | undefined = undefined,
eventName extends string | undefined = undefined,
strict extends boolean | undefined = undefined,
fromBlock extends BlockNumber | BlockTag | undefined = undefined,
toBlock extends BlockNumber | BlockTag | undefined = undefined,
> = {
filter: Filter<'event', abi, eventName, any, strict, fromBlock, toBlock>
}
export type GetFilterLogsReturnType<
abi extends Abi | readonly unknown[] | undefined = undefined,
eventName extends string | undefined = undefined,
strict extends boolean | undefined = undefined,
fromBlock extends BlockNumber | BlockTag | undefined = undefined,
toBlock extends BlockNumber | BlockTag | undefined = undefined,
_AbiEvent extends AbiEvent | undefined = abi extends Abi
? eventName extends string
? ExtractAbiEvent<abi, eventName>
: undefined
: undefined,
_Pending extends boolean =
| (fromBlock extends 'pending' ? true : false)
| (toBlock extends 'pending' ? true : false),
> = Log<bigint, number, _Pending, _AbiEvent, strict, abi, eventName>[]
export type GetFilterLogsErrorType =
| RequestErrorType
| DecodeEventLogErrorType
| FormatLogErrorType
| ErrorType
/**
* Returns a list of event logs since the filter was created.
*
* - Docs: https://viem.sh/docs/actions/public/getFilterLogs
* - JSON-RPC Methods: [`eth_getFilterLogs`](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getfilterlogs)
*
* `getFilterLogs` is only compatible with **event filters**.
*
* @param client - Client to use
* @param parameters - {@link GetFilterLogsParameters}
* @returns A list of event logs. {@link GetFilterLogsReturnType}
*
* @example
* import { createPublicClient, http, parseAbiItem } from 'viem'
* import { mainnet } from 'viem/chains'
* import { createEventFilter, getFilterLogs } from 'viem/public'
*
* const client = createPublicClient({
* chain: mainnet,
* transport: http(),
* })
* const filter = await createEventFilter(client, {
* address: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
* event: parseAbiItem('event Transfer(address indexed, address indexed, uint256)'),
* })
* const logs = await getFilterLogs(client, { filter })
*/
export async function getFilterLogs<
chain extends Chain | undefined,
const abi extends Abi | readonly unknown[] | undefined,
eventName extends string | undefined,
strict extends boolean | undefined = undefined,
fromBlock extends BlockNumber | BlockTag | undefined = undefined,
toBlock extends BlockNumber | BlockTag | undefined = undefined,
>(
_client: Client<Transport, chain>,
{
filter,
}: GetFilterLogsParameters<abi, eventName, strict, fromBlock, toBlock>,
): Promise<
GetFilterLogsReturnType<abi, eventName, strict, fromBlock, toBlock>
> {
const strict = filter.strict ?? false
const logs = await filter.request({
method: 'eth_getFilterLogs',
params: [filter.id],
})
const formattedLogs = logs.map((log) => formatLog(log))
if (!filter.abi)
return formattedLogs as GetFilterLogsReturnType<
abi,
eventName,
strict,
fromBlock,
toBlock
>
return parseEventLogs({
abi: filter.abi,
logs: formattedLogs,
strict,
}) as unknown as GetFilterLogsReturnType<
abi,
eventName,
strict,
fromBlock,
toBlock
>
}

40
node_modules/viem/actions/public/getGasPrice.ts generated vendored Normal file
View File

@@ -0,0 +1,40 @@
import type { Account } from '../../accounts/types.js'
import type { Client } from '../../clients/createClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { ErrorType } from '../../errors/utils.js'
import type { Chain } from '../../types/chain.js'
import type { RequestErrorType } from '../../utils/buildRequest.js'
export type GetGasPriceReturnType = bigint
export type GetGasPriceErrorType = RequestErrorType | ErrorType
/**
* Returns the current price of gas (in wei).
*
* - Docs: https://viem.sh/docs/actions/public/getGasPrice
* - JSON-RPC Methods: [`eth_gasPrice`](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_gasprice)
*
* @param client - Client to use
* @returns The gas price (in wei). {@link GetGasPriceReturnType}
*
* @example
* import { createPublicClient, http } from 'viem'
* import { mainnet } from 'viem/chains'
* import { getGasPrice } from 'viem/public'
*
* const client = createPublicClient({
* chain: mainnet,
* transport: http(),
* })
* const gasPrice = await getGasPrice(client)
*/
export async function getGasPrice<
chain extends Chain | undefined,
account extends Account | undefined,
>(client: Client<Transport, chain, account>): Promise<GetGasPriceReturnType> {
const gasPrice = await client.request({
method: 'eth_gasPrice',
})
return BigInt(gasPrice)
}

218
node_modules/viem/actions/public/getLogs.ts generated vendored Normal file
View File

@@ -0,0 +1,218 @@
import type { AbiEvent, Address } from 'abitype'
import type { Client } from '../../clients/createClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { ErrorType } from '../../errors/utils.js'
import type { BlockNumber, BlockTag } from '../../types/block.js'
import type { Chain } from '../../types/chain.js'
import type {
MaybeAbiEventName,
MaybeExtractEventArgsFromAbi,
} from '../../types/contract.js'
import type { Log } from '../../types/log.js'
import type { Hash, LogTopic } from '../../types/misc.js'
import type { RpcLog } from '../../types/rpc.js'
import type { DecodeEventLogErrorType } from '../../utils/abi/decodeEventLog.js'
import {
type EncodeEventTopicsErrorType,
type EncodeEventTopicsParameters,
encodeEventTopics,
} from '../../utils/abi/encodeEventTopics.js'
import { parseEventLogs } from '../../utils/abi/parseEventLogs.js'
import type { RequestErrorType } from '../../utils/buildRequest.js'
import {
type NumberToHexErrorType,
numberToHex,
} from '../../utils/encoding/toHex.js'
import {
type FormatLogErrorType,
formatLog,
} from '../../utils/formatters/log.js'
export type GetLogsParameters<
abiEvent extends AbiEvent | undefined = undefined,
abiEvents extends
| readonly AbiEvent[]
| readonly unknown[]
| undefined = abiEvent extends AbiEvent ? [abiEvent] : undefined,
strict extends boolean | undefined = undefined,
fromBlock extends BlockNumber | BlockTag | undefined = undefined,
toBlock extends BlockNumber | BlockTag | undefined = undefined,
//
_eventName extends string | undefined = MaybeAbiEventName<abiEvent>,
> = {
/** Address or list of addresses from which logs originated */
address?: Address | Address[] | undefined
} & (
| {
event: abiEvent
events?: undefined
args?: MaybeExtractEventArgsFromAbi<abiEvents, _eventName> | undefined
/**
* Whether or not the logs must match the indexed/non-indexed arguments on `event`.
* @default false
*/
strict?: strict | undefined
}
| {
event?: undefined
events: abiEvents
args?: undefined
/**
* Whether or not the logs must match the indexed/non-indexed arguments on `event`.
* @default false
*/
strict?: strict | undefined
}
| {
event?: undefined
events?: undefined
args?: undefined
strict?: undefined
}
) &
(
| {
/** Block number or tag after which to include logs */
fromBlock?: fromBlock | BlockNumber | BlockTag | undefined
/** Block number or tag before which to include logs */
toBlock?: toBlock | BlockNumber | BlockTag | undefined
blockHash?: undefined
}
| {
fromBlock?: undefined
toBlock?: undefined
/** Hash of block to include logs from */
blockHash?: Hash | undefined
}
)
export type GetLogsReturnType<
abiEvent extends AbiEvent | undefined = undefined,
abiEvents extends
| readonly AbiEvent[]
| readonly unknown[]
| undefined = abiEvent extends AbiEvent ? [abiEvent] : undefined,
strict extends boolean | undefined = undefined,
fromBlock extends BlockNumber | BlockTag | undefined = undefined,
toBlock extends BlockNumber | BlockTag | undefined = undefined,
//
_eventName extends string | undefined = MaybeAbiEventName<abiEvent>,
_pending extends boolean =
| (fromBlock extends 'pending' ? true : false)
| (toBlock extends 'pending' ? true : false),
> = Log<bigint, number, _pending, abiEvent, strict, abiEvents, _eventName>[]
export type GetLogsErrorType =
| DecodeEventLogErrorType
| EncodeEventTopicsErrorType
| FormatLogErrorType
| NumberToHexErrorType
| RequestErrorType
| ErrorType
/**
* Returns a list of event logs matching the provided parameters.
*
* - Docs: https://viem.sh/docs/actions/public/getLogs
* - Examples: https://stackblitz.com/github/wevm/viem/tree/main/examples/logs_event-logs
* - JSON-RPC Methods: [`eth_getLogs`](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getlogs)
*
* @param client - Client to use
* @param parameters - {@link GetLogsParameters}
* @returns A list of event logs. {@link GetLogsReturnType}
*
* @example
* import { createPublicClient, http, parseAbiItem } from 'viem'
* import { mainnet } from 'viem/chains'
* import { getLogs } from 'viem/public'
*
* const client = createPublicClient({
* chain: mainnet,
* transport: http(),
* })
* const logs = await getLogs(client)
*/
export async function getLogs<
chain extends Chain | undefined,
const abiEvent extends AbiEvent | undefined = undefined,
const abiEvents extends
| readonly AbiEvent[]
| readonly unknown[]
| undefined = abiEvent extends AbiEvent ? [abiEvent] : undefined,
strict extends boolean | undefined = undefined,
fromBlock extends BlockNumber | BlockTag | undefined = undefined,
toBlock extends BlockNumber | BlockTag | undefined = undefined,
>(
client: Client<Transport, chain>,
{
address,
blockHash,
fromBlock,
toBlock,
event,
events: events_,
args,
strict: strict_,
}: GetLogsParameters<abiEvent, abiEvents, strict, fromBlock, toBlock> = {},
): Promise<GetLogsReturnType<abiEvent, abiEvents, strict, fromBlock, toBlock>> {
const strict = strict_ ?? false
const events = events_ ?? (event ? [event] : undefined)
let topics: LogTopic[] = []
if (events) {
const encoded = (events as AbiEvent[]).flatMap((event) =>
encodeEventTopics({
abi: [event],
eventName: (event as AbiEvent).name,
args: events_ ? undefined : args,
} as EncodeEventTopicsParameters),
)
// TODO: Clean up type casting
topics = [encoded as LogTopic]
if (event) topics = topics[0] as LogTopic[]
}
let logs: RpcLog[]
if (blockHash) {
logs = await client.request({
method: 'eth_getLogs',
params: [{ address, topics, blockHash }],
})
} else {
logs = await client.request({
method: 'eth_getLogs',
params: [
{
address,
topics,
fromBlock:
typeof fromBlock === 'bigint' ? numberToHex(fromBlock) : fromBlock,
toBlock: typeof toBlock === 'bigint' ? numberToHex(toBlock) : toBlock,
},
],
})
}
const formattedLogs = logs.map((log) => formatLog(log))
if (!events)
return formattedLogs as GetLogsReturnType<
abiEvent,
abiEvents,
strict,
fromBlock,
toBlock
>
return parseEventLogs({
abi: events,
args: args as any,
logs: formattedLogs,
strict,
}) as unknown as GetLogsReturnType<
abiEvent,
abiEvents,
strict,
fromBlock,
toBlock
>
}

93
node_modules/viem/actions/public/getProof.ts generated vendored Normal file
View File

@@ -0,0 +1,93 @@
import type { Address } from 'abitype'
import type { Client } from '../../clients/createClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { ErrorType } from '../../errors/utils.js'
import type { BlockTag } from '../../types/block.js'
import type { Chain } from '../../types/chain.js'
import type { Hash } from '../../types/misc.js'
import type { Proof } from '../../types/proof.js'
import type { RequestErrorType } from '../../utils/buildRequest.js'
import {
type NumberToHexErrorType,
numberToHex,
} from '../../utils/encoding/toHex.js'
import {
type FormatProofErrorType,
formatProof,
} from '../../utils/formatters/proof.js'
export type GetProofParameters = {
/** Account address. */
address: Address
/** Array of storage-keys that should be proofed and included. */
storageKeys: Hash[]
} & (
| {
/** The block number. */
blockNumber?: bigint | undefined
blockTag?: undefined
}
| {
blockNumber?: undefined
/**
* The block tag.
* @default 'latest'
*/
blockTag?: BlockTag | undefined
}
)
export type GetProofReturnType = Proof
export type GetProofErrorType =
| NumberToHexErrorType
| FormatProofErrorType
| RequestErrorType
| ErrorType
/**
* Returns the account and storage values of the specified account including the Merkle-proof.
*
* - Docs: https://viem.sh/docs/actions/public/getProof
* - JSON-RPC Methods:
* - Calls [`eth_getProof`](https://eips.ethereum.org/EIPS/eip-1186)
*
* @param client - Client to use
* @param parameters - {@link GetProofParameters}
* @returns Proof data. {@link GetProofReturnType}
*
* @example
* import { createPublicClient, http } from 'viem'
* import { mainnet } from 'viem/chains'
* import { getProof } from 'viem/public'
*
* const client = createPublicClient({
* chain: mainnet,
* transport: http(),
* })
* const block = await getProof(client, {
* address: '0x...',
* storageKeys: ['0x...'],
* })
*/
export async function getProof<chain extends Chain | undefined>(
client: Client<Transport, chain>,
{
address,
blockNumber,
blockTag: blockTag_,
storageKeys,
}: GetProofParameters,
): Promise<GetProofReturnType> {
const blockTag = blockTag_ ?? 'latest'
const blockNumberHex =
blockNumber !== undefined ? numberToHex(blockNumber) : undefined
const proof = await client.request({
method: 'eth_getProof',
params: [address, storageKeys, blockNumberHex || blockTag],
})
return formatProof(proof)
}

71
node_modules/viem/actions/public/getStorageAt.ts generated vendored Normal file
View File

@@ -0,0 +1,71 @@
import type { Address } from 'abitype'
import type { Client } from '../../clients/createClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { ErrorType } from '../../errors/utils.js'
import type { BlockTag } from '../../types/block.js'
import type { Chain } from '../../types/chain.js'
import type { Hex } from '../../types/misc.js'
import type { RequestErrorType } from '../../utils/buildRequest.js'
import {
type NumberToHexErrorType,
numberToHex,
} from '../../utils/encoding/toHex.js'
export type GetStorageAtParameters = {
address: Address
slot: Hex
} & (
| {
blockNumber?: undefined
blockTag?: BlockTag | undefined
}
| {
blockNumber?: bigint | undefined
blockTag?: undefined
}
)
export type GetStorageAtReturnType = Hex | undefined
export type GetStorageAtErrorType =
| NumberToHexErrorType
| RequestErrorType
| ErrorType
/**
* Returns the value from a storage slot at a given address.
*
* - Docs: https://viem.sh/docs/contract/getStorageAt
* - JSON-RPC Methods: [`eth_getStorageAt`](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getstorageat)
*
* @param client - Client to use
* @param parameters - {@link GetStorageAtParameters}
* @returns The value of the storage slot. {@link GetStorageAtReturnType}
*
* @example
* import { createPublicClient, http } from 'viem'
* import { mainnet } from 'viem/chains'
* import { getStorageAt } from 'viem/contract'
*
* const client = createPublicClient({
* chain: mainnet,
* transport: http(),
* })
* const code = await getStorageAt(client, {
* address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
* slot: toHex(0),
* })
*/
export async function getStorageAt<chain extends Chain | undefined>(
client: Client<Transport, chain>,
{ address, blockNumber, blockTag = 'latest', slot }: GetStorageAtParameters,
): Promise<GetStorageAtReturnType> {
const blockNumberHex =
blockNumber !== undefined ? numberToHex(blockNumber) : undefined
const data = await client.request({
method: 'eth_getStorageAt',
params: [address, slot, blockNumberHex || blockTag],
})
return data
}

163
node_modules/viem/actions/public/getTransaction.ts generated vendored Normal file
View File

@@ -0,0 +1,163 @@
import type { Address } from '../../accounts/index.js'
import type { Client } from '../../clients/createClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import {
TransactionNotFoundError,
type TransactionNotFoundErrorType,
} from '../../errors/transaction.js'
import type { ErrorType } from '../../errors/utils.js'
import type { BlockTag } from '../../types/block.js'
import type { Chain } from '../../types/chain.js'
import type { Hash } from '../../types/misc.js'
import type { RpcTransaction } from '../../types/rpc.js'
import type { OneOf, Prettify } from '../../types/utils.js'
import type { RequestErrorType } from '../../utils/buildRequest.js'
import {
type NumberToHexErrorType,
numberToHex,
} from '../../utils/encoding/toHex.js'
import {
type FormattedTransaction,
formatTransaction,
} from '../../utils/formatters/transaction.js'
export type GetTransactionParameters<blockTag extends BlockTag = 'latest'> =
OneOf<
// eth_getTransactionByBlockHashAndIndex
| {
/** The block hash */
blockHash: Hash
/** The index of the transaction on the block. */
index: number
}
// eth_getTransactionByBlockNumberAndIndex
| {
/** The block number */
blockNumber: bigint
/** The index of the transaction on the block. */
index: number
}
// eth_getTransactionByBlockNumberAndIndex
| {
/** The block tag. */
blockTag: blockTag | BlockTag
/** The index of the transaction on the block. */
index: number
}
// eth_getTransactionByHash
| {
/** The hash of the transaction. */
hash: Hash
}
// eth_getTransactionBySenderAndNonce
| {
/** The sender of the transaction. */
sender: Address
/** The nonce of the transaction on the sender. */
nonce: number
}
>
export type GetTransactionReturnType<
chain extends Chain | undefined = undefined,
blockTag extends BlockTag = 'latest',
> = Prettify<FormattedTransaction<chain, blockTag>>
export type GetTransactionErrorType =
| TransactionNotFoundErrorType
| NumberToHexErrorType
| RequestErrorType
| ErrorType
/**
* Returns information about a [Transaction](https://viem.sh/docs/glossary/terms#transaction) given a hash or block identifier.
*
* - Docs: https://viem.sh/docs/actions/public/getTransaction
* - Example: https://stackblitz.com/github/wevm/viem/tree/main/examples/transactions_fetching-transactions
* - JSON-RPC Methods: [`eth_getTransactionByHash`](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getTransactionByHash)
*
* @param client - Client to use
* @param parameters - {@link GetTransactionParameters}
* @returns The transaction information. {@link GetTransactionReturnType}
*
* @example
* import { createPublicClient, http } from 'viem'
* import { mainnet } from 'viem/chains'
* import { getTransaction } from 'viem/public'
*
* const client = createPublicClient({
* chain: mainnet,
* transport: http(),
* })
* const transaction = await getTransaction(client, {
* hash: '0x4ca7ee652d57678f26e887c149ab0735f41de37bcad58c9f6d3ed5824f15b74d',
* })
*/
export async function getTransaction<
chain extends Chain | undefined,
blockTag extends BlockTag = 'latest',
>(
client: Client<Transport, chain>,
{
blockHash,
blockNumber,
blockTag: blockTag_,
hash,
index,
sender,
nonce,
}: GetTransactionParameters<blockTag>,
): Promise<GetTransactionReturnType<chain, blockTag>> {
const blockTag = blockTag_ || 'latest'
const blockNumberHex =
blockNumber !== undefined ? numberToHex(blockNumber) : undefined
let transaction: RpcTransaction | null = null
if (hash) {
transaction = await client.request(
{
method: 'eth_getTransactionByHash',
params: [hash],
},
{ dedupe: true },
)
} else if (blockHash) {
transaction = await client.request(
{
method: 'eth_getTransactionByBlockHashAndIndex',
params: [blockHash, numberToHex(index)],
},
{ dedupe: true },
)
} else if ((blockNumberHex || blockTag) && typeof index === 'number') {
transaction = await client.request(
{
method: 'eth_getTransactionByBlockNumberAndIndex',
params: [blockNumberHex || blockTag, numberToHex(index)],
},
{ dedupe: Boolean(blockNumberHex) },
)
} else if (sender && typeof nonce === 'number') {
transaction = await client.request(
{
method: 'eth_getTransactionBySenderAndNonce',
params: [sender, numberToHex(nonce)],
},
{ dedupe: true },
)
}
if (!transaction)
throw new TransactionNotFoundError({
blockHash,
blockNumber,
blockTag,
hash,
index,
})
const format =
client.chain?.formatters?.transaction?.format || formatTransaction
return format(transaction, 'getTransaction')
}

View File

@@ -0,0 +1,79 @@
import type { Client } from '../../clients/createClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { ErrorType } from '../../errors/utils.js'
import type { Chain } from '../../types/chain.js'
import type { Hash } from '../../types/misc.js'
import type { FormattedTransactionReceipt } from '../../utils/formatters/transactionReceipt.js'
import { getAction } from '../../utils/getAction.js'
import {
type GetBlockNumberErrorType,
getBlockNumber,
} from './getBlockNumber.js'
import {
type GetTransactionErrorType,
getTransaction,
} from './getTransaction.js'
export type GetTransactionConfirmationsParameters<
chain extends Chain | undefined = Chain,
> =
| {
/** The transaction hash. */
hash: Hash
transactionReceipt?: undefined
}
| {
hash?: undefined
/** The transaction receipt. */
transactionReceipt: FormattedTransactionReceipt<chain>
}
export type GetTransactionConfirmationsReturnType = bigint
export type GetTransactionConfirmationsErrorType =
| GetBlockNumberErrorType
| GetTransactionErrorType
| ErrorType
/**
* Returns the number of blocks passed (confirmations) since the transaction was processed on a block.
*
* - Docs: https://viem.sh/docs/actions/public/getTransactionConfirmations
* - Example: https://stackblitz.com/github/wevm/viem/tree/main/examples/transactions_fetching-transactions
* - JSON-RPC Methods: [`eth_getTransactionConfirmations`](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getTransactionConfirmations)
*
* @param client - Client to use
* @param parameters - {@link GetTransactionConfirmationsParameters}
* @returns The number of blocks passed since the transaction was processed. If confirmations is 0, then the Transaction has not been confirmed & processed yet. {@link GetTransactionConfirmationsReturnType}
*
* @example
* import { createPublicClient, http } from 'viem'
* import { mainnet } from 'viem/chains'
* import { getTransactionConfirmations } from 'viem/public'
*
* const client = createPublicClient({
* chain: mainnet,
* transport: http(),
* })
* const confirmations = await getTransactionConfirmations(client, {
* hash: '0x4ca7ee652d57678f26e887c149ab0735f41de37bcad58c9f6d3ed5824f15b74d',
* })
*/
export async function getTransactionConfirmations<
chain extends Chain | undefined,
>(
client: Client<Transport, chain>,
{ hash, transactionReceipt }: GetTransactionConfirmationsParameters<chain>,
): Promise<GetTransactionConfirmationsReturnType> {
const [blockNumber, transaction] = await Promise.all([
getAction(client, getBlockNumber, 'getBlockNumber')({}),
hash
? getAction(client, getTransaction, 'getTransaction')({ hash })
: undefined,
])
const transactionBlockNumber =
transactionReceipt?.blockNumber || transaction?.blockNumber
if (!transactionBlockNumber) return 0n
return blockNumber - transactionBlockNumber! + 1n
}

View File

@@ -0,0 +1,85 @@
import type { Address } from 'abitype'
import type { Account } from '../../accounts/types.js'
import type { Client } from '../../clients/createClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { ErrorType } from '../../errors/utils.js'
import type { BlockTag } from '../../types/block.js'
import type { Chain } from '../../types/chain.js'
import type { RequestErrorType } from '../../utils/buildRequest.js'
import {
type HexToNumberErrorType,
hexToNumber,
} from '../../utils/encoding/fromHex.js'
import {
type NumberToHexErrorType,
numberToHex,
} from '../../utils/encoding/toHex.js'
export type GetTransactionCountParameters = {
/** The account address. */
address: Address
} & (
| {
/** The block number. */
blockNumber?: bigint | undefined
blockTag?: undefined
}
| {
blockNumber?: undefined
/** The block tag. Defaults to 'latest'. */
blockTag?: BlockTag | undefined
}
)
export type GetTransactionCountReturnType = number
export type GetTransactionCountErrorType =
| RequestErrorType
| NumberToHexErrorType
| HexToNumberErrorType
| ErrorType
/**
* Returns the number of [Transactions](https://viem.sh/docs/glossary/terms#transaction) an Account has sent.
*
* - Docs: https://viem.sh/docs/actions/public/getTransactionCount
* - JSON-RPC Methods: [`eth_getTransactionCount`](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_gettransactioncount)
*
* @param client - Client to use
* @param parameters - {@link GetTransactionCountParameters}
* @returns The number of transactions an account has sent. {@link GetTransactionCountReturnType}
*
* @example
* import { createPublicClient, http } from 'viem'
* import { mainnet } from 'viem/chains'
* import { getTransactionCount } from 'viem/public'
*
* const client = createPublicClient({
* chain: mainnet,
* transport: http(),
* })
* const transactionCount = await getTransactionCount(client, {
* address: '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e',
* })
*/
export async function getTransactionCount<
chain extends Chain | undefined,
account extends Account | undefined,
>(
client: Client<Transport, chain, account>,
{ address, blockTag = 'latest', blockNumber }: GetTransactionCountParameters,
): Promise<GetTransactionCountReturnType> {
const count = await client.request(
{
method: 'eth_getTransactionCount',
params: [
address,
typeof blockNumber === 'bigint' ? numberToHex(blockNumber) : blockTag,
],
},
{
dedupe: Boolean(blockNumber),
},
)
return hexToNumber(count)
}

View File

@@ -0,0 +1,75 @@
import type { Client } from '../../clients/createClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import {
TransactionReceiptNotFoundError,
type TransactionReceiptNotFoundErrorType,
} from '../../errors/transaction.js'
import type { ErrorType } from '../../errors/utils.js'
import type { Chain } from '../../types/chain.js'
import type { Hash } from '../../types/misc.js'
import type { RequestErrorType } from '../../utils/buildRequest.js'
import {
type FormattedTransactionReceipt,
formatTransactionReceipt,
} from '../../utils/formatters/transactionReceipt.js'
export type GetTransactionReceiptParameters = {
/** The hash of the transaction. */
hash: Hash
}
export type GetTransactionReceiptReturnType<
chain extends Chain | undefined = undefined,
> = FormattedTransactionReceipt<chain>
export type GetTransactionReceiptErrorType =
| RequestErrorType
| TransactionReceiptNotFoundErrorType
| ErrorType
/**
* Returns the [Transaction Receipt](https://viem.sh/docs/glossary/terms#transaction-receipt) given a [Transaction](https://viem.sh/docs/glossary/terms#transaction) hash.
*
* - Docs: https://viem.sh/docs/actions/public/getTransactionReceipt
* - Example: https://stackblitz.com/github/wevm/viem/tree/main/examples/transactions_fetching-transactions
* - JSON-RPC Methods: [`eth_getTransactionReceipt`](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_gettransactionreceipt)
*
* @param client - Client to use
* @param parameters - {@link GetTransactionReceiptParameters}
* @returns The transaction receipt. {@link GetTransactionReceiptReturnType}
*
* @example
* import { createPublicClient, http } from 'viem'
* import { mainnet } from 'viem/chains'
* import { getTransactionReceipt } from 'viem/public'
*
* const client = createPublicClient({
* chain: mainnet,
* transport: http(),
* })
* const transactionReceipt = await getTransactionReceipt(client, {
* hash: '0x4ca7ee652d57678f26e887c149ab0735f41de37bcad58c9f6d3ed5824f15b74d',
* })
*/
export async function getTransactionReceipt<chain extends Chain | undefined>(
client: Client<Transport, chain>,
{ hash }: GetTransactionReceiptParameters,
) {
const receipt = await client.request(
{
method: 'eth_getTransactionReceipt',
params: [hash],
},
{ dedupe: true },
)
if (!receipt) throw new TransactionReceiptNotFoundError({ hash })
const format =
client.chain?.formatters?.transactionReceipt?.format ||
formatTransactionReceipt
return format(
receipt,
'getTransactionReceipt',
) as GetTransactionReceiptReturnType<chain>
}

309
node_modules/viem/actions/public/multicall.ts generated vendored Normal file
View File

@@ -0,0 +1,309 @@
import type { AbiStateMutability, Address, Narrow } from 'abitype'
import type { Client } from '../../clients/createClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import { multicall3Abi } from '../../constants/abis.js'
import { multicall3Bytecode } from '../../constants/contracts.js'
import { AbiDecodingZeroDataError } from '../../errors/abi.js'
import { BaseError } from '../../errors/base.js'
import { RawContractError } from '../../errors/contract.js'
import type { ErrorType } from '../../errors/utils.js'
import type { Chain } from '../../types/chain.js'
import type { ContractFunctionParameters } from '../../types/contract.js'
import type { Hex } from '../../types/misc.js'
import type {
MulticallContracts,
MulticallResults,
} from '../../types/multicall.js'
import {
type DecodeFunctionResultErrorType,
decodeFunctionResult,
} from '../../utils/abi/decodeFunctionResult.js'
import {
type EncodeFunctionDataErrorType,
encodeFunctionData,
} from '../../utils/abi/encodeFunctionData.js'
import {
type GetChainContractAddressErrorType,
getChainContractAddress,
} from '../../utils/chain/getChainContractAddress.js'
import {
type GetContractErrorReturnType,
getContractError,
} from '../../utils/errors/getContractError.js'
import { getAction } from '../../utils/getAction.js'
import type { CallParameters } from './call.js'
import { type ReadContractErrorType, readContract } from './readContract.js'
export type MulticallParameters<
contracts extends readonly unknown[] = readonly ContractFunctionParameters[],
allowFailure extends boolean = true,
options extends {
optional?: boolean
properties?: Record<string, any>
} = {},
> = Pick<
CallParameters,
| 'authorizationList'
| 'blockNumber'
| 'blockOverrides'
| 'blockTag'
| 'stateOverride'
> & {
/** The account to use for the multicall. */
account?: Address | undefined
/** Whether to allow failures. */
allowFailure?: allowFailure | boolean | undefined
/** The size of each batch of calls. */
batchSize?: number | undefined
/** Enable deployless multicall. */
deployless?: boolean | undefined
/** The contracts to call. */
contracts: MulticallContracts<
Narrow<contracts>,
{ mutability: AbiStateMutability } & options
>
/** The address of the multicall3 contract to use. */
multicallAddress?: Address | undefined
}
export type MulticallReturnType<
contracts extends readonly unknown[] = readonly ContractFunctionParameters[],
allowFailure extends boolean = true,
options extends {
error?: Error
} = { error: Error },
> = MulticallResults<
Narrow<contracts>,
allowFailure,
{ mutability: AbiStateMutability } & options
>
export type MulticallErrorType =
| GetChainContractAddressErrorType
| ReadContractErrorType
| GetContractErrorReturnType<
EncodeFunctionDataErrorType | DecodeFunctionResultErrorType
>
| ErrorType
/**
* Similar to [`readContract`](https://viem.sh/docs/contract/readContract), but batches up multiple functions on a contract in a single RPC call via the [`multicall3` contract](https://github.com/mds1/multicall).
*
* - Docs: https://viem.sh/docs/contract/multicall
*
* @param client - Client to use
* @param parameters - {@link MulticallParameters}
* @returns An array of results with accompanying status. {@link MulticallReturnType}
*
* @example
* import { createPublicClient, http, parseAbi } from 'viem'
* import { mainnet } from 'viem/chains'
* import { multicall } from 'viem/contract'
*
* const client = createPublicClient({
* chain: mainnet,
* transport: http(),
* })
* const abi = parseAbi([
* 'function balanceOf(address) view returns (uint256)',
* 'function totalSupply() view returns (uint256)',
* ])
* const results = await multicall(client, {
* contracts: [
* {
* address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
* abi,
* functionName: 'balanceOf',
* args: ['0xA0Cf798816D4b9b9866b5330EEa46a18382f251e'],
* },
* {
* address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
* abi,
* functionName: 'totalSupply',
* },
* ],
* })
* // [{ result: 424122n, status: 'success' }, { result: 1000000n, status: 'success' }]
*/
export async function multicall<
const contracts extends readonly unknown[],
chain extends Chain | undefined,
allowFailure extends boolean = true,
>(
client: Client<Transport, chain>,
parameters: MulticallParameters<contracts, allowFailure>,
): Promise<MulticallReturnType<contracts, allowFailure>> {
const {
account,
authorizationList,
allowFailure = true,
blockNumber,
blockOverrides,
blockTag,
stateOverride,
} = parameters
const contracts = parameters.contracts as ContractFunctionParameters[]
const {
batchSize = parameters.batchSize ?? 1024,
deployless = parameters.deployless ?? false,
} = typeof client.batch?.multicall === 'object' ? client.batch.multicall : {}
const multicallAddress = (() => {
if (parameters.multicallAddress) return parameters.multicallAddress
if (deployless) return null
if (client.chain) {
return getChainContractAddress({
blockNumber,
chain: client.chain,
contract: 'multicall3',
})
}
throw new Error(
'client chain not configured. multicallAddress is required.',
)
})()
type Aggregate3Calls = {
allowFailure: boolean
callData: Hex
target: Address
}[]
const chunkedCalls: Aggregate3Calls[] = [[]]
let currentChunk = 0
let currentChunkSize = 0
for (let i = 0; i < contracts.length; i++) {
const { abi, address, args, functionName } = contracts[i]
try {
const callData = encodeFunctionData({ abi, args, functionName })
currentChunkSize += (callData.length - 2) / 2
// Check to see if we need to create a new chunk.
if (
// Check if batching is enabled.
batchSize > 0 &&
// Check if the current size of the batch exceeds the size limit.
currentChunkSize > batchSize &&
// Check if the current chunk is not already empty.
chunkedCalls[currentChunk].length > 0
) {
currentChunk++
currentChunkSize = (callData.length - 2) / 2
chunkedCalls[currentChunk] = []
}
chunkedCalls[currentChunk] = [
...chunkedCalls[currentChunk],
{
allowFailure: true,
callData,
target: address,
},
]
} catch (err) {
const error = getContractError(err as BaseError, {
abi,
address,
args,
docsPath: '/docs/contract/multicall',
functionName,
sender: account,
})
if (!allowFailure) throw error
chunkedCalls[currentChunk] = [
...chunkedCalls[currentChunk],
{
allowFailure: true,
callData: '0x' as Hex,
target: address,
},
]
}
}
const aggregate3Results = await Promise.allSettled(
chunkedCalls.map((calls) =>
getAction(
client,
readContract,
'readContract',
)({
...(multicallAddress === null
? { code: multicall3Bytecode }
: { address: multicallAddress }),
abi: multicall3Abi,
account,
args: [calls],
authorizationList,
blockNumber,
blockOverrides,
blockTag,
functionName: 'aggregate3',
stateOverride,
}),
),
)
const results = []
for (let i = 0; i < aggregate3Results.length; i++) {
const result = aggregate3Results[i]
// If an error occurred in a `readContract` invocation (ie. network error),
// then append the failure reason to each contract result.
if (result.status === 'rejected') {
if (!allowFailure) throw result.reason
for (let j = 0; j < chunkedCalls[i].length; j++) {
results.push({
status: 'failure',
error: result.reason,
result: undefined,
})
}
continue
}
// If the `readContract` call was successful, then decode the results.
const aggregate3Result = result.value
for (let j = 0; j < aggregate3Result.length; j++) {
// Extract the response from `readContract`
const { returnData, success } = aggregate3Result[j]
// Extract the request call data from the original call.
const { callData } = chunkedCalls[i][j]
// Extract the contract config for this call from the `contracts` argument
// for decoding.
const { abi, address, functionName, args } = contracts[
results.length
] as ContractFunctionParameters
try {
if (callData === '0x') throw new AbiDecodingZeroDataError()
if (!success) throw new RawContractError({ data: returnData })
const result = decodeFunctionResult({
abi,
args,
data: returnData,
functionName,
})
results.push(allowFailure ? { result, status: 'success' } : result)
} catch (err) {
const error = getContractError(err as BaseError, {
abi,
address,
args,
docsPath: '/docs/contract/multicall',
functionName,
})
if (!allowFailure) throw error
results.push({ error, result: undefined, status: 'failure' })
}
}
}
if (results.length !== contracts.length)
throw new BaseError('multicall results mismatch')
return results as MulticallReturnType<contracts, allowFailure>
}

146
node_modules/viem/actions/public/readContract.ts generated vendored Normal file
View File

@@ -0,0 +1,146 @@
import type { Abi } from 'abitype'
import type { Client } from '../../clients/createClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { BaseError } from '../../errors/base.js'
import type { Chain } from '../../types/chain.js'
import type {
ContractFunctionArgs,
ContractFunctionName,
ContractFunctionParameters,
ContractFunctionReturnType,
} from '../../types/contract.js'
import type { UnionEvaluate } from '../../types/utils.js'
import {
type DecodeFunctionResultErrorType,
decodeFunctionResult,
} from '../../utils/abi/decodeFunctionResult.js'
import {
type EncodeFunctionDataErrorType,
type EncodeFunctionDataParameters,
encodeFunctionData,
} from '../../utils/abi/encodeFunctionData.js'
import {
type GetContractErrorReturnType,
getContractError,
} from '../../utils/errors/getContractError.js'
import { getAction } from '../../utils/getAction.js'
import { type CallErrorType, type CallParameters, call } from './call.js'
export type ReadContractParameters<
abi extends Abi | readonly unknown[] = Abi,
functionName extends ContractFunctionName<
abi,
'pure' | 'view'
> = ContractFunctionName<abi, 'pure' | 'view'>,
args extends ContractFunctionArgs<
abi,
'pure' | 'view',
functionName
> = ContractFunctionArgs<abi, 'pure' | 'view', functionName>,
> = UnionEvaluate<
Pick<
CallParameters,
| 'account'
| 'authorizationList'
| 'blockNumber'
| 'blockOverrides'
| 'blockTag'
| 'factory'
| 'factoryData'
| 'stateOverride'
>
> &
ContractFunctionParameters<abi, 'pure' | 'view', functionName, args, boolean>
export type ReadContractReturnType<
abi extends Abi | readonly unknown[] = Abi,
functionName extends ContractFunctionName<
abi,
'pure' | 'view'
> = ContractFunctionName<abi, 'pure' | 'view'>,
args extends ContractFunctionArgs<
abi,
'pure' | 'view',
functionName
> = ContractFunctionArgs<abi, 'pure' | 'view', functionName>,
> = ContractFunctionReturnType<abi, 'pure' | 'view', functionName, args>
export type ReadContractErrorType = GetContractErrorReturnType<
CallErrorType | EncodeFunctionDataErrorType | DecodeFunctionResultErrorType
>
/**
* Calls a read-only function on a contract, and returns the response.
*
* - Docs: https://viem.sh/docs/contract/readContract
* - Examples: https://stackblitz.com/github/wevm/viem/tree/main/examples/contracts_reading-contracts
*
* A "read-only" function (constant function) on a Solidity contract is denoted by a `view` or `pure` keyword. They can only read the state of the contract, and cannot make any changes to it. Since read-only methods do not change the state of the contract, they do not require any gas to be executed, and can be called by any user without the need to pay for gas.
*
* Internally, uses a [Public Client](https://viem.sh/docs/clients/public) to call the [`call` action](https://viem.sh/docs/actions/public/call) with [ABI-encoded `data`](https://viem.sh/docs/contract/encodeFunctionData).
*
* @param client - Client to use
* @param parameters - {@link ReadContractParameters}
* @returns The response from the contract. Type is inferred. {@link ReadContractReturnType}
*
* @example
* import { createPublicClient, http, parseAbi } from 'viem'
* import { mainnet } from 'viem/chains'
* import { readContract } from 'viem/contract'
*
* const client = createPublicClient({
* chain: mainnet,
* transport: http(),
* })
* const result = await readContract(client, {
* address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
* abi: parseAbi(['function balanceOf(address) view returns (uint256)']),
* functionName: 'balanceOf',
* args: ['0xA0Cf798816D4b9b9866b5330EEa46a18382f251e'],
* })
* // 424122n
*/
export async function readContract<
chain extends Chain | undefined,
const abi extends Abi | readonly unknown[],
functionName extends ContractFunctionName<abi, 'pure' | 'view'>,
const args extends ContractFunctionArgs<abi, 'pure' | 'view', functionName>,
>(
client: Client<Transport, chain>,
parameters: ReadContractParameters<abi, functionName, args>,
): Promise<ReadContractReturnType<abi, functionName, args>> {
const { abi, address, args, functionName, ...rest } =
parameters as ReadContractParameters
const calldata = encodeFunctionData({
abi,
args,
functionName,
} as EncodeFunctionDataParameters)
try {
const { data } = await getAction(
client,
call,
'call',
)({
...(rest as CallParameters),
data: calldata,
to: address!,
})
return decodeFunctionResult({
abi,
args,
functionName,
data: data || '0x',
}) as ReadContractReturnType<abi, functionName>
} catch (error) {
throw getContractError(error as BaseError, {
abi,
address,
args,
docsPath: '/docs/contract/readContract',
functionName,
})
}
}

299
node_modules/viem/actions/public/simulateBlocks.ts generated vendored Normal file
View File

@@ -0,0 +1,299 @@
import type { Abi, AbiStateMutability, Address, Narrow } from 'abitype'
import * as BlockOverrides from 'ox/BlockOverrides'
import {
type ParseAccountErrorType,
parseAccount,
} from '../../accounts/utils/parseAccount.js'
import type { Client } from '../../clients/createClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import { AbiDecodingZeroDataError } from '../../errors/abi.js'
import type { BaseError } from '../../errors/base.js'
import { RawContractError } from '../../errors/contract.js'
import { UnknownNodeError } from '../../errors/node.js'
import type { ErrorType } from '../../errors/utils.js'
import type { Account } from '../../types/account.js'
import type { Block, BlockTag } from '../../types/block.js'
import type { Call, Calls } from '../../types/calls.js'
import type { Chain } from '../../types/chain.js'
import type { Log } from '../../types/log.js'
import type { Hex } from '../../types/misc.js'
import type { MulticallResults } from '../../types/multicall.js'
import type { StateOverride } from '../../types/stateOverride.js'
import type { TransactionRequest } from '../../types/transaction.js'
import type { ExactPartial, UnionOmit } from '../../types/utils.js'
import {
type DecodeFunctionResultErrorType,
decodeFunctionResult,
} from '../../utils/abi/decodeFunctionResult.js'
import {
type EncodeFunctionDataErrorType,
encodeFunctionData,
} from '../../utils/abi/encodeFunctionData.js'
import { concat } from '../../utils/data/concat.js'
import {
type NumberToHexErrorType,
numberToHex,
} from '../../utils/encoding/toHex.js'
import { getContractError } from '../../utils/errors/getContractError.js'
import {
type GetNodeErrorReturnType,
getNodeError,
} from '../../utils/errors/getNodeError.js'
import {
type FormatBlockErrorType,
formatBlock,
} from '../../utils/formatters/block.js'
import { formatLog } from '../../utils/formatters/log.js'
import {
type FormatTransactionRequestErrorType,
formatTransactionRequest,
} from '../../utils/formatters/transactionRequest.js'
import {
type SerializeStateOverrideErrorType,
serializeStateOverride,
} from '../../utils/stateOverride.js'
import {
type AssertRequestErrorType,
assertRequest,
} from '../../utils/transaction/assertRequest.js'
type CallExtraProperties = ExactPartial<
UnionOmit<
TransactionRequest,
'blobs' | 'data' | 'kzg' | 'to' | 'sidecars' | 'value'
>
> & {
/** Account attached to the call (msg.sender). */
account?: Account | Address | undefined
/** Recipient. `null` if contract deployment. */
to?: Address | null | undefined
}
export type SimulateBlocksParameters<
calls extends readonly unknown[] = readonly unknown[],
> = {
/** Blocks to simulate. */
blocks: readonly {
/** Block overrides. */
blockOverrides?: BlockOverrides.BlockOverrides | undefined
/** Calls to execute. */
calls: Calls<Narrow<calls>, CallExtraProperties>
/** State overrides. */
stateOverrides?: StateOverride | undefined
}[]
/** Whether to return the full transactions. */
returnFullTransactions?: boolean | undefined
/** Whether to trace transfers. */
traceTransfers?: boolean | undefined
/** Whether to enable validation mode. */
validation?: boolean | undefined
} & (
| {
/** The balance of the account at a block number. */
blockNumber?: bigint | undefined
blockTag?: undefined
}
| {
blockNumber?: undefined
/**
* The balance of the account at a block tag.
* @default 'latest'
*/
blockTag?: BlockTag | undefined
}
)
export type SimulateBlocksReturnType<
calls extends readonly unknown[] = readonly unknown[],
> = readonly (Block & {
calls: MulticallResults<
Narrow<calls>,
true,
{
extraProperties: {
data: Hex
gasUsed: bigint
logs?: Log[] | undefined
}
error: Error
mutability: AbiStateMutability
}
>
})[]
export type SimulateBlocksErrorType =
| AssertRequestErrorType
| DecodeFunctionResultErrorType
| EncodeFunctionDataErrorType
| FormatBlockErrorType
| FormatTransactionRequestErrorType
| GetNodeErrorReturnType
| ParseAccountErrorType
| SerializeStateOverrideErrorType
| NumberToHexErrorType
| ErrorType
/**
* Simulates a set of calls on block(s) with optional block and state overrides.
*
* @example
* ```ts
* import { createClient, http, parseEther } from 'viem'
* import { simulate } from 'viem/actions'
* import { mainnet } from 'viem/chains'
*
* const client = createClient({
* chain: mainnet,
* transport: http(),
* })
*
* const result = await simulate(client, {
* blocks: [{
* blockOverrides: {
* number: 69420n,
* },
* calls: [{
* {
* account: '0x5a0b54d5dc17e482fe8b0bdca5320161b95fb929',
* data: '0xdeadbeef',
* to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
* },
* {
* account: '0x5a0b54d5dc17e482fe8b0bdca5320161b95fb929',
* to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
* value: parseEther('1'),
* },
* }],
* stateOverrides: [{
* address: '0x5a0b54d5dc17e482fe8b0bdca5320161b95fb929',
* balance: parseEther('10'),
* }],
* }]
* })
* ```
*
* @param client - Client to use.
* @param parameters - {@link SimulateBlocksParameters}
* @returns Simulated blocks. {@link SimulateBlocksReturnType}
*/
export async function simulateBlocks<
chain extends Chain | undefined,
const calls extends readonly unknown[],
>(
client: Client<Transport, chain>,
parameters: SimulateBlocksParameters<calls>,
): Promise<SimulateBlocksReturnType<calls>> {
const {
blockNumber,
blockTag = client.experimental_blockTag ?? 'latest',
blocks,
returnFullTransactions,
traceTransfers,
validation,
} = parameters
try {
const blockStateCalls = []
for (const block of blocks) {
const blockOverrides = block.blockOverrides
? BlockOverrides.toRpc(block.blockOverrides)
: undefined
const calls = block.calls.map((call_) => {
const call = call_ as Call<unknown, CallExtraProperties>
const account = call.account ? parseAccount(call.account) : undefined
const data = call.abi ? encodeFunctionData(call) : call.data
const request = {
...call,
account,
data: call.dataSuffix
? concat([data || '0x', call.dataSuffix])
: data,
from: call.from ?? account?.address,
} as const
assertRequest(request)
return formatTransactionRequest(request)
})
const stateOverrides = block.stateOverrides
? serializeStateOverride(block.stateOverrides)
: undefined
blockStateCalls.push({
blockOverrides,
calls,
stateOverrides,
})
}
const blockNumberHex =
typeof blockNumber === 'bigint' ? numberToHex(blockNumber) : undefined
const block = blockNumberHex || blockTag
const result = await client.request({
method: 'eth_simulateV1',
params: [
{ blockStateCalls, returnFullTransactions, traceTransfers, validation },
block,
],
})
return result.map((block, i) => ({
...formatBlock(block),
calls: block.calls.map((call, j) => {
const { abi, args, functionName, to } = blocks[i].calls[j] as Call<
unknown,
CallExtraProperties
>
const data = call.error?.data ?? call.returnData
const gasUsed = BigInt(call.gasUsed)
const logs = call.logs?.map((log) => formatLog(log))
const status = call.status === '0x1' ? 'success' : 'failure'
const result =
abi && status === 'success' && data !== '0x'
? decodeFunctionResult({
abi,
data,
functionName,
})
: null
const error = (() => {
if (status === 'success') return undefined
let error: Error | undefined
if (data === '0x') error = new AbiDecodingZeroDataError()
else if (data) error = new RawContractError({ data })
if (!error) return undefined
return getContractError(error, {
abi: (abi ?? []) as Abi,
address: to ?? '0x',
args,
functionName: functionName ?? '<unknown>',
})
})()
return {
data,
gasUsed,
logs,
status,
...(status === 'success'
? {
result,
}
: {
error,
}),
}
}),
})) as unknown as SimulateBlocksReturnType<calls>
} catch (e) {
const cause = e as BaseError
const error = getNodeError(cause, {})
if (error instanceof UnknownNodeError) throw cause
throw error
}
}

404
node_modules/viem/actions/public/simulateCalls.ts generated vendored Normal file
View File

@@ -0,0 +1,404 @@
import type { AbiStateMutability, Address, Narrow } from 'abitype'
import * as AbiConstructor from 'ox/AbiConstructor'
import * as AbiFunction from 'ox/AbiFunction'
import { parseAccount } from '../../accounts/utils/parseAccount.js'
import type { Client } from '../../clients/createClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import { ethAddress, zeroAddress } from '../../constants/address.js'
import { deploylessCallViaBytecodeBytecode } from '../../constants/contracts.js'
import { BaseError } from '../../errors/base.js'
import type { ErrorType } from '../../errors/utils.js'
import type { Account } from '../../types/account.js'
import type { Block } from '../../types/block.js'
import type { Call, Calls } from '../../types/calls.js'
import type { Chain } from '../../types/chain.js'
import type { Log } from '../../types/log.js'
import type { Hex } from '../../types/misc.js'
import type { MulticallResults } from '../../types/multicall.js'
import type { StateOverride } from '../../types/stateOverride.js'
import type { Mutable } from '../../types/utils.js'
import {
type EncodeFunctionDataErrorType,
encodeFunctionData,
} from '../../utils/abi/encodeFunctionData.js'
import { hexToBigInt } from '../../utils/index.js'
import {
type CreateAccessListErrorType,
createAccessList,
} from './createAccessList.js'
import {
type SimulateBlocksErrorType,
type SimulateBlocksParameters,
simulateBlocks,
} from './simulateBlocks.js'
const getBalanceCode =
'0x6080604052348015600e575f80fd5b5061016d8061001c5f395ff3fe608060405234801561000f575f80fd5b5060043610610029575f3560e01c8063f8b2cb4f1461002d575b5f80fd5b610047600480360381019061004291906100db565b61005d565b604051610054919061011e565b60405180910390f35b5f8173ffffffffffffffffffffffffffffffffffffffff16319050919050565b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6100aa82610081565b9050919050565b6100ba816100a0565b81146100c4575f80fd5b50565b5f813590506100d5816100b1565b92915050565b5f602082840312156100f0576100ef61007d565b5b5f6100fd848285016100c7565b91505092915050565b5f819050919050565b61011881610106565b82525050565b5f6020820190506101315f83018461010f565b9291505056fea26469706673582212203b9fe929fe995c7cf9887f0bdba8a36dd78e8b73f149b17d2d9ad7cd09d2dc6264736f6c634300081a0033'
export type SimulateCallsParameters<
calls extends readonly unknown[] = readonly unknown[],
account extends Account | Address | undefined = Account | Address | undefined,
> = Omit<SimulateBlocksParameters, 'blocks' | 'returnFullTransactions'> & {
/** Account attached to the calls (msg.sender). */
account?: account | undefined
/** Calls to simulate. */
calls: Calls<Narrow<calls>>
/** State overrides. */
stateOverrides?: StateOverride | undefined
/** Whether to trace asset changes. */
traceAssetChanges?: boolean | undefined
}
export type SimulateCallsReturnType<
calls extends readonly unknown[] = readonly unknown[],
> = {
/** Asset changes. */
assetChanges: readonly {
token: {
address: Address
decimals?: number | undefined
symbol?: string | undefined
}
value: { pre: bigint; post: bigint; diff: bigint }
}[]
/** Block results. */
block: Block
/** Call results. */
results: MulticallResults<
Narrow<calls>,
true,
{
extraProperties: {
data: Hex
gasUsed: bigint
logs?: Log[] | undefined
}
error: Error
mutability: AbiStateMutability
}
>
}
export type SimulateCallsErrorType =
| AbiFunction.encodeData.ErrorType
| AbiFunction.from.ErrorType
| CreateAccessListErrorType
| EncodeFunctionDataErrorType
| SimulateBlocksErrorType
| ErrorType
/**
* Simulates execution of a batch of calls.
*
* @param client - Client to use
* @param parameters - {@link SimulateCallsParameters}
* @returns Results. {@link SimulateCallsReturnType}
*
* @example
* ```ts
* import { createPublicClient, http, parseEther } from 'viem'
* import { mainnet } from 'viem/chains'
* import { simulateCalls } from 'viem/actions'
*
* const client = createPublicClient({
* chain: mainnet,
* transport: http(),
* })
*
* const result = await simulateCalls(client, {
* account: '0x5a0b54d5dc17e482fe8b0bdca5320161b95fb929',
* calls: [{
* {
* data: '0xdeadbeef',
* to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
* },
* {
* to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
* value: parseEther('1'),
* },
* ]
* })
* ```
*/
export async function simulateCalls<
const calls extends readonly unknown[],
chain extends Chain | undefined,
account extends Account | Address | undefined = undefined,
>(
client: Client<Transport, chain>,
parameters: SimulateCallsParameters<calls, account>,
): Promise<SimulateCallsReturnType<calls>> {
const {
blockNumber,
blockTag,
calls,
stateOverrides,
traceAssetChanges,
traceTransfers,
validation,
} = parameters
const account = parameters.account
? parseAccount(parameters.account)
: undefined
if (traceAssetChanges && !account)
throw new BaseError(
'`account` is required when `traceAssetChanges` is true',
)
// Derive bytecode to extract ETH balance via a contract call.
const getBalanceData = account
? AbiConstructor.encode(AbiConstructor.from('constructor(bytes, bytes)'), {
bytecode: deploylessCallViaBytecodeBytecode,
args: [
getBalanceCode,
AbiFunction.encodeData(
AbiFunction.from('function getBalance(address)'),
[account.address],
),
],
})
: undefined
// Fetch ERC20/721 addresses that were "touched" from the calls.
const assetAddresses = traceAssetChanges
? await Promise.all(
parameters.calls.map(async (call: any) => {
if (!call.data && !call.abi) return
const { accessList } = await createAccessList(client, {
account: account!.address,
...call,
data: call.abi ? encodeFunctionData(call) : call.data,
})
return accessList.map(({ address, storageKeys }) =>
storageKeys.length > 0 ? address : null,
)
}),
).then((x) => x.flat().filter(Boolean))
: []
const blocks = await simulateBlocks(client, {
blockNumber,
blockTag: blockTag as undefined,
blocks: [
...(traceAssetChanges
? [
// ETH pre balances
{
calls: [{ data: getBalanceData }],
stateOverrides,
},
// Asset pre balances
{
calls: assetAddresses.map((address, i) => ({
abi: [
AbiFunction.from(
'function balanceOf(address) returns (uint256)',
),
],
functionName: 'balanceOf',
args: [account!.address],
to: address,
from: zeroAddress,
nonce: i,
})),
stateOverrides: [
{
address: zeroAddress,
nonce: 0,
},
],
},
]
: []),
{
calls: [...calls, { to: zeroAddress }].map((call) => ({
...(call as Call),
from: account?.address,
})) as any,
stateOverrides,
},
...(traceAssetChanges
? [
// ETH post balances
{
calls: [{ data: getBalanceData }],
},
// Asset post balances
{
calls: assetAddresses.map((address, i) => ({
abi: [
AbiFunction.from(
'function balanceOf(address) returns (uint256)',
),
],
functionName: 'balanceOf',
args: [account!.address],
to: address,
from: zeroAddress,
nonce: i,
})),
stateOverrides: [
{
address: zeroAddress,
nonce: 0,
},
],
},
// Decimals
{
calls: assetAddresses.map((address, i) => ({
to: address,
abi: [
AbiFunction.from('function decimals() returns (uint256)'),
],
functionName: 'decimals',
from: zeroAddress,
nonce: i,
})),
stateOverrides: [
{
address: zeroAddress,
nonce: 0,
},
],
},
// Token URI
{
calls: assetAddresses.map((address, i) => ({
to: address,
abi: [
AbiFunction.from(
'function tokenURI(uint256) returns (string)',
),
],
functionName: 'tokenURI',
args: [0n],
from: zeroAddress,
nonce: i,
})),
stateOverrides: [
{
address: zeroAddress,
nonce: 0,
},
],
},
// Symbols
{
calls: assetAddresses.map((address, i) => ({
to: address,
abi: [AbiFunction.from('function symbol() returns (string)')],
functionName: 'symbol',
from: zeroAddress,
nonce: i,
})),
stateOverrides: [
{
address: zeroAddress,
nonce: 0,
},
],
},
]
: []),
],
traceTransfers,
validation,
})
const block_results = traceAssetChanges ? blocks[2] : blocks[0]
const [
block_ethPre,
block_assetsPre,
,
block_ethPost,
block_assetsPost,
block_decimals,
block_tokenURI,
block_symbols,
] = traceAssetChanges ? blocks : []
// Extract call results from the simulation.
const { calls: block_calls, ...block } = block_results
const results = block_calls.slice(0, -1) ?? []
// Extract pre-execution ETH and asset balances.
const ethPre = block_ethPre?.calls ?? []
const assetsPre = block_assetsPre?.calls ?? []
const balancesPre = [...ethPre, ...assetsPre].map((call) =>
call.status === 'success' ? hexToBigInt(call.data) : null,
)
// Extract post-execution ETH and asset balances.
const ethPost = block_ethPost?.calls ?? []
const assetsPost = block_assetsPost?.calls ?? []
const balancesPost = [...ethPost, ...assetsPost].map((call) =>
call.status === 'success' ? hexToBigInt(call.data) : null,
)
// Extract asset symbols & decimals.
const decimals = (block_decimals?.calls ?? []).map((x) =>
x.status === 'success' ? x.result : null,
) as (number | null)[]
const symbols = (block_symbols?.calls ?? []).map((x) =>
x.status === 'success' ? x.result : null,
) as (string | null)[]
const tokenURI = (block_tokenURI?.calls ?? []).map((x) =>
x.status === 'success' ? x.result : null,
) as (string | null)[]
const changes: Mutable<SimulateCallsReturnType<calls>['assetChanges']> = []
for (const [i, balancePost] of balancesPost.entries()) {
const balancePre = balancesPre[i]
if (typeof balancePost !== 'bigint') continue
if (typeof balancePre !== 'bigint') continue
const decimals_ = decimals[i - 1]
const symbol_ = symbols[i - 1]
const tokenURI_ = tokenURI[i - 1]
const token = (() => {
if (i === 0)
return {
address: ethAddress,
decimals: 18,
symbol: 'ETH',
}
return {
address: assetAddresses[i - 1]! as Address,
decimals: tokenURI_ || decimals_ ? Number(decimals_ ?? 1) : undefined,
symbol: symbol_ ?? undefined,
}
})()
if (changes.some((change) => change.token.address === token.address))
continue
changes.push({
token,
value: {
pre: balancePre,
post: balancePost,
diff: balancePost - balancePre,
},
})
}
return {
assetChanges: changes,
block,
results,
} as unknown as SimulateCallsReturnType<calls>
}

325
node_modules/viem/actions/public/simulateContract.ts generated vendored Normal file
View File

@@ -0,0 +1,325 @@
import type { Abi, AbiFunction, AbiStateMutability, Address } from 'abitype'
import {
type ParseAccountErrorType,
parseAccount,
} from '../../accounts/utils/parseAccount.js'
import type { Client } from '../../clients/createClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { BaseError } from '../../errors/base.js'
import type { ErrorType } from '../../errors/utils.js'
import type { Account, ParseAccount } from '../../types/account.js'
import type { Chain, DeriveChain } from '../../types/chain.js'
import type {
ContractFunctionArgs,
ContractFunctionName,
ContractFunctionParameters,
ContractFunctionReturnType,
ExtractAbiFunctionForArgs,
} from '../../types/contract.js'
import type { Hex } from '../../types/misc.js'
import type { TransactionRequest } from '../../types/transaction.js'
import type {
IsNarrowable,
NoInfer,
Prettify,
UnionEvaluate,
UnionOmit,
} from '../../types/utils.js'
import {
type DecodeFunctionResultErrorType,
decodeFunctionResult,
} from '../../utils/abi/decodeFunctionResult.js'
import {
type EncodeFunctionDataErrorType,
encodeFunctionData,
} from '../../utils/abi/encodeFunctionData.js'
import {
type GetContractErrorReturnType,
getContractError,
} from '../../utils/errors/getContractError.js'
import { getAction } from '../../utils/getAction.js'
import type { WriteContractParameters } from '../wallet/writeContract.js'
import { type CallErrorType, type CallParameters, call } from './call.js'
export type GetMutabilityAwareValue<
abi extends Abi | readonly unknown[],
mutability extends AbiStateMutability = AbiStateMutability,
functionName extends ContractFunctionName<
abi,
mutability
> = ContractFunctionName<abi, mutability>,
valueType = TransactionRequest['value'],
args extends ContractFunctionArgs<
abi,
mutability,
functionName
> = ContractFunctionArgs<abi, mutability, functionName>,
abiFunction extends AbiFunction = abi extends Abi
? ExtractAbiFunctionForArgs<abi, mutability, functionName, args>
: AbiFunction,
_Narrowable extends boolean = IsNarrowable<abi, Abi>,
> = _Narrowable extends true
? abiFunction['stateMutability'] extends 'payable'
? { value?: NoInfer<valueType> | undefined }
: abiFunction['payable'] extends true
? { value?: NoInfer<valueType> | undefined }
: { value?: undefined }
: { value?: NoInfer<valueType> | undefined }
export type SimulateContractParameters<
abi extends Abi | readonly unknown[] = Abi,
functionName extends ContractFunctionName<
abi,
'nonpayable' | 'payable'
> = ContractFunctionName<abi, 'nonpayable' | 'payable'>,
args extends ContractFunctionArgs<
abi,
'nonpayable' | 'payable',
functionName
> = ContractFunctionArgs<abi, 'nonpayable' | 'payable', functionName>,
chain extends Chain | undefined = Chain | undefined,
chainOverride extends Chain | undefined = Chain | undefined,
accountOverride extends Account | Address | null | undefined = undefined,
///
derivedChain extends Chain | undefined = DeriveChain<chain, chainOverride>,
callParameters extends
CallParameters<derivedChain> = CallParameters<derivedChain>,
> = {
account?: accountOverride | null | undefined
chain?: chainOverride | undefined
/** Data to append to the end of the calldata. Useful for adding a ["domain" tag](https://opensea.notion.site/opensea/Seaport-Order-Attributions-ec2d69bf455041a5baa490941aad307f). */
dataSuffix?: Hex | undefined
} & ContractFunctionParameters<
abi,
'nonpayable' | 'payable',
functionName,
args
> &
UnionOmit<
callParameters,
| 'account'
| 'batch'
| 'code'
| 'to'
| 'data'
| 'factory'
| 'factoryData'
| 'value'
> &
GetMutabilityAwareValue<
abi,
'nonpayable' | 'payable',
functionName,
callParameters['value'],
args
>
export type SimulateContractReturnType<
out abi extends Abi | readonly unknown[] = Abi,
in out functionName extends ContractFunctionName<
abi,
'nonpayable' | 'payable'
> = ContractFunctionName<abi, 'nonpayable' | 'payable'>,
in out args extends ContractFunctionArgs<
abi,
'nonpayable' | 'payable',
functionName
> = ContractFunctionArgs<abi, 'nonpayable' | 'payable', functionName>,
/** @ts-expect-error cast variance */
out chain extends Chain | undefined = Chain | undefined,
out account extends Account | undefined = Account | undefined,
out chainOverride extends Chain | undefined = Chain | undefined,
out accountOverride extends Account | Address | null | undefined =
| Account
| Address
| null
| undefined,
///
in out minimizedAbi extends Abi = readonly [
ExtractAbiFunctionForArgs<
abi extends Abi ? abi : Abi,
'nonpayable' | 'payable',
functionName,
args
>,
],
out resolvedAccount extends
| Account
| null
| undefined = accountOverride extends Account | Address | null
? ParseAccount<accountOverride>
: account,
> = {
result: ContractFunctionReturnType<
minimizedAbi,
'nonpayable' | 'payable',
functionName,
args
>
request: Prettify<
UnionEvaluate<
UnionOmit<
WriteContractParameters<
minimizedAbi,
functionName,
args,
chain,
undefined,
chainOverride
>,
'account' | 'abi' | 'args' | 'chain' | 'functionName'
>
> &
ContractFunctionParameters<
minimizedAbi,
'nonpayable' | 'payable',
functionName,
args
> & {
chain: DeriveChain<chain, chainOverride>
} & (resolvedAccount extends Account | null
? { account: resolvedAccount }
: { account?: undefined })
>
}
export type SimulateContractErrorType =
| ParseAccountErrorType
| EncodeFunctionDataErrorType
| GetContractErrorReturnType<CallErrorType | DecodeFunctionResultErrorType>
| ErrorType
/**
* Simulates/validates a contract interaction. This is useful for retrieving **return data** and **revert reasons** of contract write functions.
*
* - Docs: https://viem.sh/docs/contract/simulateContract
* - Examples: https://stackblitz.com/github/wevm/viem/tree/main/examples/contracts_writing-to-contracts
*
* This function does not require gas to execute and _**does not**_ change the state of the blockchain. It is almost identical to [`readContract`](https://viem.sh/docs/contract/readContract), but also supports contract write functions.
*
* Internally, uses a [Public Client](https://viem.sh/docs/clients/public) to call the [`call` action](https://viem.sh/docs/actions/public/call) with [ABI-encoded `data`](https://viem.sh/docs/contract/encodeFunctionData).
*
* @param client - Client to use
* @param parameters - {@link SimulateContractParameters}
* @returns The simulation result and write request. {@link SimulateContractReturnType}
*
* @example
* import { createPublicClient, http } from 'viem'
* import { mainnet } from 'viem/chains'
* import { simulateContract } from 'viem/contract'
*
* const client = createPublicClient({
* chain: mainnet,
* transport: http(),
* })
* const result = await simulateContract(client, {
* address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
* abi: parseAbi(['function mint(uint32) view returns (uint32)']),
* functionName: 'mint',
* args: ['69420'],
* account: '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e',
* })
*/
export async function simulateContract<
chain extends Chain | undefined,
account extends Account | undefined,
const abi extends Abi | readonly unknown[],
functionName extends ContractFunctionName<abi, 'nonpayable' | 'payable'>,
const args extends ContractFunctionArgs<
abi,
'nonpayable' | 'payable',
functionName
>,
chainOverride extends Chain | undefined = undefined,
accountOverride extends Account | Address | null | undefined = undefined,
>(
client: Client<Transport, chain, account>,
parameters: SimulateContractParameters<
abi,
functionName,
args,
chain,
chainOverride,
accountOverride
>,
): Promise<
SimulateContractReturnType<
abi,
functionName,
args,
chain,
account,
chainOverride,
accountOverride
>
> {
const {
abi,
address,
args,
functionName,
dataSuffix = typeof client.dataSuffix === 'string'
? client.dataSuffix
: client.dataSuffix?.value,
...callRequest
} = parameters as SimulateContractParameters
const account = callRequest.account
? parseAccount(callRequest.account)
: client.account
const calldata = encodeFunctionData({ abi, args, functionName })
try {
const { data } = await getAction(
client,
call,
'call',
)({
batch: false,
data: `${calldata}${dataSuffix ? dataSuffix.replace('0x', '') : ''}`,
to: address,
...callRequest,
account,
})
const result = decodeFunctionResult({
abi,
args,
functionName,
data: data || '0x',
})
const minimizedAbi = abi.filter(
(abiItem) =>
'name' in abiItem && abiItem.name === parameters.functionName,
)
return {
result,
request: {
abi: minimizedAbi,
address,
args,
dataSuffix,
functionName,
...callRequest,
account,
},
} as unknown as SimulateContractReturnType<
abi,
functionName,
args,
chain,
account,
chainOverride,
accountOverride
>
} catch (error) {
throw getContractError(error as BaseError, {
abi,
address,
args,
docsPath: '/docs/contract/simulateContract',
functionName,
sender: account?.address,
})
}
}

50
node_modules/viem/actions/public/uninstallFilter.ts generated vendored Normal file
View File

@@ -0,0 +1,50 @@
import type { Client } from '../../clients/createClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { ErrorType } from '../../errors/utils.js'
import type { Chain } from '../../types/chain.js'
import type { Filter } from '../../types/filter.js'
import type { RequestErrorType } from '../../utils/buildRequest.js'
export type UninstallFilterParameters = {
filter: Filter<any>
}
export type UninstallFilterReturnType = boolean
export type UninstallFilterErrorType = RequestErrorType | ErrorType
/**
* Destroys a [`Filter`](https://viem.sh/docs/glossary/types#filter).
*
* - Docs: https://viem.sh/docs/actions/public/uninstallFilter
* - JSON-RPC Methods: [`eth_uninstallFilter`](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_uninstallFilter)
*
* Destroys a Filter that was created from one of the following Actions:
* - [`createBlockFilter`](https://viem.sh/docs/actions/public/createBlockFilter)
* - [`createEventFilter`](https://viem.sh/docs/actions/public/createEventFilter)
* - [`createPendingTransactionFilter`](https://viem.sh/docs/actions/public/createPendingTransactionFilter)
*
* @param client - Client to use
* @param parameters - {@link UninstallFilterParameters}
* @returns A boolean indicating if the Filter was successfully uninstalled. {@link UninstallFilterReturnType}
*
* @example
* import { createPublicClient, http } from 'viem'
* import { mainnet } from 'viem/chains'
* import { createPendingTransactionFilter, uninstallFilter } from 'viem/public'
*
* const filter = await createPendingTransactionFilter(client)
* const uninstalled = await uninstallFilter(client, { filter })
* // true
*/
export async function uninstallFilter<
transport extends Transport,
chain extends Chain | undefined,
>(
_client: Client<transport, chain>,
{ filter }: UninstallFilterParameters,
): Promise<UninstallFilterReturnType> {
return filter.request({
method: 'eth_uninstallFilter',
params: [filter.id],
})
}

402
node_modules/viem/actions/public/verifyHash.ts generated vendored Normal file
View File

@@ -0,0 +1,402 @@
import type { Address } from 'abitype'
import { SignatureErc6492 } from 'ox/erc6492'
import { SignatureErc8010 } from 'ox/erc8010'
import type { Client } from '../../clients/createClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import {
erc1271Abi,
erc6492SignatureValidatorAbi,
multicall3Abi,
} from '../../constants/abis.js'
import {
erc6492SignatureValidatorByteCode,
multicall3Bytecode,
} from '../../constants/contracts.js'
import {
CallExecutionError,
ContractFunctionExecutionError,
} from '../../errors/contract.js'
import type { InvalidHexBooleanError } from '../../errors/encoding.js'
import type { ErrorType } from '../../errors/utils.js'
import type { Chain } from '../../types/chain.js'
import type { ByteArray, Hex, Signature } from '../../types/misc.js'
import type { OneOf } from '../../types/utils.js'
import {
type EncodeDeployDataErrorType,
encodeDeployData,
} from '../../utils/abi/encodeDeployData.js'
import {
type EncodeFunctionDataErrorType,
encodeFunctionData,
} from '../../utils/abi/encodeFunctionData.js'
import {
type GetAddressErrorType,
getAddress,
} from '../../utils/address/getAddress.js'
import {
type IsAddressEqualErrorType,
isAddressEqual,
} from '../../utils/address/isAddressEqual.js'
import { verifyAuthorization } from '../../utils/authorization/verifyAuthorization.js'
import { type ConcatHexErrorType, concatHex } from '../../utils/data/concat.js'
import { type IsHexErrorType, isHex } from '../../utils/data/isHex.js'
import { hexToBool } from '../../utils/encoding/fromHex.js'
import {
type BytesToHexErrorType,
bytesToHex,
type NumberToHexErrorType,
numberToHex,
} from '../../utils/encoding/toHex.js'
import { getAction } from '../../utils/getAction.js'
import {
type RecoverAddressErrorType,
recoverAddress,
} from '../../utils/signature/recoverAddress.js'
import {
type SerializeSignatureErrorType,
serializeSignature,
} from '../../utils/signature/serializeSignature.js'
import { type CallErrorType, type CallParameters, call } from './call.js'
import { type GetCodeErrorType, getCode } from './getCode.js'
import { type ReadContractErrorType, readContract } from './readContract.js'
export type VerifyHashParameters = Pick<
CallParameters,
'blockNumber' | 'blockTag'
> & {
/** The address that signed the original message. */
address: Address
/** The chain to use. */
chain?: Chain | null | undefined
/** The address of the ERC-6492 signature verifier contract. */
erc6492VerifierAddress?: Address | undefined
/** The hash to be verified. */
hash: Hex
/** Multicall3 address for ERC-8010 verification. */
multicallAddress?: Address | undefined
/** The signature that was generated by signing the message with the address's private key. */
signature: Hex | ByteArray | Signature
/** @deprecated use `erc6492VerifierAddress` instead. */
universalSignatureVerifierAddress?: Address | undefined
/** Chooses which verification path to try first before falling back. */
mode?: 'auto' | 'eoa' | (string & {}) | undefined
} & OneOf<{ factory: Address; factoryData: Hex } | {}>
export type VerifyHashReturnType = boolean
export type VerifyHashErrorType =
| BytesToHexErrorType
| CallErrorType
| ConcatHexErrorType
| EncodeDeployDataErrorType
| EncodeFunctionDataErrorType
| ErrorType
| GetAddressErrorType
| GetCodeErrorType
| InvalidHexBooleanError
| IsAddressEqualErrorType
| IsHexErrorType
| NumberToHexErrorType
| ReadContractErrorType
| RecoverAddressErrorType
| SerializeSignatureErrorType
/**
* Verifies a message hash onchain using ERC-6492.
*
* @param client - Client to use.
* @param parameters - {@link VerifyHashParameters}
* @returns Whether or not the signature is valid. {@link VerifyHashReturnType}
*/
export async function verifyHash<chain extends Chain | undefined>(
client: Client<Transport, chain>,
parameters: VerifyHashParameters,
): Promise<VerifyHashReturnType> {
const {
address,
chain = client.chain,
hash,
erc6492VerifierAddress:
verifierAddress = parameters.universalSignatureVerifierAddress ??
chain?.contracts?.erc6492Verifier?.address,
multicallAddress = parameters.multicallAddress ??
chain?.contracts?.multicall3?.address,
mode = 'auto',
} = parameters
if (chain?.verifyHash) return await chain.verifyHash(client, parameters)
const signature = (() => {
const signature = parameters.signature
if (isHex(signature)) return signature
if (typeof signature === 'object' && 'r' in signature && 's' in signature)
return serializeSignature(signature)
return bytesToHex(signature)
})()
try {
if (mode === 'eoa') {
try {
const verified = isAddressEqual(
getAddress(address),
await recoverAddress({ hash, signature }),
)
if (verified) return true
} catch {}
}
if (SignatureErc8010.validate(signature))
return await verifyErc8010(client, {
...parameters,
multicallAddress,
signature,
})
return await verifyErc6492(client, {
...parameters,
verifierAddress,
signature,
})
} catch (error) {
if (mode !== 'eoa') {
// Fallback attempt to verify the signature via ECDSA recovery.
try {
const verified = isAddressEqual(
getAddress(address),
await recoverAddress({ hash, signature }),
)
if (verified) return true
} catch {}
}
if (error instanceof VerificationError) {
// if the execution fails, the signature was not valid and an internal method inside of the validator reverted
// this can happen for many reasons, for example if signer can not be recovered from the signature
// or if the signature has no valid format
return false
}
throw error
}
}
/** @internal */
export async function verifyErc8010(
client: Client,
parameters: verifyErc8010.Parameters,
) {
const { address, blockNumber, blockTag, hash, multicallAddress } = parameters
const {
authorization: authorization_ox,
data: initData,
signature,
to,
} = SignatureErc8010.unwrap(parameters.signature)
// Check if already delegated
const code = await getCode(client, {
address,
blockNumber,
blockTag,
} as never)
// If already delegated, perform standard ERC-1271 verification.
if (code === concatHex(['0xef0100', authorization_ox.address]))
return await verifyErc1271(client, {
address,
blockNumber,
blockTag,
hash,
signature,
})
const authorization = {
address: authorization_ox.address,
chainId: Number(authorization_ox.chainId),
nonce: Number(authorization_ox.nonce),
r: numberToHex(authorization_ox.r, { size: 32 }),
s: numberToHex(authorization_ox.s, { size: 32 }),
yParity: authorization_ox.yParity,
} as const
const valid = await verifyAuthorization({
address,
authorization,
})
if (!valid) throw new VerificationError()
// Deployless verification.
const results = await getAction(
client,
readContract,
'readContract',
)({
...(multicallAddress
? { address: multicallAddress }
: { code: multicall3Bytecode }),
authorizationList: [authorization],
abi: multicall3Abi,
blockNumber,
blockTag: 'pending',
functionName: 'aggregate3',
args: [
[
...(initData
? ([
{
allowFailure: true,
target: to ?? address,
callData: initData,
},
] as const)
: []),
{
allowFailure: true,
target: address,
callData: encodeFunctionData({
abi: erc1271Abi,
functionName: 'isValidSignature',
args: [hash, signature],
}),
},
],
],
})
const data = results[results.length - 1]?.returnData
if (data?.startsWith('0x1626ba7e')) return true
throw new VerificationError()
}
export namespace verifyErc8010 {
export type Parameters = Pick<CallParameters, 'blockNumber' | 'blockTag'> & {
/** The address that signed the original message. */
address: Address
/** The hash to be verified. */
hash: Hex
/** Multicall3 address for ERC-8010 verification. */
multicallAddress?: Address | undefined
/** The signature that was generated by signing the message with the address's private key. */
signature: Hex
}
}
/** @internal */
// biome-ignore lint/correctness/noUnusedVariables: _
async function verifyErc6492(
client: Client,
parameters: verifyErc6492.Parameters,
) {
const {
address,
factory,
factoryData,
hash,
signature,
verifierAddress,
...rest
} = parameters
const wrappedSignature = await (async () => {
// If no `factory` or `factoryData` is provided, it is assumed that the
// address is not a Smart Account, or the Smart Account is already deployed.
if (!factory && !factoryData) return signature
// If the signature is already wrapped, return the signature.
if (SignatureErc6492.validate(signature)) return signature
// If the Smart Account is not deployed, wrap the signature with a 6492 wrapper
// to perform counterfactual validation.
return SignatureErc6492.wrap({
data: factoryData!,
signature,
to: factory!,
})
})()
const args = verifierAddress
? ({
to: verifierAddress,
data: encodeFunctionData({
abi: erc6492SignatureValidatorAbi,
functionName: 'isValidSig',
args: [address, hash, wrappedSignature],
}),
...rest,
} as unknown as CallParameters)
: ({
data: encodeDeployData({
abi: erc6492SignatureValidatorAbi,
args: [address, hash, wrappedSignature],
bytecode: erc6492SignatureValidatorByteCode,
}),
...rest,
} as unknown as CallParameters)
const { data } = await getAction(
client,
call,
'call',
)(args).catch((error) => {
if (error instanceof CallExecutionError) throw new VerificationError()
throw error
})
if (hexToBool(data ?? '0x0')) return true
throw new VerificationError()
}
export namespace verifyErc6492 {
export type Parameters = Pick<CallParameters, 'blockNumber' | 'blockTag'> & {
/** The address that signed the original message. */
address: Address
/** The hash to be verified. */
hash: Hex
/** The signature that was generated by signing the message with the address's private key. */
signature: Hex
/** The address of the ERC-6492 signature verifier contract. */
verifierAddress?: Address | undefined
} & OneOf<{ factory: Address; factoryData: Hex } | {}>
}
/** @internal */
export async function verifyErc1271(
client: Client,
parameters: verifyErc1271.Parameters,
) {
const { address, blockNumber, blockTag, hash, signature } = parameters
const result = await getAction(
client,
readContract,
'readContract',
)({
address,
abi: erc1271Abi,
args: [hash, signature],
blockNumber,
blockTag,
functionName: 'isValidSignature',
}).catch((error) => {
if (error instanceof ContractFunctionExecutionError)
throw new VerificationError()
throw error
})
if (result.startsWith('0x1626ba7e')) return true
throw new VerificationError()
}
export namespace verifyErc1271 {
export type Parameters = Pick<CallParameters, 'blockNumber' | 'blockTag'> & {
/** The address that signed the original message. */
address: Address
/** The hash to be verified. */
hash: Hex
/** The signature that was generated by signing the message with the address's private key. */
signature: Hex
}
}
class VerificationError extends Error {}

76
node_modules/viem/actions/public/verifyMessage.ts generated vendored Normal file
View File

@@ -0,0 +1,76 @@
import type { Address } from 'abitype'
import type { Client } from '../../clients/createClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { ErrorType } from '../../errors/utils.js'
import type { Chain } from '../../types/chain.js'
import type {
ByteArray,
Hex,
SignableMessage,
Signature,
} from '../../types/misc.js'
import type { Prettify } from '../../types/utils.js'
import { getAction } from '../../utils/getAction.js'
import type { HashMessageErrorType } from '../../utils/signature/hashMessage.js'
import { hashMessage } from '../../utils/signature/hashMessage.js'
import {
type VerifyHashErrorType,
type VerifyHashParameters,
verifyHash,
} from './verifyHash.js'
export type VerifyMessageParameters = Prettify<
Omit<VerifyHashParameters, 'hash'> & {
/** The address that signed the original message. */
address: Address
/** The message to be verified. */
message: SignableMessage
/** The signature that was generated by signing the message with the address's private key. */
signature: Hex | ByteArray | Signature
}
>
export type VerifyMessageReturnType = boolean
export type VerifyMessageErrorType =
| HashMessageErrorType
| VerifyHashErrorType
| ErrorType
/**
* Verify that a message was signed by the provided address.
*
* Compatible with Smart Contract Accounts & Externally Owned Accounts via [ERC-6492](https://eips.ethereum.org/EIPS/eip-6492).
*
* - Docs {@link https://viem.sh/docs/actions/public/verifyMessage}
*
* @param client - Client to use.
* @param parameters - {@link VerifyMessageParameters}
* @returns Whether or not the signature is valid. {@link VerifyMessageReturnType}
*/
export async function verifyMessage<chain extends Chain | undefined>(
client: Client<Transport, chain>,
{
address,
message,
factory,
factoryData,
signature,
...callRequest
}: VerifyMessageParameters,
): Promise<VerifyMessageReturnType> {
const hash = hashMessage(message)
return getAction(
client,
verifyHash,
'verifyHash',
)({
address,
factory: factory!,
factoryData: factoryData!,
hash,
signature,
...callRequest,
})
}

79
node_modules/viem/actions/public/verifyTypedData.ts generated vendored Normal file
View File

@@ -0,0 +1,79 @@
import type { Address, TypedData } from 'abitype'
import type { Client } from '../../clients/createClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { ErrorType } from '../../errors/utils.js'
import type { Chain } from '../../types/chain.js'
import type { ByteArray, Hex, Signature } from '../../types/misc.js'
import type { TypedDataDefinition } from '../../types/typedData.js'
import { getAction } from '../../utils/getAction.js'
import {
type HashTypedDataErrorType,
hashTypedData,
} from '../../utils/signature/hashTypedData.js'
import {
type VerifyHashErrorType,
type VerifyHashParameters,
verifyHash,
} from './verifyHash.js'
export type VerifyTypedDataParameters<
typedData extends TypedData | Record<string, unknown> = TypedData,
primaryType extends keyof typedData | 'EIP712Domain' = keyof typedData,
> = Omit<VerifyHashParameters, 'hash'> &
TypedDataDefinition<typedData, primaryType> & {
/** The address to verify the typed data for. */
address: Address
/** The signature to verify */
signature: Hex | ByteArray | Signature
}
export type VerifyTypedDataReturnType = boolean
export type VerifyTypedDataErrorType =
| HashTypedDataErrorType
| VerifyHashErrorType
| ErrorType
/**
* Verify that typed data was signed by the provided address.
*
* - Docs {@link https://viem.sh/docs/actions/public/verifyTypedData}
*
* @param client - Client to use.
* @param parameters - {@link VerifyTypedDataParameters}
* @returns Whether or not the signature is valid. {@link VerifyTypedDataReturnType}
*/
export async function verifyTypedData<
const typedData extends TypedData | Record<string, unknown>,
primaryType extends keyof typedData | 'EIP712Domain',
chain extends Chain | undefined,
>(
client: Client<Transport, chain>,
parameters: VerifyTypedDataParameters<typedData, primaryType>,
): Promise<VerifyTypedDataReturnType> {
const {
address,
factory,
factoryData,
signature,
message,
primaryType,
types,
domain,
...callRequest
} = parameters as VerifyTypedDataParameters
const hash = hashTypedData({ message, primaryType, types, domain })
return getAction(
client,
verifyHash,
'verifyHash',
)({
address,
factory: factory!,
factoryData: factoryData!,
hash,
signature,
...callRequest,
})
}

View File

@@ -0,0 +1,377 @@
import type { Client } from '../../clients/createClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import { BlockNotFoundError } from '../../errors/block.js'
import {
TransactionNotFoundError,
TransactionReceiptNotFoundError,
WaitForTransactionReceiptTimeoutError,
type WaitForTransactionReceiptTimeoutErrorType,
} from '../../errors/transaction.js'
import type { ErrorType } from '../../errors/utils.js'
import type { Chain } from '../../types/chain.js'
import type { Hash } from '../../types/misc.js'
import type { Transaction } from '../../types/transaction.js'
import { getAction } from '../../utils/getAction.js'
import { type ObserveErrorType, observe } from '../../utils/observe.js'
import { withResolvers } from '../../utils/promise/withResolvers.js'
import {
type WithRetryParameters,
withRetry,
} from '../../utils/promise/withRetry.js'
import { stringify } from '../../utils/stringify.js'
import { type GetBlockErrorType, getBlock } from './getBlock.js'
import {
type GetTransactionErrorType,
type GetTransactionReturnType,
getTransaction,
} from './getTransaction.js'
import {
type GetTransactionReceiptErrorType,
type GetTransactionReceiptReturnType,
getTransactionReceipt,
} from './getTransactionReceipt.js'
import {
type WatchBlockNumberErrorType,
watchBlockNumber,
} from './watchBlockNumber.js'
export type ReplacementReason = 'cancelled' | 'replaced' | 'repriced'
export type ReplacementReturnType<
chain extends Chain | undefined = Chain | undefined,
> = {
reason: ReplacementReason
replacedTransaction: Transaction
transaction: Transaction
transactionReceipt: GetTransactionReceiptReturnType<chain>
}
export type WaitForTransactionReceiptReturnType<
chain extends Chain | undefined = Chain | undefined,
> = GetTransactionReceiptReturnType<chain>
export type WaitForTransactionReceiptParameters<
chain extends Chain | undefined = Chain | undefined,
> = {
/**
* Whether to check for transaction replacements.
* @default true
*/
checkReplacement?: boolean | undefined
/**
* The number of confirmations (blocks that have passed) to wait before resolving.
* @default 1
*/
confirmations?: number | undefined
/** The hash of the transaction. */
hash: Hash
/** Optional callback to emit if the transaction has been replaced. */
onReplaced?: ((response: ReplacementReturnType<chain>) => void) | undefined
/**
* Polling frequency (in ms). Defaults to the client's pollingInterval config.
* @default client.pollingInterval
*/
pollingInterval?: number | undefined
/**
* Number of times to retry if the transaction or block is not found.
* @default 6 (exponential backoff)
*/
retryCount?: WithRetryParameters['retryCount'] | undefined
/**
* Time to wait (in ms) between retries.
* @default `({ count }) => ~~(1 << count) * 200` (exponential backoff)
*/
retryDelay?: WithRetryParameters['delay'] | undefined
/**
* Optional timeout (in milliseconds) to wait before stopping polling.
* @default 180_000
*/
timeout?: number | undefined
}
export type WaitForTransactionReceiptErrorType =
| ObserveErrorType
| GetBlockErrorType
| GetTransactionErrorType
| GetTransactionReceiptErrorType
| WatchBlockNumberErrorType
| WaitForTransactionReceiptTimeoutErrorType
| ErrorType
/**
* Waits for the [Transaction](https://viem.sh/docs/glossary/terms#transaction) to be included on a [Block](https://viem.sh/docs/glossary/terms#block) (one confirmation), and then returns the [Transaction Receipt](https://viem.sh/docs/glossary/terms#transaction-receipt).
*
* - Docs: https://viem.sh/docs/actions/public/waitForTransactionReceipt
* - Example: https://stackblitz.com/github/wevm/viem/tree/main/examples/transactions_sending-transactions
* - JSON-RPC Methods:
* - Polls [`eth_getTransactionReceipt`](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getTransactionReceipt) on each block until it has been processed.
* - If a Transaction has been replaced:
* - Calls [`eth_getBlockByNumber`](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getblockbynumber) and extracts the transactions
* - Checks if one of the Transactions is a replacement
* - If so, calls [`eth_getTransactionReceipt`](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getTransactionReceipt).
*
* The `waitForTransactionReceipt` action additionally supports Replacement detection (e.g. sped up Transactions).
*
* Transactions can be replaced when a user modifies their transaction in their wallet (to speed up or cancel). Transactions are replaced when they are sent from the same nonce.
*
* There are 3 types of Transaction Replacement reasons:
*
* - `repriced`: The gas price has been modified (e.g. different `maxFeePerGas`)
* - `cancelled`: The Transaction has been cancelled (e.g. `value === 0n`)
* - `replaced`: The Transaction has been replaced (e.g. different `value` or `data`)
*
* @param client - Client to use
* @param parameters - {@link WaitForTransactionReceiptParameters}
* @returns The transaction receipt. {@link WaitForTransactionReceiptReturnType}
*
* @example
* import { createPublicClient, waitForTransactionReceipt, http } from 'viem'
* import { mainnet } from 'viem/chains'
*
* const client = createPublicClient({
* chain: mainnet,
* transport: http(),
* })
* const transactionReceipt = await waitForTransactionReceipt(client, {
* hash: '0x4ca7ee652d57678f26e887c149ab0735f41de37bcad58c9f6d3ed5824f15b74d',
* })
*/
export async function waitForTransactionReceipt<
chain extends Chain | undefined,
>(
client: Client<Transport, chain>,
parameters: WaitForTransactionReceiptParameters<chain>,
): Promise<WaitForTransactionReceiptReturnType<chain>> {
const {
checkReplacement = true,
confirmations = 1,
hash,
onReplaced,
retryCount = 6,
retryDelay = ({ count }) => ~~(1 << count) * 200, // exponential backoff
timeout = 180_000,
} = parameters
const observerId = stringify(['waitForTransactionReceipt', client.uid, hash])
const pollingInterval = (() => {
if (parameters.pollingInterval) return parameters.pollingInterval
if (client.chain?.experimental_preconfirmationTime)
return client.chain.experimental_preconfirmationTime
return client.pollingInterval
})()
let transaction: GetTransactionReturnType<chain> | undefined
let replacedTransaction: GetTransactionReturnType<chain> | undefined
let receipt: GetTransactionReceiptReturnType<chain> | undefined
let retrying = false
let _unobserve: () => void
let _unwatch: () => void
const { promise, resolve, reject } =
withResolvers<WaitForTransactionReceiptReturnType<chain>>()
const timer = timeout
? setTimeout(() => {
_unwatch?.()
_unobserve?.()
reject(new WaitForTransactionReceiptTimeoutError({ hash }))
}, timeout)
: undefined
_unobserve = observe(
observerId,
{ onReplaced, resolve, reject },
async (emit) => {
receipt = await getAction(
client,
getTransactionReceipt,
'getTransactionReceipt',
)({ hash }).catch(() => undefined)
if (receipt && confirmations <= 1) {
clearTimeout(timer)
emit.resolve(receipt)
_unobserve?.()
return
}
_unwatch = getAction(
client,
watchBlockNumber,
'watchBlockNumber',
)({
emitMissed: true,
emitOnBegin: true,
poll: true,
pollingInterval,
async onBlockNumber(blockNumber_) {
const done = (fn: () => void) => {
clearTimeout(timer)
_unwatch?.()
fn()
_unobserve?.()
}
let blockNumber = blockNumber_
if (retrying) return
try {
// If we already have a valid receipt, let's check if we have enough
// confirmations. If we do, then we can resolve.
if (receipt) {
if (
confirmations > 1 &&
(!receipt.blockNumber ||
blockNumber - receipt.blockNumber + 1n < confirmations)
)
return
done(() => emit.resolve(receipt!))
return
}
// Get the transaction to check if it's been replaced.
// We need to retry as some RPC Providers may be slow to sync
// up mined transactions.
if (checkReplacement && !transaction) {
retrying = true
await withRetry(
async () => {
transaction = (await getAction(
client,
getTransaction,
'getTransaction',
)({ hash })) as GetTransactionReturnType<chain>
if (transaction.blockNumber)
blockNumber = transaction.blockNumber
},
{
delay: retryDelay,
retryCount,
},
)
retrying = false
}
// Get the receipt to check if it's been processed.
receipt = await getAction(
client,
getTransactionReceipt,
'getTransactionReceipt',
)({ hash })
// Check if we have enough confirmations. If not, continue polling.
if (
confirmations > 1 &&
(!receipt.blockNumber ||
blockNumber - receipt.blockNumber + 1n < confirmations)
)
return
done(() => emit.resolve(receipt!))
} catch (err) {
// If the receipt is not found, the transaction will be pending.
// We need to check if it has potentially been replaced.
if (
err instanceof TransactionNotFoundError ||
err instanceof TransactionReceiptNotFoundError
) {
if (!transaction) {
retrying = false
return
}
try {
replacedTransaction = transaction
// Let's retrieve the transactions from the current block.
// We need to retry as some RPC Providers may be slow to sync
// up mined blocks.
retrying = true
const block = await withRetry(
() =>
getAction(
client,
getBlock,
'getBlock',
)({
blockNumber,
includeTransactions: true,
}),
{
delay: retryDelay,
retryCount,
shouldRetry: ({ error }) =>
error instanceof BlockNotFoundError,
},
)
retrying = false
const replacementTransaction = (
block.transactions as {} as Transaction[]
).find(
({ from, nonce }) =>
from === replacedTransaction!.from &&
nonce === replacedTransaction!.nonce,
)
// If we couldn't find a replacement transaction, continue polling.
if (!replacementTransaction) return
// If we found a replacement transaction, return it's receipt.
receipt = await getAction(
client,
getTransactionReceipt,
'getTransactionReceipt',
)({
hash: replacementTransaction.hash,
})
// Check if we have enough confirmations. If not, continue polling.
if (
confirmations > 1 &&
(!receipt.blockNumber ||
blockNumber - receipt.blockNumber + 1n < confirmations)
)
return
let reason: ReplacementReason = 'replaced'
if (
replacementTransaction.to === replacedTransaction.to &&
replacementTransaction.value === replacedTransaction.value &&
replacementTransaction.input === replacedTransaction.input
) {
reason = 'repriced'
} else if (
replacementTransaction.from === replacementTransaction.to &&
replacementTransaction.value === 0n
) {
reason = 'cancelled'
}
done(() => {
emit.onReplaced?.({
reason,
replacedTransaction: replacedTransaction! as any,
transaction: replacementTransaction,
transactionReceipt: receipt!,
})
emit.resolve(receipt!)
})
} catch (err_) {
done(() => emit.reject(err_))
}
} else {
done(() => emit.reject(err))
}
}
},
})
},
)
return promise
}

216
node_modules/viem/actions/public/watchBlockNumber.ts generated vendored Normal file
View File

@@ -0,0 +1,216 @@
import type { Client } from '../../clients/createClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { ErrorType } from '../../errors/utils.js'
import type { Chain } from '../../types/chain.js'
import type { HasTransportType } from '../../types/transport.js'
import { hexToBigInt } from '../../utils/encoding/fromHex.js'
import { getAction } from '../../utils/getAction.js'
import { observe } from '../../utils/observe.js'
import { type PollErrorType, poll } from '../../utils/poll.js'
import { stringify } from '../../utils/stringify.js'
import {
type GetBlockNumberReturnType,
getBlockNumber,
} from './getBlockNumber.js'
export type OnBlockNumberParameter = GetBlockNumberReturnType
export type OnBlockNumberFn = (
blockNumber: OnBlockNumberParameter,
prevBlockNumber: OnBlockNumberParameter | undefined,
) => void
export type WatchBlockNumberParameters<
transport extends Transport = Transport,
> = {
/** The callback to call when a new block number is received. */
onBlockNumber: OnBlockNumberFn
/** The callback to call when an error occurred when trying to get for a new block. */
onError?: ((error: Error) => void) | undefined
} & (
| (HasTransportType<transport, 'webSocket' | 'ipc'> extends true
? {
emitMissed?: undefined
emitOnBegin?: undefined
/** Whether or not the WebSocket Transport should poll the JSON-RPC, rather than using `eth_subscribe`. */
poll?: false | undefined
pollingInterval?: undefined
}
: never)
| {
/** Whether or not to emit the missed block numbers to the callback. */
emitMissed?: boolean | undefined
/** Whether or not to emit the latest block number to the callback when the subscription opens. */
emitOnBegin?: boolean | undefined
poll?: true | undefined
/** Polling frequency (in ms). Defaults to Client's pollingInterval config. */
pollingInterval?: number | undefined
}
)
export type WatchBlockNumberReturnType = () => void
export type WatchBlockNumberErrorType = PollErrorType | ErrorType
/**
* Watches and returns incoming block numbers.
*
* - Docs: https://viem.sh/docs/actions/public/watchBlockNumber
* - Examples: https://stackblitz.com/github/wevm/viem/tree/main/examples/blocks_watching-blocks
* - JSON-RPC Methods:
* - When `poll: true`, calls [`eth_blockNumber`](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_blocknumber) on a polling interval.
* - When `poll: false` & WebSocket Transport, uses a WebSocket subscription via [`eth_subscribe`](https://docs.alchemy.com/reference/eth-subscribe-polygon) and the `"newHeads"` event.
*
* @param client - Client to use
* @param parameters - {@link WatchBlockNumberParameters}
* @returns A function that can be invoked to stop watching for new block numbers. {@link WatchBlockNumberReturnType}
*
* @example
* import { createPublicClient, watchBlockNumber, http } from 'viem'
* import { mainnet } from 'viem/chains'
*
* const client = createPublicClient({
* chain: mainnet,
* transport: http(),
* })
* const unwatch = watchBlockNumber(client, {
* onBlockNumber: (blockNumber) => console.log(blockNumber),
* })
*/
export function watchBlockNumber<
chain extends Chain | undefined,
transport extends Transport,
>(
client: Client<transport, chain>,
{
emitOnBegin = false,
emitMissed = false,
onBlockNumber,
onError,
poll: poll_,
pollingInterval = client.pollingInterval,
}: WatchBlockNumberParameters<transport>,
): WatchBlockNumberReturnType {
const enablePolling = (() => {
if (typeof poll_ !== 'undefined') return poll_
if (
client.transport.type === 'webSocket' ||
client.transport.type === 'ipc'
)
return false
if (
client.transport.type === 'fallback' &&
(client.transport.transports[0].config.type === 'webSocket' ||
client.transport.transports[0].config.type === 'ipc')
)
return false
return true
})()
let prevBlockNumber: GetBlockNumberReturnType | undefined
const pollBlockNumber = () => {
const observerId = stringify([
'watchBlockNumber',
client.uid,
emitOnBegin,
emitMissed,
pollingInterval,
])
return observe(observerId, { onBlockNumber, onError }, (emit) =>
poll(
async () => {
try {
const blockNumber = await getAction(
client,
getBlockNumber,
'getBlockNumber',
)({ cacheTime: 0 })
if (prevBlockNumber !== undefined) {
// If the current block number is the same as the previous,
// we can skip.
if (blockNumber === prevBlockNumber) return
// If we have missed out on some previous blocks, and the
// `emitMissed` flag is truthy, let's emit those blocks.
if (blockNumber - prevBlockNumber > 1 && emitMissed) {
for (let i = prevBlockNumber + 1n; i < blockNumber; i++) {
emit.onBlockNumber(i, prevBlockNumber)
prevBlockNumber = i
}
}
}
// If the next block number is greater than the previous,
// it is not in the past, and we can emit the new block number.
if (
prevBlockNumber === undefined ||
blockNumber > prevBlockNumber
) {
emit.onBlockNumber(blockNumber, prevBlockNumber)
prevBlockNumber = blockNumber
}
} catch (err) {
emit.onError?.(err as Error)
}
},
{
emitOnBegin,
interval: pollingInterval,
},
),
)
}
const subscribeBlockNumber = () => {
const observerId = stringify([
'watchBlockNumber',
client.uid,
emitOnBegin,
emitMissed,
])
return observe(observerId, { onBlockNumber, onError }, (emit) => {
let active = true
let unsubscribe = () => (active = false)
;(async () => {
try {
const transport = (() => {
if (client.transport.type === 'fallback') {
const transport = client.transport.transports.find(
(transport: ReturnType<Transport>) =>
transport.config.type === 'webSocket' ||
transport.config.type === 'ipc',
)
if (!transport) return client.transport
return transport.value
}
return client.transport
})()
const { unsubscribe: unsubscribe_ } = await transport.subscribe({
params: ['newHeads'],
onData(data: any) {
if (!active) return
const blockNumber = hexToBigInt(data.result?.number)
emit.onBlockNumber(blockNumber, prevBlockNumber)
prevBlockNumber = blockNumber
},
onError(error: Error) {
emit.onError?.(error)
},
})
unsubscribe = unsubscribe_
if (!active) unsubscribe()
} catch (err) {
onError?.(err as Error)
}
})()
return () => unsubscribe()
})
}
return enablePolling ? pollBlockNumber() : subscribeBlockNumber()
}

275
node_modules/viem/actions/public/watchBlocks.ts generated vendored Normal file
View File

@@ -0,0 +1,275 @@
import type { Client } from '../../clients/createClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { ErrorType } from '../../errors/utils.js'
import type { BlockTag } from '../../types/block.js'
import type { Chain } from '../../types/chain.js'
import type { HasTransportType } from '../../types/transport.js'
import { getAction } from '../../utils/getAction.js'
import { observe } from '../../utils/observe.js'
import { type PollErrorType, poll } from '../../utils/poll.js'
import { type StringifyErrorType, stringify } from '../../utils/stringify.js'
import { type GetBlockReturnType, getBlock } from './getBlock.js'
export type OnBlockParameter<
chain extends Chain | undefined = Chain,
includeTransactions extends boolean = false,
blockTag extends BlockTag = 'latest',
> = GetBlockReturnType<chain, includeTransactions, blockTag>
export type OnBlock<
chain extends Chain | undefined = Chain,
includeTransactions extends boolean = false,
blockTag extends BlockTag = 'latest',
> = (
block: OnBlockParameter<chain, includeTransactions, blockTag>,
prevBlock: OnBlockParameter<chain, includeTransactions, blockTag> | undefined,
) => void
export type WatchBlocksParameters<
transport extends Transport = Transport,
chain extends Chain | undefined = Chain,
includeTransactions extends boolean = false,
blockTag extends BlockTag = 'latest',
> = {
/** The callback to call when a new block is received. */
onBlock: OnBlock<chain, includeTransactions, blockTag>
/** The callback to call when an error occurred when trying to get for a new block. */
onError?: ((error: Error) => void) | undefined
} & (
| (HasTransportType<transport, 'webSocket' | 'ipc'> extends true
? {
blockTag?: undefined
emitMissed?: undefined
emitOnBegin?: undefined
includeTransactions?: undefined
/** Whether or not the WebSocket Transport should poll the JSON-RPC, rather than using `eth_subscribe`. */
poll?: false | undefined
pollingInterval?: undefined
}
: never)
| {
/** The block tag. Defaults to "latest". */
blockTag?: blockTag | BlockTag | undefined
/** Whether or not to emit the missed blocks to the callback. */
emitMissed?: boolean | undefined
/** Whether or not to emit the block to the callback when the subscription opens. */
emitOnBegin?: boolean | undefined
/** Whether or not to include transaction data in the response. */
includeTransactions?: includeTransactions | undefined
poll?: true | undefined
/** Polling frequency (in ms). Defaults to the client's pollingInterval config. */
pollingInterval?: number | undefined
}
)
export type WatchBlocksReturnType = () => void
export type WatchBlocksErrorType =
| StringifyErrorType
| PollErrorType
| ErrorType
/**
* Watches and returns information for incoming blocks.
*
* - Docs: https://viem.sh/docs/actions/public/watchBlocks
* - Examples: https://stackblitz.com/github/wevm/viem/tree/main/examples/blocks_watching-blocks
* - JSON-RPC Methods:
* - When `poll: true`, calls [`eth_getBlockByNumber`](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getBlockByNumber) on a polling interval.
* - When `poll: false` & WebSocket Transport, uses a WebSocket subscription via [`eth_subscribe`](https://docs.alchemy.com/reference/eth-subscribe-polygon) and the `"newHeads"` event.
*
* @param client - Client to use
* @param parameters - {@link WatchBlocksParameters}
* @returns A function that can be invoked to stop watching for new block numbers. {@link WatchBlocksReturnType}
*
* @example
* import { createPublicClient, watchBlocks, http } from 'viem'
* import { mainnet } from 'viem/chains'
*
* const client = createPublicClient({
* chain: mainnet,
* transport: http(),
* })
* const unwatch = watchBlocks(client, {
* onBlock: (block) => console.log(block),
* })
*/
export function watchBlocks<
transport extends Transport,
chain extends Chain | undefined,
includeTransactions extends boolean = false,
blockTag extends BlockTag = 'latest',
>(
client: Client<transport, chain>,
{
blockTag = client.experimental_blockTag ?? 'latest',
emitMissed = false,
emitOnBegin = false,
onBlock,
onError,
includeTransactions: includeTransactions_,
poll: poll_,
pollingInterval = client.pollingInterval,
}: WatchBlocksParameters<transport, chain, includeTransactions, blockTag>,
): WatchBlocksReturnType {
const enablePolling = (() => {
if (typeof poll_ !== 'undefined') return poll_
if (
client.transport.type === 'webSocket' ||
client.transport.type === 'ipc'
)
return false
if (
client.transport.type === 'fallback' &&
(client.transport.transports[0].config.type === 'webSocket' ||
client.transport.transports[0].config.type === 'ipc')
)
return false
return true
})()
const includeTransactions = includeTransactions_ ?? false
let prevBlock:
| GetBlockReturnType<chain, false | includeTransactions, 'latest'>
| undefined
const pollBlocks = () => {
const observerId = stringify([
'watchBlocks',
client.uid,
blockTag,
emitMissed,
emitOnBegin,
includeTransactions,
pollingInterval,
])
return observe(observerId, { onBlock, onError }, (emit) =>
poll(
async () => {
try {
const block = await getAction(
client,
getBlock,
'getBlock',
)({
blockTag,
includeTransactions,
})
if (block.number !== null && prevBlock?.number != null) {
// If the current block number is the same as the previous,
// we can skip.
if (block.number === prevBlock.number) return
// If we have missed out on some previous blocks, and the
// `emitMissed` flag is truthy, let's emit those blocks.
if (block.number - prevBlock.number > 1 && emitMissed) {
for (let i = prevBlock?.number + 1n; i < block.number; i++) {
const block = (await getAction(
client,
getBlock,
'getBlock',
)({
blockNumber: i,
includeTransactions,
})) as GetBlockReturnType<chain>
emit.onBlock(block as any, prevBlock as any)
prevBlock = block
}
}
}
if (
// If no previous block exists, emit.
prevBlock?.number == null ||
// If the block tag is "pending" with no block number, emit.
(blockTag === 'pending' && block?.number == null) ||
// If the next block number is greater than the previous block number, emit.
// We don't want to emit blocks in the past.
(block.number !== null && block.number > prevBlock.number)
) {
emit.onBlock(block as any, prevBlock as any)
prevBlock = block as any
}
} catch (err) {
emit.onError?.(err as Error)
}
},
{
emitOnBegin,
interval: pollingInterval,
},
),
)
}
const subscribeBlocks = () => {
let active = true
let emitFetched = true
let unsubscribe = () => (active = false)
;(async () => {
try {
if (emitOnBegin) {
getAction(
client,
getBlock,
'getBlock',
)({
blockTag,
includeTransactions,
})
.then((block) => {
if (!active) return
if (!emitFetched) return
onBlock(block as any, undefined)
emitFetched = false
})
.catch(onError)
}
const transport = (() => {
if (client.transport.type === 'fallback') {
const transport = client.transport.transports.find(
(transport: ReturnType<Transport>) =>
transport.config.type === 'webSocket' ||
transport.config.type === 'ipc',
)
if (!transport) return client.transport
return transport.value
}
return client.transport
})()
const { unsubscribe: unsubscribe_ } = await transport.subscribe({
params: ['newHeads'],
async onData(data: any) {
if (!active) return
const block = (await getAction(
client,
getBlock,
'getBlock',
)({
blockNumber: data.result?.number,
includeTransactions,
}).catch(() => {})) as GetBlockReturnType<chain>
if (!active) return
onBlock(block as any, prevBlock as any)
emitFetched = false
prevBlock = block
},
onError(error: Error) {
onError?.(error)
},
})
unsubscribe = unsubscribe_
if (!active) unsubscribe()
} catch (err) {
onError?.(err as Error)
}
})()
return () => unsubscribe()
}
return enablePolling ? pollBlocks() : subscribeBlocks()
}

379
node_modules/viem/actions/public/watchContractEvent.ts generated vendored Normal file
View File

@@ -0,0 +1,379 @@
import type { Abi, Address, ExtractAbiEvent } from 'abitype'
import type { Client } from '../../clients/createClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import {
DecodeLogDataMismatch,
DecodeLogTopicsMismatch,
} from '../../errors/abi.js'
import { InvalidInputRpcError } from '../../errors/rpc.js'
import type { ErrorType } from '../../errors/utils.js'
import type { BlockNumber } from '../../types/block.js'
import type { Chain } from '../../types/chain.js'
import type {
ContractEventArgs,
ContractEventName,
} from '../../types/contract.js'
import type { Filter } from '../../types/filter.js'
import type { Log } from '../../types/log.js'
import type { LogTopic } from '../../types/misc.js'
import type { GetPollOptions } from '../../types/transport.js'
import { decodeEventLog } from '../../utils/abi/decodeEventLog.js'
import {
type EncodeEventTopicsParameters,
encodeEventTopics,
} from '../../utils/abi/encodeEventTopics.js'
import { formatLog } from '../../utils/formatters/log.js'
import { getAction } from '../../utils/getAction.js'
import { type ObserveErrorType, observe } from '../../utils/observe.js'
import { poll } from '../../utils/poll.js'
import { type StringifyErrorType, stringify } from '../../utils/stringify.js'
import { createContractEventFilter } from './createContractEventFilter.js'
import { getBlockNumber } from './getBlockNumber.js'
import {
type GetContractEventsParameters,
getContractEvents,
} from './getContractEvents.js'
import { getFilterChanges } from './getFilterChanges.js'
import { uninstallFilter } from './uninstallFilter.js'
export type WatchContractEventOnLogsParameter<
abi extends Abi | readonly unknown[] = Abi,
eventName extends ContractEventName<abi> = ContractEventName<abi>,
strict extends boolean | undefined = undefined,
> = abi extends Abi
? Abi extends abi
? Log[]
: Log<bigint, number, false, ExtractAbiEvent<abi, eventName>, strict>[]
: Log[]
export type WatchContractEventOnLogsFn<
abi extends Abi | readonly unknown[] = Abi,
eventName extends ContractEventName<abi> = ContractEventName<abi>,
strict extends boolean | undefined = undefined,
> = (logs: WatchContractEventOnLogsParameter<abi, eventName, strict>) => void
export type WatchContractEventParameters<
abi extends Abi | readonly unknown[] = Abi,
eventName extends ContractEventName<abi> | undefined = ContractEventName<abi>,
strict extends boolean | undefined = undefined,
transport extends Transport = Transport,
> = {
/** The address of the contract. */
address?: Address | Address[] | undefined
/** Contract ABI. */
abi: abi
args?:
| ContractEventArgs<
abi,
eventName extends ContractEventName<abi>
? eventName
: ContractEventName<abi>
>
| undefined
/** Contract event. */
eventName?: eventName | ContractEventName<abi> | undefined
/** Block to start listening from. */
fromBlock?: BlockNumber<bigint> | undefined
/** The callback to call when an error occurred when trying to get for a new block. */
onError?: ((error: Error) => void) | undefined
/** The callback to call when new event logs are received. */
onLogs: WatchContractEventOnLogsFn<
abi,
eventName extends ContractEventName<abi>
? eventName
: ContractEventName<abi>,
strict
>
/**
* Whether or not the logs must match the indexed/non-indexed arguments on `event`.
* @default false
*/
strict?: strict | boolean | undefined
} & GetPollOptions<transport>
export type WatchContractEventReturnType = () => void
export type WatchContractEventErrorType =
| StringifyErrorType
| ObserveErrorType
| ErrorType
/**
* Watches and returns emitted contract event logs.
*
* - Docs: https://viem.sh/docs/contract/watchContractEvent
*
* This Action will batch up all the event logs found within the [`pollingInterval`](https://viem.sh/docs/contract/watchContractEvent#pollinginterval-optional), and invoke them via [`onLogs`](https://viem.sh/docs/contract/watchContractEvent#onLogs).
*
* `watchContractEvent` will attempt to create an [Event Filter](https://viem.sh/docs/contract/createContractEventFilter) and listen to changes to the Filter per polling interval, however, if the RPC Provider does not support Filters (e.g. `eth_newFilter`), then `watchContractEvent` will fall back to using [`getLogs`](https://viem.sh/docs/actions/public/getLogs) instead.
*
* @param client - Client to use
* @param parameters - {@link WatchContractEventParameters}
* @returns A function that can be invoked to stop watching for new event logs. {@link WatchContractEventReturnType}
*
* @example
* import { createPublicClient, http, parseAbi } from 'viem'
* import { mainnet } from 'viem/chains'
* import { watchContractEvent } from 'viem/contract'
*
* const client = createPublicClient({
* chain: mainnet,
* transport: http(),
* })
* const unwatch = watchContractEvent(client, {
* address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
* abi: parseAbi(['event Transfer(address indexed from, address indexed to, uint256 value)']),
* eventName: 'Transfer',
* args: { from: '0xc961145a54C96E3aE9bAA048c4F4D6b04C13916b' },
* onLogs: (logs) => console.log(logs),
* })
*/
export function watchContractEvent<
chain extends Chain | undefined,
const abi extends Abi | readonly unknown[],
eventName extends ContractEventName<abi> | undefined = undefined,
strict extends boolean | undefined = undefined,
transport extends Transport = Transport,
>(
client: Client<transport, chain>,
parameters: WatchContractEventParameters<abi, eventName, strict, transport>,
): WatchContractEventReturnType {
const {
abi,
address,
args,
batch = true,
eventName,
fromBlock,
onError,
onLogs,
poll: poll_,
pollingInterval = client.pollingInterval,
strict: strict_,
} = parameters
const enablePolling = (() => {
if (typeof poll_ !== 'undefined') return poll_
if (typeof fromBlock === 'bigint') return true
if (
client.transport.type === 'webSocket' ||
client.transport.type === 'ipc'
)
return false
if (
client.transport.type === 'fallback' &&
(client.transport.transports[0].config.type === 'webSocket' ||
client.transport.transports[0].config.type === 'ipc')
)
return false
return true
})()
const pollContractEvent = () => {
const strict = strict_ ?? false
const observerId = stringify([
'watchContractEvent',
address,
args,
batch,
client.uid,
eventName,
pollingInterval,
strict,
fromBlock,
])
return observe(observerId, { onLogs, onError }, (emit) => {
let previousBlockNumber: bigint
if (fromBlock !== undefined) previousBlockNumber = fromBlock - 1n
let filter: Filter<'event', abi, eventName> | undefined
let initialized = false
const unwatch = poll(
async () => {
if (!initialized) {
try {
filter = (await getAction(
client,
createContractEventFilter,
'createContractEventFilter',
)({
abi,
address,
args: args as any,
eventName: eventName as any,
strict: strict as any,
fromBlock,
})) as Filter<'event', abi, eventName>
} catch {}
initialized = true
return
}
try {
let logs: Log[]
if (filter) {
logs = await getAction(
client,
getFilterChanges,
'getFilterChanges',
)({ filter })
} else {
// If the filter doesn't exist, we will fall back to use `getLogs`.
// The fall back exists because some RPC Providers do not support filters.
// Fetch the block number to use for `getLogs`.
const blockNumber = await getAction(
client,
getBlockNumber,
'getBlockNumber',
)({})
// If the block number has changed, we will need to fetch the logs.
// If the block number doesn't exist, we are yet to reach the first poll interval,
// so do not emit any logs.
if (previousBlockNumber && previousBlockNumber < blockNumber) {
logs = await getAction(
client,
getContractEvents,
'getContractEvents',
)({
abi,
address,
args,
eventName,
fromBlock: previousBlockNumber + 1n,
toBlock: blockNumber,
strict,
} as {} as GetContractEventsParameters)
} else {
logs = []
}
previousBlockNumber = blockNumber
}
if (logs.length === 0) return
if (batch) emit.onLogs(logs as any)
else for (const log of logs) emit.onLogs([log] as any)
} catch (err) {
// If a filter has been set and gets uninstalled, providers will throw an InvalidInput error.
// Reinitialize the filter when this occurs
if (filter && err instanceof InvalidInputRpcError)
initialized = false
emit.onError?.(err as Error)
}
},
{
emitOnBegin: true,
interval: pollingInterval,
},
)
return async () => {
if (filter)
await getAction(
client,
uninstallFilter,
'uninstallFilter',
)({ filter })
unwatch()
}
})
}
const subscribeContractEvent = () => {
const strict = strict_ ?? false
const observerId = stringify([
'watchContractEvent',
address,
args,
batch,
client.uid,
eventName,
pollingInterval,
strict,
])
let active = true
let unsubscribe = () => (active = false)
return observe(observerId, { onLogs, onError }, (emit) => {
;(async () => {
try {
const transport = (() => {
if (client.transport.type === 'fallback') {
const transport = client.transport.transports.find(
(transport: ReturnType<Transport>) =>
transport.config.type === 'webSocket' ||
transport.config.type === 'ipc',
)
if (!transport) return client.transport
return transport.value
}
return client.transport
})()
const topics: LogTopic[] = eventName
? encodeEventTopics({
abi: abi,
eventName: eventName,
args,
} as EncodeEventTopicsParameters)
: []
const { unsubscribe: unsubscribe_ } = await transport.subscribe({
params: ['logs', { address, topics }],
onData(data: any) {
if (!active) return
const log = data.result
try {
const { eventName, args } = decodeEventLog({
abi: abi,
data: log.data,
topics: log.topics as any,
strict: strict_,
})
const formatted = formatLog(log, {
args,
eventName: eventName as string,
})
emit.onLogs([formatted] as any)
} catch (err) {
let eventName: string | undefined
let isUnnamed: boolean | undefined
if (
err instanceof DecodeLogDataMismatch ||
err instanceof DecodeLogTopicsMismatch
) {
// If strict mode is on, and log data/topics do not match event definition, skip.
if (strict_) return
eventName = err.abiItem.name
isUnnamed = err.abiItem.inputs?.some(
(x) => !('name' in x && x.name),
)
}
// Set args to empty if there is an error decoding (e.g. indexed/non-indexed params mismatch).
const formatted = formatLog(log, {
args: isUnnamed ? [] : {},
eventName,
})
emit.onLogs([formatted] as any)
}
},
onError(error: Error) {
emit.onError?.(error)
},
})
unsubscribe = unsubscribe_
if (!active) unsubscribe()
} catch (err) {
onError?.(err as Error)
}
})()
return () => unsubscribe()
})
}
return enablePolling ? pollContractEvent() : subscribeContractEvent()
}

391
node_modules/viem/actions/public/watchEvent.ts generated vendored Normal file
View File

@@ -0,0 +1,391 @@
import type { AbiEvent, Address } from 'abitype'
import type { Client } from '../../clients/createClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import {
DecodeLogDataMismatch,
DecodeLogTopicsMismatch,
} from '../../errors/abi.js'
import { InvalidInputRpcError } from '../../errors/rpc.js'
import type { ErrorType } from '../../errors/utils.js'
import type { BlockNumber } from '../../types/block.js'
import type { Chain } from '../../types/chain.js'
import type {
MaybeAbiEventName,
MaybeExtractEventArgsFromAbi,
} from '../../types/contract.js'
import type { Filter } from '../../types/filter.js'
import type { Log } from '../../types/log.js'
import type { LogTopic } from '../../types/misc.js'
import type { GetPollOptions } from '../../types/transport.js'
import { decodeEventLog } from '../../utils/abi/decodeEventLog.js'
import {
type EncodeEventTopicsParameters,
encodeEventTopics,
} from '../../utils/abi/encodeEventTopics.js'
import { formatLog } from '../../utils/formatters/log.js'
import { getAction } from '../../utils/getAction.js'
import { type ObserveErrorType, observe } from '../../utils/observe.js'
import { poll } from '../../utils/poll.js'
import { type StringifyErrorType, stringify } from '../../utils/stringify.js'
import {
type CreateEventFilterParameters,
createEventFilter,
} from './createEventFilter.js'
import { getBlockNumber } from './getBlockNumber.js'
import { getFilterChanges } from './getFilterChanges.js'
import { type GetLogsParameters, getLogs } from './getLogs.js'
import { uninstallFilter } from './uninstallFilter.js'
export type WatchEventOnLogsParameter<
abiEvent extends AbiEvent | undefined = undefined,
abiEvents extends
| readonly AbiEvent[]
| readonly unknown[]
| undefined = abiEvent extends AbiEvent ? [abiEvent] : undefined,
strict extends boolean | undefined = undefined,
eventName extends string | undefined = MaybeAbiEventName<abiEvent>,
> = Log<bigint, number, false, abiEvent, strict, abiEvents, eventName>[]
export type WatchEventOnLogsFn<
abiEvent extends AbiEvent | undefined = undefined,
abiEvents extends
| readonly AbiEvent[]
| readonly unknown[]
| undefined = abiEvent extends AbiEvent ? [abiEvent] : undefined,
strict extends boolean | undefined = undefined,
//
_eventName extends string | undefined = MaybeAbiEventName<abiEvent>,
> = (
logs: WatchEventOnLogsParameter<abiEvent, abiEvents, strict, _eventName>,
) => void
export type WatchEventParameters<
abiEvent extends AbiEvent | undefined = undefined,
abiEvents extends
| readonly AbiEvent[]
| readonly unknown[]
| undefined = abiEvent extends AbiEvent ? [abiEvent] : undefined,
strict extends boolean | undefined = undefined,
transport extends Transport = Transport,
//
_eventName extends string | undefined = MaybeAbiEventName<abiEvent>,
> = {
/** The address of the contract. */
address?: Address | Address[] | undefined
/** Block to start listening from. */
fromBlock?: BlockNumber<bigint> | undefined
/** The callback to call when an error occurred when trying to get for a new block. */
onError?: ((error: Error) => void) | undefined
/** The callback to call when new event logs are received. */
onLogs: WatchEventOnLogsFn<abiEvent, abiEvents, strict, _eventName>
} & GetPollOptions<transport> &
(
| {
event: abiEvent
events?: undefined
args?: MaybeExtractEventArgsFromAbi<abiEvents, _eventName> | undefined
/**
* Whether or not the logs must match the indexed/non-indexed arguments on `event`.
* @default false
*/
strict?: strict | undefined
}
| {
event?: undefined
events?: abiEvents | undefined
args?: undefined
/**
* Whether or not the logs must match the indexed/non-indexed arguments on `event`.
* @default false
*/
strict?: strict | undefined
}
| {
event?: undefined
events?: undefined
args?: undefined
strict?: undefined
}
)
export type WatchEventReturnType = () => void
export type WatchEventErrorType =
| StringifyErrorType
| ObserveErrorType
| ErrorType
/**
* Watches and returns emitted [Event Logs](https://viem.sh/docs/glossary/terms#event-log).
*
* - Docs: https://viem.sh/docs/actions/public/watchEvent
* - JSON-RPC Methods:
* - **RPC Provider supports `eth_newFilter`:**
* - Calls [`eth_newFilter`](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_newfilter) to create a filter (called on initialize).
* - On a polling interval, it will call [`eth_getFilterChanges`](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getfilterchanges).
* - **RPC Provider does not support `eth_newFilter`:**
* - Calls [`eth_getLogs`](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getlogs) for each block between the polling interval.
*
* This Action will batch up all the Event Logs found within the [`pollingInterval`](https://viem.sh/docs/actions/public/watchEvent#pollinginterval-optional), and invoke them via [`onLogs`](https://viem.sh/docs/actions/public/watchEvent#onLogs).
*
* `watchEvent` will attempt to create an [Event Filter](https://viem.sh/docs/actions/public/createEventFilter) and listen to changes to the Filter per polling interval, however, if the RPC Provider does not support Filters (e.g. `eth_newFilter`), then `watchEvent` will fall back to using [`getLogs`](https://viem.sh/docs/actions/public/getLogs) instead.
*
* @param client - Client to use
* @param parameters - {@link WatchEventParameters}
* @returns A function that can be invoked to stop watching for new Event Logs. {@link WatchEventReturnType}
*
* @example
* import { createPublicClient, http } from 'viem'
* import { mainnet } from 'viem/chains'
* import { watchEvent } from 'viem/public'
*
* const client = createPublicClient({
* chain: mainnet,
* transport: http(),
* })
* const unwatch = watchEvent(client, {
* onLogs: (logs) => console.log(logs),
* })
*/
export function watchEvent<
chain extends Chain | undefined,
const abiEvent extends AbiEvent | undefined = undefined,
const abiEvents extends
| readonly AbiEvent[]
| readonly unknown[]
| undefined = abiEvent extends AbiEvent ? [abiEvent] : undefined,
strict extends boolean | undefined = undefined,
transport extends Transport = Transport,
_eventName extends string | undefined = undefined,
>(
client: Client<transport, chain>,
{
address,
args,
batch = true,
event,
events,
fromBlock,
onError,
onLogs,
poll: poll_,
pollingInterval = client.pollingInterval,
strict: strict_,
}: WatchEventParameters<abiEvent, abiEvents, strict, transport>,
): WatchEventReturnType {
const enablePolling = (() => {
if (typeof poll_ !== 'undefined') return poll_
if (typeof fromBlock === 'bigint') return true
if (
client.transport.type === 'webSocket' ||
client.transport.type === 'ipc'
)
return false
if (
client.transport.type === 'fallback' &&
(client.transport.transports[0].config.type === 'webSocket' ||
client.transport.transports[0].config.type === 'ipc')
)
return false
return true
})()
const strict = strict_ ?? false
const pollEvent = () => {
const observerId = stringify([
'watchEvent',
address,
args,
batch,
client.uid,
event,
pollingInterval,
fromBlock,
])
return observe(observerId, { onLogs, onError }, (emit) => {
let previousBlockNumber: bigint
if (fromBlock !== undefined) previousBlockNumber = fromBlock - 1n
let filter: Filter<'event', abiEvents, _eventName, any>
let initialized = false
const unwatch = poll(
async () => {
if (!initialized) {
try {
filter = (await getAction(
client,
createEventFilter as any,
'createEventFilter',
)({
address,
args,
event: event!,
events,
strict,
fromBlock,
} as unknown as CreateEventFilterParameters)) as unknown as Filter<
'event',
abiEvents,
_eventName
>
} catch {}
initialized = true
return
}
try {
let logs: Log[]
if (filter) {
logs = await getAction(
client,
getFilterChanges,
'getFilterChanges',
)({ filter })
} else {
// If the filter doesn't exist, we will fall back to use `getLogs`.
// The fall back exists because some RPC Providers do not support filters.
// Fetch the block number to use for `getLogs`.
const blockNumber = await getAction(
client,
getBlockNumber,
'getBlockNumber',
)({})
// If the block number has changed, we will need to fetch the logs.
// If the block number doesn't exist, we are yet to reach the first poll interval,
// so do not emit any logs.
if (previousBlockNumber && previousBlockNumber !== blockNumber) {
logs = await getAction(
client,
getLogs,
'getLogs',
)({
address,
args,
event: event!,
events,
fromBlock: previousBlockNumber + 1n,
toBlock: blockNumber,
} as unknown as GetLogsParameters)
} else {
logs = []
}
previousBlockNumber = blockNumber
}
if (logs.length === 0) return
if (batch) emit.onLogs(logs as any)
else for (const log of logs) emit.onLogs([log] as any)
} catch (err) {
// If a filter has been set and gets uninstalled, providers will throw an InvalidInput error.
// Reinitialize the filter when this occurs
if (filter && err instanceof InvalidInputRpcError)
initialized = false
emit.onError?.(err as Error)
}
},
{
emitOnBegin: true,
interval: pollingInterval,
},
)
return async () => {
if (filter)
await getAction(
client,
uninstallFilter,
'uninstallFilter',
)({ filter })
unwatch()
}
})
}
const subscribeEvent = () => {
let active = true
let unsubscribe = () => (active = false)
;(async () => {
try {
const transport = (() => {
if (client.transport.type === 'fallback') {
const transport = client.transport.transports.find(
(transport: ReturnType<Transport>) =>
transport.config.type === 'webSocket' ||
transport.config.type === 'ipc',
)
if (!transport) return client.transport
return transport.value
}
return client.transport
})()
const events_ = events ?? (event ? [event] : undefined)
let topics: LogTopic[] = []
if (events_) {
const encoded = (events_ as AbiEvent[]).flatMap((event) =>
encodeEventTopics({
abi: [event],
eventName: (event as AbiEvent).name,
args,
} as EncodeEventTopicsParameters),
)
// TODO: Clean up type casting
topics = [encoded as LogTopic]
if (event) topics = topics[0] as LogTopic[]
}
const { unsubscribe: unsubscribe_ } = await transport.subscribe({
params: ['logs', { address, topics }],
onData(data: any) {
if (!active) return
const log = data.result
try {
const { eventName, args } = decodeEventLog({
abi: events_ ?? [],
data: log.data,
topics: log.topics,
strict,
})
const formatted = formatLog(log, { args, eventName })
onLogs([formatted] as any)
} catch (err) {
let eventName: string | undefined
let isUnnamed: boolean | undefined
if (
err instanceof DecodeLogDataMismatch ||
err instanceof DecodeLogTopicsMismatch
) {
// If strict mode is on, and log data/topics do not match event definition, skip.
if (strict_) return
eventName = err.abiItem.name
isUnnamed = err.abiItem.inputs?.some(
(x) => !('name' in x && x.name),
)
}
// Set args to empty if there is an error decoding (e.g. indexed/non-indexed params mismatch).
const formatted = formatLog(log, {
args: isUnnamed ? [] : {},
eventName,
})
onLogs([formatted] as any)
}
},
onError(error: Error) {
onError?.(error)
},
})
unsubscribe = unsubscribe_
if (!active) unsubscribe()
} catch (err) {
onError?.(err as Error)
}
})()
return () => unsubscribe()
}
return enablePolling ? pollEvent() : subscribeEvent()
}

View File

@@ -0,0 +1,168 @@
import type { Client } from '../../clients/createClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { ErrorType } from '../../errors/utils.js'
import type { Chain } from '../../types/chain.js'
import type { Filter } from '../../types/filter.js'
import type { Hash } from '../../types/misc.js'
import type { GetPollOptions } from '../../types/transport.js'
import { getAction } from '../../utils/getAction.js'
import { type ObserveErrorType, observe } from '../../utils/observe.js'
import { poll } from '../../utils/poll.js'
import { type StringifyErrorType, stringify } from '../../utils/stringify.js'
import { createPendingTransactionFilter } from './createPendingTransactionFilter.js'
import { getFilterChanges } from './getFilterChanges.js'
import { uninstallFilter } from './uninstallFilter.js'
export type OnTransactionsParameter = Hash[]
export type OnTransactionsFn = (transactions: OnTransactionsParameter) => void
export type WatchPendingTransactionsParameters<
transport extends Transport = Transport,
> = {
/** The callback to call when an error occurred when trying to get for a new block. */
onError?: ((error: Error) => void) | undefined
/** The callback to call when new transactions are received. */
onTransactions: OnTransactionsFn
} & GetPollOptions<transport>
export type WatchPendingTransactionsReturnType = () => void
export type WatchPendingTransactionsErrorType =
| StringifyErrorType
| ObserveErrorType
| ErrorType
/**
* Watches and returns pending transaction hashes.
*
* - Docs: https://viem.sh/docs/actions/public/watchPendingTransactions
* - JSON-RPC Methods:
* - When `poll: true`
* - Calls [`eth_newPendingTransactionFilter`](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_newpendingtransactionfilter) to initialize the filter.
* - Calls [`eth_getFilterChanges`](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getFilterChanges) on a polling interval.
* - When `poll: false` & WebSocket Transport, uses a WebSocket subscription via [`eth_subscribe`](https://docs.alchemy.com/reference/eth-subscribe-polygon) and the `"newPendingTransactions"` event.
*
* This Action will batch up all the pending transactions found within the [`pollingInterval`](https://viem.sh/docs/actions/public/watchPendingTransactions#pollinginterval-optional), and invoke them via [`onTransactions`](https://viem.sh/docs/actions/public/watchPendingTransactions#ontransactions).
*
* @param client - Client to use
* @param parameters - {@link WatchPendingTransactionsParameters}
* @returns A function that can be invoked to stop watching for new pending transaction hashes. {@link WatchPendingTransactionsReturnType}
*
* @example
* import { createPublicClient, http } from 'viem'
* import { mainnet } from 'viem/chains'
* import { watchPendingTransactions } from 'viem/public'
*
* const client = createPublicClient({
* chain: mainnet,
* transport: http(),
* })
* const unwatch = await watchPendingTransactions(client, {
* onTransactions: (hashes) => console.log(hashes),
* })
*/
export function watchPendingTransactions<
transport extends Transport,
chain extends Chain | undefined,
>(
client: Client<transport, chain>,
{
batch = true,
onError,
onTransactions,
poll: poll_,
pollingInterval = client.pollingInterval,
}: WatchPendingTransactionsParameters<transport>,
) {
const enablePolling =
typeof poll_ !== 'undefined'
? poll_
: client.transport.type !== 'webSocket' && client.transport.type !== 'ipc'
const pollPendingTransactions = () => {
const observerId = stringify([
'watchPendingTransactions',
client.uid,
batch,
pollingInterval,
])
return observe(observerId, { onTransactions, onError }, (emit) => {
let filter: Filter<'transaction'>
const unwatch = poll(
async () => {
try {
if (!filter) {
try {
filter = await getAction(
client,
createPendingTransactionFilter,
'createPendingTransactionFilter',
)({})
return
} catch (err) {
unwatch()
throw err
}
}
const hashes = await getAction(
client,
getFilterChanges,
'getFilterChanges',
)({ filter })
if (hashes.length === 0) return
if (batch) emit.onTransactions(hashes)
else for (const hash of hashes) emit.onTransactions([hash])
} catch (err) {
emit.onError?.(err as Error)
}
},
{
emitOnBegin: true,
interval: pollingInterval,
},
)
return async () => {
if (filter)
await getAction(
client,
uninstallFilter,
'uninstallFilter',
)({ filter })
unwatch()
}
})
}
const subscribePendingTransactions = () => {
let active = true
let unsubscribe = () => (active = false)
;(async () => {
try {
const { unsubscribe: unsubscribe_ } = await client.transport.subscribe({
params: ['newPendingTransactions'],
onData(data: any) {
if (!active) return
const transaction = data.result
onTransactions([transaction])
},
onError(error: Error) {
onError?.(error)
},
})
unsubscribe = unsubscribe_
if (!active) unsubscribe()
} catch (err) {
onError?.(err as Error)
}
})()
return () => unsubscribe()
}
return enablePolling
? pollPendingTransactions()
: subscribePendingTransactions()
}

90
node_modules/viem/actions/siwe/verifySiweMessage.ts generated vendored Normal file
View File

@@ -0,0 +1,90 @@
import type { Client } from '../../clients/createClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { ErrorType } from '../../errors/utils.js'
import type { Chain } from '../../types/chain.js'
import type { Hex } from '../../types/misc.js'
import type { Prettify } from '../../types/utils.js'
import type { HashMessageErrorType } from '../../utils/signature/hashMessage.js'
import { hashMessage } from '../../utils/signature/hashMessage.js'
import { parseSiweMessage } from '../../utils/siwe/parseSiweMessage.js'
import {
type ValidateSiweMessageParameters,
validateSiweMessage,
} from '../../utils/siwe/validateSiweMessage.js'
import {
type VerifyHashErrorType,
type VerifyHashParameters,
verifyHash,
} from '../public/verifyHash.js'
export type VerifySiweMessageParameters = Prettify<
Pick<VerifyHashParameters, 'blockNumber' | 'blockTag'> &
Pick<
ValidateSiweMessageParameters,
'address' | 'domain' | 'nonce' | 'scheme' | 'time'
> & {
/**
* EIP-4361 formatted message.
*/
message: string
/**
* Signature to check against.
*/
signature: Hex
}
>
export type VerifySiweMessageReturnType = boolean
export type VerifySiweMessageErrorType =
| HashMessageErrorType
| VerifyHashErrorType
| ErrorType
/**
* Verifies [EIP-4361](https://eips.ethereum.org/EIPS/eip-4361) formatted message was signed.
*
* Compatible with Smart Contract Accounts & Externally Owned Accounts via [ERC-6492](https://eips.ethereum.org/EIPS/eip-6492).
*
* - Docs {@link https://viem.sh/docs/siwe/actions/verifySiweMessage}
*
* @param client - Client to use.
* @param parameters - {@link VerifySiweMessageParameters}
* @returns Whether or not the signature is valid. {@link VerifySiweMessageReturnType}
*/
export async function verifySiweMessage<chain extends Chain | undefined>(
client: Client<Transport, chain>,
parameters: VerifySiweMessageParameters,
): Promise<VerifySiweMessageReturnType> {
const {
address,
domain,
message,
nonce,
scheme,
signature,
time = new Date(),
...callRequest
} = parameters
const parsed = parseSiweMessage(message)
if (!parsed.address) return false
const isValid = validateSiweMessage({
address,
domain,
message: parsed,
nonce,
scheme,
time,
})
if (!isValid) return false
const hash = hashMessage(message)
return verifyHash(client, {
address: parsed.address,
hash,
signature,
...callRequest,
})
}

52
node_modules/viem/actions/test/dropTransaction.ts generated vendored Normal file
View File

@@ -0,0 +1,52 @@
import type {
TestClient,
TestClientMode,
} from '../../clients/createTestClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { ErrorType } from '../../errors/utils.js'
import type { Account } from '../../types/account.js'
import type { Chain } from '../../types/chain.js'
import type { Hash } from '../../types/misc.js'
import type { RequestErrorType } from '../../utils/buildRequest.js'
export type DropTransactionParameters = {
/** The hash of the transaction to drop. */
hash: Hash
}
export type DropTransactionErrorType = RequestErrorType | ErrorType
/**
* Removes a transaction from the mempool.
*
* - Docs: https://viem.sh/docs/actions/test/dropTransaction
*
* @param client - Client to use
* @param parameters - {@link DropTransactionParameters}
*
* @example
* import { createTestClient, http } from 'viem'
* import { foundry } from 'viem/chains'
* import { dropTransaction } from 'viem/test'
*
* const client = createTestClient({
* mode: 'anvil',
* chain: 'foundry',
* transport: http(),
* })
* await dropTransaction(client, {
* hash: '0xe58dceb6b20b03965bb678e27d141e151d7d4efc2334c2d6a49b9fac523f7364'
* })
*/
export async function dropTransaction<
chain extends Chain | undefined,
account extends Account | undefined,
>(
client: TestClient<TestClientMode, Transport, chain, account, false>,
{ hash }: DropTransactionParameters,
) {
await client.request({
method: `${client.mode}_dropTransaction`,
params: [hash],
})
}

44
node_modules/viem/actions/test/dumpState.ts generated vendored Normal file
View File

@@ -0,0 +1,44 @@
import type {
TestClient,
TestClientMode,
} from '../../clients/createTestClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { ErrorType } from '../../errors/utils.js'
import type { Account } from '../../types/account.js'
import type { Chain } from '../../types/chain.js'
import type { Hex } from '../../types/misc.js'
import type { RequestErrorType } from '../../utils/buildRequest.js'
export type DumpStateReturnType = Hex
export type DumpStateErrorType = RequestErrorType | ErrorType
/**
* Serializes the current state (including contracts code, contract's storage,
* accounts properties, etc.) into a savable data blob.
*
* - Docs: https://viem.sh/docs/actions/test/dumpState
*
* @param client - Client to use
*
* @example
* import { createTestClient, http } from 'viem'
* import { foundry } from 'viem/chains'
* import { dumpState } from 'viem/test'
*
* const client = createTestClient({
* mode: 'anvil',
* chain: 'foundry',
* transport: http(),
* })
* await dumpState(client)
*/
export async function dumpState<
chain extends Chain | undefined,
account extends Account | undefined,
>(
client: TestClient<TestClientMode, Transport, chain, account, false>,
): Promise<DumpStateReturnType> {
return client.request({
method: `${client.mode}_dumpState`,
})
}

48
node_modules/viem/actions/test/getAutomine.ts generated vendored Normal file
View File

@@ -0,0 +1,48 @@
import type {
TestClient,
TestClientMode,
} from '../../clients/createTestClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { ErrorType } from '../../errors/utils.js'
import type { Account } from '../../types/account.js'
import type { Chain } from '../../types/chain.js'
import type { RequestErrorType } from '../../utils/buildRequest.js'
export type GetAutomineReturnType = boolean
export type GetAutomineErrorType = RequestErrorType | ErrorType
/**
* Returns the automatic mining status of the node.
*
* - Docs: https://viem.sh/docs/actions/test/getAutomine
*
* @param client - Client to use
* @returns Whether or not the node is auto mining. {@link GetAutomineReturnType}
*
* @example
* import { createTestClient, http } from 'viem'
* import { foundry } from 'viem/chains'
* import { getAutomine } from 'viem/test'
*
* const client = createTestClient({
* mode: 'anvil',
* chain: 'foundry',
* transport: http(),
* })
* const isAutomining = await getAutomine(client)
*/
export async function getAutomine<
chain extends Chain | undefined,
account extends Account | undefined,
>(
client: TestClient<TestClientMode, Transport, chain, account, false>,
): Promise<GetAutomineReturnType> {
if (client.mode === 'ganache')
return await client.request({
method: 'eth_mining',
})
return await client.request({
method: `${client.mode}_getAutomine`,
})
}

52
node_modules/viem/actions/test/getTxpoolContent.ts generated vendored Normal file
View File

@@ -0,0 +1,52 @@
import type { Address } from 'abitype'
import type {
TestClient,
TestClientMode,
} from '../../clients/createTestClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { ErrorType } from '../../errors/utils.js'
import type { Account } from '../../types/account.js'
import type { Chain } from '../../types/chain.js'
import type { RpcTransaction } from '../../types/rpc.js'
import type { RequestErrorType } from '../../utils/buildRequest.js'
export type GetTxpoolContentReturnType = {
/** Pending transactions in the pool */
pending: Record<Address, Record<string, RpcTransaction>>
/** Queued transactions in the pool */
queued: Record<Address, Record<string, RpcTransaction>>
}
export type GetTxpoolContentErrorType = RequestErrorType | ErrorType
/**
* Returns the details of all transactions currently pending for inclusion in the next block(s), as well as the ones that are being scheduled for future execution only.
*
* - Docs: https://viem.sh/docs/actions/test/getTxpoolContent
*
* @param client - Client to use
* @returns Transaction pool content. {@link GetTxpoolContentReturnType}
*
* @example
* import { createTestClient, http } from 'viem'
* import { foundry } from 'viem/chains'
* import { getTxpoolContent } from 'viem/test'
*
* const client = createTestClient({
* mode: 'anvil',
* chain: 'foundry',
* transport: http(),
* })
* const content = await getTxpoolContent(client)
*/
export async function getTxpoolContent<
chain extends Chain | undefined,
account extends Account | undefined,
>(
client: TestClient<TestClientMode, Transport, chain, account, false>,
): Promise<GetTxpoolContentReturnType> {
return await client.request({
method: 'txpool_content',
})
}

52
node_modules/viem/actions/test/getTxpoolStatus.ts generated vendored Normal file
View File

@@ -0,0 +1,52 @@
import type {
TestClient,
TestClientMode,
} from '../../clients/createTestClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { ErrorType } from '../../errors/utils.js'
import type { Account } from '../../types/account.js'
import type { Chain } from '../../types/chain.js'
import type { RequestErrorType } from '../../utils/buildRequest.js'
import { hexToNumber } from '../../utils/encoding/fromHex.js'
export type GetTxpoolStatusReturnType = {
pending: number
queued: number
}
export type GetTxpoolStatusErrorType = RequestErrorType | ErrorType
/**
* Returns a summary of all the transactions currently pending for inclusion in the next block(s), as well as the ones that are being scheduled for future execution only.
*
* - Docs: https://viem.sh/docs/actions/test/getTxpoolStatus
*
* @param client - Client to use
* @returns Transaction pool status. {@link GetTxpoolStatusReturnType}
*
* @example
* import { createTestClient, http } from 'viem'
* import { foundry } from 'viem/chains'
* import { getTxpoolStatus } from 'viem/test'
*
* const client = createTestClient({
* mode: 'anvil',
* chain: 'foundry',
* transport: http(),
* })
* const status = await getTxpoolStatus(client)
*/
export async function getTxpoolStatus<
chain extends Chain | undefined,
account extends Account | undefined,
>(
client: TestClient<TestClientMode, Transport, chain, account, false>,
): Promise<GetTxpoolStatusReturnType> {
const { pending, queued } = await client.request({
method: 'txpool_status',
})
return {
pending: hexToNumber(pending),
queued: hexToNumber(queued),
}
}

53
node_modules/viem/actions/test/impersonateAccount.ts generated vendored Normal file
View File

@@ -0,0 +1,53 @@
import type { Address } from 'abitype'
import type {
TestClient,
TestClientMode,
} from '../../clients/createTestClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { ErrorType } from '../../errors/utils.js'
import type { Account } from '../../types/account.js'
import type { Chain } from '../../types/chain.js'
import type { RequestErrorType } from '../../utils/buildRequest.js'
export type ImpersonateAccountParameters = {
/** The account to impersonate. */
address: Address
}
export type ImpersonateAccountErrorType = RequestErrorType | ErrorType
/**
* Impersonate an account or contract address. This lets you send transactions from that account even if you don't have access to its private key.
*
* - Docs: https://viem.sh/docs/actions/test/impersonateAccount
*
* @param client - Client to use
* @param parameters - {@link ImpersonateAccountParameters}
*
* @example
* import { createTestClient, http } from 'viem'
* import { foundry } from 'viem/chains'
* import { impersonateAccount } from 'viem/test'
*
* const client = createTestClient({
* mode: 'anvil',
* chain: 'foundry',
* transport: http(),
* })
* const content = await impersonateAccount(client, {
* address: '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e',
* })
*/
export async function impersonateAccount<
chain extends Chain | undefined,
account extends Account | undefined,
>(
client: TestClient<TestClientMode, Transport, chain, account, false>,
{ address }: ImpersonateAccountParameters,
) {
await client.request({
method: `${client.mode}_impersonateAccount`,
params: [address],
})
}

52
node_modules/viem/actions/test/increaseTime.ts generated vendored Normal file
View File

@@ -0,0 +1,52 @@
import type {
TestClient,
TestClientMode,
} from '../../clients/createTestClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { ErrorType } from '../../errors/utils.js'
import type { Account } from '../../types/account.js'
import type { Chain } from '../../types/chain.js'
import type { RequestErrorType } from '../../utils/buildRequest.js'
import { numberToHex } from '../../utils/encoding/toHex.js'
export type IncreaseTimeParameters = {
/** The amount of seconds to jump forward in time. */
seconds: number
}
export type IncreaseTimeErrorType = RequestErrorType | ErrorType
/**
* Jump forward in time by the given amount of time, in seconds.
*
* - Docs: https://viem.sh/docs/actions/test/increaseTime
*
* @param client - Client to use
* @param parameters {@link IncreaseTimeParameters}
*
* @example
* import { createTestClient, http } from 'viem'
* import { foundry } from 'viem/chains'
* import { increaseTime } from 'viem/test'
*
* const client = createTestClient({
* mode: 'anvil',
* chain: 'foundry',
* transport: http(),
* })
* await increaseTime(client, {
* seconds: 420,
* })
*/
export async function increaseTime<
chain extends Chain | undefined,
account extends Account | undefined,
>(
client: TestClient<TestClientMode, Transport, chain, account, false>,
{ seconds }: IncreaseTimeParameters,
) {
return await client.request({
method: 'evm_increaseTime',
params: [numberToHex(seconds)],
})
}

49
node_modules/viem/actions/test/inspectTxpool.ts generated vendored Normal file
View File

@@ -0,0 +1,49 @@
import type { Address } from 'abitype'
import type {
TestClient,
TestClientMode,
} from '../../clients/createTestClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { ErrorType } from '../../errors/utils.js'
import type { Account } from '../../types/account.js'
import type { Chain } from '../../types/chain.js'
import type { RequestErrorType } from '../../utils/buildRequest.js'
export type InspectTxpoolReturnType = {
pending: Record<Address, Record<string, string>>
queued: Record<Address, Record<string, string>>
}
export type InspectTxpoolErrorType = RequestErrorType | ErrorType
/**
* Returns a summary of all the transactions currently pending for inclusion in the next block(s), as well as the ones that are being scheduled for future execution only.
*
* - Docs: https://viem.sh/docs/actions/test/inspectTxpool
*
* @param client - Client to use
* @returns Transaction pool inspection data. {@link InspectTxpoolReturnType}
*
* @example
* import { createTestClient, http } from 'viem'
* import { foundry } from 'viem/chains'
* import { inspectTxpool } from 'viem/test'
*
* const client = createTestClient({
* mode: 'anvil',
* chain: 'foundry',
* transport: http(),
* })
* const data = await inspectTxpool(client)
*/
export async function inspectTxpool<
chain extends Chain | undefined,
account extends Account | undefined,
>(
client: TestClient<TestClientMode, Transport, chain, account, false>,
): Promise<InspectTxpoolReturnType> {
return await client.request({
method: 'txpool_inspect',
})
}

47
node_modules/viem/actions/test/loadState.ts generated vendored Normal file
View File

@@ -0,0 +1,47 @@
import type {
TestClient,
TestClientMode,
} from '../../clients/createTestClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { ErrorType } from '../../errors/utils.js'
import type { Account } from '../../types/account.js'
import type { Chain } from '../../types/chain.js'
import type { Hex } from '../../types/misc.js'
import type { RequestErrorType } from '../../utils/buildRequest.js'
export type LoadStateParameters = { state: Hex }
export type LoadStateReturnType = void
export type LoadStateErrorType = RequestErrorType | ErrorType
/**
* Adds state previously dumped with `dumpState` to the current chain.
*
* - Docs: https://viem.sh/docs/actions/test/loadState
*
* @param client - Client to use
* @param parameters - {@link LoadStateParameters}
*
* @example
* import { createTestClient, http } from 'viem'
* import { foundry } from 'viem/chains'
* import { loadState } from 'viem/test'
*
* const client = createTestClient({
* mode: 'anvil',
* chain: 'foundry',
* transport: http(),
* })
* await loadState(client, { state: '0x...' })
*/
export async function loadState<
chain extends Chain | undefined,
account extends Account | undefined,
>(
client: TestClient<TestClientMode, Transport, chain, account, false>,
{ state }: LoadStateParameters,
): Promise<LoadStateReturnType> {
await client.request({
method: `${client.mode}_loadState`,
params: [state],
})
}

58
node_modules/viem/actions/test/mine.ts generated vendored Normal file
View File

@@ -0,0 +1,58 @@
import type {
TestClient,
TestClientMode,
} from '../../clients/createTestClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { ErrorType } from '../../errors/utils.js'
import type { Account } from '../../types/account.js'
import type { Chain } from '../../types/chain.js'
import type { RequestErrorType } from '../../utils/buildRequest.js'
import { numberToHex } from '../../utils/encoding/toHex.js'
export type MineParameters = {
/** Number of blocks to mine. */
blocks: number
/** Interval between each block in seconds. */
interval?: number | undefined
}
export type MineErrorType = RequestErrorType | ErrorType
/**
* Mine a specified number of blocks.
*
* - Docs: https://viem.sh/docs/actions/test/mine
*
* @param client - Client to use
* @param parameters {@link MineParameters}
*
* @example
* import { createTestClient, http } from 'viem'
* import { foundry } from 'viem/chains'
* import { mine } from 'viem/test'
*
* const client = createTestClient({
* mode: 'anvil',
* chain: 'foundry',
* transport: http(),
* })
* await mine(client, { blocks: 1 })
*/
export async function mine<
chain extends Chain | undefined,
account extends Account | undefined,
>(
client: TestClient<TestClientMode, Transport, chain, account, false>,
{ blocks, interval }: MineParameters,
) {
if (client.mode === 'ganache')
await client.request({
method: 'evm_mine',
params: [{ blocks: numberToHex(blocks) }],
})
else
await client.request({
method: `${client.mode}_mine`,
params: [numberToHex(blocks), numberToHex(interval || 0)],
})
}

View File

@@ -0,0 +1,39 @@
import type {
TestClient,
TestClientMode,
} from '../../clients/createTestClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { ErrorType } from '../../errors/utils.js'
import type { Account } from '../../types/account.js'
import type { Chain } from '../../types/chain.js'
import type { RequestErrorType } from '../../utils/buildRequest.js'
export type RemoveBlockTimestampIntervalErrorType = RequestErrorType | ErrorType
/**
* Removes [`setBlockTimestampInterval`](https://viem.sh/docs/actions/test/setBlockTimestampInterval) if it exists.
*
* - Docs: https://viem.sh/docs/actions/test/removeBlockTimestampInterval
*
* @param client - Client to use
*
* @example
* import { createTestClient, http } from 'viem'
* import { foundry } from 'viem/chains'
* import { removeBlockTimestampInterval } from 'viem/test'
*
* const client = createTestClient({
* mode: 'anvil',
* chain: 'foundry',
* transport: http(),
* })
* await removeBlockTimestampInterval(client)
*/
export async function removeBlockTimestampInterval<
chain extends Chain | undefined,
account extends Account | undefined,
>(client: TestClient<TestClientMode, Transport, chain, account, false>) {
await client.request({
method: `${client.mode}_removeBlockTimestampInterval`,
})
}

51
node_modules/viem/actions/test/reset.ts generated vendored Normal file
View File

@@ -0,0 +1,51 @@
import type {
TestClient,
TestClientMode,
} from '../../clients/createTestClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { ErrorType } from '../../errors/utils.js'
import type { Account } from '../../types/account.js'
import type { Chain } from '../../types/chain.js'
import type { RequestErrorType } from '../../utils/buildRequest.js'
export type ResetParameters = {
/** The block number to reset from. */
blockNumber?: bigint | undefined
/** The JSON RPC URL. */
jsonRpcUrl?: string | undefined
}
export type ResetErrorType = RequestErrorType | ErrorType
/**
* Resets fork back to its original state.
*
* - Docs: https://viem.sh/docs/actions/test/reset
*
* @param client - Client to use
* @param parameters {@link ResetParameters}
*
* @example
* import { createTestClient, http } from 'viem'
* import { foundry } from 'viem/chains'
* import { reset } from 'viem/test'
*
* const client = createTestClient({
* mode: 'anvil',
* chain: 'foundry',
* transport: http(),
* })
* await reset(client, { blockNumber: 69420n })
*/
export async function reset<
chain extends Chain | undefined,
account extends Account | undefined,
>(
client: TestClient<TestClientMode, Transport, chain, account, false>,
{ blockNumber, jsonRpcUrl }: ResetParameters = {},
) {
await client.request({
method: `${client.mode}_reset`,
params: [{ forking: { blockNumber: Number(blockNumber), jsonRpcUrl } }],
})
}

50
node_modules/viem/actions/test/revert.ts generated vendored Normal file
View File

@@ -0,0 +1,50 @@
import type {
TestClient,
TestClientMode,
} from '../../clients/createTestClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { ErrorType } from '../../errors/utils.js'
import type { Account } from '../../types/account.js'
import type { Chain } from '../../types/chain.js'
import type { Quantity } from '../../types/rpc.js'
import type { RequestErrorType } from '../../utils/buildRequest.js'
export type RevertParameters = {
/** The snapshot ID to revert to. */
id: Quantity
}
export type RevertErrorType = RequestErrorType | ErrorType
/**
* Revert the state of the blockchain at the current block.
*
* - Docs: https://viem.sh/docs/actions/test/revert
*
* @param client - Client to use
* @param parameters {@link RevertParameters}
*
* @example
* import { createTestClient, http } from 'viem'
* import { foundry } from 'viem/chains'
* import { revert } from 'viem/test'
*
* const client = createTestClient({
* mode: 'anvil',
* chain: 'foundry',
* transport: http(),
* })
* await revert(client, { id: '0x…' })
*/
export async function revert<
chain extends Chain | undefined,
account extends Account | undefined,
>(
client: TestClient<TestClientMode, Transport, chain, account, false>,
{ id }: RevertParameters,
) {
await client.request({
method: 'evm_revert',
params: [id],
})
}

View File

@@ -0,0 +1,97 @@
import type {
TestClient,
TestClientMode,
} from '../../clients/createTestClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { ErrorType } from '../../errors/utils.js'
import type { Account } from '../../types/account.js'
import type { Chain } from '../../types/chain.js'
import type { Hash } from '../../types/misc.js'
import type { TransactionRequest } from '../../types/transaction.js'
import type { RequestErrorType } from '../../utils/buildRequest.js'
import { extract } from '../../utils/formatters/extract.js'
import {
type FormattedTransactionRequest,
formatTransactionRequest,
} from '../../utils/formatters/transactionRequest.js'
export type SendUnsignedTransactionParameters<
chain extends Chain | undefined = Chain | undefined,
> = FormattedTransactionRequest<chain>
export type SendUnsignedTransactionReturnType = Hash
export type SendUnsignedTransactionErrorType = RequestErrorType | ErrorType
/**
* Executes a transaction regardless of the signature.
*
* - Docs: https://viem.sh/docs/actions/test/sendUnsignedTransaction#sendunsignedtransaction
*
* @param client - Client to use
* @param parameters {@link SendUnsignedTransactionParameters}
* @returns The transaction hash. {@link SendUnsignedTransactionReturnType}
*
* @example
* import { createTestClient, http } from 'viem'
* import { foundry } from 'viem/chains'
* import { sendUnsignedTransaction } from 'viem/test'
*
* const client = createTestClient({
* mode: 'anvil',
* chain: 'foundry',
* transport: http(),
* })
* const hash = await sendUnsignedTransaction(client, {
* from: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266',
* to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
* value: 1000000000000000000n,
* })
*/
export async function sendUnsignedTransaction<
chain extends Chain | undefined,
account extends Account | undefined,
>(
client: TestClient<TestClientMode, Transport, chain, account, false>,
args: SendUnsignedTransactionParameters<chain>,
): Promise<SendUnsignedTransactionReturnType> {
const {
accessList,
data,
from,
gas,
gasPrice,
maxFeePerGas,
maxPriorityFeePerGas,
nonce,
to,
value,
...rest
} = args
const chainFormat = client.chain?.formatters?.transactionRequest?.format
const format = chainFormat || formatTransactionRequest
const request = format(
{
// Pick out extra data that might exist on the chain's transaction request type.
...extract(rest, { format: chainFormat }),
accessList,
data,
from,
gas,
gasPrice,
maxFeePerGas,
maxPriorityFeePerGas,
nonce,
to,
value,
} as TransactionRequest,
'sendUnsignedTransaction',
)
const hash = await client.request({
method: 'eth_sendUnsignedTransaction',
params: [request],
})
return hash
}

47
node_modules/viem/actions/test/setAutomine.ts generated vendored Normal file
View File

@@ -0,0 +1,47 @@
import type {
TestClient,
TestClientMode,
} from '../../clients/createTestClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { ErrorType } from '../../errors/utils.js'
import type { Account } from '../../types/account.js'
import type { Chain } from '../../types/chain.js'
import type { RequestErrorType } from '../../utils/buildRequest.js'
export type SetAutomineErrorType = RequestErrorType | ErrorType
/**
* Enables or disables the automatic mining of new blocks with each new transaction submitted to the network.
*
* - Docs: https://viem.sh/docs/actions/test/setAutomine
*
* @param client - Client to use
*
* @example
* import { createTestClient, http } from 'viem'
* import { foundry } from 'viem/chains'
* import { setAutomine } from 'viem/test'
*
* const client = createTestClient({
* mode: 'anvil',
* chain: 'foundry',
* transport: http(),
* })
* await setAutomine(client)
*/
export async function setAutomine<
chain extends Chain | undefined,
account extends Account | undefined,
>(
client: TestClient<TestClientMode, Transport, chain, account, false>,
enabled: boolean,
) {
if (client.mode === 'ganache') {
if (enabled) await client.request({ method: 'miner_start' })
else await client.request({ method: 'miner_stop' })
} else
await client.request({
method: 'evm_setAutomine',
params: [enabled],
})
}

63
node_modules/viem/actions/test/setBalance.ts generated vendored Normal file
View File

@@ -0,0 +1,63 @@
import type { Address } from 'abitype'
import type {
TestClient,
TestClientMode,
} from '../../clients/createTestClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { ErrorType } from '../../errors/utils.js'
import type { Account } from '../../types/account.js'
import type { Chain } from '../../types/chain.js'
import type { RequestErrorType } from '../../utils/buildRequest.js'
import { numberToHex } from '../../utils/encoding/toHex.js'
export type SetBalanceParameters = {
/** The account address. */
address: Address
/** Amount (in wei) to set */
value: bigint
}
export type SetBalanceErrorType = RequestErrorType | ErrorType
/**
* Modifies the balance of an account.
*
* - Docs: https://viem.sh/docs/actions/test/setBalance
*
* @param client - Client to use
* @param parameters {@link SetBalanceParameters}
*
* @example
* import { createTestClient, http, parseEther } from 'viem'
* import { foundry } from 'viem/chains'
* import { setBalance } from 'viem/test'
*
* const client = createTestClient({
* mode: 'anvil',
* chain: 'foundry',
* transport: http(),
* })
* await setBalance(client, {
* address: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC',
* value: parseEther('1'),
* })
*/
export async function setBalance<
chain extends Chain | undefined,
account extends Account | undefined,
>(
client: TestClient<TestClientMode, Transport, chain, account, false>,
{ address, value }: SetBalanceParameters,
) {
if (client.mode === 'ganache')
await client.request({
method: 'evm_setAccountBalance',
params: [address, numberToHex(value)],
})
else
await client.request({
method: `${client.mode}_setBalance`,
params: [address, numberToHex(value)],
})
}

50
node_modules/viem/actions/test/setBlockGasLimit.ts generated vendored Normal file
View File

@@ -0,0 +1,50 @@
import type {
TestClient,
TestClientMode,
} from '../../clients/createTestClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { ErrorType } from '../../errors/utils.js'
import type { Account } from '../../types/account.js'
import type { Chain } from '../../types/chain.js'
import type { RequestErrorType } from '../../utils/buildRequest.js'
import { numberToHex } from '../../utils/encoding/toHex.js'
export type SetBlockGasLimitParameters = {
/** Gas limit (in wei). */
gasLimit: bigint
}
export type SetBlockGasLimitErrorType = RequestErrorType | ErrorType
/**
* Sets the block's gas limit.
*
* - Docs: https://viem.sh/docs/actions/test/setBlockGasLimit
*
* @param client - Client to use
* @param parameters {@link SetBlockGasLimitParameters}
*
* @example
* import { createTestClient, http } from 'viem'
* import { foundry } from 'viem/chains'
* import { setBlockGasLimit } from 'viem/test'
*
* const client = createTestClient({
* mode: 'anvil',
* chain: 'foundry',
* transport: http(),
* })
* await setBlockGasLimit(client, { gasLimit: 420_000n })
*/
export async function setBlockGasLimit<
chain extends Chain | undefined,
account extends Account | undefined,
>(
client: TestClient<TestClientMode, Transport, chain, account, false>,
{ gasLimit }: SetBlockGasLimitParameters,
) {
await client.request({
method: 'evm_setBlockGasLimit',
params: [numberToHex(gasLimit)],
})
}

View File

@@ -0,0 +1,54 @@
import type {
TestClient,
TestClientMode,
} from '../../clients/createTestClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { ErrorType } from '../../errors/utils.js'
import type { Account } from '../../types/account.js'
import type { Chain } from '../../types/chain.js'
import type { RequestErrorType } from '../../utils/buildRequest.js'
export type SetBlockTimestampIntervalParameters = {
/** The interval (in seconds). */
interval: number
}
export type SetBlockTimestampIntervalErrorType = RequestErrorType | ErrorType
/**
* Similar to [`increaseTime`](https://viem.sh/docs/actions/test/increaseTime), but sets a block timestamp `interval`. The timestamp of future blocks will be computed as `lastBlock_timestamp` + `interval`.
*
* - Docs: https://viem.sh/docs/actions/test/setBlockTimestampInterval
*
* @param client - Client to use
* @param parameters {@link SetBlockTimestampIntervalParameters}
*
* @example
* import { createTestClient, http } from 'viem'
* import { foundry } from 'viem/chains'
* import { setBlockTimestampInterval } from 'viem/test'
*
* const client = createTestClient({
* mode: 'anvil',
* chain: 'foundry',
* transport: http(),
* })
* await setBlockTimestampInterval(client, { interval: 5 })
*/
export async function setBlockTimestampInterval<
chain extends Chain | undefined,
account extends Account | undefined,
>(
client: TestClient<TestClientMode, Transport, chain, account, false>,
{ interval }: SetBlockTimestampIntervalParameters,
) {
const interval_ = (() => {
if (client.mode === 'hardhat') return interval * 1000
return interval
})()
await client.request({
method: `${client.mode}_setBlockTimestampInterval`,
params: [interval_],
})
}

63
node_modules/viem/actions/test/setCode.ts generated vendored Normal file
View File

@@ -0,0 +1,63 @@
import type { Address } from 'abitype'
import type {
TestClient,
TestClientMode,
} from '../../clients/createTestClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { ErrorType } from '../../errors/utils.js'
import type { Account } from '../../types/account.js'
import type { Chain } from '../../types/chain.js'
import type { Hex } from '../../types/misc.js'
import type { RequestErrorType } from '../../utils/buildRequest.js'
export type SetCodeParameters = {
/** The account address. */
address: Address
/** The bytecode to set */
bytecode: Hex
}
export type SetCodeErrorType = RequestErrorType | ErrorType
/**
* Modifies the bytecode stored at an account's address.
*
* - Docs: https://viem.sh/docs/actions/test/setCode
*
* @param client - Client to use
* @param parameters {@link SetCodeParameters}
*
* @example
* import { createTestClient, http } from 'viem'
* import { foundry } from 'viem/chains'
* import { setCode } from 'viem/test'
*
* const client = createTestClient({
* mode: 'anvil',
* chain: 'foundry',
* transport: http(),
* })
* await setCode(client, {
* address: '0xe846c6fcf817734ca4527b28ccb4aea2b6663c79',
* bytecode: '0x60806040526000600355600019600955600c80546001600160a01b031916737a250d5630b4cf539739df…',
* })
*/
export async function setCode<
chain extends Chain | undefined,
account extends Account | undefined,
>(
client: TestClient<TestClientMode, Transport, chain, account, false>,
{ address, bytecode }: SetCodeParameters,
) {
if (client.mode === 'ganache')
await client.request({
method: 'evm_setAccountCode',
params: [address, bytecode],
})
else
await client.request({
method: `${client.mode}_setCode`,
params: [address, bytecode],
})
}

53
node_modules/viem/actions/test/setCoinbase.ts generated vendored Normal file
View File

@@ -0,0 +1,53 @@
import type { Address } from 'abitype'
import type {
TestClient,
TestClientMode,
} from '../../clients/createTestClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { ErrorType } from '../../errors/utils.js'
import type { Account } from '../../types/account.js'
import type { Chain } from '../../types/chain.js'
import type { RequestErrorType } from '../../utils/buildRequest.js'
export type SetCoinbaseParameters = {
/** The coinbase address. */
address: Address
}
export type SetCoinbaseErrorType = RequestErrorType | ErrorType
/**
* Sets the coinbase address to be used in new blocks.
*
* - Docs: https://viem.sh/docs/actions/test/setCoinbase
*
* @param client - Client to use
* @param parameters {@link SetCoinbaseParameters}
*
* @example
* import { createTestClient, http } from 'viem'
* import { foundry } from 'viem/chains'
* import { setCoinbase } from 'viem/test'
*
* const client = createTestClient({
* mode: 'anvil',
* chain: 'foundry',
* transport: http(),
* })
* await setCoinbase(client, {
* address: '0xe846c6fcf817734ca4527b28ccb4aea2b6663c79',
* })
*/
export async function setCoinbase<
chain extends Chain | undefined,
account extends Account | undefined,
>(
client: TestClient<TestClientMode, Transport, chain, account, false>,
{ address }: SetCoinbaseParameters,
) {
await client.request({
method: `${client.mode}_setCoinbase`,
params: [address],
})
}

54
node_modules/viem/actions/test/setIntervalMining.ts generated vendored Normal file
View File

@@ -0,0 +1,54 @@
import type {
TestClient,
TestClientMode,
} from '../../clients/createTestClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { ErrorType } from '../../errors/utils.js'
import type { Account } from '../../types/account.js'
import type { Chain } from '../../types/chain.js'
import type { RequestErrorType } from '../../utils/buildRequest.js'
export type SetIntervalMiningParameters = {
/** The mining interval. */
interval: number
}
export type SetIntervalMiningErrorType = RequestErrorType | ErrorType
/**
* Sets the automatic mining interval (in seconds) of blocks. Setting the interval to 0 will disable automatic mining.
*
* - Docs: https://viem.sh/docs/actions/test/setIntervalMining
*
* @param client - Client to use
* @param parameters {@link SetIntervalMiningParameters}
*
* @example
* import { createTestClient, http } from 'viem'
* import { foundry } from 'viem/chains'
* import { setIntervalMining } from 'viem/test'
*
* const client = createTestClient({
* mode: 'anvil',
* chain: 'foundry',
* transport: http(),
* })
* await setIntervalMining(client, { interval: 5 })
*/
export async function setIntervalMining<
chain extends Chain | undefined,
account extends Account | undefined,
>(
client: TestClient<TestClientMode, Transport, chain, account, false>,
{ interval }: SetIntervalMiningParameters,
) {
const interval_ = (() => {
if (client.mode === 'hardhat') return interval * 1000
return interval
})()
await client.request({
method: 'evm_setIntervalMining',
params: [interval_],
})
}

43
node_modules/viem/actions/test/setLoggingEnabled.ts generated vendored Normal file
View File

@@ -0,0 +1,43 @@
import type {
TestClient,
TestClientMode,
} from '../../clients/createTestClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { ErrorType } from '../../errors/utils.js'
import type { Account } from '../../types/account.js'
import type { Chain } from '../../types/chain.js'
import type { RequestErrorType } from '../../utils/buildRequest.js'
export type SetLoggingEnabledErrorType = RequestErrorType | ErrorType
/**
* Enable or disable logging on the test node network.
*
* - Docs: https://viem.sh/docs/actions/test/setLoggingEnabled
*
* @param client - Client to use
*
* @example
* import { createTestClient, http } from 'viem'
* import { foundry } from 'viem/chains'
* import { setLoggingEnabled } from 'viem/test'
*
* const client = createTestClient({
* mode: 'anvil',
* chain: 'foundry',
* transport: http(),
* })
* await setLoggingEnabled(client)
*/
export async function setLoggingEnabled<
chain extends Chain | undefined,
account extends Account | undefined,
>(
client: TestClient<TestClientMode, Transport, chain, account, false>,
enabled: boolean,
) {
await client.request({
method: `${client.mode}_setLoggingEnabled`,
params: [enabled],
})
}

54
node_modules/viem/actions/test/setMinGasPrice.ts generated vendored Normal file
View File

@@ -0,0 +1,54 @@
import type {
TestClient,
TestClientMode,
} from '../../clients/createTestClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { ErrorType } from '../../errors/utils.js'
import type { Account } from '../../types/account.js'
import type { Chain } from '../../types/chain.js'
import type { RequestErrorType } from '../../utils/buildRequest.js'
import { numberToHex } from '../../utils/encoding/toHex.js'
export type SetMinGasPriceParameters = {
/** The gas price. */
gasPrice: bigint
}
export type SetMinGasPriceErrorType = RequestErrorType | ErrorType
/**
* Change the minimum gas price accepted by the network (in wei).
*
* - Docs: https://viem.sh/docs/actions/test/setMinGasPrice
*
* Note: `setMinGasPrice` can only be used on clients that do not have EIP-1559 enabled.
*
* @param client - Client to use
* @param parameters {@link SetBlockGasLimitParameters}
*
* @example
* import { createTestClient, http, parseGwei } from 'viem'
* import { foundry } from 'viem/chains'
* import { setMinGasPrice } from 'viem/test'
*
* const client = createTestClient({
* mode: 'anvil',
* chain: 'foundry',
* transport: http(),
* })
* await setMinGasPrice(client, {
* gasPrice: parseGwei('20'),
* })
*/
export async function setMinGasPrice<
chain extends Chain | undefined,
account extends Account | undefined,
>(
client: TestClient<TestClientMode, Transport, chain, account, false>,
{ gasPrice }: SetMinGasPriceParameters,
) {
await client.request({
method: `${client.mode}_setMinGasPrice`,
params: [numberToHex(gasPrice)],
})
}

View File

@@ -0,0 +1,52 @@
import type {
TestClient,
TestClientMode,
} from '../../clients/createTestClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { ErrorType } from '../../errors/utils.js'
import type { Account } from '../../types/account.js'
import type { Chain } from '../../types/chain.js'
import type { RequestErrorType } from '../../utils/buildRequest.js'
import { numberToHex } from '../../utils/encoding/toHex.js'
export type SetNextBlockBaseFeePerGasParameters = {
/** Base fee per gas (in wei). */
baseFeePerGas: bigint
}
export type SetNextBlockBaseFeePerGasErrorType = RequestErrorType | ErrorType
/**
* Sets the next block's base fee per gas.
*
* - Docs: https://viem.sh/docs/actions/test/setNextBlockBaseFeePerGas
*
* @param client - Client to use
* @param parameters {@link SetNextBlockBaseFeePerGasParameters}
*
* @example
* import { createTestClient, http, parseGwei } from 'viem'
* import { foundry } from 'viem/chains'
* import { setNextBlockBaseFeePerGas } from 'viem/test'
*
* const client = createTestClient({
* mode: 'anvil',
* chain: 'foundry',
* transport: http(),
* })
* await setNextBlockBaseFeePerGas(client, {
* baseFeePerGas: parseGwei('20'),
* })
*/
export async function setNextBlockBaseFeePerGas<
chain extends Chain | undefined,
account extends Account | undefined,
>(
client: TestClient<TestClientMode, Transport, chain, account, false>,
{ baseFeePerGas }: SetNextBlockBaseFeePerGasParameters,
) {
await client.request({
method: `${client.mode}_setNextBlockBaseFeePerGas`,
params: [numberToHex(baseFeePerGas)],
})
}

View File

@@ -0,0 +1,50 @@
import type {
TestClient,
TestClientMode,
} from '../../clients/createTestClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { ErrorType } from '../../errors/utils.js'
import type { Account } from '../../types/account.js'
import type { Chain } from '../../types/chain.js'
import type { RequestErrorType } from '../../utils/buildRequest.js'
import { numberToHex } from '../../utils/encoding/toHex.js'
export type SetNextBlockTimestampParameters = {
/** The timestamp (in seconds). */
timestamp: bigint
}
export type SetNextBlockTimestampErrorType = RequestErrorType | ErrorType
/**
* Sets the next block's timestamp.
*
* - Docs: https://viem.sh/docs/actions/test/setNextBlockTimestamp
*
* @param client - Client to use
* @param parameters {@link SetNextBlockTimestampParameters}
*
* @example
* import { createTestClient, http } from 'viem'
* import { foundry } from 'viem/chains'
* import { setNextBlockTimestamp } from 'viem/test'
*
* const client = createTestClient({
* mode: 'anvil',
* chain: 'foundry',
* transport: http(),
* })
* await setNextBlockTimestamp(client, { timestamp: 1671744314n })
*/
export async function setNextBlockTimestamp<
chain extends Chain | undefined,
account extends Account | undefined,
>(
client: TestClient<TestClientMode, Transport, chain, account, false>,
{ timestamp }: SetNextBlockTimestampParameters,
) {
await client.request({
method: 'evm_setNextBlockTimestamp',
params: [numberToHex(timestamp)],
})
}

57
node_modules/viem/actions/test/setNonce.ts generated vendored Normal file
View File

@@ -0,0 +1,57 @@
import type { Address } from 'abitype'
import type {
TestClient,
TestClientMode,
} from '../../clients/createTestClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { ErrorType } from '../../errors/utils.js'
import type { Account } from '../../types/account.js'
import type { Chain } from '../../types/chain.js'
import type { RequestErrorType } from '../../utils/buildRequest.js'
import { numberToHex } from '../../utils/encoding/toHex.js'
export type SetNonceParameters = {
/** The account address. */
address: Address
/** The nonce to set. */
nonce: number
}
export type SetNonceErrorType = RequestErrorType | ErrorType
/**
* Modifies (overrides) the nonce of an account.
*
* - Docs: https://viem.sh/docs/actions/test/setNonce
*
* @param client - Client to use
* @param parameters {@link SetNonceParameters}
*
* @example
* import { createTestClient, http } from 'viem'
* import { foundry } from 'viem/chains'
* import { setNonce } from 'viem/test'
*
* const client = createTestClient({
* mode: 'anvil',
* chain: 'foundry',
* transport: http(),
* })
* await setNonce(client, {
* address: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC',
* nonce: 420,
* })
*/
export async function setNonce<
chain extends Chain | undefined,
account extends Account | undefined,
>(
client: TestClient<TestClientMode, Transport, chain, account, false>,
{ address, nonce }: SetNonceParameters,
) {
await client.request({
method: `${client.mode}_setNonce`,
params: [address, numberToHex(nonce)],
})
}

44
node_modules/viem/actions/test/setRpcUrl.ts generated vendored Normal file
View File

@@ -0,0 +1,44 @@
import type {
TestClient,
TestClientMode,
} from '../../clients/createTestClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { ErrorType } from '../../errors/utils.js'
import type { Account } from '../../types/account.js'
import type { Chain } from '../../types/chain.js'
import type { RequestErrorType } from '../../utils/buildRequest.js'
export type SetRpcUrlErrorType = RequestErrorType | ErrorType
/**
* Sets the backend RPC URL.
*
* - Docs: https://viem.sh/docs/actions/test/setRpcUrl
*
* @param client - Client to use
* @param jsonRpcUrl RPC URL
*
* @example
* import { createTestClient, http } from 'viem'
* import { foundry } from 'viem/chains'
* import { setRpcUrl } from 'viem/test'
*
* const client = createTestClient({
* mode: 'anvil',
* chain: 'foundry',
* transport: http(),
* })
* await setRpcUrl(client, 'https://eth-mainnet.g.alchemy.com/v2')
*/
export async function setRpcUrl<
chain extends Chain | undefined,
account extends Account | undefined,
>(
client: TestClient<TestClientMode, Transport, chain, account, false>,
jsonRpcUrl: string,
) {
await client.request({
method: `${client.mode}_setRpcUrl`,
params: [jsonRpcUrl],
})
}

65
node_modules/viem/actions/test/setStorageAt.ts generated vendored Normal file
View File

@@ -0,0 +1,65 @@
import type { Address } from 'abitype'
import type {
TestClient,
TestClientMode,
} from '../../clients/createTestClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { ErrorType } from '../../errors/utils.js'
import type { Account } from '../../types/account.js'
import type { Chain } from '../../types/chain.js'
import type { Hash, Hex } from '../../types/misc.js'
import type { RequestErrorType } from '../../utils/buildRequest.js'
import { numberToHex } from '../../utils/encoding/toHex.js'
export type SetStorageAtParameters = {
/** The account address. */
address: Address
/** The storage slot (index). Can either be a number or hash value. */
index: number | Hash
/** The value to store as a 32 byte hex string. */
value: Hex
}
export type SetStorageAtErrorType = RequestErrorType | ErrorType
/**
* Writes to a slot of an account's storage.
*
* - Docs: https://viem.sh/docs/actions/test/setStorageAt
*
* @param client - Client to use
* @param parameters {@link SetStorageAtParameters}
*
* @example
* import { createTestClient, http } from 'viem'
* import { foundry } from 'viem/chains'
* import { setStorageAt } from 'viem/test'
*
* const client = createTestClient({
* mode: 'anvil',
* chain: 'foundry',
* transport: http(),
* })
* await setStorageAt(client, {
* address: '0xe846c6fcf817734ca4527b28ccb4aea2b6663c79',
* index: 2,
* value: '0x0000000000000000000000000000000000000000000000000000000000000069',
* })
*/
export async function setStorageAt<
chain extends Chain | undefined,
account extends Account | undefined,
>(
client: TestClient<TestClientMode, Transport, chain, account, false>,
{ address, index, value }: SetStorageAtParameters,
) {
await client.request({
method: `${client.mode}_setStorageAt`,
params: [
address,
typeof index === 'number' ? numberToHex(index) : index,
value,
],
})
}

39
node_modules/viem/actions/test/snapshot.ts generated vendored Normal file
View File

@@ -0,0 +1,39 @@
import type {
TestClient,
TestClientMode,
} from '../../clients/createTestClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { ErrorType } from '../../errors/utils.js'
import type { Account } from '../../types/account.js'
import type { Chain } from '../../types/chain.js'
import type { RequestErrorType } from '../../utils/buildRequest.js'
export type SnapshotErrorType = RequestErrorType | ErrorType
/**
* Snapshot the state of the blockchain at the current block.
*
* - Docs: https://viem.sh/docs/actions/test/snapshot
*
* @param client - Client to use
*
* @example
* import { createTestClient, http } from 'viem'
* import { foundry } from 'viem/chains'
* import { snapshot } from 'viem/test'
*
* const client = createTestClient({
* mode: 'anvil',
* chain: 'foundry',
* transport: http(),
* })
* await snapshot(client)
*/
export async function snapshot<
chain extends Chain | undefined,
account extends Account | undefined,
>(client: TestClient<TestClientMode, Transport, chain, account, false>) {
return await client.request({
method: 'evm_snapshot',
})
}

View File

@@ -0,0 +1,53 @@
import type { Address } from 'abitype'
import type {
TestClient,
TestClientMode,
} from '../../clients/createTestClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { ErrorType } from '../../errors/utils.js'
import type { Account } from '../../types/account.js'
import type { Chain } from '../../types/chain.js'
import type { RequestErrorType } from '../../utils/buildRequest.js'
export type StopImpersonatingAccountParameters = {
/** The account to impersonate. */
address: Address
}
export type StopImpersonatingAccountErrorType = RequestErrorType | ErrorType
/**
* Stop impersonating an account after having previously used [`impersonateAccount`](https://viem.sh/docs/actions/test/impersonateAccount).
*
* - Docs: https://viem.sh/docs/actions/test/stopImpersonatingAccount
*
* @param client - Client to use
* @param parameters {@link StopImpersonatingAccountParameters}
*
* @example
* import { createTestClient, http } from 'viem'
* import { foundry } from 'viem/chains'
* import { stopImpersonatingAccount } from 'viem/test'
*
* const client = createTestClient({
* mode: 'anvil',
* chain: 'foundry',
* transport: http(),
* })
* await stopImpersonatingAccount(client, {
* address: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC',
* })
*/
export async function stopImpersonatingAccount<
chain extends Chain | undefined,
account extends Account | undefined,
>(
client: TestClient<TestClientMode, Transport, chain, account, false>,
{ address }: StopImpersonatingAccountParameters,
) {
await client.request({
method: `${client.mode}_stopImpersonatingAccount`,
params: [address],
})
}

63
node_modules/viem/actions/wallet/addChain.ts generated vendored Normal file
View File

@@ -0,0 +1,63 @@
import type { Account } from '../../accounts/types.js'
import type { Client } from '../../clients/createClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { ErrorType } from '../../errors/utils.js'
import type { Chain } from '../../types/chain.js'
import type { RequestErrorType } from '../../utils/buildRequest.js'
import {
type NumberToHexErrorType,
numberToHex,
} from '../../utils/encoding/toHex.js'
export type AddChainParameters = {
/** The chain to add to the wallet. */
chain: Chain
}
export type AddChainErrorType =
| RequestErrorType
| NumberToHexErrorType
| ErrorType
/**
* Adds an EVM chain to the wallet.
*
* - Docs: https://viem.sh/docs/actions/wallet/addChain
* - JSON-RPC Methods: [`eth_addEthereumChain`](https://eips.ethereum.org/EIPS/eip-3085)
*
* @param client - Client to use
* @param parameters - {@link AddChainParameters}
*
* @example
* import { createWalletClient, custom } from 'viem'
* import { optimism } from 'viem/chains'
* import { addChain } from 'viem/wallet'
*
* const client = createWalletClient({
* transport: custom(window.ethereum),
* })
* await addChain(client, { chain: optimism })
*/
export async function addChain<
chain extends Chain | undefined,
account extends Account | undefined,
>(client: Client<Transport, chain, account>, { chain }: AddChainParameters) {
const { id, name, nativeCurrency, rpcUrls, blockExplorers } = chain
await client.request(
{
method: 'wallet_addEthereumChain',
params: [
{
chainId: numberToHex(id),
chainName: name,
nativeCurrency,
rpcUrls: rpcUrls.default.http,
blockExplorerUrls: blockExplorers
? Object.values(blockExplorers).map(({ url }) => url)
: undefined,
},
],
},
{ dedupe: true, retryCount: 0 },
)
}

88
node_modules/viem/actions/wallet/deployContract.ts generated vendored Normal file
View File

@@ -0,0 +1,88 @@
import type { Abi } from 'abitype'
import type { Account } from '../../accounts/types.js'
import type { Client } from '../../clients/createClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { ErrorType } from '../../errors/utils.js'
import type { Chain, GetChainParameter } from '../../types/chain.js'
import type { ContractConstructorArgs } from '../../types/contract.js'
import type { Hex } from '../../types/misc.js'
import type { UnionEvaluate, UnionOmit } from '../../types/utils.js'
import { encodeDeployData } from '../../utils/abi/encodeDeployData.js'
import {
type SendTransactionErrorType,
type SendTransactionParameters,
type SendTransactionReturnType,
sendTransaction,
} from './sendTransaction.js'
export type DeployContractParameters<
abi extends Abi | readonly unknown[] = Abi,
chain extends Chain | undefined = Chain | undefined,
account extends Account | undefined = Account | undefined,
chainOverride extends Chain | undefined = Chain | undefined,
///
allArgs = ContractConstructorArgs<abi>,
> = UnionOmit<
SendTransactionParameters<chain, account, chainOverride>,
'accessList' | 'chain' | 'to' | 'data'
> &
GetChainParameter<chain, chainOverride> &
UnionEvaluate<
readonly [] extends allArgs
? { args?: allArgs | undefined }
: { args: allArgs }
> & {
abi: abi
bytecode: Hex
}
export type DeployContractReturnType = SendTransactionReturnType
export type DeployContractErrorType = SendTransactionErrorType | ErrorType
/**
* Deploys a contract to the network, given bytecode and constructor arguments.
*
* - Docs: https://viem.sh/docs/contract/deployContract
* - Examples: https://stackblitz.com/github/wevm/viem/tree/main/examples/contracts_deploying-contracts
*
* @param client - Client to use
* @param parameters - {@link DeployContractParameters}
* @returns The [Transaction](https://viem.sh/docs/glossary/terms#transaction) hash. {@link DeployContractReturnType}
*
* @example
* import { createWalletClient, http } from 'viem'
* import { privateKeyToAccount } from 'viem/accounts'
* import { mainnet } from 'viem/chains'
* import { deployContract } from 'viem/contract'
*
* const client = createWalletClient({
* account: privateKeyToAccount('0x…'),
* chain: mainnet,
* transport: http(),
* })
* const hash = await deployContract(client, {
* abi: [],
* account: '0x…,
* bytecode: '0x608060405260405161083e38038061083e833981016040819052610...',
* })
*/
export function deployContract<
const abi extends Abi | readonly unknown[],
chain extends Chain | undefined,
account extends Account | undefined,
chainOverride extends Chain | undefined,
>(
walletClient: Client<Transport, chain, account>,
parameters: DeployContractParameters<abi, chain, account, chainOverride>,
): Promise<DeployContractReturnType> {
const { abi, args, bytecode, ...request } =
parameters as DeployContractParameters
const calldata = encodeDeployData({ abi, args, bytecode })
return sendTransaction(walletClient, {
...request,
...(request.authorizationList ? { to: null } : {}),
data: calldata,
} as unknown as SendTransactionParameters<chain, account, chainOverride>)
}

51
node_modules/viem/actions/wallet/getAddresses.ts generated vendored Normal file
View File

@@ -0,0 +1,51 @@
import type { Address } from 'abitype'
import type { Account } from '../../accounts/types.js'
import type { Client } from '../../clients/createClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { ErrorType } from '../../errors/utils.js'
import type { Chain } from '../../types/chain.js'
import {
type ChecksumAddressErrorType,
checksumAddress,
} from '../../utils/address/getAddress.js'
import type { RequestErrorType } from '../../utils/buildRequest.js'
export type GetAddressesReturnType = Address[]
export type GetAddressesErrorType =
| RequestErrorType
| ChecksumAddressErrorType
| ErrorType
/**
* Returns a list of account addresses owned by the wallet or client.
*
* - Docs: https://viem.sh/docs/actions/wallet/getAddresses
* - JSON-RPC Methods: [`eth_accounts`](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_accounts)
*
* @param client - Client to use
* @returns List of account addresses owned by the wallet or client. {@link GetAddressesReturnType}
*
* @example
* import { createWalletClient, custom } from 'viem'
* import { mainnet } from 'viem/chains'
* import { getAddresses } from 'viem/wallet'
*
* const client = createWalletClient({
* chain: mainnet,
* transport: custom(window.ethereum),
* })
* const accounts = await getAddresses(client)
*/
export async function getAddresses<
chain extends Chain | undefined,
account extends Account | undefined = undefined,
>(client: Client<Transport, chain, account>): Promise<GetAddressesReturnType> {
if (client.account?.type === 'local') return [client.account.address]
const addresses = await client.request(
{ method: 'eth_accounts' },
{ dedupe: true },
)
return addresses.map((address) => checksumAddress(address))
}

147
node_modules/viem/actions/wallet/getCallsStatus.ts generated vendored Normal file
View File

@@ -0,0 +1,147 @@
import type { Client } from '../../clients/createClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { ErrorType } from '../../errors/utils.js'
import type { Account } from '../../types/account.js'
import type { ExtractCapabilities } from '../../types/capabilities.js'
import type { Chain } from '../../types/chain.js'
import type { WalletGetCallsStatusReturnType } from '../../types/eip1193.js'
import type { Hex } from '../../types/misc.js'
import type { RpcTransactionReceipt } from '../../types/rpc.js'
import type { Prettify } from '../../types/utils.js'
import type { RequestErrorType } from '../../utils/buildRequest.js'
import { sliceHex } from '../../utils/data/slice.js'
import { trim } from '../../utils/data/trim.js'
import { hexToBigInt, hexToNumber } from '../../utils/encoding/fromHex.js'
import { receiptStatuses } from '../../utils/formatters/transactionReceipt.js'
import {
fallbackMagicIdentifier,
fallbackTransactionErrorMagicIdentifier,
} from './sendCalls.js'
export type GetCallsStatusParameters = { id: string }
export type GetCallsStatusReturnType = Prettify<
Omit<
WalletGetCallsStatusReturnType<
ExtractCapabilities<'getCallsStatus', 'ReturnType'>,
number,
bigint,
'success' | 'reverted'
>,
'status'
> & {
statusCode: number
status: 'pending' | 'success' | 'failure' | undefined
}
>
export type GetCallsStatusErrorType = RequestErrorType | ErrorType
/**
* Returns the status of a call batch that was sent via `sendCalls`.
*
* - Docs: https://viem.sh/docs/actions/wallet/getCallsStatus
* - JSON-RPC Methods: [`wallet_getCallsStatus`](https://eips.ethereum.org/EIPS/eip-5792)
*
* @param client - Client to use
* @returns Status of the calls. {@link GetCallsStatusReturnType}
*
* @example
* import { createWalletClient, custom } from 'viem'
* import { mainnet } from 'viem/chains'
* import { getCallsStatus } from 'viem/actions'
*
* const client = createWalletClient({
* chain: mainnet,
* transport: custom(window.ethereum),
* })
* const { receipts, status } = await getCallsStatus(client, { id: '0xdeadbeef' })
*/
export async function getCallsStatus<
chain extends Chain | undefined,
account extends Account | undefined = undefined,
>(
client: Client<Transport, chain, account>,
parameters: GetCallsStatusParameters,
): Promise<GetCallsStatusReturnType> {
async function getStatus(id: Hex) {
const isTransactions = id.endsWith(fallbackMagicIdentifier.slice(2))
if (isTransactions) {
const chainId = trim(sliceHex(id, -64, -32))
const hashes = sliceHex(id, 0, -64)
.slice(2)
.match(/.{1,64}/g)
const receipts = await Promise.all(
hashes!.map((hash) =>
fallbackTransactionErrorMagicIdentifier.slice(2) !== hash
? client.request(
{
method: 'eth_getTransactionReceipt',
params: [`0x${hash}`],
},
{ dedupe: true },
)
: undefined,
),
)
const status = (() => {
if (receipts.some((r) => r === null)) return 100 // pending
if (receipts.every((r) => r?.status === '0x1')) return 200 // success
if (receipts.every((r) => r?.status === '0x0')) return 500 // complete failure
return 600 // partial failure
})()
return {
atomic: false,
chainId: hexToNumber(chainId),
receipts: receipts.filter(Boolean) as RpcTransactionReceipt[],
status,
version: '2.0.0',
}
}
return client.request({
method: 'wallet_getCallsStatus',
params: [id],
})
}
const {
atomic = false,
chainId,
receipts,
version = '2.0.0',
...response
} = await getStatus(parameters.id as Hex)
const [status, statusCode] = (() => {
const statusCode = response.status
if (statusCode >= 100 && statusCode < 200)
return ['pending', statusCode] as const
if (statusCode >= 200 && statusCode < 300)
return ['success', statusCode] as const
if (statusCode >= 300 && statusCode < 700)
return ['failure', statusCode] as const
// @ts-expect-error: for backwards compatibility
if (statusCode === 'CONFIRMED') return ['success', 200] as const
// @ts-expect-error: for backwards compatibility
if (statusCode === 'PENDING') return ['pending', 100] as const
return [undefined, statusCode]
})()
return {
...response,
atomic,
// @ts-expect-error: for backwards compatibility
chainId: chainId ? hexToNumber(chainId) : undefined,
receipts:
receipts?.map((receipt) => ({
...receipt,
blockNumber: hexToBigInt(receipt.blockNumber),
gasUsed: hexToBigInt(receipt.gasUsed),
status: receiptStatuses[receipt.status as '0x0' | '0x1'],
})) ?? [],
statusCode,
status,
version,
}
}

89
node_modules/viem/actions/wallet/getCapabilities.ts generated vendored Normal file
View File

@@ -0,0 +1,89 @@
import type { Address } from 'abitype'
import { parseAccount } from '../../accounts/utils/parseAccount.js'
import type { Client } from '../../clients/createClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { ErrorType } from '../../errors/utils.js'
import type { Account } from '../../types/account.js'
import type {
Capabilities,
ChainIdToCapabilities,
ExtractCapabilities,
} from '../../types/capabilities.js'
import type { Prettify } from '../../types/utils.js'
import type { RequestErrorType } from '../../utils/buildRequest.js'
import { numberToHex } from '../../utils/encoding/toHex.js'
export type GetCapabilitiesParameters<
chainId extends number | undefined = undefined,
> = {
account?: Account | Address | undefined
chainId?: chainId | number | undefined
}
export type GetCapabilitiesReturnType<
chainId extends number | undefined = undefined,
> = Prettify<
chainId extends number
? ExtractCapabilities<'getCapabilities', 'ReturnType'>
: ChainIdToCapabilities<
Capabilities<ExtractCapabilities<'getCapabilities', 'ReturnType'>>,
number
>
>
export type GetCapabilitiesErrorType = RequestErrorType | ErrorType
/**
* Extract capabilities that a connected wallet supports (e.g. paymasters, session keys, etc).
*
* - Docs: https://viem.sh/docs/actions/wallet/getCapabilities
* - JSON-RPC Methods: [`wallet_getCapabilities`](https://eips.ethereum.org/EIPS/eip-5792)
*
* @param client - Client to use
* @returns The wallet's capabilities. {@link GetCapabilitiesReturnType}
*
* @example
* import { createWalletClient, custom } from 'viem'
* import { mainnet } from 'viem/chains'
* import { getCapabilities } from 'viem/actions'
*
* const client = createWalletClient({
* chain: mainnet,
* transport: custom(window.ethereum),
* })
* const capabilities = await getCapabilities(client)
*/
export async function getCapabilities<
chainId extends number | undefined = undefined,
>(
client: Client<Transport>,
parameters: GetCapabilitiesParameters<chainId> = {},
): Promise<GetCapabilitiesReturnType<chainId>> {
const { account = client.account, chainId } = parameters
const account_ = account ? parseAccount(account) : undefined
const params = chainId
? ([account_?.address, [numberToHex(chainId)]] as const)
: ([account_?.address] as const)
const capabilities_raw = await client.request({
method: 'wallet_getCapabilities',
params,
})
const capabilities = {} as ChainIdToCapabilities<
ExtractCapabilities<'getCapabilities', 'ReturnType'>,
number
>
for (const [chainId, capabilities_] of Object.entries(capabilities_raw)) {
capabilities[Number(chainId)] = {}
for (let [key, value] of Object.entries(capabilities_)) {
if (key === 'addSubAccount') key = 'unstable_addSubAccount'
capabilities[Number(chainId)][key] = value
}
}
return (
typeof chainId === 'number' ? capabilities[chainId] : capabilities
) as never
}

42
node_modules/viem/actions/wallet/getPermissions.ts generated vendored Normal file
View File

@@ -0,0 +1,42 @@
import type { Account } from '../../accounts/types.js'
import type { Client } from '../../clients/createClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { ErrorType } from '../../errors/utils.js'
import type { Chain } from '../../types/chain.js'
import type { WalletPermission } from '../../types/eip1193.js'
import type { RequestErrorType } from '../../utils/buildRequest.js'
export type GetPermissionsReturnType = WalletPermission[]
export type GetPermissionsErrorType = RequestErrorType | ErrorType
/**
* Gets the wallets current permissions.
*
* - Docs: https://viem.sh/docs/actions/wallet/getPermissions
* - JSON-RPC Methods: [`wallet_getPermissions`](https://eips.ethereum.org/EIPS/eip-2255)
*
* @param client - Client to use
* @returns The wallet permissions. {@link GetPermissionsReturnType}
*
* @example
* import { createWalletClient, custom } from 'viem'
* import { mainnet } from 'viem/chains'
* import { getPermissions } from 'viem/wallet'
*
* const client = createWalletClient({
* chain: mainnet,
* transport: custom(window.ethereum),
* })
* const permissions = await getPermissions(client)
*/
export async function getPermissions<
chain extends Chain | undefined,
account extends Account | undefined = undefined,
>(client: Client<Transport, chain, account>) {
const permissions = await client.request(
{ method: 'wallet_getPermissions' },
{ dedupe: true },
)
return permissions
}

View File

@@ -0,0 +1,138 @@
import type { Address } from 'abitype'
import type { Account } from '../../accounts/types.js'
import {
type ParseAccountErrorType,
parseAccount,
} from '../../accounts/utils/parseAccount.js'
import type { Client } from '../../clients/createClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import {
AccountNotFoundError,
type AccountNotFoundErrorType,
} from '../../errors/account.js'
import type { ErrorType } from '../../errors/utils.js'
import type { GetAccountParameter } from '../../types/account.js'
import type {
Authorization,
AuthorizationRequest,
} from '../../types/authorization.js'
import type { Chain } from '../../types/chain.js'
import type { PartialBy } from '../../types/utils.js'
import { isAddressEqual } from '../../utils/address/isAddressEqual.js'
import type { RequestErrorType } from '../../utils/buildRequest.js'
import { getAction } from '../../utils/getAction.js'
import { getChainId } from '../public/getChainId.js'
import { getTransactionCount } from '../public/getTransactionCount.js'
export type PrepareAuthorizationParameters<
account extends Account | undefined = Account | undefined,
> = GetAccountParameter<account> &
PartialBy<AuthorizationRequest, 'chainId' | 'nonce'> & {
/**
* Whether the EIP-7702 Transaction will be executed by the EOA (signing this Authorization) or another Account.
*
* By default, it will be assumed that the EIP-7702 Transaction will
* be executed by another Account.
*/
executor?: 'self' | Account | Address | undefined
}
export type PrepareAuthorizationReturnType = Authorization
export type PrepareAuthorizationErrorType =
| ParseAccountErrorType
| RequestErrorType
| AccountNotFoundErrorType
| ErrorType
/**
* Prepares an [EIP-7702 Authorization](https://eips.ethereum.org/EIPS/eip-7702) object for signing.
* This Action will fill the required fields of the Authorization object if they are not provided (e.g. `nonce` and `chainId`).
*
* With the prepared Authorization object, you can use [`signAuthorization`](https://viem.sh/docs/eip7702/signAuthorization) to sign over the Authorization object.
*
* @param client - Client to use
* @param parameters - {@link PrepareAuthorizationParameters}
* @returns The prepared Authorization object. {@link PrepareAuthorizationReturnType}
*
* @example
* import { createClient, http } from 'viem'
* import { privateKeyToAccount } from 'viem/accounts'
* import { mainnet } from 'viem/chains'
* import { prepareAuthorization } from 'viem/experimental'
*
* const client = createClient({
* chain: mainnet,
* transport: http(),
* })
* const authorization = await prepareAuthorization(client, {
* account: privateKeyToAccount('0x..'),
* contractAddress: '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e',
* })
*
* @example
* // Account Hoisting
* import { createClient, http } from 'viem'
* import { privateKeyToAccount } from 'viem/accounts'
* import { mainnet } from 'viem/chains'
* import { prepareAuthorization } from 'viem/experimental'
*
* const client = createClient({
* account: privateKeyToAccount('0x…'),
* chain: mainnet,
* transport: http(),
* })
* const authorization = await prepareAuthorization(client, {
* contractAddress: '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e',
* })
*/
export async function prepareAuthorization<
chain extends Chain | undefined,
account extends Account | undefined,
>(
client: Client<Transport, chain, account>,
parameters: PrepareAuthorizationParameters<account>,
): Promise<PrepareAuthorizationReturnType> {
const { account: account_ = client.account, chainId, nonce } = parameters
if (!account_)
throw new AccountNotFoundError({
docsPath: '/docs/eip7702/prepareAuthorization',
})
const account = parseAccount(account_)
const executor = (() => {
if (!parameters.executor) return undefined
if (parameters.executor === 'self') return parameters.executor
return parseAccount(parameters.executor)
})()
const authorization = {
address: parameters.contractAddress ?? parameters.address,
chainId,
nonce,
} as Authorization
if (typeof authorization.chainId === 'undefined')
authorization.chainId =
client.chain?.id ??
(await getAction(client, getChainId, 'getChainId')({}))
if (typeof authorization.nonce === 'undefined') {
authorization.nonce = await getAction(
client,
getTransactionCount,
'getTransactionCount',
)({
address: account.address,
blockTag: 'pending',
})
if (
executor === 'self' ||
(executor?.address && isAddressEqual(executor.address, account.address))
)
authorization.nonce += 1
}
return authorization
}

View File

@@ -0,0 +1,646 @@
import type { Address } from 'abitype'
import type { Account } from '../../accounts/types.js'
import {
type ParseAccountErrorType,
parseAccount,
} from '../../accounts/utils/parseAccount.js'
import {
type EstimateFeesPerGasErrorType,
internal_estimateFeesPerGas,
} from '../../actions/public/estimateFeesPerGas.js'
import {
type EstimateGasErrorType,
type EstimateGasParameters,
estimateGas,
} from '../../actions/public/estimateGas.js'
import {
type GetBlockErrorType,
getBlock as getBlock_,
} from '../../actions/public/getBlock.js'
import {
type GetTransactionCountErrorType,
getTransactionCount,
} from '../../actions/public/getTransactionCount.js'
import type { Client } from '../../clients/createClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { AccountNotFoundErrorType } from '../../errors/account.js'
import type { BaseError } from '../../errors/base.js'
import {
Eip1559FeesNotSupportedError,
MaxFeePerGasTooLowError,
} from '../../errors/fee.js'
import type { DeriveAccount, GetAccountParameter } from '../../types/account.js'
import type { Block } from '../../types/block.js'
import type { ExtractCapabilities } from '../../types/capabilities.js'
import type {
Chain,
DeriveChain,
GetChainParameter,
} from '../../types/chain.js'
import type { GetTransactionRequestKzgParameter } from '../../types/kzg.js'
import type {
TransactionRequest,
TransactionRequestEIP1559,
TransactionRequestEIP2930,
TransactionRequestEIP4844,
TransactionRequestEIP7702,
TransactionRequestLegacy,
TransactionSerializable,
} from '../../types/transaction.js'
import type {
ExactPartial,
IsNever,
Prettify,
UnionOmit,
UnionRequiredBy,
} from '../../types/utils.js'
import { blobsToCommitments } from '../../utils/blob/blobsToCommitments.js'
import { blobsToProofs } from '../../utils/blob/blobsToProofs.js'
import { commitmentsToVersionedHashes } from '../../utils/blob/commitmentsToVersionedHashes.js'
import { toBlobSidecars } from '../../utils/blob/toBlobSidecars.js'
import type { FormattedTransactionRequest } from '../../utils/formatters/transactionRequest.js'
import { getAction } from '../../utils/getAction.js'
import { LruMap } from '../../utils/lru.js'
import type { NonceManager } from '../../utils/nonceManager.js'
import {
type AssertRequestErrorType,
type AssertRequestParameters,
assertRequest,
} from '../../utils/transaction/assertRequest.js'
import {
type GetTransactionType,
getTransactionType,
} from '../../utils/transaction/getTransactionType.js'
import {
type FillTransactionErrorType,
type FillTransactionParameters,
fillTransaction,
} from '../public/fillTransaction.js'
import { getChainId as getChainId_ } from '../public/getChainId.js'
export const defaultParameters = [
'blobVersionedHashes',
'chainId',
'fees',
'gas',
'nonce',
'type',
] as const
/** @internal */
export const eip1559NetworkCache = /*#__PURE__*/ new Map<string, boolean>()
/** @internal */
export const supportsFillTransaction = /*#__PURE__*/ new LruMap<boolean>(128)
export type PrepareTransactionRequestParameterType =
| 'blobVersionedHashes'
| 'chainId'
| 'fees'
| 'gas'
| 'nonce'
| 'sidecars'
| 'type'
type ParameterTypeToParameters<
parameterType extends PrepareTransactionRequestParameterType,
> = parameterType extends 'fees'
? 'maxFeePerGas' | 'maxPriorityFeePerGas' | 'gasPrice'
: parameterType
export type PrepareTransactionRequestRequest<
chain extends Chain | undefined = Chain | undefined,
chainOverride extends Chain | undefined = Chain | undefined,
///
_derivedChain extends Chain | undefined = DeriveChain<chain, chainOverride>,
> = UnionOmit<FormattedTransactionRequest<_derivedChain>, 'from'> &
GetTransactionRequestKzgParameter & {
/**
* Nonce manager to use for the transaction request.
*/
nonceManager?: NonceManager | undefined
/**
* Parameters to prepare for the transaction request.
*
* @default ['blobVersionedHashes', 'chainId', 'fees', 'gas', 'nonce', 'type']
*/
parameters?: readonly PrepareTransactionRequestParameterType[] | undefined
}
export type PrepareTransactionRequestParameters<
chain extends Chain | undefined = Chain | undefined,
account extends Account | undefined = Account | undefined,
chainOverride extends Chain | undefined = Chain | undefined,
accountOverride extends Account | Address | undefined =
| Account
| Address
| undefined,
request extends PrepareTransactionRequestRequest<
chain,
chainOverride
> = PrepareTransactionRequestRequest<chain, chainOverride>,
> = request &
GetAccountParameter<account, accountOverride, false, true> &
GetChainParameter<chain, chainOverride> &
GetTransactionRequestKzgParameter<request> & { chainId?: number | undefined }
export type PrepareTransactionRequestReturnType<
chain extends Chain | undefined = Chain | undefined,
account extends Account | undefined = Account | undefined,
chainOverride extends Chain | undefined = Chain | undefined,
accountOverride extends Account | Address | undefined =
| Account
| Address
| undefined,
request extends PrepareTransactionRequestRequest<
chain,
chainOverride
> = PrepareTransactionRequestRequest<chain, chainOverride>,
///
_derivedAccount extends Account | Address | undefined = DeriveAccount<
account,
accountOverride
>,
_derivedChain extends Chain | undefined = DeriveChain<chain, chainOverride>,
_transactionType = request['type'] extends string | undefined
? request['type']
: GetTransactionType<request> extends 'legacy'
? unknown
: GetTransactionType<request>,
_transactionRequest extends TransactionRequest =
| (_transactionType extends 'legacy' ? TransactionRequestLegacy : never)
| (_transactionType extends 'eip1559' ? TransactionRequestEIP1559 : never)
| (_transactionType extends 'eip2930' ? TransactionRequestEIP2930 : never)
| (_transactionType extends 'eip4844' ? TransactionRequestEIP4844 : never)
| (_transactionType extends 'eip7702' ? TransactionRequestEIP7702 : never),
> = Prettify<
UnionRequiredBy<
Extract<
UnionOmit<FormattedTransactionRequest<_derivedChain>, 'from'> &
(_derivedChain extends Chain
? { chain: _derivedChain }
: { chain?: undefined }) &
(_derivedAccount extends Account
? { account: _derivedAccount; from: Address }
: { account?: undefined; from?: undefined }),
IsNever<_transactionRequest> extends true
? unknown
: ExactPartial<_transactionRequest>
> & { chainId?: number | undefined },
ParameterTypeToParameters<
request['parameters'] extends readonly PrepareTransactionRequestParameterType[]
? request['parameters'][number]
: (typeof defaultParameters)[number]
>
> &
(unknown extends request['kzg'] ? {} : Pick<request, 'kzg'>) & {
// TODO(v3): Extract `prepareTransactionRequest` response into a named object of `{ capabilities, request }.
_capabilities?:
| ExtractCapabilities<'fillTransaction', 'ReturnType'>
| undefined
}
>
export type PrepareTransactionRequestErrorType =
| AccountNotFoundErrorType
| AssertRequestErrorType
| ParseAccountErrorType
| GetBlockErrorType
| GetTransactionCountErrorType
| EstimateGasErrorType
| EstimateFeesPerGasErrorType
/**
* Prepares a transaction request for signing.
*
* - Docs: https://viem.sh/docs/actions/wallet/prepareTransactionRequest
*
* @param args - {@link PrepareTransactionRequestParameters}
* @returns The transaction request. {@link PrepareTransactionRequestReturnType}
*
* @example
* import { createWalletClient, custom } from 'viem'
* import { mainnet } from 'viem/chains'
* import { prepareTransactionRequest } from 'viem/actions'
*
* const client = createWalletClient({
* chain: mainnet,
* transport: custom(window.ethereum),
* })
* const request = await prepareTransactionRequest(client, {
* account: '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e',
* to: '0x0000000000000000000000000000000000000000',
* value: 1n,
* })
*
* @example
* // Account Hoisting
* import { createWalletClient, http } from 'viem'
* import { privateKeyToAccount } from 'viem/accounts'
* import { mainnet } from 'viem/chains'
* import { prepareTransactionRequest } from 'viem/actions'
*
* const client = createWalletClient({
* account: privateKeyToAccount('0x…'),
* chain: mainnet,
* transport: custom(window.ethereum),
* })
* const request = await prepareTransactionRequest(client, {
* to: '0x0000000000000000000000000000000000000000',
* value: 1n,
* })
*/
export async function prepareTransactionRequest<
chain extends Chain | undefined,
account extends Account | undefined,
const request extends PrepareTransactionRequestRequest<chain, chainOverride>,
accountOverride extends Account | Address | undefined = undefined,
chainOverride extends Chain | undefined = undefined,
>(
client: Client<Transport, chain, account>,
args: PrepareTransactionRequestParameters<
chain,
account,
chainOverride,
accountOverride,
request
>,
): Promise<
PrepareTransactionRequestReturnType<
chain,
account,
chainOverride,
accountOverride,
request
>
> {
let request = args as PrepareTransactionRequestParameters
request.account ??= client.account
request.parameters ??= defaultParameters
const {
account: account_,
chain = client.chain,
nonceManager,
parameters,
} = request
const prepareTransactionRequest = (() => {
if (typeof chain?.prepareTransactionRequest === 'function')
return {
fn: chain.prepareTransactionRequest,
runAt: ['beforeFillTransaction'],
}
if (Array.isArray(chain?.prepareTransactionRequest))
return {
fn: chain.prepareTransactionRequest[0],
runAt: chain.prepareTransactionRequest[1].runAt,
}
return undefined
})()
let chainId: number | undefined
async function getChainId(): Promise<number> {
if (chainId) return chainId
if (typeof request.chainId !== 'undefined') return request.chainId
if (chain) return chain.id
const chainId_ = await getAction(client, getChainId_, 'getChainId')({})
chainId = chainId_
return chainId
}
const account = account_ ? parseAccount(account_) : account_
let nonce = request.nonce
if (
parameters.includes('nonce') &&
typeof nonce === 'undefined' &&
account &&
nonceManager
) {
const chainId = await getChainId()
nonce = await nonceManager.consume({
address: account.address,
chainId,
client,
})
}
if (
prepareTransactionRequest?.fn &&
prepareTransactionRequest.runAt?.includes('beforeFillTransaction')
) {
request = await prepareTransactionRequest.fn(
{ ...request, chain },
{
phase: 'beforeFillTransaction',
},
)
nonce ??= request.nonce
}
const attemptFill = (() => {
// Do not attempt if blobs are provided.
if (
(parameters.includes('blobVersionedHashes') ||
parameters.includes('sidecars')) &&
request.kzg &&
request.blobs
)
return false
// Do not attempt if `eth_fillTransaction` is not supported.
if (supportsFillTransaction.get(client.uid) === false) return false
// Should attempt `eth_fillTransaction` if "fees" or "gas" are required to be populated,
// otherwise, can just use the other individual calls.
const shouldAttempt = ['fees', 'gas'].some((parameter) =>
parameters.includes(parameter as PrepareTransactionRequestParameterType),
)
if (!shouldAttempt) return false
// Check if `eth_fillTransaction` needs to be called.
if (parameters.includes('chainId') && typeof request.chainId !== 'number')
return true
if (parameters.includes('nonce') && typeof nonce !== 'number') return true
if (
parameters.includes('fees') &&
typeof request.gasPrice !== 'bigint' &&
(typeof request.maxFeePerGas !== 'bigint' ||
typeof (request as any).maxPriorityFeePerGas !== 'bigint')
)
return true
if (parameters.includes('gas') && typeof request.gas !== 'bigint')
return true
return false
})()
const fillResult = attemptFill
? await getAction(
client,
fillTransaction,
'fillTransaction',
)({ ...request, nonce } as FillTransactionParameters)
.then((result) => {
const {
chainId,
from,
gas,
gasPrice,
nonce,
maxFeePerBlobGas,
maxFeePerGas,
maxPriorityFeePerGas,
type,
...rest
} = result.transaction
supportsFillTransaction.set(client.uid, true)
return {
...request,
...(from ? { from } : {}),
...(type && !request.type ? { type } : {}),
...(typeof chainId !== 'undefined' ? { chainId } : {}),
...(typeof gas !== 'undefined' ? { gas } : {}),
...(typeof gasPrice !== 'undefined' ? { gasPrice } : {}),
...(typeof nonce !== 'undefined' ? { nonce } : {}),
...(typeof maxFeePerBlobGas !== 'undefined' &&
request.type !== 'legacy' &&
request.type !== 'eip2930'
? { maxFeePerBlobGas }
: {}),
...(typeof maxFeePerGas !== 'undefined' &&
request.type !== 'legacy' &&
request.type !== 'eip2930'
? { maxFeePerGas }
: {}),
...(typeof maxPriorityFeePerGas !== 'undefined' &&
request.type !== 'legacy' &&
request.type !== 'eip2930'
? { maxPriorityFeePerGas }
: {}),
...('nonceKey' in rest && typeof rest.nonceKey !== 'undefined'
? { nonceKey: rest.nonceKey }
: {}),
...('keyAuthorization' in rest &&
typeof rest.keyAuthorization !== 'undefined' &&
rest.keyAuthorization !== null &&
!('keyAuthorization' in request)
? { keyAuthorization: rest.keyAuthorization }
: {}),
...('feePayerSignature' in rest &&
typeof rest.feePayerSignature !== 'undefined' &&
rest.feePayerSignature !== null
? { feePayerSignature: rest.feePayerSignature }
: {}),
...('feeToken' in rest &&
typeof rest.feeToken !== 'undefined' &&
rest.feeToken !== null &&
!('feeToken' in request)
? { feeToken: rest.feeToken }
: {}),
...(result.capabilities
? { _capabilities: result.capabilities }
: {}),
}
})
.catch((e) => {
const error = e as FillTransactionErrorType
if (error.name !== 'TransactionExecutionError') return request
const executionReverted = error.walk?.((e) => {
const error = e as BaseError
return error.name === 'ExecutionRevertedError'
})
if (executionReverted) throw e
const unsupported = error.walk?.((e) => {
const error = e as BaseError
return (
error.name === 'MethodNotFoundRpcError' ||
error.name === 'MethodNotSupportedRpcError' ||
error.message?.includes('eth_fillTransaction is not available')
)
})
if (unsupported) supportsFillTransaction.set(client.uid, false)
return request
})
: request
nonce ??= fillResult.nonce
request = {
...(fillResult as any),
...(account ? { from: account?.address } : {}),
...(typeof nonce !== 'undefined' ? { nonce } : {}),
}
const { blobs, gas, kzg, type } = request
if (
prepareTransactionRequest?.fn &&
prepareTransactionRequest.runAt?.includes('beforeFillParameters')
) {
request = await prepareTransactionRequest.fn(
{ ...request, chain },
{
phase: 'beforeFillParameters',
},
)
}
let block: Block | undefined
async function getBlock(): Promise<Block> {
if (block) return block
block = await getAction(
client,
getBlock_,
'getBlock',
)({ blockTag: 'latest' })
return block
}
if (
parameters.includes('nonce') &&
typeof nonce === 'undefined' &&
account &&
!nonceManager
)
request.nonce = await getAction(
client,
getTransactionCount,
'getTransactionCount',
)({
address: account.address,
blockTag: 'pending',
})
if (
(parameters.includes('blobVersionedHashes') ||
parameters.includes('sidecars')) &&
blobs &&
kzg
) {
const commitments = blobsToCommitments({ blobs, kzg })
if (parameters.includes('blobVersionedHashes')) {
const versionedHashes = commitmentsToVersionedHashes({
commitments,
to: 'hex',
})
request.blobVersionedHashes = versionedHashes
}
if (parameters.includes('sidecars')) {
const proofs = blobsToProofs({ blobs, commitments, kzg })
const sidecars = toBlobSidecars({
blobs,
commitments,
proofs,
to: 'hex',
})
request.sidecars = sidecars
}
}
if (parameters.includes('chainId')) request.chainId = await getChainId()
if (
(parameters.includes('fees') || parameters.includes('type')) &&
typeof type === 'undefined'
) {
try {
request.type = getTransactionType(
request as TransactionSerializable,
) as any
} catch {
let isEip1559Network = eip1559NetworkCache.get(client.uid)
if (typeof isEip1559Network === 'undefined') {
const block = await getBlock()
isEip1559Network = typeof block?.baseFeePerGas === 'bigint'
eip1559NetworkCache.set(client.uid, isEip1559Network)
}
request.type = isEip1559Network ? 'eip1559' : 'legacy'
}
}
if (parameters.includes('fees')) {
// TODO(4844): derive blob base fees once https://github.com/ethereum/execution-apis/pull/486 is merged.
if (request.type !== 'legacy' && request.type !== 'eip2930') {
// EIP-1559 fees
if (
typeof request.maxFeePerGas === 'undefined' ||
typeof request.maxPriorityFeePerGas === 'undefined'
) {
const block = await getBlock()
const { maxFeePerGas, maxPriorityFeePerGas } =
await internal_estimateFeesPerGas(client, {
block: block as Block,
chain,
request: request as PrepareTransactionRequestParameters,
})
if (
typeof request.maxPriorityFeePerGas === 'undefined' &&
request.maxFeePerGas &&
request.maxFeePerGas < maxPriorityFeePerGas
)
throw new MaxFeePerGasTooLowError({
maxPriorityFeePerGas,
})
request.maxPriorityFeePerGas = maxPriorityFeePerGas
request.maxFeePerGas = maxFeePerGas
}
} else {
// Legacy fees
if (
typeof request.maxFeePerGas !== 'undefined' ||
typeof request.maxPriorityFeePerGas !== 'undefined'
)
throw new Eip1559FeesNotSupportedError()
if (typeof request.gasPrice === 'undefined') {
const block = await getBlock()
const { gasPrice: gasPrice_ } = await internal_estimateFeesPerGas(
client,
{
block: block as Block,
chain,
request: request as PrepareTransactionRequestParameters,
type: 'legacy',
},
)
request.gasPrice = gasPrice_
}
}
}
if (parameters.includes('gas') && typeof gas === 'undefined')
request.gas = await getAction(
client,
estimateGas,
'estimateGas',
)({
...request,
account,
prepare: account?.type === 'local' ? [] : ['blobVersionedHashes'],
} as EstimateGasParameters)
if (
prepareTransactionRequest?.fn &&
prepareTransactionRequest.runAt?.includes('afterFillParameters')
)
request = await prepareTransactionRequest.fn(
{ ...request, chain },
{
phase: 'afterFillParameters',
},
)
assertRequest(request as AssertRequestParameters)
delete request.parameters
return request as any
}

50
node_modules/viem/actions/wallet/requestAddresses.ts generated vendored Normal file
View File

@@ -0,0 +1,50 @@
import type { Address } from 'abitype'
import type { Account } from '../../accounts/types.js'
import type { Client } from '../../clients/createClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { ErrorType } from '../../errors/utils.js'
import type { Chain } from '../../types/chain.js'
import { getAddress } from '../../utils/address/getAddress.js'
import type { RequestErrorType } from '../../utils/buildRequest.js'
export type RequestAddressesReturnType = Address[]
export type RequestAddressesErrorType = RequestErrorType | ErrorType
/**
* Requests a list of accounts managed by a wallet.
*
* - Docs: https://viem.sh/docs/actions/wallet/requestAddresses
* - JSON-RPC Methods: [`eth_requestAccounts`](https://eips.ethereum.org/EIPS/eip-1102)
*
* Sends a request to the wallet, asking for permission to access the user's accounts. After the user accepts the request, it will return a list of accounts (addresses).
*
* This API can be useful for dapps that need to access the user's accounts in order to execute transactions or interact with smart contracts.
*
* @param client - Client to use
* @returns List of accounts managed by a wallet {@link RequestAddressesReturnType}
*
* @example
* import { createWalletClient, custom } from 'viem'
* import { mainnet } from 'viem/chains'
* import { requestAddresses } from 'viem/wallet'
*
* const client = createWalletClient({
* chain: mainnet,
* transport: custom(window.ethereum),
* })
* const accounts = await requestAddresses(client)
*/
export async function requestAddresses<
chain extends Chain | undefined,
account extends Account | undefined = undefined,
>(
client: Client<Transport, chain, account>,
): Promise<RequestAddressesReturnType> {
const addresses = await client.request(
{ method: 'eth_requestAccounts' },
{ dedupe: true, retryCount: 0 },
)
return addresses.map((address) => getAddress(address))
}

58
node_modules/viem/actions/wallet/requestPermissions.ts generated vendored Normal file
View File

@@ -0,0 +1,58 @@
import type { Account } from '../../accounts/types.js'
import type { Client } from '../../clients/createClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { ErrorType } from '../../errors/utils.js'
import type { Chain } from '../../types/chain.js'
import type { WalletPermission } from '../../types/eip1193.js'
import type { Prettify } from '../../types/utils.js'
import type { RequestErrorType } from '../../utils/buildRequest.js'
export type RequestPermissionsParameters = Prettify<
{
eth_accounts: Record<string, any>
} & {
[key: string]: Record<string, any>
}
>
export type RequestPermissionsReturnType = WalletPermission[]
export type RequestPermissionsErrorType = RequestErrorType | ErrorType
/**
* Requests permissions for a wallet.
*
* - Docs: https://viem.sh/docs/actions/wallet/requestPermissions
* - JSON-RPC Methods: [`wallet_requestPermissions`](https://eips.ethereum.org/EIPS/eip-2255)
*
* @param client - Client to use
* @param parameters - {@link RequestPermissionsParameters}
* @returns The wallet permissions. {@link RequestPermissionsReturnType}
*
* @example
* import { createWalletClient, custom } from 'viem'
* import { mainnet } from 'viem/chains'
* import { requestPermissions } from 'viem/wallet'
*
* const client = createWalletClient({
* chain: mainnet,
* transport: custom(window.ethereum),
* })
* const permissions = await requestPermissions(client, {
* eth_accounts: {}
* })
*/
export async function requestPermissions<
chain extends Chain | undefined,
account extends Account | undefined = undefined,
>(
client: Client<Transport, chain, account>,
permissions: RequestPermissionsParameters,
) {
return client.request(
{
method: 'wallet_requestPermissions',
params: [permissions],
},
{ retryCount: 0 },
)
}

264
node_modules/viem/actions/wallet/sendCalls.ts generated vendored Normal file
View File

@@ -0,0 +1,264 @@
import type { Address, Narrow } from 'abitype'
import { parseAccount } from '../../accounts/utils/parseAccount.js'
import type { Client } from '../../clients/createClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import { BaseError } from '../../errors/base.js'
import {
AtomicityNotSupportedError,
UnsupportedNonOptionalCapabilityError,
} from '../../errors/rpc.js'
import type { ErrorType } from '../../errors/utils.js'
import type { Account, GetAccountParameter } from '../../types/account.js'
import type { Call, Calls } from '../../types/calls.js'
import type { ExtractCapabilities } from '../../types/capabilities.js'
import type { Chain, DeriveChain } from '../../types/chain.js'
import type { WalletSendCallsParameters } from '../../types/eip1193.js'
import type { Hex } from '../../types/misc.js'
import type { Prettify } from '../../types/utils.js'
import { encodeFunctionData } from '../../utils/abi/encodeFunctionData.js'
import type { RequestErrorType } from '../../utils/buildRequest.js'
import { concat } from '../../utils/data/concat.js'
import { hexToBigInt } from '../../utils/encoding/fromHex.js'
import { numberToHex } from '../../utils/encoding/toHex.js'
import { getTransactionError } from '../../utils/errors/getTransactionError.js'
import { sendTransaction } from './sendTransaction.js'
export const fallbackMagicIdentifier =
'0x5792579257925792579257925792579257925792579257925792579257925792'
export const fallbackTransactionErrorMagicIdentifier = numberToHex(0, {
size: 32,
})
export type SendCallsParameters<
chain extends Chain | undefined = Chain | undefined,
account extends Account | undefined = Account | undefined,
chainOverride extends Chain | undefined = Chain | undefined,
calls extends readonly unknown[] = readonly unknown[],
//
_chain extends Chain | undefined = DeriveChain<chain, chainOverride>,
> = {
chain?: chainOverride | Chain | undefined
calls: Calls<Narrow<calls>>
capabilities?: ExtractCapabilities<'sendCalls', 'Request'> | undefined
experimental_fallback?: boolean | undefined
experimental_fallbackDelay?: number | undefined
forceAtomic?: boolean | undefined
id?: string | undefined
version?: WalletSendCallsParameters[number]['version'] | undefined
} & GetAccountParameter<account, Account | Address, false, true>
export type SendCallsReturnType = Prettify<{
capabilities?: ExtractCapabilities<'sendCalls', 'ReturnType'> | undefined
id: string
}>
export type SendCallsErrorType = RequestErrorType | ErrorType
/**
* Requests the connected wallet to send a batch of calls.
*
* - Docs: https://viem.sh/docs/actions/wallet/sendCalls
* - JSON-RPC Methods: [`wallet_sendCalls`](https://eips.ethereum.org/EIPS/eip-5792)
*
* @param client - Client to use
* @returns Transaction identifier. {@link SendCallsReturnType}
*
* @example
* import { createWalletClient, custom } from 'viem'
* import { mainnet } from 'viem/chains'
* import { sendCalls } from 'viem/actions'
*
* const client = createWalletClient({
* chain: mainnet,
* transport: custom(window.ethereum),
* })
* const id = await sendCalls(client, {
* account: '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e',
* calls: [
* {
* data: '0xdeadbeef',
* to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
* },
* {
* to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
* value: 69420n,
* },
* ],
* })
*/
export async function sendCalls<
const calls extends readonly unknown[],
chain extends Chain | undefined,
account extends Account | undefined = undefined,
chainOverride extends Chain | undefined = undefined,
>(
client: Client<Transport, chain, account>,
parameters: SendCallsParameters<chain, account, chainOverride, calls>,
): Promise<SendCallsReturnType> {
const {
account: account_ = client.account,
chain = client.chain,
experimental_fallback,
experimental_fallbackDelay = 32,
forceAtomic = false,
id,
version = '2.0.0',
} = parameters
const account = account_ ? parseAccount(account_) : null
let capabilities = parameters.capabilities
if (client.dataSuffix && !parameters.capabilities?.dataSuffix) {
if (typeof client.dataSuffix === 'string')
capabilities = {
...parameters.capabilities,
dataSuffix: { value: client.dataSuffix, optional: true },
}
else
capabilities = {
...parameters.capabilities,
dataSuffix: {
value: client.dataSuffix.value,
...(client.dataSuffix.required ? {} : { optional: true }),
},
}
}
const calls = parameters.calls.map((call_: unknown) => {
const call = call_ as Call
const data = call.abi
? encodeFunctionData({
abi: call.abi,
functionName: call.functionName,
args: call.args,
})
: call.data
return {
data: call.dataSuffix && data ? concat([data, call.dataSuffix]) : data,
to: call.to,
value: call.value ? numberToHex(call.value) : undefined,
}
})
try {
const response = await client.request(
{
method: 'wallet_sendCalls',
params: [
{
atomicRequired: forceAtomic,
calls,
capabilities,
chainId: numberToHex(chain!.id),
from: account?.address,
id,
version,
},
],
},
{ retryCount: 0 },
)
if (typeof response === 'string') return { id: response }
return response as never
} catch (err) {
const error = err as BaseError
// If the transport does not support EIP-5792, fall back to
// `eth_sendTransaction`.
if (
experimental_fallback &&
(error.name === 'MethodNotFoundRpcError' ||
error.name === 'MethodNotSupportedRpcError' ||
error.name === 'UnknownRpcError' ||
error.details
.toLowerCase()
.includes('does not exist / is not available') ||
error.details.toLowerCase().includes('missing or invalid. request()') ||
error.details
.toLowerCase()
.includes('did not match any variant of untagged enum') ||
error.details
.toLowerCase()
.includes('account upgraded to unsupported contract') ||
error.details.toLowerCase().includes('eip-7702 not supported') ||
error.details.toLowerCase().includes('unsupported wc_ method') ||
// magic.link
error.details
.toLowerCase()
.includes('feature toggled misconfigured') ||
// Trust Wallet
error.details
.toLowerCase()
.includes(
'jsonrpcengine: response has no error or result for request',
))
) {
if (capabilities) {
const hasNonOptionalCapability = Object.values(capabilities).some(
(capability) => !capability.optional,
)
if (hasNonOptionalCapability) {
const message =
'non-optional `capabilities` are not supported on fallback to `eth_sendTransaction`.'
throw new UnsupportedNonOptionalCapabilityError(
new BaseError(message, {
details: message,
}),
)
}
}
if (forceAtomic && calls.length > 1) {
const message =
'`forceAtomic` is not supported on fallback to `eth_sendTransaction`.'
throw new AtomicityNotSupportedError(
new BaseError(message, {
details: message,
}),
)
}
const promises: Promise<Hex>[] = []
for (const call of calls) {
const promise = sendTransaction(client, {
account,
chain,
data: call.data,
to: call.to,
value: call.value ? hexToBigInt(call.value) : undefined,
})
promises.push(promise)
// Note: some browser wallets require a small delay between transactions
// to prevent duplicate JSON-RPC requests.
if (experimental_fallbackDelay > 0)
await new Promise((resolve) =>
setTimeout(resolve, experimental_fallbackDelay),
)
}
const results = await Promise.allSettled(promises)
if (results.every((r) => r.status === 'rejected')) throw results[0].reason
const hashes = results.map((result) => {
if (result.status === 'fulfilled') return result.value
return fallbackTransactionErrorMagicIdentifier
})
return {
id: concat([
...hashes,
numberToHex(chain!.id, { size: 32 }),
fallbackMagicIdentifier,
]),
}
}
throw getTransactionError(err as BaseError, {
...parameters,
account,
chain: parameters.chain!,
})
}
}

90
node_modules/viem/actions/wallet/sendCallsSync.ts generated vendored Normal file
View File

@@ -0,0 +1,90 @@
import type { Client } from '../../clients/createClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { Account } from '../../types/account.js'
import type { Chain } from '../../types/chain.js'
import { getAction } from '../../utils/getAction.js'
import type { GetCallsStatusReturnType } from './getCallsStatus.js'
import {
type SendCallsErrorType,
type SendCallsParameters,
sendCalls,
} from './sendCalls.js'
import {
type WaitForCallsStatusParameters,
waitForCallsStatus,
} from './waitForCallsStatus.js'
export type SendCallsSyncParameters<
chain extends Chain | undefined = Chain | undefined,
account extends Account | undefined = Account | undefined,
chainOverride extends Chain | undefined = Chain | undefined,
calls extends readonly unknown[] = readonly unknown[],
> = SendCallsParameters<chain, account, chainOverride, calls> &
Pick<
WaitForCallsStatusParameters,
'pollingInterval' | 'status' | 'throwOnFailure'
> & {
/** Timeout (ms) to wait for calls to be included in a block. @default chain.blockTime * 3 */
timeout?: number | undefined
}
export type SendCallsSyncReturnType = GetCallsStatusReturnType
export type SendCallsSyncErrorType = SendCallsErrorType
/**
* Requests the connected wallet to send a batch of calls, and waits for the calls to be included in a block.
*
* - Docs: https://viem.sh/docs/actions/wallet/sendCallsSync
* - JSON-RPC Methods: [`wallet_sendCalls`](https://eips.ethereum.org/EIPS/eip-5792)
*
* @param client - Client to use
* @returns Calls status. {@link SendCallsSyncReturnType}
*
* @example
* import { createWalletClient, custom } from 'viem'
* import { mainnet } from 'viem/chains'
* import { sendCalls } from 'viem/actions'
*
* const client = createWalletClient({
* chain: mainnet,
* transport: custom(window.ethereum),
* })
* const status = await sendCallsSync(client, {
* account: '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e',
* calls: [
* {
* data: '0xdeadbeef',
* to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
* },
* {
* to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
* value: 69420n,
* },
* ],
* })
*/
export async function sendCallsSync<
const calls extends readonly unknown[],
chain extends Chain | undefined,
account extends Account | undefined = undefined,
chainOverride extends Chain | undefined = undefined,
>(
client: Client<Transport, chain, account>,
parameters: SendCallsSyncParameters<chain, account, chainOverride, calls>,
): Promise<SendCallsSyncReturnType> {
const { chain = client.chain } = parameters
const timeout =
parameters.timeout ?? Math.max((chain?.blockTime ?? 0) * 3, 5_000)
const result = await getAction(client, sendCalls, 'sendCalls')(parameters)
const status = await getAction(
client,
waitForCallsStatus,
'waitForCallsStatus',
)({
...parameters,
id: result.id,
timeout,
})
return status
}

53
node_modules/viem/actions/wallet/sendRawTransaction.ts generated vendored Normal file
View File

@@ -0,0 +1,53 @@
import type { Client } from '../../clients/createClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { ErrorType } from '../../errors/utils.js'
import type { Chain } from '../../types/chain.js'
import type { Hash } from '../../types/misc.js'
import type { TransactionSerializedGeneric } from '../../types/transaction.js'
import type { RequestErrorType } from '../../utils/buildRequest.js'
export type SendRawTransactionParameters = {
/** The signed serialized transaction. */
serializedTransaction: TransactionSerializedGeneric
}
export type SendRawTransactionReturnType = Hash
export type SendRawTransactionErrorType = RequestErrorType | ErrorType
/**
* Sends a **signed** transaction to the network
*
* - Docs: https://viem.sh/docs/actions/wallet/sendRawTransaction
* - JSON-RPC Method: [`eth_sendRawTransaction`](https://ethereum.github.io/execution-apis/api-documentation/)
*
* @param client - Client to use
* @param parameters - {@link SendRawTransactionParameters}
* @returns The transaction hash. {@link SendRawTransactionReturnType}
*
* @example
* import { createWalletClient, custom } from 'viem'
* import { mainnet } from 'viem/chains'
* import { sendRawTransaction } from 'viem/wallet'
*
* const client = createWalletClient({
* chain: mainnet,
* transport: custom(window.ethereum),
* })
*
* const hash = await sendRawTransaction(client, {
* serializedTransaction: '0x02f850018203118080825208808080c080a04012522854168b27e5dc3d5839bab5e6b39e1a0ffd343901ce1622e3d64b48f1a04e00902ae0502c4728cbf12156290df99c3ed7de85b1dbfe20b5c36931733a33'
* })
*/
export async function sendRawTransaction<chain extends Chain | undefined>(
client: Client<Transport, chain>,
{ serializedTransaction }: SendRawTransactionParameters,
): Promise<SendRawTransactionReturnType> {
return client.request(
{
method: 'eth_sendRawTransaction',
params: [serializedTransaction],
},
{ retryCount: 0 },
)
}

View File

@@ -0,0 +1,76 @@
import type { Client } from '../../clients/createClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import { TransactionReceiptRevertedError } from '../../errors/transaction.js'
import type { ErrorType } from '../../errors/utils.js'
import type { Chain } from '../../types/chain.js'
import type { TransactionSerializedGeneric } from '../../types/transaction.js'
import type { RequestErrorType } from '../../utils/buildRequest.js'
import { formatTransactionReceipt } from '../../utils/formatters/transactionReceipt.js'
import type { FormattedTransactionReceipt } from '../../utils/index.js'
export type SendRawTransactionSyncParameters = {
/** The signed serialized transaction. */
serializedTransaction: TransactionSerializedGeneric
/** Whether to throw an error if the transaction was detected as reverted. @default true */
throwOnReceiptRevert?: boolean | undefined
/** The timeout for the transaction. */
timeout?: number | undefined
}
export type SendRawTransactionSyncReturnType<
chain extends Chain | undefined = undefined,
> = FormattedTransactionReceipt<chain>
export type SendRawTransactionSyncErrorType = RequestErrorType | ErrorType
/**
* Sends a **signed** transaction to the network synchronously,
* and waits for the transaction to be included in a block.
*
* - Docs: https://viem.sh/docs/actions/wallet/sendRawTransactionSync
* - JSON-RPC Method: [`eth_sendRawTransactionSync`](https://eips.ethereum.org/EIPS/eip-7966)
*
* @param client - Client to use
* @param parameters - {@link SendRawTransactionParameters}
* @returns The transaction receipt. {@link SendRawTransactionSyncReturnType}
*
* @example
* import { createWalletClient, custom } from 'viem'
* import { mainnet } from 'viem/chains'
* import { sendRawTransactionSync } from 'viem/wallet'
*
* const client = createWalletClient({
* chain: mainnet,
* transport: custom(window.ethereum),
* })
*
* const receipt = await sendRawTransactionSync(client, {
* serializedTransaction: '0x02f850018203118080825208808080c080a04012522854168b27e5dc3d5839bab5e6b39e1a0ffd343901ce1622e3d64b48f1a04e00902ae0502c4728cbf12156290df99c3ed7de85b1dbfe20b5c36931733a33'
* })
*/
export async function sendRawTransactionSync<chain extends Chain | undefined>(
client: Client<Transport, chain>,
{
serializedTransaction,
throwOnReceiptRevert,
timeout,
}: SendRawTransactionSyncParameters,
): Promise<SendRawTransactionSyncReturnType<chain>> {
const receipt = await client.request(
{
method: 'eth_sendRawTransactionSync',
params: timeout
? [serializedTransaction, timeout]
: [serializedTransaction],
},
{ retryCount: 0 },
)
const format =
client.chain?.formatters?.transactionReceipt?.format ||
formatTransactionReceipt
const formatted = format(receipt) as SendRawTransactionSyncReturnType<chain>
if (formatted.status === 'reverted' && throwOnReceiptRevert)
throw new TransactionReceiptRevertedError({ receipt: formatted })
return formatted
}

Some files were not shown because too many files have changed in this diff Show More