Documentation ¶
Overview ¶
send_sign_userop.go
send_sign_userop.go
Index ¶
Constants ¶
const ( FailedOpSelector = "220266b6" UserOperationRevertSelector = "220266b7" SenderAddressResultSelector = "63c9b437" SignatureValidationFailSelector = "08c379a0" )
Known EntryPoint error selectors
const EntryPointErrorABI = `` /* 675-byte string literal not displayed */
Variables ¶
var ExtractUserOpCmd = &cobra.Command{ Use: "extract", Short: "Extract the embedded userOp from an aggregate userOp and prints them.", RunE: func(cmd *cobra.Command, args []string) error { providedHashes, err := utils.GetHashes(cmd) if err != nil { return config.NewError("failed to get hashes", err) } if len(providedHashes) > 0 { return config.NewError("extraction does not support hash arguments", nil) } userOps, err := utils.GetUserOps(cmd) if len(userOps) != 1 || err != nil { return config.NewError("Provide a single aggregate userOp", err) } embeddedOp, err := userOps[0].ExtractEmbeddedOp() if err != nil { return config.NewError("error extracting embedded userOp", err) } fmt.Printf("Source userOp:\n%s\n", userOps[0]) if err := userOps[0].SetEVMInstructions([]byte{}); err != nil { return config.NewError("failed setting the sourceOp EVM instructions", err) } if err := utils.PrintSignedOpJSON(userOps[0]); err != nil { return config.NewError("failed to print source userOp", err) } fmt.Printf("\n===================== Extracted userOp =====================>\n\n") fmt.Printf("%s\n", embeddedOp.String()) if err := embeddedOp.SetEVMInstructions([]byte{}); err != nil { return config.NewError("failed setting the embedded EVM instructions", err) } if err := utils.PrintSignedOpJSON(embeddedOp); err != nil { return config.NewError("failed to print extracted userOp", err) } return nil }, }
ExtractUserOpCmd represents the command to extract embedded user operations from aggregate user operations.
var HashUserOpCmd = &cobra.Command{ Use: "hash", Short: "Print the userOp's hash", RunE: func(cmd *cobra.Command, args []string) error { nodes, _, entrypointAddr, eoaSigner, err := config.ReadConf(false) if err != nil { return config.NewError("failed to read configuration", err) } userOps, err := utils.GetUserOps(cmd) if err != nil { return config.NewError("failed to get user operations", err) } if len(userOps) != 1 { return config.NewError("invalid number of user operations", fmt.Errorf("expected 1 userOp, got %d", len(userOps))) } chainMonikers, err := utils.GetChainMonikers(cmd, nodes, len(userOps)) if err != nil { return config.NewError("failed to get chain monikers", err) } providedHashes, err := utils.GetHashes(cmd) if err != nil { return config.NewError("failed to get hashes", err) } p, err := NewUserOpProcessor(userOps, nodes, "", entrypointAddr, eoaSigner, providedHashes, chainMonikers) if err != nil { return config.NewError("failed to create user operation processor", err) } if err := p.setXOpHashes(userOps, Offline); err != nil { return config.NewError("failed to set operation hashes", err) } return nil }, }
HashUserOpCmd represents the command to sign user operations.
var OnChainUserOpCmd = &cobra.Command{ Use: "onchain", Short: "Submit a signed userOp on-chain bypassing the bundler", RunE: func(cmd *cobra.Command, args []string) error { nodes, bundlerURL, entrypointAddr, eoaSigner, err := config.ReadConf(false) if err != nil { return config.NewError("failed to read configuration", err) } userOps, err := utils.GetUserOps(cmd) if err != nil { return config.NewError("failed to get user operations", err) } hashes, err := utils.GetHashes(cmd) if err != nil { return config.NewError("failed to get hashes", err) } chainMonikers, err := utils.GetChainMonikers(cmd, nodes, len(userOps)) if err != nil { return config.NewError("failed to get chain monikers", err) } processor, err := NewUserOpProcessor(userOps, nodes, bundlerURL, entrypointAddr, eoaSigner, hashes, chainMonikers) if err != nil { return config.NewError("failed to create user operation processor", err) } if err := processor.ProcessUserOps(userOps, DirectSubmit); err != nil { return config.NewError("failed to process user operations", err) } return nil }, }
OnChainUserOpCmd represents the command to submit user operations on-chain.
var RecoverSignerCmd = &cobra.Command{ Use: "recover", Short: "Recover the userOp signature's signer. Signatures with appended xData are supported. with 1 or more hashes and a signature", RunE: func(cmd *cobra.Command, args []string) error { nodes, _, entrypointAddr, eoaSigner, err := config.ReadConf(true) if err != nil { return config.NewError("failed to read configuration", err) } providedHashes, err := utils.GetHashes(cmd) if err != nil { return config.NewError("failed to get hashes", err) } if len(providedHashes) > 0 { return config.NewError("Only a single userOp is required", nil) } userOps, err := utils.GetUserOps(cmd) if len(userOps) == 0 || len(userOps) > 1 || err != nil { return config.NewError("Only a single userOp is supported", err) } chainMonikers, err := utils.GetChainMonikers(cmd, nodes, len(userOps)) if len(chainMonikers) > 2 || err != nil { return config.NewError("Only 1 additional chain is supported besides the default", err) } var chainID *big.Int if len(chainMonikers) == 1 { chainID = nodes[chainMonikers[0]].ChainID fmt.Printf("Recovering for the default chain: %s\n", nodes[chainMonikers[0]].ChainID) } else { chainID = nodes[chainMonikers[1]].ChainID fmt.Printf("Recovering for the provided chain: %s\n", nodes[chainMonikers[1]].ChainID) } op := userOps[0] opHash, err := getUserOpHash(op, entrypointAddr, chainID) if err != nil { return config.NewError("could not generate userOp hash", err) } recoverSigner(opHash, op.Signature[:op.GetSignatureEndIdx()], eoaSigner.Address.String()) displayUserOpStatus(op, chainID) if op.IsCrossChainOperation() { traceRes, err := userop.NewXDataExtractor().ExtractAndDebug(op) if err != nil { return config.NewError("No xData found", err) } fmt.Printf("Cross-chain tracing result: %s\n", traceRes) } return nil }, }
RecoverSignerCmd represents the command to sign user operations.
var SendAndSignUserOpCmd = &cobra.Command{ Use: "sign-send", Short: "Sign and send userOps with JSON input", RunE: func(cmd *cobra.Command, args []string) error { nodes, bundlerURL, entrypointAddr, eoaSigner, err := config.ReadConf(false) if err != nil { return config.NewError("failed to read configuration", err) } userOps, err := utils.GetUserOps(cmd) if err != nil { return config.NewError("failed to get user operations", err) } hashes, err := utils.GetHashes(cmd) if err != nil { return config.NewError("failed to get hashes", err) } chainMonikers, err := utils.GetChainMonikers(cmd, nodes, len(userOps)) if err != nil { return config.NewError("failed to get chain monikers", err) } processor, err := NewUserOpProcessor(userOps, nodes, bundlerURL, entrypointAddr, eoaSigner, hashes, chainMonikers) if err != nil { return config.NewError("failed to create user operation processor", err) } if err := processor.ProcessUserOps(userOps, BundlerSignSubmit); err != nil { return config.NewError("failed to process user operations", err) } return nil }, }
SendAndSignUserOpCmd represents the command to sign and send user operations.
var SendUserOpCmd = &cobra.Command{ Use: "send", Short: "Send userOps with JSON input", RunE: func(cmd *cobra.Command, args []string) error { nodes, bundlerURL, entrypointAddr, eoaSigner, err := config.ReadConf(false) if err != nil { return config.NewError("failed to read configuration", err) } userOps, err := utils.GetUserOps(cmd) if err != nil { return config.NewError("failed to get user operations", err) } hashes, err := utils.GetHashes(cmd) if err != nil { return config.NewError("failed to get hashes", err) } chainMonikers, err := utils.GetChainMonikers(cmd, nodes, len(userOps)) if err != nil { return config.NewError("failed to get chain monikers", err) } processor, err := NewUserOpProcessor(userOps, nodes, bundlerURL, entrypointAddr, eoaSigner, hashes, chainMonikers) if err != nil { return config.NewError("failed to create user operation processor", err) } if err := processor.ProcessUserOps(userOps, BundlerSubmit); err != nil { return config.NewError("failed to process user operations", err) } return nil }, }
SendUserOpCmd represents the command to send user operations.
var SignUserOpCmd = &cobra.Command{ Use: "sign", Short: "Sign userOps with JSON input", RunE: func(cmd *cobra.Command, args []string) error { nodes, bundlerURL, entrypointAddr, eoaSigner, err := config.ReadConf(false) if err != nil { return config.NewError("failed to read configuration", err) } userOps, err := utils.GetUserOps(cmd) if err != nil { return config.NewError("failed to get user operations", err) } hashes, err := utils.GetHashes(cmd) if err != nil { return config.NewError("failed to get hashes", err) } chainMonikers, err := utils.GetChainMonikers(cmd, nodes, len(userOps)) if err != nil { return config.NewError("failed to get chain monikers", err) } processor, err := NewUserOpProcessor(userOps, nodes, bundlerURL, entrypointAddr, eoaSigner, hashes, chainMonikers) if err != nil { return config.NewError("failed to create user operation processor", err) } if err := processor.ProcessUserOps(userOps, Offline); err != nil { return config.NewError("failed to process user operations", err) } return nil }, }
SignUserOpCmd represents the command to sign user operations.
Functions ¶
This section is empty.
Types ¶
type EntryPointError ¶
EntryPointError represents a decoded error from the EntryPoint contract
func DecodeEntryPointError ¶
func DecodeEntryPointError(data []byte) (*EntryPointError, error)
func (*EntryPointError) Error ¶
func (e *EntryPointError) Error() string
Error implements the error interface
type SubmissionType ¶
type SubmissionType int
SubmissionType represents different methods of submitting a UserOperation
const ( // Offline mode - only signs or generates or validates but does not submit the UserOperation Offline SubmissionType = iota // BundlerSubmit sends the UserOperation to an EIP-4337 bundler BundlerSubmit // BundlerSignSubmit signs and sends the UserOperation to an EIP-4337 bundler BundlerSignSubmit // DirectSubmit bypasses the bundler and sends directly to an Ethereum node DirectSubmit )
type UserOpProcessor ¶
type UserOpProcessor struct { Nodes config.NodesMap BundlerURL string EntrypointAddr common.Address Signer *signer.EOA ProvidedHashes []common.Hash CachedHashes []common.Hash ChainMonikers []string ChainIDs []*big.Int }
func NewUserOpProcessor ¶
func (*UserOpProcessor) ProcessUserOps ¶
func (p *UserOpProcessor) ProcessUserOps(userOps []*model.UserOperation, submissionAction SubmissionType) error
ProcessUserOps processes the UserOperations by setting the UserOperation hashes, signing the UserOperations, and submitting the UserOperations to the bundler or directly to the Ethereum node.
func (*UserOpProcessor) Set4337Nonce ¶
func (p *UserOpProcessor) Set4337Nonce(op *model.UserOperation, chainMoniker string) error