Documentation ¶
Overview ¶
Package model provides common data structures shared among blndgs projects. This file has been copied from the Bundler project. It is included in the model package to avoid introducing a cyclical dependency between the Model and Bundler projects and accommodate Bundler<->Solver communication. Any modifications made to the Bundler file should be reflected here as well to maintain consistency.
Note: In the future, this file may move here as the single source of truth.
Package model provides structures and methods for the communication between the Bundler and Solver. This file defines extensions to the UserOperation struct and methods for extracting and inserting Intent JSON from/to the CallData and Signature fields.
The CallData field in a userOperation is expected to contain either the Intent JSON or the EVM instructions but not both. The Intent JSON is expected to be appended to the signature value within the Signature field when the Calldata field contains the EVM instructions. The Signature field is expected to contain only the signature when the userOperation is unsolved.
Index ¶
- Constants
- Variables
- func BuildCrossChainData(intentJSON []byte, hashList []CrossChainHashListEntry) ([]byte, error)
- func ExtractDestinationChainID(intent *pb.Intent) (*big.Int, error)
- func ExtractJSONFromField(fieldData string) (string, bool)
- func ExtractSourceChainID(intent *pb.Intent) (*big.Int, error)
- func FromBigInt(i *big.Int) (*protov1.BigInt, error)
- func IsCrossChainData(data []byte, minHashListLength int, maxHashListLength int) bool
- func IsCrossChainIntent(intent *pb.Intent) (bool, error)
- func ToBigInt(b *protov1.BigInt) (*big.Int, error)
- type BodyOfUserOps
- type CrossChainData
- type CrossChainHashListEntry
- type KernelSignaturePrefix
- type UserOpSolvedStatus
- type UserOperation
- func (op *UserOperation) Aggregate(embeddedOp *UserOperation) error
- func (op *UserOperation) EncodeCrossChainCallData(entrypoint common.Address, otherOpHash common.Hash, isSourceOp bool) ([]byte, error)
- func (op *UserOperation) ExtractEmbeddedOp() (*UserOperation, error)
- func (op *UserOperation) GetDynamicGasPrice(basefee *big.Int) *big.Int
- func (op *UserOperation) GetFactory() common.Address
- func (op *UserOperation) GetIntent() (*pb.Intent, error)
- func (op *UserOperation) GetIntentJSON() (string, error)
- func (op *UserOperation) GetMaxGasAvailable() *big.Int
- func (op *UserOperation) GetMaxPrefund() *big.Int
- func (op *UserOperation) GetPaymaster() common.Address
- func (op *UserOperation) GetSignatureEndIdx() int
- func (op *UserOperation) GetSignatureValue() []byte
- func (op *UserOperation) GetUserOpHash(entryPoint common.Address, chainID *big.Int) common.Hash
- func (op *UserOperation) HasIntent() bool
- func (op *UserOperation) HasSignature() bool
- func (op *UserOperation) HasSignatureExact() bool
- func (op *UserOperation) IsCrossChainIntent() (bool, error)
- func (op *UserOperation) IsCrossChainOperation() bool
- func (op *UserOperation) MarshalJSON() ([]byte, error)
- func (op *UserOperation) Pack() []byte
- func (op *UserOperation) PackForSignature() []byte
- func (op *UserOperation) SetEVMInstructions(callDataValue []byte) error
- func (op *UserOperation) SetIntent(intentJSON string) error
- func (op *UserOperation) String() string
- func (op *UserOperation) ToMap() (map[string]any, error)
- func (op *UserOperation) UnmarshalJSON(data []byte) error
- func (op *UserOperation) Validate() (UserOpSolvedStatus, error)
- type UserOperationExt
Constants ¶
const ( ErrNoIntentFound userOperationError = "no Intent found" ErrIntentInvalidJSON userOperationError = "invalid Intent JSON" ErrNoSignatureValue userOperationError = "signature value is not found" ErrNoCallData userOperationError = "no CallData found" ErrInvalidCallData userOperationError = "invalid hex-encoded CallData" ErrInvalidSignature userOperationError = "invalid hex-encoded signature" ErrInvalidUserOp userOperationError = "ambiguous UserOperation solved state" ErrDoubleIntentDef userOperationError = "intent JSON is set in both calldata and signature fields" ErrUnsupportedIntentType userOperationError = "unsupported intent type" ErrInvalidChainID userOperationError = "invalid chain ID" )
Define error constants
const ( KernelSignatureLength = 69 SimpleSignatureLength = 65 )
const ( CrossChainMarker uint16 = 0xFFFF HashPlaceholder uint16 = 0xFFFF // Placeholder for the userOp hash that will be computed during validation OpTypeLength = 2 IntentJSONLengthSize = 2 HashLength = 32 HashListLengthSize = 1 MinOpCount = 2 MaxOpCount = 3 PlaceholderSize = 2 OperationHashSize = 32 )
Variables ¶
var ( // UserOpPrimitives is the primitive ABI types for each UserOperation field. UserOpPrimitives = []abi.ArgumentMarshaling{ {Name: "sender", InternalType: "Sender", Type: "address"}, {Name: "nonce", InternalType: "Nonce", Type: "uint256"}, {Name: "initCode", InternalType: "InitCode", Type: "bytes"}, {Name: "callData", InternalType: "CallData", Type: "bytes"}, {Name: "callGasLimit", InternalType: "CallGasLimit", Type: "uint256"}, {Name: "verificationGasLimit", InternalType: "VerificationGasLimit", Type: "uint256"}, {Name: "preVerificationGas", InternalType: "PreVerificationGas", Type: "uint256"}, {Name: "maxFeePerGas", InternalType: "MaxFeePerGas", Type: "uint256"}, {Name: "maxPriorityFeePerGas", InternalType: "MaxPriorityFeePerGas", Type: "uint256"}, {Name: "paymasterAndData", InternalType: "PaymasterAndData", Type: "bytes"}, {Name: "signature", InternalType: "Signature", Type: "bytes"}, } // UserOpType is the ABI type of a UserOperation. UserOpType, _ = abi.NewType("tuple", "op", UserOpPrimitives) // UserOpArr is the ABI type for an array of UserOperations. UserOpArr, _ = abi.NewType("tuple[]", "ops", UserOpPrimitives) )
var ( ErrInvalidHashListLength = errors.New("invalid hash list length") ErrInvalidHashListEntry = errors.New("invalid hash list entry") ErrPlaceholderNotFound = errors.New("invalid hash list with missing placeholder") ErrHashListInvalidValue = errors.New("invalid hash list hash value") ErrMissingCrossChainData = errors.New("missing cross-chain data") ErrCrossChainSameChain = errors.New("destination and source chain cannot be the same") ErrNoIntent = errors.New("no intent found") )
Error definitions
var EntrypointV06 = common.HexToAddress("0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789")
var KernelSignaturePrefixValues = map[KernelSignaturePrefix][]byte{ Prefix0: []byte{0, 0, 0, 0}, Prefix1: []byte{0, 0, 0, 1}, Prefix2: []byte{0, 0, 0, 2}, }
Functions ¶
func BuildCrossChainData ¶ added in v0.45.0
func BuildCrossChainData(intentJSON []byte, hashList []CrossChainHashListEntry) ([]byte, error)
BuildCrossChainData constructs the cross-chain data payload used in cross-chain UserOperations.
**Purpose:** This low-level utility function constructs the cross-chain data payload by combining the Intent JSON and a provided hash list. It formats the data according to the specified cross-chain data structure required by cross-chain operations.
**When to Use:** Use `BuildCrossChainData` when you have the Intent JSON and the hash list already prepared and need to construct the cross-chain data payload manually. This function does not perform any sorting or validation of the hash list entries.
**Parameters:**
- `intentJSON`: The Intent JSON bytes.
- `hashList`: A slice of `CrossChainHashListEntry` representing operation hashes and placeholders.
**Returns:**
- `[]byte`: The constructed cross-chain data payload.
- `error`: An error if building fails (e.g., if the Intent JSON exceeds the maximum allowed size).
**Cross-Chain Data Format:** The cross-chain data is structured as follows: - **OpType (2 bytes)**: A marker indicating a cross-chain operation (`0xFFFF`). - **Intent JSON Length (2 bytes)**: The length of the Intent JSON. - **Intent JSON (variable length)**: The serialized Intent JSON. - **Hash List Length (1 byte)**: The number of entries in the hash list. - **Hash List Entries (variable length)**: Each entry is either:
- **Placeholder (2 bytes)**: `0xFFFF`, representing the current operation's hash.
- **Operation Hash (32 bytes)**: The hash of another operation in the cross-chain set.
**Usage Notes:** - This function assumes that the hash list entries are already in the correct order. - It does not perform any sorting or validation on the hash list. - The caller is responsible for ensuring the hash list is correctly constructed.
**Related Functions:**
- `EncodeCrossChainCallData`: A higher-level function that builds the cross-chain call data for a `UserOperation`, including sorting and constructing the hash list.
func ExtractDestinationChainID ¶ added in v0.45.0
ExtractDestinationChainID retrieves the chain ID from the 'to' field of the intent.
func ExtractJSONFromField ¶ added in v0.14.0
ExtractJSONFromField tries to unmarshal the provided field data into an Intent struct. If successful, it assumes the field data is a valid JSON string of the Intent.
Returns:
- string: The JSON data if unmarshalling is successful.
- bool: A boolean indicating if the unmarshalling was successful.
func ExtractSourceChainID ¶ added in v0.45.0
ExtractSourceChainID retrieves the chain ID from the 'from' field of the intent.
func FromBigInt ¶ added in v0.18.3
FromBigInt converts a *big.Int to a protobuf BigInt message.
func IsCrossChainData ¶ added in v0.50.0
IsCrossChainData checks if the provided data represents cross-chain data.
Parameters:
- data: The data to check.
- minHashListLength: Minimum required length of the hash list.
- maxHashListLength: Maximum allowed length of the hash list.
Returns:
- bool: True if it's cross-chain data, false otherwise.
func IsCrossChainIntent ¶ added in v0.45.0
IsCrossChainIntent checks if the given Intent represents a cross-chain intent.
Parameters:
- intent: The Intent struct to check.
Returns:
- bool: True if it's a cross-chain intent, false otherwise.
- error: An error if chain IDs cannot be extracted.
Types ¶
type BodyOfUserOps ¶ added in v0.4.0
type BodyOfUserOps struct { UserOps []*UserOperation `json:"user_ops" binding:"required,dive"` UserOpsExt []UserOperationExt `json:"user_ops_ext" binding:"required,dive"` }
BodyOfUserOps represents the request body for HTTP requests sent to the Solver. It contains slices of UserOperation and UserOperationExt, representing the primary data and its extended information required for processing by the Solver.
type CrossChainData ¶ added in v0.45.0
type CrossChainData struct { IntentJSON []byte HashList []CrossChainHashListEntry }
CrossChainData represents the parsed components of cross-chain data.
func ParseCrossChainData ¶ added in v0.45.0
func ParseCrossChainData(data []byte) (*CrossChainData, error)
ParseCrossChainData parses the cross-chain data into a structured format.
type CrossChainHashListEntry ¶ added in v0.45.0
CrossChainHashListEntry represents an entry in the cross-chain hash list.
func BuildSortedHashList ¶ added in v0.45.0
func BuildSortedHashList(thisOpHash common.Hash, otherOpHashes []common.Hash) ([]CrossChainHashListEntry, error)
BuildSortedHashList constructs a sorted hash list for cross-chain operations.
**Purpose:** This utility function creates a hash list containing the placeholder for the current operation's hash and the hashes of other operations involved in the cross-chain set. It sorts the hash list entries in ascending order to establish a deterministic hash calculation.
**Parameters:**
- `thisOpHash`: The hash of the current `UserOperation`.
- `otherOpHashes`: A slice of hashes (`[]common.Hash`) representing other operations in the cross-chain set.
**Returns:**
- `[]CrossChainHashListEntry`: The sorted hash list entries.
- `error`: An error if the operation hashes are invalid.
**Usage Notes:** - Use this function to build the hash list when preparing cross-chain call data. - It ensures the placeholder and other operation hashes are correctly ordered.
**Example:** ```go hashList, err := BuildSortedHashList(thisOpHash, []common.Hash{otherOpHash})
if err != nil { // Handle error }
crossChainData, err := BuildCrossChainData(intentJSONBytes, hashList) ```
**Related Functions:** - `EncodeCrossChainCallData`: Can utilize this function to build the hash list. - `BuildCrossChainData`: Consumes the hash list entries to construct the cross-chain data payload.
type KernelSignaturePrefix ¶ added in v0.34.0
type KernelSignaturePrefix int
const ( Prefix0 KernelSignaturePrefix = iota Prefix1 Prefix2 )
type UserOpSolvedStatus ¶ added in v0.16.0
type UserOpSolvedStatus int
UserOpSolvedStatus is an enum type that defines the possible states of a UserOperation's resolution.It indicates whether an operation is unsolved, solved, conventional, or in an unknown state.
const ( UnsolvedUserOp UserOpSolvedStatus = iota UnsolvedAggregateUserOp // Unsolved Cross-chain userOp that contains 1 or more cross-chain unsolved userOps SolvedUserOp // Intent Json values must be present // ConventionalUserOp indicates that the UserOperation does not contain Intent JSON and // must have a valid EVM calldata value. ConventionalUserOp UnSignedUserOp // UnSignedUserOp indicates that the UserOperation does not contain a signature value. // UnknownUserOp indicates that the UserOperation's state is unknown or ambiguous. UnknownUserOp )
type UserOperation ¶ added in v0.4.0
type UserOperation struct { Sender common.Address `json:"sender" mapstructure:"sender" validate:"required"` Nonce *big.Int `json:"nonce" mapstructure:"nonce" validate:"required"` InitCode []byte `json:"initCode" mapstructure:"initCode" validate:"required"` CallData []byte `json:"callData" mapstructure:"callData" validate:"required"` CallGasLimit *big.Int `json:"callGasLimit" mapstructure:"callGasLimit" validate:"required"` VerificationGasLimit *big.Int `json:"verificationGasLimit" mapstructure:"verificationGasLimit" validate:"required"` PreVerificationGas *big.Int `json:"preVerificationGas" mapstructure:"preVerificationGas" validate:"required"` MaxFeePerGas *big.Int `json:"maxFeePerGas" mapstructure:"maxFeePerGas" validate:"required"` MaxPriorityFeePerGas *big.Int `json:"maxPriorityFeePerGas" mapstructure:"maxPriorityFeePerGas" validate:"required"` PaymasterAndData []byte `json:"paymasterAndData" mapstructure:"paymasterAndData" validate:"required"` Signature []byte `json:"signature" mapstructure:"signature"` }
UserOperation represents an EIP-4337 style transaction for a smart contract account.
func (*UserOperation) Aggregate ¶ added in v0.47.0
func (op *UserOperation) Aggregate(embeddedOp *UserOperation) error
Aggregate combines the current UserOperation with another unsolved cross-chain UserOperation.
Preconditions:
- Both the called UserOperation and the embeddedOp are valid unsolved userOps (Validate() returns UnsolvedUserOp).
- Both userOps are valid cross-chain userOps.
If any precondition is not met, returns an error indicating which userOp didn't meet the precondition.
Behavior:
- Copies the embeddedOp's packed data into the signature field of the called UserOperation.
- If initCode is set in the embeddedOp, it is copied into the called UserOperation.
- If the same embeddedOp is already aggregated, the operation is idempotent.
- If a different embeddedOp is already aggregated, the existing packed
- data is replaced with the new embeddedOp's data.
Returns:
- error: An error if the operation fails.
func (*UserOperation) EncodeCrossChainCallData ¶ added in v0.45.0
func (op *UserOperation) EncodeCrossChainCallData(entrypoint common.Address, otherOpHash common.Hash, isSourceOp bool) ([]byte, error)
EncodeCrossChainCallData constructs the cross-chain call data payload for a `UserOperation`.
**Purpose:** This high-level function (vs the `BuildCrossChainData`) prepares the cross-chain call data by calculating the current operation's hash, building and sorting the hash list, and constructing the cross-chain data payload. It encapsulates the logic required for cross-chain operations involving two `UserOperation`s or extended for more in the future.
**When to Use:** Use `EncodeCrossChainCallData` when you need to construct the cross-chain call data for a `UserOperation` and have all the necessary parameters, including the entry point, the hash of the other operation, and the Intent JSON. This function handles the calculation of hashes, sorting of the hash list, and building the cross-chain data payload.
**Parameters:**
- `entrypoint`: The entry point address used to calculate the `UserOperation` hash.
- `otherOpHash`: The operation hash of the other chain's `UserOperation`.
- `isSourceOp`: A boolean indicating if this is the source operation (`true`) or the destination operation (`false`).
**Returns:**
- `[]byte`: The encoded cross-chain call data payload: Intent JSON and sorted hash list.
- `error`: An error if encoding fails (e.g., invalid chain IDs or Intent JSON exceeds maximum size).
**Cross-Chain Data Construction Steps:** 1. **Calculate Current Operation Hash**: Computes the hash of the current `UserOperation`. 2. **Build and Sort Hash List**:
- Create a hash list containing a placeholder for the current operation's hash and the other operation's hash.
- Sort the hash list in ascending order based on the hash values.
3. **Construct Cross-Chain Data**:
- Use `BuildCrossChainData` to assemble the cross-chain data payload.
**Related Functions:** - `BuildCrossChainData`: Used internally to construct the cross-chain data payload.
func (*UserOperation) ExtractEmbeddedOp ¶ added in v0.47.0
func (op *UserOperation) ExtractEmbeddedOp() (*UserOperation, error)
ExtractEmbeddedOp reverses the Aggregate operation and extracts the packed other UserOperation from the signature field.
Returns:
- *UserOperation: The extracted UserOperation.
- error: An error if extraction fails.
func (*UserOperation) GetDynamicGasPrice ¶ added in v0.4.0
func (op *UserOperation) GetDynamicGasPrice(basefee *big.Int) *big.Int
GetDynamicGasPrice returns the effective gas price paid by the UserOperation given a basefee. If basefee is nil, it will assume a value of 0.
func (*UserOperation) GetFactory ¶ added in v0.4.0
func (op *UserOperation) GetFactory() common.Address
GetFactory returns the address portion of InitCode if applicable. Otherwise it returns the zero address.
func (*UserOperation) GetIntent ¶ added in v0.4.0
func (op *UserOperation) GetIntent() (*pb.Intent, error)
GetIntent takes the Intent Type from the CallData or Signature field, decodes it into an Intent struct, and returns the struct.
func (*UserOperation) GetIntentJSON ¶ added in v0.4.0
func (op *UserOperation) GetIntentJSON() (string, error)
GetIntentJSON returns the Intent JSON from the CallData or signature fields, if present.
func (*UserOperation) GetMaxGasAvailable ¶ added in v0.4.0
func (op *UserOperation) GetMaxGasAvailable() *big.Int
GetMaxGasAvailable returns the max amount of gas that can be consumed by this UserOperation.
func (*UserOperation) GetMaxPrefund ¶ added in v0.4.0
func (op *UserOperation) GetMaxPrefund() *big.Int
GetMaxPrefund returns the max amount of wei required to pay for gas fees by either the sender or paymaster.
func (*UserOperation) GetPaymaster ¶ added in v0.4.0
func (op *UserOperation) GetPaymaster() common.Address
GetPaymaster returns the address portion of PaymasterAndData if applicable. Otherwise it returns the zero address.
func (*UserOperation) GetSignatureEndIdx ¶ added in v0.34.0
func (op *UserOperation) GetSignatureEndIdx() int
GetSignatureEndIdx returns the end index of the signature value in the UserOperation's Signature field. Returns either of the 3 following values:
- KernelSignatureLength: If the signature is a kernel signature with a prefix.
- SimpleSignatureLength: If the signature is an ECDSA signature without a prefix.
- 0: If the signature is a kernel signature without a prefix or as a fallback
func (*UserOperation) GetSignatureValue ¶ added in v0.34.0
func (op *UserOperation) GetSignatureValue() []byte
GetSignatureValue retrieves the signature value from a UserOperation.
This function supports three use cases:
No, or invalid signature value: It returns nil.
If the UserOperation has a Kernel signature (identified by a specific prefix), and the length of the signature is greater than or equal to the KernelSignatureLength, it returns the signature up to the KernelSignatureLength.
Treated as a fallback if the UserOperation has a sufficient length for a conventional signature, it returns the signature up to the SignatureLength.
Otherwise, it returns nil.
func (*UserOperation) GetUserOpHash ¶ added in v0.4.0
GetUserOpHash returns the hash of the userOp + entryPoint address + chainID.
func (*UserOperation) HasIntent ¶ added in v0.4.0
func (op *UserOperation) HasIntent() bool
HasIntent checks if the CallData or signature field contains a valid Intent JSON that decodes successfully into an Intent struct.
func (*UserOperation) HasSignature ¶ added in v0.13.0
func (op *UserOperation) HasSignature() bool
HasSignature checks if the signature field contains a fixed length ECDSA hex-encoded signature value either a conventional (65 bytes) or a kernel with or without Intent.
func (*UserOperation) HasSignatureExact ¶ added in v0.34.0
func (op *UserOperation) HasSignatureExact() bool
HasSignatureExact checks for an exact match of the signature length and the signature field contains a fixed length hex-encoded signature value either a conventional or a kernel without Intent.
func (*UserOperation) IsCrossChainIntent ¶ added in v0.45.0
func (op *UserOperation) IsCrossChainIntent() (bool, error)
IsCrossChainIntent checks if the UserOperation represents a cross-chain intent.
func (*UserOperation) IsCrossChainOperation ¶ added in v0.45.0
func (op *UserOperation) IsCrossChainOperation() bool
IsCrossChainOperation checks if the UserOperation is a cross-chain operation.
func (*UserOperation) MarshalJSON ¶ added in v0.4.0
func (op *UserOperation) MarshalJSON() ([]byte, error)
MarshalJSON returns a JSON encoding of the UserOperation.
func (*UserOperation) Pack ¶ added in v0.4.0
func (op *UserOperation) Pack() []byte
Pack returns a standard message of the userOp. This cannot be used to generate a userOpHash.
func (*UserOperation) PackForSignature ¶ added in v0.4.0
func (op *UserOperation) PackForSignature() []byte
PackForSignature returns a minimal message of the userOp. This can be used to generate a userOpHash.
func (*UserOperation) SetEVMInstructions ¶ added in v0.6.0
func (op *UserOperation) SetEVMInstructions(callDataValue []byte) error
SetEVMInstructions sets the EVM instructions in the CallData field of the UserOperation.
If the operation is unsolved, it moves the Intent JSON to the Signature field if present, and then sets the provided EVM instructions in the CallData field.
func (*UserOperation) SetIntent ¶ added in v0.4.0
func (op *UserOperation) SetIntent(intentJSON string) error
SetIntent sets the Intent JSON in the appropriate field of the UserOperation based on the operation's solution state.
If the UserOperation is unsolved, the Intent JSON is set in the CallData field. If the UserOperation is solved, the Intent JSON is appended to the Signature field.
func (*UserOperation) String ¶ added in v0.7.0
func (op *UserOperation) String() string
String returns a string representation of the UserOperation.
func (*UserOperation) ToMap ¶ added in v0.4.0
func (op *UserOperation) ToMap() (map[string]any, error)
ToMap returns the current UserOp struct as a map type.
func (*UserOperation) UnmarshalJSON ¶ added in v0.6.0
func (op *UserOperation) UnmarshalJSON(data []byte) error
UnmarshalJSON does the reverse of the provided bundler custom JSON marshaler for a UserOperation.
func (*UserOperation) Validate ¶ added in v0.16.0
func (op *UserOperation) Validate() (UserOpSolvedStatus, error)
Validate checks the status of the UserOperation and returns its UserOpSolvedStatus. It determines if the operation is conventional, unsolved, or solved based on the presence and content of CallData and Signature.
Returns:
- UserOpSolvedStatus: The solved status of the UserOperation.
- error: An error if there's an issue with the operation's state or contents.
type UserOperationExt ¶ added in v0.4.0
type UserOperationExt struct { OriginalHashValue string `json:"original_hash_value" mapstructure:"original_hash_value" validate:"required"` ProcessingStatus pb.ProcessingStatus `json:"processing_status" mapstructure:"processing_status" validate:"required"` }
UserOperationExt extends the UserOperation with additional information necessary for processing by the Solver.This includes the original hash value of the UserOperation and its processing status.The sequence of UserOperationExt instances must correspond to the sequence in the UserOps slice.
func (*UserOperationExt) MarshalJSON ¶ added in v0.27.0
func (u *UserOperationExt) MarshalJSON() ([]byte, error)
func (*UserOperationExt) UnmarshalJSON ¶ added in v0.24.0
func (u *UserOperationExt) UnmarshalJSON(data []byte) error
UnmarshalJSON makes sure we can support using strings instead of arbitrary numbers for the proto processing