> ## Documentation Index
> Fetch the complete documentation index at: https://voltaire.tevm.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# PackedUserOperation

> ERC-4337 packed user operation structure (v0.7)

# PackedUserOperation

PackedUserOperation represents an ERC-4337 v0.7+ user operation with optimized field packing. Gas limits and fees are packed into bytes32 fields, reducing calldata size and lowering costs for bundlers.

## Quick Start

```typescript theme={null}
import { PackedUserOperation } from '@tevm/voltaire/primitives/PackedUserOperation';
import { UserOperation } from '@tevm/voltaire/primitives/UserOperation';
import { ENTRYPOINT_V07 } from '@tevm/voltaire/primitives/EntryPoint';

// Create from v0.6 UserOperation
const userOp = UserOperation.from({
  sender: "0x742d35Cc6634C0532925a3b844Bc9e7595f251e3",
  nonce: 0n,
  initCode: "0x",
  callData: "0x...",
  callGasLimit: 100000n,
  verificationGasLimit: 200000n,
  preVerificationGas: 50000n,
  maxFeePerGas: 1000000000n,
  maxPriorityFeePerGas: 1000000000n,
  paymasterAndData: "0x",
  signature: "0x",
});

// Pack to v0.7
const packed = UserOperation.pack(userOp);

// Hash for signing
const hash = PackedUserOperation.hash(packed, ENTRYPOINT_V07, 1);

// Unpack back to v0.6
const unpacked = PackedUserOperation.unpack(packed);
```

## Type Definition

```typescript theme={null}
export type PackedUserOperationType = {
  readonly sender: AddressType;
  readonly nonce: Uint256Type;
  readonly initCode: Uint8Array;
  readonly callData: Uint8Array;
  readonly accountGasLimits: Uint8Array; // bytes32
  readonly preVerificationGas: Uint256Type;
  readonly gasFees: Uint8Array; // bytes32
  readonly paymasterAndData: Uint8Array;
  readonly signature: Uint8Array;
} & { readonly [brand]: "PackedUserOperation" };
```

## Field Packing

### accountGasLimits (bytes32)

Packs verification and call gas limits:

```
verificationGasLimit (128 bits) || callGasLimit (128 bits)
```

### gasFees (bytes32)

Packs priority fee and max fee:

```
maxPriorityFeePerGas (128 bits) || maxFeePerGas (128 bits)
```

## API Reference

### from

Create PackedUserOperation from parameters.

```typescript theme={null}
function from(params: {
  sender: AddressType | string | number | bigint | Uint8Array;
  nonce: Uint256Type | bigint | number | string;
  initCode: Uint8Array | string;
  callData: Uint8Array | string;
  accountGasLimits: Uint8Array | string; // 32 bytes
  preVerificationGas: Uint256Type | bigint | number | string;
  gasFees: Uint8Array | string; // 32 bytes
  paymasterAndData: Uint8Array | string;
  signature: Uint8Array | string;
}): PackedUserOperationType
```

### hash

Compute userOpHash for signing.

```typescript theme={null}
function hash(
  packedUserOp: PackedUserOperationType,
  entryPoint: AddressType | string | number | bigint | Uint8Array,
  chainId: bigint | number
): Uint8Array
```

### unpack

Convert PackedUserOperation (v0.7) to UserOperation (v0.6).

```typescript theme={null}
function unpack(
  packedUserOp: PackedUserOperationType
): UserOperationType
```

## Packing Implementation

### Pack Gas Limits

```typescript theme={null}
// accountGasLimits = verificationGasLimit (128) || callGasLimit (128)
const accountGasLimits = new Uint8Array(32);

// High 16 bytes: verificationGasLimit
let verification = verificationGasLimit;
for (let i = 15; i >= 0; i--) {
  accountGasLimits[i] = Number(verification & 0xffn);
  verification >>= 8n;
}

// Low 16 bytes: callGasLimit
let call = callGasLimit;
for (let i = 31; i >= 16; i--) {
  accountGasLimits[i] = Number(call & 0xffn);
  call >>= 8n;
}
```

### Pack Gas Fees

```typescript theme={null}
// gasFees = maxPriorityFeePerGas (128) || maxFeePerGas (128)
const gasFees = new Uint8Array(32);

// High 16 bytes: maxPriorityFeePerGas
let priority = maxPriorityFeePerGas;
for (let i = 15; i >= 0; i--) {
  gasFees[i] = Number(priority & 0xffn);
  priority >>= 8n;
}

// Low 16 bytes: maxFeePerGas
let max = maxFeePerGas;
for (let i = 31; i >= 16; i--) {
  gasFees[i] = Number(max & 0xffn);
  max >>= 8n;
}
```

## Benefits Over v0.6

1. **Reduced calldata**: Smaller operation size
2. **Lower gas costs**: Less data to submit
3. **Bundler efficiency**: Lower costs for bundlers
4. **Backward compatible**: Can convert to/from v0.6

## Usage Patterns

### Round-trip Conversion

```typescript theme={null}
import { UserOperation } from '@tevm/voltaire/primitives/UserOperation';
import { PackedUserOperation } from '@tevm/voltaire/primitives/PackedUserOperation';

// Start with v0.6
const userOp = UserOperation.from({
  sender: "0x...",
  nonce: 0n,
  initCode: "0x",
  callData: "0x...",
  callGasLimit: 100000n,
  verificationGasLimit: 200000n,
  preVerificationGas: 50000n,
  maxFeePerGas: 1500000000n,
  maxPriorityFeePerGas: 1000000000n,
  paymasterAndData: "0x",
  signature: "0x",
});

// Pack to v0.7
const packed = UserOperation.pack(userOp);

// Unpack back to v0.6
const unpacked = PackedUserOperation.unpack(packed);

// Values match
console.log(unpacked.callGasLimit === userOp.callGasLimit); // true
console.log(unpacked.maxFeePerGas === userOp.maxFeePerGas); // true
```

### Direct Creation

```typescript theme={null}
import { PackedUserOperation } from '@tevm/voltaire/primitives/PackedUserOperation';

// Manually create packed fields
const accountGasLimits = new Uint8Array(32);
// ... pack verification and call gas

const gasFees = new Uint8Array(32);
// ... pack priority and max fees

const packed = PackedUserOperation.from({
  sender: "0x...",
  nonce: 0n,
  initCode: "0x",
  callData: "0x...",
  accountGasLimits,
  preVerificationGas: 50000n,
  gasFees,
  paymasterAndData: "0x",
  signature: "0x",
});
```

## Related Types

* [PackedUserOperation (Effect)](https://voltaire-effect.tevm.sh/primitives/packed-user-operation) - Effect.ts integration with Schema validation
* [UserOperation](/primitives/user-operation) - v0.6 format
* [EntryPoint](/primitives/entry-point) - Entry point contract
* [Paymaster](/primitives/paymaster) - Gas sponsorship
* [Bundler](/primitives/bundler) - Operation bundler

## References

* [ERC-4337 Specification](https://eips.ethereum.org/EIPS/eip-4337)
* [Entry Point v0.7](https://github.com/eth-infinitism/account-abstraction/tree/v0.7.0)
