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

View File

@@ -0,0 +1,165 @@
import type { EstimateFeesPerGasReturnType } from '../../actions/public/estimateFeesPerGas.js'
import {
type Client,
type ClientConfig,
type CreateClientErrorType,
createClient,
} 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 { BundlerRpcSchema, RpcSchema } from '../../types/eip1193.js'
import type { Hex } from '../../types/misc.js'
import type { Prettify } from '../../types/utils.js'
import type { SmartAccount } from '../accounts/types.js'
import type { UserOperationRequest } from '../types/userOperation.js'
import { type BundlerActions, bundlerActions } from './decorators/bundler.js'
import type { PaymasterActions } from './decorators/paymaster.js'
export type BundlerClientConfig<
transport extends Transport = Transport,
chain extends Chain | undefined = Chain | undefined,
account extends SmartAccount | undefined = SmartAccount | undefined,
client extends Client | undefined = Client | undefined,
rpcSchema extends RpcSchema | undefined = undefined,
> = Prettify<
Pick<
ClientConfig<transport, chain, account, rpcSchema>,
| 'account'
| 'cacheTime'
| 'chain'
| 'key'
| 'name'
| 'pollingInterval'
| 'rpcSchema'
| 'transport'
>
> & {
/** Client that points to an Execution RPC URL. */
client?: client | Client | undefined
/** Data to append to the end of User Operation calldata. */
dataSuffix?: Hex | undefined
/** Paymaster configuration. */
paymaster?:
| true
| {
/** Retrieves paymaster-related User Operation properties to be used for sending the User Operation. */
getPaymasterData?: PaymasterActions['getPaymasterData'] | undefined
/** Retrieves paymaster-related User Operation properties to be used for gas estimation. */
getPaymasterStubData?:
| PaymasterActions['getPaymasterStubData']
| undefined
}
| undefined
/** Paymaster context to pass to `getPaymasterData` and `getPaymasterStubData` calls. */
paymasterContext?: unknown
/** User Operation configuration. */
userOperation?:
| {
/** Prepares fee properties for the User Operation request. */
estimateFeesPerGas?:
| ((parameters: {
account: account | SmartAccount
bundlerClient: Client
userOperation: UserOperationRequest
}) => Promise<EstimateFeesPerGasReturnType<'eip1559'>>)
| undefined
}
| undefined
}
export type BundlerClient<
transport extends Transport = Transport,
chain extends Chain | undefined = Chain | undefined,
account extends SmartAccount | undefined = SmartAccount | undefined,
client extends Client | undefined = Client | undefined,
rpcSchema extends RpcSchema | undefined = undefined,
> = Prettify<
Client<
transport,
chain extends Chain
? chain
: client extends Client<any, infer chain>
? chain
: undefined,
account,
rpcSchema extends RpcSchema
? [...BundlerRpcSchema, ...rpcSchema]
: BundlerRpcSchema,
BundlerActions<account>
>
> & {
client: client
dataSuffix: Hex | undefined
paymaster: BundlerClientConfig['paymaster'] | undefined
paymasterContext: BundlerClientConfig['paymasterContext'] | undefined
userOperation: BundlerClientConfig['userOperation'] | undefined
}
export type CreateBundlerClientErrorType = CreateClientErrorType | ErrorType
/**
* Creates a Bundler Client with a given [Transport](https://viem.sh/docs/clients/intro) configured for a [Chain](https://viem.sh/docs/clients/chains).
*
* - Docs: https://viem.sh/account-abstraction/clients/bundler
*
* @param config - {@link BundlerClientConfig}
* @returns A Bundler Client. {@link BundlerClient}
*
* @example
* import { createPublicClient, http } from 'viem'
* import { createBundlerClient } from 'viem/account-abstraction'
* import { mainnet } from 'viem/chains'
*
* const client = createPublicClient({
* chain: mainnet,
* transport: http(),
* })
*
* const bundlerClient = createBundlerClient({
* client,
* transport: http('https://public.pimlico.io/v2/1/rpc'),
* })
*/
export function createBundlerClient<
transport extends Transport,
chain extends Chain | undefined = undefined,
account extends SmartAccount | undefined = undefined,
client extends Client | undefined = undefined,
rpcSchema extends RpcSchema | undefined = undefined,
>(
parameters: BundlerClientConfig<transport, chain, account, client, rpcSchema>,
): BundlerClient<transport, chain, account, client, rpcSchema>
export function createBundlerClient(
parameters: BundlerClientConfig,
): BundlerClient {
const {
client: client_,
dataSuffix,
key = 'bundler',
name = 'Bundler Client',
paymaster,
paymasterContext,
transport,
userOperation,
} = parameters
const client = Object.assign(
createClient({
...parameters,
chain: parameters.chain ?? client_?.chain,
key,
name,
transport,
type: 'bundlerClient',
}),
{
client: client_,
dataSuffix: dataSuffix ?? client_?.dataSuffix,
paymaster,
paymasterContext,
userOperation,
},
)
return client.extend(bundlerActions) as any
}

View File

@@ -0,0 +1,78 @@
import {
type Client,
type ClientConfig,
type CreateClientErrorType,
createClient,
} from '../../clients/createClient.js'
import type { Transport } from '../../clients/transports/createTransport.js'
import type { ErrorType } from '../../errors/utils.js'
import type { PaymasterRpcSchema, RpcSchema } from '../../types/eip1193.js'
import type { Prettify } from '../../types/utils.js'
import {
type PaymasterActions,
paymasterActions,
} from './decorators/paymaster.js'
export type PaymasterClientConfig<
transport extends Transport = Transport,
rpcSchema extends RpcSchema | undefined = undefined,
> = Prettify<
Pick<
ClientConfig<transport, undefined, undefined, rpcSchema>,
'cacheTime' | 'key' | 'name' | 'pollingInterval' | 'rpcSchema' | 'transport'
>
>
export type PaymasterClient<
transport extends Transport = Transport,
rpcSchema extends RpcSchema | undefined = undefined,
> = Prettify<
Client<
transport,
undefined,
undefined,
rpcSchema extends RpcSchema
? [...PaymasterRpcSchema, ...rpcSchema]
: PaymasterRpcSchema,
PaymasterActions
>
>
export type CreatePaymasterClientErrorType = CreateClientErrorType | ErrorType
/**
* Creates a Paymaster Client.
*
* - Docs: https://viem.sh/account-abstraction/clients/paymaster
*
* @param config - {@link PaymasterClientConfig}
* @returns A Paymaster Client. {@link PaymasterClient}
*
* @example
* import { http } from 'viem'
* import { createPaymasterClient } from 'viem/account-abstraction'
*
* const paymasterClient = createPaymasterClient({
* transport: http('https://...'),
* })
*/
export function createPaymasterClient<
transport extends Transport,
rpcSchema extends RpcSchema | undefined = undefined,
>(
parameters: PaymasterClientConfig<transport, rpcSchema>,
): PaymasterClient<transport, rpcSchema>
export function createPaymasterClient(
parameters: PaymasterClientConfig,
): PaymasterClient {
const { key = 'bundler', name = 'Bundler Client', transport } = parameters
const client = createClient({
...parameters,
key,
name,
transport,
type: 'PaymasterClient',
})
return client.extend(paymasterActions)
}

View File

@@ -0,0 +1,296 @@
import {
type GetChainIdReturnType,
getChainId,
} from '../../../actions/public/getChainId.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 { SmartAccount } from '../../accounts/types.js'
import {
type EstimateUserOperationGasParameters,
type EstimateUserOperationGasReturnType,
estimateUserOperationGas,
} from '../../actions/bundler/estimateUserOperationGas.js'
import {
type GetSupportedEntryPointsReturnType,
getSupportedEntryPoints,
} from '../../actions/bundler/getSupportedEntryPoints.js'
import {
type GetUserOperationParameters,
type GetUserOperationReturnType,
getUserOperation,
} from '../../actions/bundler/getUserOperation.js'
import {
type GetUserOperationReceiptParameters,
type GetUserOperationReceiptReturnType,
getUserOperationReceipt,
} from '../../actions/bundler/getUserOperationReceipt.js'
import {
type PrepareUserOperationParameters,
type PrepareUserOperationRequest,
type PrepareUserOperationReturnType,
prepareUserOperation,
} from '../../actions/bundler/prepareUserOperation.js'
import {
type SendUserOperationParameters,
type SendUserOperationReturnType,
sendUserOperation,
} from '../../actions/bundler/sendUserOperation.js'
import {
type WaitForUserOperationReceiptParameters,
type WaitForUserOperationReceiptReturnType,
waitForUserOperationReceipt,
} from '../../actions/bundler/waitForUserOperationReceipt.js'
export type BundlerActions<
account extends SmartAccount | undefined = SmartAccount | undefined,
> = {
/**
* Returns an estimate of gas values necessary to execute the User Operation.
*
* - Docs: https://viem.sh/actions/bundler/estimateUserOperationGas
*
* @param client - Client to use
* @param parameters - {@link EstimateUserOperationGasParameters}
* @returns The gas estimate (in wei). {@link EstimateUserOperationGasReturnType}
*
* @example
* import { createBundlerClient, http, parseEther } from 'viem'
* import { mainnet } from 'viem/chains'
* import { toSmartAccount } from 'viem/accounts'
*
* const account = await toSmartAccount({ ... })
*
* const bundlerClient = createBundlerClient({
* chain: mainnet,
* transport: http(),
* })
*
* const values = await bundlerClient.estimateUserOperationGas({
* account,
* calls: [{ to: '0x...', value: parseEther('1') }],
* })
*/
estimateUserOperationGas: <
const calls extends readonly unknown[],
accountOverride extends SmartAccount | undefined = undefined,
>(
parameters: EstimateUserOperationGasParameters<
account,
accountOverride,
calls
>,
) => Promise<EstimateUserOperationGasReturnType<account, accountOverride>>
/**
* Returns the chain ID associated with the bundler.
*
* - Docs: https://viem.sh/docs/actions/public/getChainId
* - JSON-RPC Methods: [`eth_chainId`](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_chainid)
*
* @returns The current chain ID. {@link GetChainIdReturnType}
*
* @example
* import { http } from 'viem'
* import { createBundlerClient, mainnet } from 'viem/chains'
*
* const client = createPublicClient({
* chain: mainnet,
* transport: http(),
* })
* const chainId = await client.getChainId()
* // 1
*/
getChainId: () => Promise<GetChainIdReturnType>
/**
* Returns the EntryPoints that the bundler supports.
*
* - Docs: https://viem.sh/actions/bundler/getSupportedEntryPoints
*
* @param client - Client to use
* @param parameters - {@link GetSupportedEntryPointsParameters}
* @returns Supported Entry Points. {@link GetSupportedEntryPointsReturnType}
*
* @example
* import { createBundlerClient, http, parseEther } from 'viem'
* import { mainnet } from 'viem/chains'
*
* const bundlerClient = createBundlerClient({
* chain: mainnet,
* transport: http(),
* })
*
* const addresses = await bundlerClient.getSupportedEntryPoints()
*/
getSupportedEntryPoints: () => Promise<GetSupportedEntryPointsReturnType>
/**
* Returns the information about a User Operation given a hash.
*
* - Docs: https://viem.sh/docs/actions/bundler/getUserOperation
*
* @param client - Client to use
* @param parameters - {@link GetUserOperationParameters}
* @returns The receipt. {@link GetUserOperationReturnType}
*
* @example
* import { createBundlerClient, http } from 'viem'
* import { mainnet } from 'viem/chains'
*
* const client = createBundlerClient({
* chain: mainnet,
* transport: http(),
* })
*
* const receipt = await client.getUserOperation({
* hash: '0x4ca7ee652d57678f26e887c149ab0735f41de37bcad58c9f6d3ed5824f15b74d',
* })
*/
getUserOperation: (
parameters: GetUserOperationParameters,
) => Promise<GetUserOperationReturnType>
/**
* Returns the User Operation Receipt given a User Operation hash.
*
* - Docs: https://viem.sh/docs/actions/bundler/getUserOperationReceipt
*
* @param client - Client to use
* @param parameters - {@link GetUserOperationReceiptParameters}
* @returns The receipt. {@link GetUserOperationReceiptReturnType}
*
* @example
* import { createBundlerClient, http } from 'viem'
* import { mainnet } from 'viem/chains'
*
* const client = createBundlerClient({
* chain: mainnet,
* transport: http(),
* })
*
* const receipt = await client.getUserOperationReceipt({
* hash: '0x4ca7ee652d57678f26e887c149ab0735f41de37bcad58c9f6d3ed5824f15b74d',
* })
*/
getUserOperationReceipt: (
parameters: GetUserOperationReceiptParameters,
) => Promise<GetUserOperationReceiptReturnType>
/**
* Prepares a User Operation and fills in missing properties.
*
* - Docs: https://viem.sh/actions/bundler/prepareUserOperation
*
* @param args - {@link PrepareUserOperationParameters}
* @returns The User Operation. {@link PrepareUserOperationReturnType}
*
* @example
* import { createBundlerClient, http } from 'viem'
* import { mainnet } from 'viem/chains'
* import { toSmartAccount } from 'viem/accounts'
*
* const account = await toSmartAccount({ ... })
*
* const client = createBundlerClient({
* chain: mainnet,
* transport: http(),
* })
*
* const request = await client.prepareUserOperation({
* account,
* calls: [{ to: '0x...', value: parseEther('1') }],
* })
*/
prepareUserOperation: <
const calls extends readonly unknown[],
const request extends PrepareUserOperationRequest<
account,
accountOverride,
calls
>,
accountOverride extends SmartAccount | undefined = undefined,
>(
parameters: PrepareUserOperationParameters<
account,
accountOverride,
calls,
request
>,
) => Promise<
PrepareUserOperationReturnType<account, accountOverride, calls, request>
>
/**
* Broadcasts a User Operation to the Bundler.
*
* - Docs: https://viem.sh/actions/bundler/sendUserOperation
*
* @param client - Client to use
* @param parameters - {@link SendUserOperationParameters}
* @returns The User Operation hash. {@link SendUserOperationReturnType}
*
* @example
* import { createBundlerClient, http, parseEther } from 'viem'
* import { mainnet } from 'viem/chains'
* import { toSmartAccount } from 'viem/accounts'
*
* const account = toSmartAccount({ ... })
*
* const bundlerClient = createBundlerClient({
* chain: mainnet,
* transport: http(),
* })
*
* const values = await bundlerClient.sendUserOperation({
* account,
* calls: [{ to: '0x...', value: parseEther('1') }],
* })
*/
sendUserOperation: <
const calls extends readonly unknown[],
accountOverride extends SmartAccount | undefined = undefined,
>(
parameters: SendUserOperationParameters<account, accountOverride, calls>,
) => Promise<SendUserOperationReturnType>
/**
* Waits for the User Operation to be included on a [Block](https://viem.sh/docs/glossary/terms#block) (one confirmation), and then returns the User Operation receipt.
*
* - Docs: https://viem.sh/docs/actions/bundler/waitForUserOperationReceipt
*
* @param client - Client to use
* @param parameters - {@link WaitForUserOperationReceiptParameters}
* @returns The receipt. {@link WaitForUserOperationReceiptReturnType}
*
* @example
* import { createBundlerClient, http } from 'viem'
* import { mainnet } from 'viem/chains'
*
* const client = createBundlerClient({
* chain: mainnet,
* transport: http(),
* })
*
* const receipt = await client.waitForUserOperationReceipt({
* hash: '0x4ca7ee652d57678f26e887c149ab0735f41de37bcad58c9f6d3ed5824f15b74d',
* })
*/
waitForUserOperationReceipt: (
parameters: WaitForUserOperationReceiptParameters,
) => Promise<WaitForUserOperationReceiptReturnType>
}
export function bundlerActions<
transport extends Transport = Transport,
chain extends Chain | undefined = Chain | undefined,
account extends SmartAccount | undefined = SmartAccount | undefined,
>(client: Client<transport, chain, account>): BundlerActions<account> {
return {
estimateUserOperationGas: (parameters) =>
estimateUserOperationGas(client, parameters),
getChainId: () => getChainId(client),
getSupportedEntryPoints: () => getSupportedEntryPoints(client),
getUserOperation: (parameters) => getUserOperation(client, parameters),
getUserOperationReceipt: (parameters) =>
getUserOperationReceipt(client, parameters),
prepareUserOperation: (parameters) =>
prepareUserOperation(client, parameters),
sendUserOperation: (parameters) => sendUserOperation(client, parameters),
waitForUserOperationReceipt: (parameters) =>
waitForUserOperationReceipt(client, parameters),
}
}

View File

@@ -0,0 +1,81 @@
import type { Client } from '../../../clients/createClient.js'
import type { Transport } from '../../../clients/transports/createTransport.js'
import {
type GetPaymasterDataParameters,
type GetPaymasterDataReturnType,
getPaymasterData,
} from '../../actions/paymaster/getPaymasterData.js'
import {
type GetPaymasterStubDataParameters,
type GetPaymasterStubDataReturnType,
getPaymasterStubData,
} from '../../actions/paymaster/getPaymasterStubData.js'
export type PaymasterActions = {
/**
* Retrieves paymaster-related User Operation properties to be used for sending the User Operation.
*
* - Docs: https://viem.sh/account-abstraction/actions/paymaster/getPaymasterData
*
* @param client - Client to use
* @param parameters - {@link GetPaymasterDataParameters}
* @returns Paymaster-related User Operation properties. {@link GetPaymasterDataReturnType}
*
* @example
* import { http } from 'viem'
* import { createPaymasterClient } from 'viem/account-abstraction'
*
* const paymasterClient = createPaymasterClient({
* transport: http('https://...'),
* })
*
* const userOperation = { ... }
*
* const values = await paymasterClient.getPaymasterData({
* chainId: 1,
* entryPointAddress: '0x...',
* ...userOperation,
* })
*/
getPaymasterData: (
parameters: GetPaymasterDataParameters,
) => Promise<GetPaymasterDataReturnType>
/**
* Retrieves paymaster-related User Operation properties to be used for gas estimation.
*
* - Docs: https://viem.sh/account-abstraction/actions/paymaster/getPaymasterStubData
*
* @param client - Client to use
* @param parameters - {@link GetPaymasterStubDataParameters}
* @returns Paymaster-related User Operation properties. {@link GetPaymasterStubDataReturnType}
*
* @example
* import { http } from 'viem'
* import { createPaymasterClient } from 'viem/account-abstraction'
*
* const paymasterClient = createPaymasterClient({
* transport: http('https://...'),
* })
*
* const userOperation = { ... }
*
* const values = await paymasterClient.getPaymasterStubData({
* chainId: 1,
* entryPointAddress: '0x...',
* ...userOperation,
* })
*/
getPaymasterStubData: (
parameters: GetPaymasterStubDataParameters,
) => Promise<GetPaymasterStubDataReturnType>
}
export function paymasterActions<transport extends Transport = Transport>(
client: Client<transport>,
): PaymasterActions {
return {
getPaymasterData: (parameters) => getPaymasterData(client, parameters),
getPaymasterStubData: (parameters) =>
getPaymasterStubData(client, parameters),
}
}