Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"lint": "turbo lint",
"test": "turbo run test --filter='!./packages/delegator-e2e'",
"test:e2e": "turbo run test:e2e --filter='./packages/delegator-e2e'",
"test:standalone": "cd packages/delegator-e2e && yarn test:standalone",
"test:watch": "turbo run test:watch"
},
"devDependencies": {
Expand Down
114 changes: 114 additions & 0 deletions packages/delegation-toolkit/src/actions/infuraBundlerClient.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import type { Transport, Chain, Hex } from 'viem';
import {
createBundlerClient,
type BundlerClientConfig,
type SmartAccount,
} from 'viem/account-abstraction';

/**
* Gas price tiers returned by pimlico_getUserOperationGasPrice
*/
export type GasPriceTier = {
/** Maximum fee per gas in hex format */
maxFeePerGas: Hex;
/** Maximum priority fee per gas in hex format */
maxPriorityFeePerGas: Hex;
};

/**
* Response from pimlico_getUserOperationGasPrice RPC method
*/
export type UserOperationGasPriceResponse = {
/** Slow gas price tier */
slow: GasPriceTier;
/** Standard gas price tier */
standard: GasPriceTier;
/** Fast gas price tier */
fast: GasPriceTier;
};

/**
* Infura bundler actions for extending bundler clients.
*
* @returns A function that takes a bundler client and returns the client extension with Infura bundler actions.
*/
const infuraBundlerActions = () => (client: any) => ({
Comment thread
hanzel98 marked this conversation as resolved.
Outdated
/**
* Get user operation gas prices from Infura bundler.
* Calls the pimlico_getUserOperationGasPrice RPC method.
*
* @returns Promise resolving to gas price tiers (slow, standard, fast).
* @example
* ```typescript
* const gasPrices = await bundlerClient.getUserOperationGasPrice();
* console.log(gasPrices.standard.maxFeePerGas);
* ```
*/
async getUserOperationGasPrice(): Promise<UserOperationGasPriceResponse> {
const response = await client.request({
Comment thread
hanzel98 marked this conversation as resolved.
Outdated
method: 'pimlico_getUserOperationGasPrice' as any,
params: [] as any,
});

return response as unknown as UserOperationGasPriceResponse;
},
});

/**
* Type for bundler client extended with Infura bundler actions.
*/
export type InfuraBundlerClient<
TTransport extends Transport = Transport,
TChain extends Chain | undefined = Chain | undefined,
TAccount extends SmartAccount | undefined = SmartAccount | undefined,
> = ReturnType<typeof createBundlerClient<TTransport, TChain, TAccount>> &
Comment thread
hanzel98 marked this conversation as resolved.
Outdated
ReturnType<ReturnType<typeof infuraBundlerActions>>;

/**
* Creates an Infura bundler client extended with Infura bundler actions.
*
* This is a wrapper around viem's createBundlerClient that extends it with
* the getUserOperationGasPrice method for retrieving gas prices from Pimlico's
* bundler infrastructure via Infura's proxy.
*
* @param config - Configuration for the bundler client.
* @returns Extended bundler client with Infura bundler actions.
* @example
* ```typescript
* import { createPublicClient, http } from 'viem';
* import { sepolia } from 'viem/chains';
* import { createInfuraBundlerClient } from '@metamask/delegation-toolkit';
*
* const publicClient = createPublicClient({
* chain: sepolia,
* transport: http('https://sepolia.infura.io/v3/YOUR_API_KEY'),
* });
*
* const bundlerClient = createInfuraBundlerClient({
* client: publicClient,
* transport: http('https://sepolia.infura.io/v3/YOUR_API_KEY'),
* chain: sepolia,
* });
*
* // Use standard bundler methods
* const userOpHash = await bundlerClient.sendUserOperation({...});
*
* // Use Infura specific methods
* const gasPrices = await bundlerClient.getUserOperationGasPrice();
* ```
*/
export function createInfuraBundlerClient<
TTransport extends Transport,
TChain extends Chain | undefined = undefined,
TAccount extends SmartAccount | undefined = undefined,
>(
config: BundlerClientConfig<TTransport, TChain, TAccount>,
): InfuraBundlerClient<TTransport, TChain, TAccount> {
// Create the base bundler client using viem's function
const baseBundlerClient = createBundlerClient(config);

// Extend the client with Infura bundler actions
return baseBundlerClient.extend(
infuraBundlerActions(),
) as unknown as InfuraBundlerClient<TTransport, TChain, TAccount>;
Comment thread
hanzel98 marked this conversation as resolved.
}
7 changes: 7 additions & 0 deletions packages/delegation-toolkit/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,10 @@ export {
createCaveatEnforcerClient,
type CaveatEnforcerClient,
} from './actions/caveatEnforcerClient';

export {
createInfuraBundlerClient,
type InfuraBundlerClient,
type GasPriceTier,
type UserOperationGasPriceResponse,
} from './actions/infuraBundlerClient';
Loading
Loading