Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
## [1.0.1] - 2025-09-25
- Removed `chainId` parameter from `createFreeBundler()`, changed interface `CreateFreeBundlerOptions` to make `chain` mandatory.
- Upgraded `viem` to 2.37.8.
- Removed `bun.lock` file.
21 changes: 12 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,14 @@ pnpm add @etherspot/free-bundler viem

```typescript
import { createFreeBundler } from '@etherspot/free-bundler'
import { mainnet } from 'viem/chains'

// Create bundler client for Ethereum Sepolia
const bundlerClient = createFreeBundler(11155111)
const bundlerClient = createFreeBundler({ chain: mainnet })

// Send a user operation
const hash = await bundlerClient.sendUserOperation({
account,
userOperation: {
sender: '0x...',
nonce: 0n,
Expand Down Expand Up @@ -89,16 +91,15 @@ bun run lint:fix

## API Reference

### `createFreeBundler(chainId, options?)`
### `createFreeBundler(options)`

Creates a bundler client with preconfigured settings.

#### Parameters

- `chainId` (number): Target blockchain chain ID
- `options` (object, optional):
- `bundlerUrl?` (string): Custom bundler URL
- `chain?` (Chain): Viem chain configuration
- `chain` (Chain): Viem chain configuration
- `account?` (Account): Viem account configuration
- `transport?` (object): HTTP transport options
- `timeout?` (number): Request timeout in ms (default: 30000)
Expand Down Expand Up @@ -138,20 +139,22 @@ const name = getChainName(1) // 'Ethereum Mainnet'
### Custom Transport Configuration

```typescript
const bundlerClient = createFreeBundler(137, {
const bundlerClient = createFreeBundler({
transport: {
timeout: 15000,
retryCount: 5,
retryDelay: 200
}
},
chain: mainnet
})
```

### Custom Bundler URL

```typescript
const bundlerClient = createFreeBundler(1, {
bundlerUrl: 'https://your-custom-bundler.com'
const bundlerClient = createFreeBundler({
bundlerUrl: 'https://your-custom-bundler.com',
chain: mainnet
})
```

Expand All @@ -164,7 +167,7 @@ import { privateKeyToAccount } from 'viem/accounts'

const account = privateKeyToAccount('0x...')

const bundlerClient = createFreeBundler(1, {
const bundlerClient = createFreeBundler({
chain: mainnet,
account,
client: {
Expand Down
554 changes: 0 additions & 554 deletions bun.lock

This file was deleted.

Binary file modified bun.lockb
Binary file not shown.
23 changes: 7 additions & 16 deletions examples/accounts/simple7702.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,12 @@ import { privateKeyToAccount } from "viem/accounts";
import {
http,
parseUnits,
createClient,
publicActions,
walletActions,
SignAuthorizationReturnType,
Hex,
Chain
} from "viem";
import { FREE_BUNDLER_URLS } from "../../src/config.js";


export default async (
{
Expand All @@ -36,41 +33,35 @@ export default async (
) => {
const owner = privateKeyToAccount(privateKey);

const client = createClient({
account: owner,
transport: http(rpcUrl || FREE_BUNDLER_URLS[chain.id]),
chain
}).extend(publicActions).extend(walletActions);
const bundlerClient = createFreeBundler({chain})
.extend(walletActions)
.extend(publicActions);

const smartAccount: ToSimple7702SmartAccountReturnType = await toSimple7702SmartAccount({
client,
client: bundlerClient,
owner,
});

console.log("wallet:: ", smartAccount.address);

const bundlerClient = createFreeBundler(
chain.id,
{account: smartAccount, chain}
);

// check sender's code to decide if eip7702Auth tuple is necessary for userOp.
const senderCode = await client.getCode({
const senderCode = await bundlerClient.getCode({
address: smartAccount.address
});

let authorization: SignAuthorizationReturnType | undefined;
const { address: delegateAddress } = smartAccount.authorization;

if(senderCode !== `0xef0100${delegateAddress.toLowerCase().substring(2)}`) {
authorization = await client.signAuthorization(smartAccount.authorization)
authorization = await bundlerClient.signAuthorization(smartAccount.authorization)
}

const paymasterClient = paymasterUrl ? createPaymasterClient({
transport: http(paymasterUrl)
}) : undefined;

const userOpHash = await bundlerClient.sendUserOperation({
account: smartAccount,
authorization,
calls: [
{to: "0x09FD4F6088f2025427AB1e89257A44747081Ed59", value: parseUnits('0.0000001', 18)}
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@etherspot/free-bundler",
"version": "1.0.1-alpha.0",
"version": "1.0.1",
"type": "module",
"description": "Free bundler client for ERC-4337 account abstraction with preconfigured endpoints",
"main": "dist/index.js",
Expand Down Expand Up @@ -64,7 +64,7 @@
},
"homepage": "https://github.com/etherspot/free-bundler#readme",
"peerDependencies": {
"viem": "^2.37.4"
"viem": "2.37.8"
},
"devDependencies": {
"@types/node": "^20.0.0",
Expand Down
11 changes: 5 additions & 6 deletions src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,17 +41,16 @@ import { getFreeBundlerUrl, validateChainId } from './utils.js'
* ```
*/
export function createFreeBundler<
chain extends Chain | undefined = undefined,
chain extends Chain,
account extends SmartAccount | undefined = undefined,
>(
chainId: number,
options: CreateFreeBundlerOptions<chain, account> = {}
options: CreateFreeBundlerOptions<chain, account>
): FreeBundlerClient<Transport, chain, account> {
// Get bundler URL from options or use preconfigured free endpoint
const bundlerUrl = options.bundlerUrl || getFreeBundlerUrl(chainId)
const bundlerUrl = options.bundlerUrl || getFreeBundlerUrl(options.chain.id)

if (!bundlerUrl) {
validateChainId(chainId)
validateChainId(options.chain.id)
}

// Create HTTP transport with configuration
Expand Down
4 changes: 2 additions & 2 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@ export interface ClientOptions {
}

export interface CreateFreeBundlerOptions<
chain extends Chain | undefined = undefined,
chain extends Chain,
account extends SmartAccount | undefined = undefined,
> {
/** Custom bundler URL to override default */
bundlerUrl?: string
/** Chain configuration */
chain?: chain
chain: chain
/** Account configuration */
account?: account
/** Transport configuration options */
Expand Down