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

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
}

375
node_modules/viem/actions/wallet/sendTransaction.ts generated vendored Normal file
View File

@@ -0,0 +1,375 @@
import type { Address } from 'abitype'
import type { Account } from '../../accounts/types.js'
import {
type ParseAccountErrorType,
parseAccount,
} from '../../accounts/utils/parseAccount.js'
import type { SignTransactionErrorType } from '../../accounts/utils/signTransaction.js'
import type { Client } from '../../clients/createClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import {
AccountNotFoundError,
type AccountNotFoundErrorType,
AccountTypeNotSupportedError,
type AccountTypeNotSupportedErrorType,
} from '../../errors/account.js'
import { BaseError } from '../../errors/base.js'
import type { ErrorType } from '../../errors/utils.js'
import type { GetAccountParameter } from '../../types/account.js'
import type {
Chain,
DeriveChain,
GetChainParameter,
} from '../../types/chain.js'
import type { GetTransactionRequestKzgParameter } from '../../types/kzg.js'
import type { Hash, Hex } from '../../types/misc.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 AssertCurrentChainErrorType,
assertCurrentChain,
} from '../../utils/chain/assertCurrentChain.js'
import { concat } from '../../utils/data/concat.js'
import {
type GetTransactionErrorReturnType,
getTransactionError,
} from '../../utils/errors/getTransactionError.js'
import { extract } from '../../utils/formatters/extract.js'
import {
type FormattedTransactionRequest,
formatTransactionRequest,
} from '../../utils/formatters/transactionRequest.js'
import { getAction } from '../../utils/getAction.js'
import { LruMap } from '../../utils/lru.js'
import {
type AssertRequestErrorType,
type AssertRequestParameters,
assertRequest,
} from '../../utils/transaction/assertRequest.js'
import { type GetChainIdErrorType, getChainId } from '../public/getChainId.js'
import {
defaultParameters,
type PrepareTransactionRequestErrorType,
prepareTransactionRequest,
} from './prepareTransactionRequest.js'
import {
type SendRawTransactionErrorType,
sendRawTransaction,
} from './sendRawTransaction.js'
const supportsWalletNamespace = new LruMap<boolean>(128)
export type SendTransactionRequest<
chain extends Chain | undefined = Chain | undefined,
chainOverride extends Chain | undefined = Chain | undefined,
///
_derivedChain extends Chain | undefined = DeriveChain<chain, chainOverride>,
> = UnionOmit<FormattedTransactionRequest<_derivedChain>, 'from'> &
GetTransactionRequestKzgParameter
export type SendTransactionParameters<
chain extends Chain | undefined = Chain | undefined,
account extends Account | undefined = Account | undefined,
chainOverride extends Chain | undefined = Chain | undefined,
request extends SendTransactionRequest<
chain,
chainOverride
> = SendTransactionRequest<chain, chainOverride>,
> = request &
GetAccountParameter<account, Account | Address, true, true> &
GetChainParameter<chain, chainOverride> &
GetTransactionRequestKzgParameter<request> & {
/** Whether to assert that the client chain is on the correct chain. @default true */
assertChainId?: boolean | undefined
/** Data to append to the end of the calldata. Takes precedence over `client.dataSuffix`. */
dataSuffix?: Hex | undefined
}
export type SendTransactionReturnType = Hash
export type SendTransactionErrorType =
| ParseAccountErrorType
| GetTransactionErrorReturnType<
| AccountNotFoundErrorType
| AccountTypeNotSupportedErrorType
| AssertCurrentChainErrorType
| AssertRequestErrorType
| GetChainIdErrorType
| PrepareTransactionRequestErrorType
| SendRawTransactionErrorType
| RecoverAuthorizationAddressErrorType
| SignTransactionErrorType
| RequestErrorType
>
| ErrorType
/**
* Creates, signs, and sends a new transaction to the network.
*
* - Docs: https://viem.sh/docs/actions/wallet/sendTransaction
* - Examples: https://stackblitz.com/github/wevm/viem/tree/main/examples/transactions_sending-transactions
* - JSON-RPC Methods:
* - JSON-RPC Accounts: [`eth_sendTransaction`](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_sendtransaction)
* - Local Accounts: [`eth_sendRawTransaction`](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_sendrawtransaction)
*
* @param client - Client to use
* @param parameters - {@link SendTransactionParameters}
* @returns The [Transaction](https://viem.sh/docs/glossary/terms#transaction) hash. {@link SendTransactionReturnType}
*
* @example
* import { createWalletClient, custom } from 'viem'
* import { mainnet } from 'viem/chains'
* import { sendTransaction } from 'viem/wallet'
*
* const client = createWalletClient({
* chain: mainnet,
* transport: custom(window.ethereum),
* })
* const hash = await sendTransaction(client, {
* account: '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e',
* to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
* value: 1000000000000000000n,
* })
*
* @example
* // Account Hoisting
* import { createWalletClient, http } from 'viem'
* import { privateKeyToAccount } from 'viem/accounts'
* import { mainnet } from 'viem/chains'
* import { sendTransaction } from 'viem/wallet'
*
* const client = createWalletClient({
* account: privateKeyToAccount('0x…'),
* chain: mainnet,
* transport: http(),
* })
* const hash = await sendTransaction(client, {
* to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
* value: 1000000000000000000n,
* })
*/
export async function sendTransaction<
chain extends Chain | undefined,
account extends Account | undefined,
const request extends SendTransactionRequest<chain, chainOverride>,
chainOverride extends Chain | undefined = undefined,
>(
client: Client<Transport, chain, account>,
parameters: SendTransactionParameters<chain, account, chainOverride, request>,
): Promise<SendTransactionReturnType> {
const {
account: account_ = client.account,
assertChainId = true,
chain = client.chain,
accessList,
authorizationList,
blobs,
data,
dataSuffix = typeof client.dataSuffix === 'string'
? client.dataSuffix
: client.dataSuffix?.value,
gas,
gasPrice,
maxFeePerBlobGas,
maxFeePerGas,
maxPriorityFeePerGas,
nonce,
type,
value,
...rest
} = parameters
if (typeof account_ === 'undefined')
throw new AccountNotFoundError({
docsPath: '/docs/actions/wallet/sendTransaction',
})
const account = account_ ? parseAccount(account_) : null
try {
assertRequest(parameters as AssertRequestParameters)
const to = await (async () => {
// If `to` exists on the parameters, use that.
if (parameters.to) return parameters.to
// If `to` is null, we are sending a deployment transaction.
if (parameters.to === null) return undefined
// If no `to` exists, and we are sending a EIP-7702 transaction, use the
// address of the first authorization in the list.
if (authorizationList && authorizationList.length > 0)
return await recoverAuthorizationAddress({
authorization: authorizationList[0],
}).catch(() => {
throw new BaseError(
'`to` is required. Could not infer from `authorizationList`.',
)
})
// Otherwise, we are sending a deployment transaction.
return undefined
})()
if (account?.type === 'json-rpc' || account === null) {
let chainId: number | undefined
if (chain !== null) {
chainId = await getAction(client, getChainId, 'getChainId')({})
if (assertChainId)
assertCurrentChain({
currentChainId: chainId,
chain,
})
}
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,
chainId,
data: dataSuffix ? concat([data ?? '0x', dataSuffix]) : data,
gas,
gasPrice,
maxFeePerBlobGas,
maxFeePerGas,
maxPriorityFeePerGas,
nonce,
to,
type,
value,
} as TransactionRequest,
'sendTransaction',
)
const isWalletNamespaceSupported = supportsWalletNamespace.get(client.uid)
const method = isWalletNamespaceSupported
? 'wallet_sendTransaction'
: 'eth_sendTransaction'
try {
return await client.request(
{
method,
params: [request],
},
{ retryCount: 0 },
)
} catch (e) {
if (isWalletNamespaceSupported === false) throw e
const error = e as BaseError
// If the transport does not support the method or input, attempt to use the
// `wallet_sendTransaction` method.
if (
error.name === 'InvalidInputRpcError' ||
error.name === 'InvalidParamsRpcError' ||
error.name === 'MethodNotFoundRpcError' ||
error.name === 'MethodNotSupportedRpcError'
) {
return await client
.request(
{
method: 'wallet_sendTransaction',
params: [request],
},
{ retryCount: 0 },
)
.then((hash) => {
supportsWalletNamespace.set(client.uid, true)
return hash
})
.catch((e) => {
const walletNamespaceError = e as BaseError
if (
walletNamespaceError.name === 'MethodNotFoundRpcError' ||
walletNamespaceError.name === 'MethodNotSupportedRpcError'
) {
supportsWalletNamespace.set(client.uid, false)
throw error
}
throw walletNamespaceError
})
}
throw error
}
}
if (account?.type === 'local') {
// Prepare the request for signing (assign appropriate fees, etc.)
const request = await getAction(
client,
prepareTransactionRequest,
'prepareTransactionRequest',
)({
account,
accessList,
authorizationList,
blobs,
chain,
data: dataSuffix ? concat([data ?? '0x', dataSuffix]) : data,
gas,
gasPrice,
maxFeePerBlobGas,
maxFeePerGas,
maxPriorityFeePerGas,
nonce,
nonceManager: account.nonceManager,
parameters: [...defaultParameters, 'sidecars'],
type,
value,
...rest,
to,
} as any)
const serializer = chain?.serializers?.transaction
const serializedTransaction = (await account.signTransaction(
request as never,
{
serializer,
},
)) as Hash
return await getAction(
client,
sendRawTransaction,
'sendRawTransaction',
)({
serializedTransaction,
})
}
if (account?.type === 'smart')
throw new AccountTypeNotSupportedError({
metaMessages: [
'Consider using the `sendUserOperation` Action instead.',
],
docsPath: '/docs/actions/bundler/sendUserOperation',
type: 'smart',
})
throw new AccountTypeNotSupportedError({
docsPath: '/docs/actions/wallet/sendTransaction',
type: (account as any)?.type,
})
} catch (err) {
if (err instanceof AccountTypeNotSupportedError) throw err
throw getTransactionError(err as BaseError, {
...parameters,
account,
chain: parameters.chain || undefined,
})
}
}

416
node_modules/viem/actions/wallet/sendTransactionSync.ts generated vendored Normal file
View File

@@ -0,0 +1,416 @@
import type { Address } from 'abitype'
import type { Account } from '../../accounts/types.js'
import {
type ParseAccountErrorType,
parseAccount,
} from '../../accounts/utils/parseAccount.js'
import type { SignTransactionErrorType } from '../../accounts/utils/signTransaction.js'
import type { Client } from '../../clients/createClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import {
AccountNotFoundError,
type AccountNotFoundErrorType,
AccountTypeNotSupportedError,
type AccountTypeNotSupportedErrorType,
} from '../../errors/account.js'
import { BaseError } from '../../errors/base.js'
import {
TransactionReceiptRevertedError,
type TransactionReceiptRevertedErrorType,
} from '../../errors/transaction.js'
import type { ErrorType } from '../../errors/utils.js'
import type { GetAccountParameter } from '../../types/account.js'
import type {
Chain,
DeriveChain,
GetChainParameter,
} from '../../types/chain.js'
import type { GetTransactionRequestKzgParameter } from '../../types/kzg.js'
import type { Hash, Hex } from '../../types/misc.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 AssertCurrentChainErrorType,
assertCurrentChain,
} from '../../utils/chain/assertCurrentChain.js'
import { concat } from '../../utils/data/concat.js'
import {
type GetTransactionErrorReturnType,
getTransactionError,
} from '../../utils/errors/getTransactionError.js'
import { extract } from '../../utils/formatters/extract.js'
import {
type FormattedTransactionRequest,
formatTransactionRequest,
} from '../../utils/formatters/transactionRequest.js'
import { getAction } from '../../utils/getAction.js'
import { LruMap } from '../../utils/lru.js'
import {
type AssertRequestErrorType,
type AssertRequestParameters,
assertRequest,
} from '../../utils/transaction/assertRequest.js'
import { type GetChainIdErrorType, getChainId } from '../public/getChainId.js'
import {
type WaitForTransactionReceiptErrorType,
waitForTransactionReceipt,
} from '../public/waitForTransactionReceipt.js'
import {
defaultParameters,
type PrepareTransactionRequestErrorType,
prepareTransactionRequest,
} from './prepareTransactionRequest.js'
import {
type SendRawTransactionSyncErrorType,
type SendRawTransactionSyncReturnType,
sendRawTransactionSync,
} from './sendRawTransactionSync.js'
const supportsWalletNamespace = new LruMap<boolean>(128)
export type SendTransactionSyncRequest<
chain extends Chain | undefined = Chain | undefined,
chainOverride extends Chain | undefined = Chain | undefined,
///
_derivedChain extends Chain | undefined = DeriveChain<chain, chainOverride>,
> = UnionOmit<FormattedTransactionRequest<_derivedChain>, 'from'> &
GetTransactionRequestKzgParameter
export type SendTransactionSyncParameters<
chain extends Chain | undefined = Chain | undefined,
account extends Account | undefined = Account | undefined,
chainOverride extends Chain | undefined = Chain | undefined,
request extends SendTransactionSyncRequest<
chain,
chainOverride
> = SendTransactionSyncRequest<chain, chainOverride>,
> = request &
GetAccountParameter<account, Account | Address, true, true> &
GetChainParameter<chain, chainOverride> &
GetTransactionRequestKzgParameter<request> & {
/** Whether to assert that the client chain is on the correct chain. @default true */
assertChainId?: boolean | undefined
/** Data to append to the end of the calldata. Takes precedence over `client.dataSuffix`. */
dataSuffix?: Hex | undefined
/** Polling interval (ms) to poll for the transaction receipt. @default client.pollingInterval */
pollingInterval?: number | undefined
/** Whether to throw an error if the transaction was detected as reverted. @default true */
throwOnReceiptRevert?: boolean | undefined
/** Timeout (ms) to wait for a response. @default Math.max(chain.blockTime * 3, 5_000) */
timeout?: number | undefined
}
export type SendTransactionSyncReturnType<
chain extends Chain | undefined = Chain | undefined,
> = SendRawTransactionSyncReturnType<chain>
export type SendTransactionSyncErrorType =
| ParseAccountErrorType
| GetTransactionErrorReturnType<
| AccountNotFoundErrorType
| AccountTypeNotSupportedErrorType
| AssertCurrentChainErrorType
| AssertRequestErrorType
| GetChainIdErrorType
| PrepareTransactionRequestErrorType
| SendRawTransactionSyncErrorType
| RecoverAuthorizationAddressErrorType
| SignTransactionErrorType
| TransactionReceiptRevertedErrorType
| RequestErrorType
>
| WaitForTransactionReceiptErrorType
| ErrorType
/**
* Creates, signs, and sends a new transaction to the network synchronously.
* Returns the transaction receipt.
*
* @param client - Client to use
* @param parameters - {@link SendTransactionSyncParameters}
* @returns The transaction receipt. {@link SendTransactionSyncReturnType}
*
* @example
* import { createWalletClient, custom } from 'viem'
* import { mainnet } from 'viem/chains'
* import { sendTransactionSync } from 'viem/wallet'
*
* const client = createWalletClient({
* chain: mainnet,
* transport: custom(window.ethereum),
* })
* const receipt = await sendTransactionSync(client, {
* account: '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e',
* to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
* value: 1000000000000000000n,
* })
*
* @example
* // Account Hoisting
* import { createWalletClient, http } from 'viem'
* import { privateKeyToAccount } from 'viem/accounts'
* import { mainnet } from 'viem/chains'
* import { sendTransactionSync } from 'viem/wallet'
*
* const client = createWalletClient({
* account: privateKeyToAccount('0x…'),
* chain: mainnet,
* transport: http(),
* })
* const receipt = await sendTransactionSync(client, {
* to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
* value: 1000000000000000000n,
* })
*/
export async function sendTransactionSync<
chain extends Chain | undefined,
account extends Account | undefined,
const request extends SendTransactionSyncRequest<chain, chainOverride>,
chainOverride extends Chain | undefined = undefined,
>(
client: Client<Transport, chain, account>,
parameters: SendTransactionSyncParameters<
chain,
account,
chainOverride,
request
>,
): Promise<SendTransactionSyncReturnType<chain>> {
const {
account: account_ = client.account,
assertChainId = true,
chain = client.chain,
accessList,
authorizationList,
blobs,
data,
dataSuffix = typeof client.dataSuffix === 'string'
? client.dataSuffix
: client.dataSuffix?.value,
gas,
gasPrice,
maxFeePerBlobGas,
maxFeePerGas,
maxPriorityFeePerGas,
nonce,
pollingInterval,
throwOnReceiptRevert,
type,
value,
...rest
} = parameters
const timeout =
parameters.timeout ?? Math.max((chain?.blockTime ?? 0) * 3, 5_000)
if (typeof account_ === 'undefined')
throw new AccountNotFoundError({
docsPath: '/docs/actions/wallet/sendTransactionSync',
})
const account = account_ ? parseAccount(account_) : null
try {
assertRequest(parameters as AssertRequestParameters)
const to = await (async () => {
// If `to` exists on the parameters, use that.
if (parameters.to) return parameters.to
// If `to` is null, we are sending a deployment transaction.
if (parameters.to === null) return undefined
// If no `to` exists, and we are sending a EIP-7702 transaction, use the
// address of the first authorization in the list.
if (authorizationList && authorizationList.length > 0)
return await recoverAuthorizationAddress({
authorization: authorizationList[0],
}).catch(() => {
throw new BaseError(
'`to` is required. Could not infer from `authorizationList`.',
)
})
// Otherwise, we are sending a deployment transaction.
return undefined
})()
if (account?.type === 'json-rpc' || account === null) {
let chainId: number | undefined
if (chain !== null) {
chainId = await getAction(client, getChainId, 'getChainId')({})
if (assertChainId)
assertCurrentChain({
currentChainId: chainId,
chain,
})
}
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,
chainId,
data: data ? concat([data, dataSuffix ?? '0x']) : data,
gas,
gasPrice,
maxFeePerBlobGas,
maxFeePerGas,
maxPriorityFeePerGas,
nonce,
to,
type,
value,
} as TransactionRequest,
'sendTransaction',
)
const isWalletNamespaceSupported = supportsWalletNamespace.get(client.uid)
const method = isWalletNamespaceSupported
? 'wallet_sendTransaction'
: 'eth_sendTransaction'
const hash = await (async () => {
try {
return await client.request(
{
method,
params: [request],
},
{ retryCount: 0 },
)
} catch (e) {
if (isWalletNamespaceSupported === false) throw e
const error = e as BaseError
// If the transport does not support the method or input, attempt to use the
// `wallet_sendTransaction` method.
if (
error.name === 'InvalidInputRpcError' ||
error.name === 'InvalidParamsRpcError' ||
error.name === 'MethodNotFoundRpcError' ||
error.name === 'MethodNotSupportedRpcError'
) {
return (await client
.request(
{
method: 'wallet_sendTransaction',
params: [request],
},
{ retryCount: 0 },
)
.then((hash) => {
supportsWalletNamespace.set(client.uid, true)
return hash
})
.catch((e) => {
const walletNamespaceError = e as BaseError
if (
walletNamespaceError.name === 'MethodNotFoundRpcError' ||
walletNamespaceError.name === 'MethodNotSupportedRpcError'
) {
supportsWalletNamespace.set(client.uid, false)
throw error
}
throw walletNamespaceError
})) as never
}
throw error
}
})()
const receipt = await getAction(
client,
waitForTransactionReceipt,
'waitForTransactionReceipt',
)({
checkReplacement: false,
hash,
pollingInterval,
timeout,
})
if (throwOnReceiptRevert && receipt.status === 'reverted')
throw new TransactionReceiptRevertedError({ receipt })
return receipt
}
if (account?.type === 'local') {
// Prepare the request for signing (assign appropriate fees, etc.)
const request = await getAction(
client,
prepareTransactionRequest,
'prepareTransactionRequest',
)({
account,
accessList,
authorizationList,
blobs,
chain,
data: data ? concat([data, dataSuffix ?? '0x']) : data,
gas,
gasPrice,
maxFeePerBlobGas,
maxFeePerGas,
maxPriorityFeePerGas,
nonce,
nonceManager: account.nonceManager,
parameters: [...defaultParameters, 'sidecars'],
type,
value,
...rest,
to,
} as any)
const serializer = chain?.serializers?.transaction
const serializedTransaction = (await account.signTransaction(
request as never,
{
serializer,
},
)) as Hash
return (await getAction(
client,
sendRawTransactionSync,
'sendRawTransactionSync',
)({
serializedTransaction,
throwOnReceiptRevert,
timeout: parameters.timeout,
})) as never
}
if (account?.type === 'smart')
throw new AccountTypeNotSupportedError({
metaMessages: [
'Consider using the `sendUserOperation` Action instead.',
],
docsPath: '/docs/actions/bundler/sendUserOperation',
type: 'smart',
})
throw new AccountTypeNotSupportedError({
docsPath: '/docs/actions/wallet/sendTransactionSync',
type: (account as any)?.type,
})
} catch (err) {
if (err instanceof AccountTypeNotSupportedError) throw err
throw getTransactionError(err as BaseError, {
...parameters,
account,
chain: parameters.chain || undefined,
})
}
}

48
node_modules/viem/actions/wallet/showCallsStatus.ts generated vendored Normal file
View File

@@ -0,0 +1,48 @@
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 { Chain } from '../../types/chain.js'
import type { RequestErrorType } from '../../utils/buildRequest.js'
export type ShowCallsStatusParameters = { id: string }
export type ShowCallsStatusReturnType = void
export type ShowCallsStatusErrorType = RequestErrorType | ErrorType
/**
* Requests for the wallet to show information about a call batch
* that was sent via `sendCalls`.
*
* - Docs: https://viem.sh/docs/actions/wallet/showCallsStatus
* - JSON-RPC Methods: [`wallet_showCallsStatus`](https://eips.ethereum.org/EIPS/eip-5792)
*
* @param client - Client to use
* @returns Status of the calls. {@link ShowCallsStatusReturnType}
*
* @example
* import { createWalletClient, custom } from 'viem'
* import { mainnet } from 'viem/chains'
* import { showCallsStatus } from 'viem/actions'
*
* const client = createWalletClient({
* chain: mainnet,
* transport: custom(window.ethereum),
* })
* await showCallsStatus(client, { id: '0xdeadbeef' })
*/
export async function showCallsStatus<
chain extends Chain | undefined,
account extends Account | undefined = undefined,
>(
client: Client<Transport, chain, account>,
parameters: ShowCallsStatusParameters,
): Promise<ShowCallsStatusReturnType> {
const { id } = parameters
await client.request({
method: 'wallet_showCallsStatus',
params: [id],
})
return
}

108
node_modules/viem/actions/wallet/signAuthorization.ts generated vendored Normal file
View File

@@ -0,0 +1,108 @@
import type { Account } from '../../accounts/types.js'
import {
type ParseAccountErrorType,
parseAccount,
} from '../../accounts/utils/parseAccount.js'
import type {
SignAuthorizationErrorType as SignAuthorizationErrorType_account,
SignAuthorizationReturnType as SignAuthorizationReturnType_account,
} from '../../accounts/utils/signAuthorization.js'
import type { Client } from '../../clients/createClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import {
AccountNotFoundError,
type AccountNotFoundErrorType,
AccountTypeNotSupportedError,
type AccountTypeNotSupportedErrorType,
} from '../../errors/account.js'
import type { ErrorType } from '../../errors/utils.js'
import type { Chain } from '../../types/chain.js'
import {
type PrepareAuthorizationErrorType,
type PrepareAuthorizationParameters,
prepareAuthorization,
} from './prepareAuthorization.js'
export type SignAuthorizationParameters<
account extends Account | undefined = Account | undefined,
> = PrepareAuthorizationParameters<account>
export type SignAuthorizationReturnType = SignAuthorizationReturnType_account
export type SignAuthorizationErrorType =
| ParseAccountErrorType
| AccountNotFoundErrorType
| AccountTypeNotSupportedErrorType
| PrepareAuthorizationErrorType
| SignAuthorizationErrorType_account
| ErrorType
/**
* Signs an [EIP-7702 Authorization](https://eips.ethereum.org/EIPS/eip-7702) object.
*
* With the calculated signature, you can:
* - use [`verifyAuthorization`](https://viem.sh/docs/eip7702/verifyAuthorization) to verify the signed Authorization object,
* - use [`recoverAuthorizationAddress`](https://viem.sh/docs/eip7702/recoverAuthorizationAddress) to recover the signing address from the signed Authorization object.
*
* @param client - Client to use
* @param parameters - {@link SignAuthorizationParameters}
* @returns The signed Authorization object. {@link SignAuthorizationReturnType}
*
* @example
* import { createClient, http } from 'viem'
* import { privateKeyToAccount } from 'viem/accounts'
* import { mainnet } from 'viem/chains'
* import { signAuthorization } from 'viem/experimental'
*
* const client = createClient({
* chain: mainnet,
* transport: http(),
* })
* const signature = await signAuthorization(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 { signAuthorization } from 'viem/experimental'
*
* const client = createClient({
* account: privateKeyToAccount('0x…'),
* chain: mainnet,
* transport: http(),
* })
* const signature = await signAuthorization(client, {
* contractAddress: '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e',
* })
*/
export async function signAuthorization<
chain extends Chain | undefined,
account extends Account | undefined,
>(
client: Client<Transport, chain, account>,
parameters: SignAuthorizationParameters<account>,
): Promise<SignAuthorizationReturnType> {
const { account: account_ = client.account } = parameters
if (!account_)
throw new AccountNotFoundError({
docsPath: '/docs/eip7702/signAuthorization',
})
const account = parseAccount(account_)
if (!account.signAuthorization)
throw new AccountTypeNotSupportedError({
docsPath: '/docs/eip7702/signAuthorization',
metaMessages: [
'The `signAuthorization` Action does not support JSON-RPC Accounts.',
],
type: account.type,
})
const authorization = await prepareAuthorization(client, parameters)
return account.signAuthorization(authorization)
}

113
node_modules/viem/actions/wallet/signMessage.ts generated vendored Normal file
View File

@@ -0,0 +1,113 @@
import type { Account } from '../../accounts/types.js'
import {
type ParseAccountErrorType,
parseAccount,
} from '../../accounts/utils/parseAccount.js'
import type { SignMessageErrorType as SignMessageErrorType_account } from '../../accounts/utils/signMessage.js'
import type { Client } from '../../clients/createClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import { AccountNotFoundError } from '../../errors/account.js'
import type { ErrorType } from '../../errors/utils.js'
import type { GetAccountParameter } from '../../types/account.js'
import type { Chain } from '../../types/chain.js'
import type { Hex, SignableMessage } from '../../types/misc.js'
import type { RequestErrorType } from '../../utils/buildRequest.js'
import {
stringToHex,
type ToHexErrorType,
toHex,
} from '../../utils/encoding/toHex.js'
export type SignMessageParameters<
account extends Account | undefined = Account | undefined,
> = GetAccountParameter<account> & {
message: SignableMessage
}
export type SignMessageReturnType = Hex
export type SignMessageErrorType =
| ParseAccountErrorType
| RequestErrorType
| SignMessageErrorType_account
| ToHexErrorType
| ErrorType
/**
* Calculates an Ethereum-specific signature in [EIP-191 format](https://eips.ethereum.org/EIPS/eip-191): `keccak256("\x19Ethereum Signed Message:\n" + len(message) + message))`.
*
* - Docs: https://viem.sh/docs/actions/wallet/signMessage
* - JSON-RPC Methods:
* - JSON-RPC Accounts: [`personal_sign`](https://docs.metamask.io/guide/signing-data#personal-sign)
* - Local Accounts: Signs locally. No JSON-RPC request.
*
* With the calculated signature, you can:
* - use [`verifyMessage`](https://viem.sh/docs/utilities/verifyMessage) to verify the signature,
* - use [`recoverMessageAddress`](https://viem.sh/docs/utilities/recoverMessageAddress) to recover the signing address from a signature.
*
* @param client - Client to use
* @param parameters - {@link SignMessageParameters}
* @returns The signed message. {@link SignMessageReturnType}
*
* @example
* import { createWalletClient, custom } from 'viem'
* import { mainnet } from 'viem/chains'
* import { signMessage } from 'viem/wallet'
*
* const client = createWalletClient({
* chain: mainnet,
* transport: custom(window.ethereum),
* })
* const signature = await signMessage(client, {
* account: '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e',
* message: 'hello world',
* })
*
* @example
* // Account Hoisting
* import { createWalletClient, custom } from 'viem'
* import { privateKeyToAccount } from 'viem/accounts'
* import { mainnet } from 'viem/chains'
* import { signMessage } from 'viem/wallet'
*
* const client = createWalletClient({
* account: privateKeyToAccount('0x…'),
* chain: mainnet,
* transport: custom(window.ethereum),
* })
* const signature = await signMessage(client, {
* message: 'hello world',
* })
*/
export async function signMessage<
chain extends Chain | undefined,
account extends Account | undefined,
>(
client: Client<Transport, chain, account>,
{
account: account_ = client.account,
message,
}: SignMessageParameters<account>,
): Promise<SignMessageReturnType> {
if (!account_)
throw new AccountNotFoundError({
docsPath: '/docs/actions/wallet/signMessage',
})
const account = parseAccount(account_)
if (account.signMessage) return account.signMessage({ message })
const message_ = (() => {
if (typeof message === 'string') return stringToHex(message)
if (message.raw instanceof Uint8Array) return toHex(message.raw)
return message.raw
})()
return client.request(
{
method: 'personal_sign',
params: [message_, account.address],
},
{ retryCount: 0 },
)
}

190
node_modules/viem/actions/wallet/signTransaction.ts generated vendored Normal file
View File

@@ -0,0 +1,190 @@
import type { Account } from '../../accounts/types.js'
import {
type ParseAccountErrorType,
parseAccount,
} from '../../accounts/utils/parseAccount.js'
import type { SignTransactionErrorType as SignTransactionErrorType_account } from '../../accounts/utils/signTransaction.js'
import type { Client } from '../../clients/createClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import { AccountNotFoundError } from '../../errors/account.js'
import type { ErrorType } from '../../errors/utils.js'
import type { GetAccountParameter } from '../../types/account.js'
import type {
Chain,
DeriveChain,
GetChainParameter,
} from '../../types/chain.js'
import type { GetTransactionRequestKzgParameter } from '../../types/kzg.js'
import type { RpcTransactionRequest } from '../../types/rpc.js'
import type {
TransactionRequest,
TransactionSerializable,
TransactionSerialized,
} from '../../types/transaction.js'
import type { UnionOmit } from '../../types/utils.js'
import type { RequestErrorType } from '../../utils/buildRequest.js'
import {
type AssertCurrentChainErrorType,
assertCurrentChain,
} from '../../utils/chain/assertCurrentChain.js'
import type { NumberToHexErrorType } from '../../utils/encoding/toHex.js'
import { numberToHex } from '../../utils/encoding/toHex.js'
import {
type FormattedTransactionRequest,
formatTransactionRequest,
} from '../../utils/formatters/transactionRequest.js'
import { getAction } from '../../utils/getAction.js'
import {
type AssertRequestErrorType,
assertRequest,
} from '../../utils/transaction/assertRequest.js'
import type { GetTransactionType } from '../../utils/transaction/getTransactionType.js'
import { type GetChainIdErrorType, getChainId } from '../public/getChainId.js'
export type SignTransactionRequest<
chain extends Chain | undefined = Chain | undefined,
chainOverride extends Chain | undefined = Chain | undefined,
///
_derivedChain extends Chain | undefined = DeriveChain<chain, chainOverride>,
> = UnionOmit<FormattedTransactionRequest<_derivedChain>, 'from'>
export type SignTransactionParameters<
chain extends Chain | undefined,
account extends Account | undefined,
chainOverride extends Chain | undefined = Chain | undefined,
request extends SignTransactionRequest<
chain,
chainOverride
> = SignTransactionRequest<chain, chainOverride>,
> = request &
GetAccountParameter<account> &
GetChainParameter<chain, chainOverride> &
GetTransactionRequestKzgParameter<request>
export type SignTransactionReturnType<
request extends SignTransactionRequest = SignTransactionRequest,
> = TransactionSerialized<GetTransactionType<request>>
export type SignTransactionErrorType =
| ParseAccountErrorType
| AssertRequestErrorType
| GetChainIdErrorType
| AssertCurrentChainErrorType
| SignTransactionErrorType_account
| NumberToHexErrorType
| RequestErrorType
| ErrorType
/**
* Signs a transaction.
*
* - Docs: https://viem.sh/docs/actions/wallet/signTransaction
* - JSON-RPC Methods:
* - JSON-RPC Accounts: [`eth_signTransaction`](https://ethereum.github.io/execution-apis/api-documentation/)
* - Local Accounts: Signs locally. No JSON-RPC request.
*
* @param args - {@link SignTransactionParameters}
* @returns The signed serialized transaction. {@link SignTransactionReturnType}
*
* @example
* import { createWalletClient, custom } from 'viem'
* import { mainnet } from 'viem/chains'
* import { signTransaction } from 'viem/actions'
*
* const client = createWalletClient({
* chain: mainnet,
* transport: custom(window.ethereum),
* })
* const signature = await signTransaction(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 { signTransaction } from 'viem/actions'
*
* const client = createWalletClient({
* account: privateKeyToAccount('0x…'),
* chain: mainnet,
* transport: custom(window.ethereum),
* })
* const signature = await signTransaction(client, {
* to: '0x0000000000000000000000000000000000000000',
* value: 1n,
* })
*/
export async function signTransaction<
chain extends Chain | undefined,
account extends Account | undefined,
chainOverride extends Chain | undefined = undefined,
const request extends SignTransactionRequest<
chain,
chainOverride
> = SignTransactionRequest<chain, chainOverride>,
>(
client: Client<Transport, chain, account>,
parameters: SignTransactionParameters<chain, account, chainOverride, request>,
): Promise<SignTransactionReturnType<request>> {
const {
account: account_ = client.account,
chain = client.chain,
...transaction
} = parameters
if (!account_)
throw new AccountNotFoundError({
docsPath: '/docs/actions/wallet/signTransaction',
})
const account = parseAccount(account_)
assertRequest({
account,
...parameters,
})
const chainId = await getAction(client, getChainId, 'getChainId')({})
if (chain !== null)
assertCurrentChain({
currentChainId: chainId,
chain,
})
const formatters = chain?.formatters || client.chain?.formatters
const format =
formatters?.transactionRequest?.format || formatTransactionRequest
if (account.signTransaction)
return account.signTransaction(
{
...transaction,
account,
chainId,
} as TransactionSerializable,
{ serializer: client.chain?.serializers?.transaction },
) as Promise<SignTransactionReturnType<request>>
return await client.request(
{
method: 'eth_signTransaction',
params: [
{
...format(
{
...transaction,
account,
} as unknown as TransactionRequest,
'signTransaction',
),
chainId: numberToHex(chainId),
from: account.address,
} as unknown as RpcTransactionRequest,
],
},
{ retryCount: 0 },
)
}

195
node_modules/viem/actions/wallet/signTypedData.ts generated vendored Normal file
View File

@@ -0,0 +1,195 @@
import type { TypedData } from 'abitype'
import type { Account } from '../../accounts/types.js'
import {
type ParseAccountErrorType,
parseAccount,
} from '../../accounts/utils/parseAccount.js'
import type { SignTypedDataErrorType as SignTypedDataErrorType_account } from '../../accounts/utils/signTypedData.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 { Chain } from '../../types/chain.js'
import type { Hex } from '../../types/misc.js'
import type { TypedDataDefinition } from '../../types/typedData.js'
import type { RequestErrorType } from '../../utils/buildRequest.js'
import type { IsHexErrorType } from '../../utils/data/isHex.js'
import type { StringifyErrorType } from '../../utils/stringify.js'
import {
type GetTypesForEIP712DomainErrorType,
getTypesForEIP712Domain,
type SerializeTypedDataErrorType,
serializeTypedData,
type ValidateTypedDataErrorType,
validateTypedData,
} from '../../utils/typedData.js'
export type SignTypedDataParameters<
typedData extends TypedData | Record<string, unknown> = TypedData,
primaryType extends keyof typedData | 'EIP712Domain' = keyof typedData,
account extends Account | undefined = undefined,
///
primaryTypes = typedData extends TypedData ? keyof typedData : string,
> = TypedDataDefinition<typedData, primaryType, primaryTypes> &
GetAccountParameter<account>
export type SignTypedDataReturnType = Hex
export type SignTypedDataErrorType =
| AccountNotFoundErrorType
| ParseAccountErrorType
| GetTypesForEIP712DomainErrorType
| ValidateTypedDataErrorType
| StringifyErrorType
| SignTypedDataErrorType_account
| IsHexErrorType
| RequestErrorType
| SerializeTypedDataErrorType
| ErrorType
/**
* Signs typed data and calculates an Ethereum-specific signature in [https://eips.ethereum.org/EIPS/eip-712](https://eips.ethereum.org/EIPS/eip-712): `sign(keccak256("\x19\x01" ‖ domainSeparator ‖ hashStruct(message)))`
*
* - Docs: https://viem.sh/docs/actions/wallet/signTypedData
* - JSON-RPC Methods:
* - JSON-RPC Accounts: [`eth_signTypedData_v4`](https://docs.metamask.io/guide/signing-data#signtypeddata-v4)
* - Local Accounts: Signs locally. No JSON-RPC request.
*
* @param client - Client to use
* @param parameters - {@link SignTypedDataParameters}
* @returns The signed data. {@link SignTypedDataReturnType}
*
* @example
* import { createWalletClient, custom } from 'viem'
* import { mainnet } from 'viem/chains'
* import { signTypedData } from 'viem/wallet'
*
* const client = createWalletClient({
* chain: mainnet,
* transport: custom(window.ethereum),
* })
* const signature = await signTypedData(client, {
* account: '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e',
* domain: {
* name: 'Ether Mail',
* version: '1',
* chainId: 1,
* verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC',
* },
* types: {
* Person: [
* { name: 'name', type: 'string' },
* { name: 'wallet', type: 'address' },
* ],
* Mail: [
* { name: 'from', type: 'Person' },
* { name: 'to', type: 'Person' },
* { name: 'contents', type: 'string' },
* ],
* },
* primaryType: 'Mail',
* message: {
* from: {
* name: 'Cow',
* wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826',
* },
* to: {
* name: 'Bob',
* wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB',
* },
* contents: 'Hello, Bob!',
* },
* })
*
* @example
* // Account Hoisting
* import { createWalletClient, http } from 'viem'
* import { privateKeyToAccount } from 'viem/accounts'
* import { mainnet } from 'viem/chains'
* import { signTypedData } from 'viem/wallet'
*
* const client = createWalletClient({
* account: privateKeyToAccount('0x…'),
* chain: mainnet,
* transport: http(),
* })
* const signature = await signTypedData(client, {
* domain: {
* name: 'Ether Mail',
* version: '1',
* chainId: 1,
* verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC',
* },
* types: {
* Person: [
* { name: 'name', type: 'string' },
* { name: 'wallet', type: 'address' },
* ],
* Mail: [
* { name: 'from', type: 'Person' },
* { name: 'to', type: 'Person' },
* { name: 'contents', type: 'string' },
* ],
* },
* primaryType: 'Mail',
* message: {
* from: {
* name: 'Cow',
* wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826',
* },
* to: {
* name: 'Bob',
* wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB',
* },
* contents: 'Hello, Bob!',
* },
* })
*/
export async function signTypedData<
const typedData extends TypedData | Record<string, unknown>,
primaryType extends keyof typedData | 'EIP712Domain',
chain extends Chain | undefined,
account extends Account | undefined,
>(
client: Client<Transport, chain, account>,
parameters: SignTypedDataParameters<typedData, primaryType, account>,
): Promise<SignTypedDataReturnType> {
const {
account: account_ = client.account,
domain,
message,
primaryType,
} = parameters as unknown as SignTypedDataParameters
if (!account_)
throw new AccountNotFoundError({
docsPath: '/docs/actions/wallet/signTypedData',
})
const account = parseAccount(account_)
const types = {
EIP712Domain: getTypesForEIP712Domain({ domain }),
...parameters.types,
}
// Need to do a runtime validation check on addresses, byte ranges, integer ranges, etc
// as we can't statically check this with TypeScript.
validateTypedData({ domain, message, primaryType, types })
if (account.signTypedData)
return account.signTypedData({ domain, message, primaryType, types })
const typedData = serializeTypedData({ domain, message, primaryType, types })
return client.request(
{
method: 'eth_signTypedData_v4',
params: [account.address, typedData],
},
{ retryCount: 0 },
)
}

57
node_modules/viem/actions/wallet/switchChain.ts generated vendored Normal file
View File

@@ -0,0 +1,57 @@
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 SwitchChainParameters = {
/** ID of Chain to switch to */
id: Chain['id']
}
export type SwitchChainErrorType =
| NumberToHexErrorType
| RequestErrorType
| ErrorType
/**
* Switch the target chain in a wallet.
*
* - Docs: https://viem.sh/docs/actions/wallet/switchChain
* - JSON-RPC Methods: [`wallet_switchEthereumChain`](https://eips.ethereum.org/EIPS/eip-3326)
*
* @param client - Client to use
* @param parameters - {@link SwitchChainParameters}
*
* @example
* import { createWalletClient, custom } from 'viem'
* import { mainnet, optimism } from 'viem/chains'
* import { switchChain } from 'viem/wallet'
*
* const client = createWalletClient({
* chain: mainnet,
* transport: custom(window.ethereum),
* })
* await switchChain(client, { id: optimism.id })
*/
export async function switchChain<
chain extends Chain | undefined,
account extends Account | undefined = undefined,
>(client: Client<Transport, chain, account>, { id }: SwitchChainParameters) {
await client.request(
{
method: 'wallet_switchEthereumChain',
params: [
{
chainId: numberToHex(id),
},
],
},
{ retryCount: 0 },
)
}

178
node_modules/viem/actions/wallet/waitForCallsStatus.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 { BaseError } from '../../errors/base.js'
import { BundleFailedError } from '../../errors/calls.js'
import type { ErrorType } from '../../errors/utils.js'
import type { Chain } from '../../types/chain.js'
import { getAction } from '../../utils/getAction.js'
import { type ObserveErrorType, observe } from '../../utils/observe.js'
import { type PollErrorType, poll } from '../../utils/poll.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 GetCallsStatusErrorType,
type GetCallsStatusReturnType,
getCallsStatus,
} from './getCallsStatus.js'
export type WaitForCallsStatusParameters = {
/**
* The id of the call batch to wait for.
*/
id: string
/**
* Polling frequency (in ms). Defaults to the client's pollingInterval config.
*
* @default client.pollingInterval
*/
pollingInterval?: number | undefined
/**
* Number of times to retry if the call bundle failed.
* @default 4 (exponential backoff)
*/
retryCount?: WithRetryParameters['retryCount'] | undefined
/**
* Time to wait (in ms) between retries.
* @default `({ count }) => ~~(1 << count) * 200` (exponential backoff)
*/
retryDelay?: WithRetryParameters['delay'] | undefined
/**
* The status range to wait for.
*
* @default (status) => status >= 200
*/
status?: ((parameters: GetCallsStatusReturnType) => boolean) | undefined
/**
* Whether to throw an error if the call bundle fails.
*
* @default false
*/
throwOnFailure?: boolean | undefined
/**
* Optional timeout (in milliseconds) to wait before stopping polling.
*
* @default 60_000
*/
timeout?: number | undefined
}
export type WaitForCallsStatusReturnType = GetCallsStatusReturnType
export type WaitForCallsStatusErrorType =
| ObserveErrorType
| PollErrorType
| GetCallsStatusErrorType
| WaitForCallsStatusTimeoutError
| ErrorType
/**
* Waits for the status & receipts of a call bundle that was sent via `sendCalls`.
*
* - Docs: https://viem.sh/docs/actions/wallet/waitForCallsStatus
* - JSON-RPC Methods: [`wallet_getCallsStatus`](https://eips.ethereum.org/EIPS/eip-5792)
*
* @param client - Client to use
* @param parameters - {@link WaitForCallsStatusParameters}
* @returns Status & receipts of the call bundle. {@link WaitForCallsStatusReturnType}
*
* @example
* import { createWalletClient, custom } from 'viem'
* import { mainnet } from 'viem/chains'
* import { waitForCallsStatus } from 'viem/actions'
*
* const client = createWalletClient({
* chain: mainnet,
* transport: custom(window.ethereum),
* })
*
* const { receipts, status } = await waitForCallsStatus(client, { id: '0xdeadbeef' })
*/
export async function waitForCallsStatus<chain extends Chain | undefined>(
client: Client<Transport, chain>,
parameters: WaitForCallsStatusParameters,
): Promise<WaitForCallsStatusReturnType> {
const {
id,
pollingInterval = client.pollingInterval,
status = ({ statusCode }) => statusCode === 200 || statusCode >= 300,
retryCount = 4,
retryDelay = ({ count }) => ~~(1 << count) * 200, // exponential backoff
timeout = 60_000,
throwOnFailure = false,
} = parameters
const observerId = stringify(['waitForCallsStatus', client.uid, id])
const { promise, resolve, reject } =
withResolvers<WaitForCallsStatusReturnType>()
let timer: ReturnType<typeof setTimeout> | undefined
const unobserve = observe(observerId, { resolve, reject }, (emit) => {
const unpoll = poll(
async () => {
const done = (fn: () => void) => {
clearTimeout(timer)
unpoll()
fn()
unobserve()
}
try {
const result = await withRetry(
async () => {
const result = await getAction(
client,
getCallsStatus,
'getCallsStatus',
)({ id })
if (throwOnFailure && result.status === 'failure')
throw new BundleFailedError(result)
return result
},
{
retryCount,
delay: retryDelay,
},
)
if (!status(result)) return
done(() => emit.resolve(result))
} catch (error) {
done(() => emit.reject(error))
}
},
{
interval: pollingInterval,
emitOnBegin: true,
},
)
return unpoll
})
timer = timeout
? setTimeout(() => {
unobserve()
clearTimeout(timer)
reject(new WaitForCallsStatusTimeoutError({ id }))
}, timeout)
: undefined
return await promise
}
export type WaitForCallsStatusTimeoutErrorType =
WaitForCallsStatusTimeoutError & {
name: 'WaitForCallsStatusTimeoutError'
}
export class WaitForCallsStatusTimeoutError extends BaseError {
constructor({ id }: { id: string }) {
super(
`Timed out while waiting for call bundle with id "${id}" to be confirmed.`,
{ name: 'WaitForCallsStatusTimeoutError' },
)
}
}

56
node_modules/viem/actions/wallet/watchAsset.ts generated vendored Normal file
View File

@@ -0,0 +1,56 @@
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 { WatchAssetParams } from '../../types/eip1193.js'
import type { RequestErrorType } from '../../utils/buildRequest.js'
export type WatchAssetParameters = WatchAssetParams
export type WatchAssetReturnType = boolean
export type WatchAssetErrorType = RequestErrorType | ErrorType
/**
* Adds an EVM chain to the wallet.
*
* - Docs: https://viem.sh/docs/actions/wallet/watchAsset
* - JSON-RPC Methods: [`eth_switchEthereumChain`](https://eips.ethereum.org/EIPS/eip-747)
*
* @param client - Client to use
* @param parameters - {@link WatchAssetParameters}
* @returns Boolean indicating if the token was successfully added. {@link WatchAssetReturnType}
*
* @example
* import { createWalletClient, custom } from 'viem'
* import { mainnet } from 'viem/chains'
* import { watchAsset } from 'viem/wallet'
*
* const client = createWalletClient({
* chain: mainnet,
* transport: custom(window.ethereum),
* })
* const success = await watchAsset(client, {
* type: 'ERC20',
* options: {
* address: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
* decimals: 18,
* symbol: 'WETH',
* },
* })
*/
export async function watchAsset<
chain extends Chain | undefined,
account extends Account | undefined = undefined,
>(
client: Client<Transport, chain, account>,
params: WatchAssetParameters,
): Promise<WatchAssetReturnType> {
const added = await client.request(
{
method: 'wallet_watchAsset',
params,
},
{ retryCount: 0 },
)
return added
}

251
node_modules/viem/actions/wallet/writeContract.ts generated vendored Normal file
View File

@@ -0,0 +1,251 @@
import type { Abi, 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 { BaseError } from '../../errors/base.js'
import type { ErrorType } from '../../errors/utils.js'
import type { GetAccountParameter } from '../../types/account.js'
import type {
Chain,
DeriveChain,
GetChainParameter,
} from '../../types/chain.js'
import type {
ContractFunctionArgs,
ContractFunctionName,
ContractFunctionParameters,
} from '../../types/contract.js'
import type { Hex } from '../../types/misc.js'
import type { Prettify, UnionEvaluate, 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 type { FormattedTransactionRequest } from '../../utils/formatters/transactionRequest.js'
import { getAction } from '../../utils/getAction.js'
import type { GetMutabilityAwareValue } from '../public/simulateContract.js'
import {
type SendTransactionErrorType,
type SendTransactionReturnType,
sendTransaction,
} from './sendTransaction.js'
import type { sendTransactionSync } from './sendTransactionSync.js'
export type WriteContractParameters<
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,
account extends Account | undefined = Account | undefined,
chainOverride extends Chain | undefined = Chain | undefined,
///
allFunctionNames = ContractFunctionName<abi, 'nonpayable' | 'payable'>,
derivedChain extends Chain | undefined = DeriveChain<chain, chainOverride>,
> = ContractFunctionParameters<
abi,
'nonpayable' | 'payable',
functionName,
args,
false,
allFunctionNames
> &
GetChainParameter<chain, chainOverride> &
Prettify<
GetAccountParameter<account, Account | Address, true, true> &
GetMutabilityAwareValue<
abi,
'nonpayable' | 'payable',
functionName,
FormattedTransactionRequest<derivedChain>['value'],
args
> & {
/** 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
}
> &
UnionEvaluate<
UnionOmit<
FormattedTransactionRequest<derivedChain>,
'data' | 'from' | 'to' | 'value'
>
>
export type WriteContractReturnType = SendTransactionReturnType
export type WriteContractErrorType =
| EncodeFunctionDataErrorType
| AccountNotFoundErrorType
| ParseAccountErrorType
| GetContractErrorReturnType<SendTransactionErrorType>
| ErrorType
/**
* Executes a write function on a contract.
*
* - Docs: https://viem.sh/docs/contract/writeContract
* - Examples: https://stackblitz.com/github/wevm/viem/tree/main/examples/contracts_writing-to-contracts
*
* A "write" function on a Solidity contract modifies the state of the blockchain. These types of functions require gas to be executed, and hence a [Transaction](https://viem.sh/docs/glossary/terms) is needed to be broadcast in order to change the state.
*
* Internally, uses a [Wallet Client](https://viem.sh/docs/clients/wallet) to call the [`sendTransaction` action](https://viem.sh/docs/actions/wallet/sendTransaction) with [ABI-encoded `data`](https://viem.sh/docs/contract/encodeFunctionData).
*
* __Warning: The `write` internally sends a transaction it does not validate if the contract write will succeed (the contract may throw an error). It is highly recommended to [simulate the contract write with `contract.simulate`](https://viem.sh/docs/contract/writeContract#usage) before you execute it.__
*
* @param client - Client to use
* @param parameters - {@link WriteContractParameters}
* @returns A [Transaction Hash](https://viem.sh/docs/glossary/terms#hash). {@link WriteContractReturnType}
*
* @example
* import { createWalletClient, custom, parseAbi } from 'viem'
* import { mainnet } from 'viem/chains'
* import { writeContract } from 'viem/contract'
*
* const client = createWalletClient({
* chain: mainnet,
* transport: custom(window.ethereum),
* })
* const hash = await writeContract(client, {
* address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
* abi: parseAbi(['function mint(uint32 tokenId) nonpayable']),
* functionName: 'mint',
* args: [69420],
* })
*
* @example
* // With Validation
* import { createWalletClient, http, parseAbi } from 'viem'
* import { mainnet } from 'viem/chains'
* import { simulateContract, writeContract } from 'viem/contract'
*
* const client = createWalletClient({
* chain: mainnet,
* transport: http(),
* })
* const { request } = await simulateContract(client, {
* address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
* abi: parseAbi(['function mint(uint32 tokenId) nonpayable']),
* functionName: 'mint',
* args: [69420],
* }
* const hash = await writeContract(client, request)
*/
export async function writeContract<
chain extends Chain | undefined,
account extends Account | undefined,
const abi extends Abi | readonly unknown[],
functionName extends ContractFunctionName<abi, 'nonpayable' | 'payable'>,
args extends ContractFunctionArgs<
abi,
'nonpayable' | 'payable',
functionName
>,
chainOverride extends Chain | undefined,
>(
client: Client<Transport, chain, account>,
parameters: WriteContractParameters<
abi,
functionName,
args,
chain,
account,
chainOverride
>,
): Promise<WriteContractReturnType> {
return writeContract.internal(
client,
sendTransaction,
'sendTransaction',
parameters,
) as never
}
export namespace writeContract {
export async function internal<
chain extends Chain | undefined,
account extends Account | undefined,
const abi extends Abi | readonly unknown[],
functionName extends ContractFunctionName<abi, 'nonpayable' | 'payable'>,
args extends ContractFunctionArgs<
abi,
'nonpayable' | 'payable',
functionName
>,
chainOverride extends Chain | undefined,
>(
client: Client<Transport, chain, account>,
actionFn: typeof sendTransaction | typeof sendTransactionSync,
name: 'sendTransaction' | 'sendTransactionSync',
parameters: WriteContractParameters<
abi,
functionName,
args,
chain,
account,
chainOverride
>,
) {
const {
abi,
account: account_ = client.account,
address,
args,
functionName,
...request
} = parameters as WriteContractParameters
if (typeof account_ === 'undefined')
throw new AccountNotFoundError({
docsPath: '/docs/contract/writeContract',
})
const account = account_ ? parseAccount(account_) : null
const data = encodeFunctionData({
abi,
args,
functionName,
} as EncodeFunctionDataParameters)
try {
return await getAction(
client,
actionFn as never,
name,
)({
data,
to: address,
account,
...request,
})
} catch (error) {
throw getContractError(error as BaseError, {
abi,
address,
args,
docsPath: '/docs/contract/writeContract',
functionName,
sender: account?.address,
})
}
}
}

111
node_modules/viem/actions/wallet/writeContractSync.ts generated vendored Normal file
View File

@@ -0,0 +1,111 @@
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 { Chain } from '../../types/chain.js'
import type {
ContractFunctionArgs,
ContractFunctionName,
} from '../../types/contract.js'
import {
type SendTransactionSyncParameters,
type SendTransactionSyncReturnType,
sendTransactionSync,
} from './sendTransactionSync.js'
import { type WriteContractParameters, writeContract } from './writeContract.js'
export type { WriteContractErrorType as WriteContractSyncErrorType } from './writeContract.js'
export type WriteContractSyncParameters<
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,
account extends Account | undefined = Account | undefined,
chainOverride extends Chain | undefined = Chain | undefined,
> = WriteContractParameters<
abi,
functionName,
args,
chain,
account,
chainOverride
> &
Pick<
SendTransactionSyncParameters<chain>,
'pollingInterval' | 'throwOnReceiptRevert' | 'timeout'
>
export type WriteContractSyncReturnType<
chain extends Chain | undefined = Chain | undefined,
> = SendTransactionSyncReturnType<chain>
/**
* Executes a write function on a contract synchronously.
* Returns the transaction receipt.
*
* - Docs: https://viem.sh/docs/contract/writeContractSync
*
* A "write" function on a Solidity contract modifies the state of the blockchain. These types of functions require gas to be executed, and hence a [Transaction](https://viem.sh/docs/glossary/terms) is needed to be broadcast in order to change the state.
*
* Internally, uses a [Wallet Client](https://viem.sh/docs/clients/wallet) to call the [`sendTransaction` action](https://viem.sh/docs/actions/wallet/sendTransaction) with [ABI-encoded `data`](https://viem.sh/docs/contract/encodeFunctionData).
*
* __Warning: The `write` internally sends a transaction it does not validate if the contract write will succeed (the contract may throw an error). It is highly recommended to [simulate the contract write with `contract.simulate`](https://viem.sh/docs/contract/writeContract#usage) before you execute it.__
*
* @param client - Client to use
* @param parameters - {@link WriteContractParameters}
* @returns A [Transaction Hash](https://viem.sh/docs/glossary/terms#hash). {@link WriteContractReturnType}
*
* @example
* import { createWalletClient, custom, parseAbi } from 'viem'
* import { mainnet } from 'viem/chains'
* import { writeContract } from 'viem/contract'
*
* const client = createWalletClient({
* chain: mainnet,
* transport: custom(window.ethereum),
* })
* const receipt = await writeContractSync(client, {
* address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
* abi: parseAbi(['function mint(uint32 tokenId) nonpayable']),
* functionName: 'mint',
* args: [69420],
* })
*/
export async function writeContractSync<
chain extends Chain | undefined,
account extends Account | undefined,
const abi extends Abi | readonly unknown[],
functionName extends ContractFunctionName<abi, 'nonpayable' | 'payable'>,
args extends ContractFunctionArgs<
abi,
'nonpayable' | 'payable',
functionName
>,
chainOverride extends Chain | undefined,
>(
client: Client<Transport, chain, account>,
parameters: WriteContractSyncParameters<
abi,
functionName,
args,
chain,
account,
chainOverride
>,
): Promise<WriteContractSyncReturnType<chain>> {
return writeContract.internal(
client,
sendTransactionSync,
'sendTransactionSync',
parameters as never,
) as never
}