Documentation
¶
Overview ¶
Package userop provides an ERC-4337 pseudo-transaction object called a UserOperation which is used to execute actions through a smart contract account. This isn't to be mistaken for a regular transaction type.
Index ¶
- Variables
- type BiconomyERC20Config
- type BiconomySmartAccountInfo
- type BiconomySponsoringConfig
- type BiconomySponsorshipInfoConfig
- type BiconomyTokenInfo
- type Client
- type ClientConfig
- type ECDSASigner
- type EthBackend
- type GasConfig
- type GasLimitOverrides
- type GasPriceOverrides
- type MockUserOperationClient
- type NonceKeyRotator
- type Overrides
- type PaymasterConfig
- type PaymasterType
- type PimlicoERC20Config
- type PimlicoVerifyingConfig
- type RPCBackend
- type Receipt
- type Signer
- type UserOperation
- type WalletDeploymentOpts
Constants ¶
This section is empty.
Variables ¶
var ( // ErrNoWalletDeploymentOpts is returned when the wallet deployment opts // are required to build and submit userop, but they are not specified. ErrNoWalletDeploymentOpts = errors.New("wallet deployment opts not specified") // ErrNoWalletOwnerInWDO is returned when the wallet owner is not specified. ErrNoWalletOwnerInWDO = errors.New("wallet deployment opts: wallet owner not specified") // ErrInvalidPollDuration is returned when blockchain poll duration is non-present or its format is invalid. ErrInvalidPollDuration = errors.New("invalid blockchain poll duration") // ErrInvalidEntryPointAddress is returned when the entrypoint address is invalid. ErrInvalidEntryPointAddress = errors.New("invalid entry point address") // ErrInvalidFactoryAddress is returned when the factory address is invalid. ErrInvalidFactoryAddress = errors.New("invalid factory address") // ErrInvalidLogicAddress is returned when the logic address is invalid. ErrInvalidLogicAddress = errors.New("invalid logic address") // ErrInvalidECDSAValidatorAddress is returned when the ECDSA validator address is invalid. ErrInvalidECDSAValidatorAddress = errors.New("invalid ECDSA validator address") // ErrInvalidPaymasterAddress is returned when the paymaster address is invalid. ErrInvalidPaymasterAddress = errors.New("invalid paymaster address") // ErrNoSigner is returned when the signer is not specified. ErrNoSigner = errors.New("signer not specified") // ErrNoCalls is returned when the calls are not specified. ErrNoCalls = errors.New("calls not specified") // ErrPaymasterNotSupported is returned on attempt to build client with an unsupported paymaster type. // Make sure that the paymaster type you are trying to use // has no `unsupported` or `untested` tags in `paymaster_type.go` source file. ErrPaymasterNotSupported = errors.New("paymaster type not supported") )
var ( PaymasterDisabled = PaymasterType{"off"} PaymasterPimlicoERC20 = PaymasterType{"pimlico_erc20"} PaymasterPimlicoVerifying = PaymasterType{"pimlico_verifying"} PaymasterBiconomyERC20 = PaymasterType{"biconomy_erc20"} // not tested PaymasterBiconomySponsoring = PaymasterType{"biconomy_sponsoring"} // not tested )
Functions ¶
This section is empty.
Types ¶
type BiconomyERC20Config ¶
type BiconomyERC20Config struct {
Mode string `yaml:"mode" env:"MODE"`
CalculateGasLimits bool `yaml:"calculate_gas_limits" env:"CALCULATE_GAS_LIMITS"`
TokenInfo BiconomyTokenInfo `yaml:"token_info" env-prefix:"TOKEN_INFO_"`
}
BiconomyERC20Config represents the configuration for the Biconomy ERC20 paymaster. See the RPC endpoint docs at https://docs.biconomy.io/Paymaster/api/sponsor-useroperation#2-mode-is-erc20-
func (*BiconomyERC20Config) Init ¶
func (config *BiconomyERC20Config) Init()
type BiconomySmartAccountInfo ¶
type BiconomySmartAccountInfo struct {
Name string `yaml:"name" env:"NAME"`
Version string `yaml:"version" env:"VERSION"`
}
BiconomySmartAccountInfo represents the configuration for the Biconomy smart contract that sponsors transactions.
type BiconomySponsoringConfig ¶
type BiconomySponsoringConfig struct {
Mode string `yaml:"mode" env:"MODE"`
CalculateGasLimits bool `yaml:"calculate_gas_limits" env:"CALCULATE_GAS_LIMITS"`
ExpiryDuration int `yaml:"expiry_duration" env:"EXPIRY_DURATION"`
SponsorshipInfo BiconomySponsorshipInfoConfig `yaml:"sponsorship_info" env-prefix:"SPONSORSHIP_INFO_"`
}
BiconomySponsoringConfig represents the configuration for the Biconomy Sponsoring paymaster. See the RPC endpoint docs at https://docs.biconomy.io/Paymaster/api/sponsor-useroperation#1-mode-is-sponsored-
func (*BiconomySponsoringConfig) Init ¶
func (config *BiconomySponsoringConfig) Init()
type BiconomySponsorshipInfoConfig ¶
type BiconomySponsorshipInfoConfig struct {
WebhookData map[string]any `yaml:"webhook_data" env:"WEBHOOK_DATA"`
SmartAccountInfo BiconomySmartAccountInfo `yaml:"smart_account_info" env-prefix:"SMART_ACCOUNT_INFO_"`
}
BiconomySponsorshipInfoConfig represents the configuration for transaction sponsoring for the Biconomy Sponsoring paymaster. More about webhooks: https://docs.biconomy.io/Paymaster/api/webhookapi
type BiconomyTokenInfo ¶
type BiconomyTokenInfo struct {
FeeTokenAddress common.Address `yaml:"fee_token_address" env:"FEE_TOKEN"`
}
BiconomyTokenInfo represents the token used to pay for fees for the Biconomy paymaster.
type Client ¶
type Client interface {
// IsAccountDeployed checks whether the smart wallet for the specified owner EOA and index is deployed.
//
// Parameters:
// - owner - is the EOA address of the smart wallet owner.
// - index - is the index of the smart wallet, 0 by default. SW index allows to deploy multiple smart wallets for the same owner.
//
// Returns:
// - bool - true if the smart wallet is deployed, false if not
// - error - if failed to check.
IsAccountDeployed(ctx context.Context, owner common.Address, index decimal.Decimal) (bool, error)
// GetAccountAddress returns the address of the smart wallet for the specified owner EOA and index.
//
// Parameters:
// - owner - is the EOA address of the smart wallet owner.
// - index - is the index of the smart wallet, 0 by default. SW index allows to deploy multiple smart wallets for the same owner.
//
// Returns:
// - common.Address - an address of the smart wallet
// - error - if failed to calculate it.
GetAccountAddress(ctx context.Context, owner common.Address, index decimal.Decimal) (common.Address, error)
// NewUserOp builds a new UserOperation and fills all the fields.
//
// NOTE: only `executeBatch` is supported for now.
//
// Parameters:
// - ctx - is the context of the operation.
// - smartWallet - is the address of the smart wallet that will execute the user operation.
// - signer - is the signer function that will sign the user operation.
// - calls - is the list of calls to be executed in the user operation. Must not be empty.
// - walletDeploymentOpts - are the options for the smart wallet deployment. Can be nil if the smart wallet is already deployed.
// - overrides - are the overrides for the middleware during the user operation creation. Can be nil.
//
// Returns:
// - UserOperation - user operation with all fields filled in.
// - error - if failed to build the user operation.
NewUserOp(
ctx context.Context,
sender common.Address,
signer Signer,
calls smart_wallet.Calls,
walletDeploymentOpts *WalletDeploymentOpts,
overrides *Overrides,
) (UserOperation, error)
// SignUserOp signs the user operation with the provided signer.
//
// Parameters:
// - ctx - is the context of the operation.
// - op - is the user operation to be signed.
// - signer - is the signer function that will sign the user operation.
//
// Returns:
// - UserOperation - user operation with modified signature.
// - error - if failed to sign the user operation
SignUserOp(
ctx context.Context,
op UserOperation,
signer Signer,
) (UserOperation, error)
// SendUserOp submits a user operation to a bundler and returns a channel to await for the userOp receipt.
//
// Parameters:
// - ctx - is the context of the operation.
// - op - is the user operation to be sent.
//
// Returns:
// - <-chan Receipt - a channel to await for the userOp receipt.
// - error - if failed to send the user operation
SendUserOp(ctx context.Context, op UserOperation) (done <-chan Receipt, err error)
}
Client represents a client for creating and posting user operations.
func NewClient ¶
func NewClient(config ClientConfig) (Client, error)
NewClient is a factory that builds a new user operation client based on the provided configuration.
type ClientConfig ¶
type ClientConfig struct {
ProviderURL string `yaml:"provider_url" env:"USEROP_CLIENT_PROVIDER_URL"`
BundlerURL string `yaml:"bundler_url" env:"USEROP_CLIENT_BUNDLER_URL"`
EntryPoint common.Address `yaml:"entry_point" env:"USEROP_CLIENT_ENTRY_POINT"`
Gas GasConfig `yaml:"gas"`
SmartWallet smart_wallet.Config `yaml:"smart_wallet"`
Paymaster PaymasterConfig `yaml:"paymaster"`
LoggerLevel string `yaml:"logger_level" env:"USEROP_CLIENT_LOGGER_LEVEL"`
}
ClientConfig represents the configuration for the user operation client.
func NewClientConfigFromEnv ¶
func NewClientConfigFromEnv() (config ClientConfig, err error)
NewClientConfigFromEnv reads the client configuration from environment variables.
func NewClientConfigFromFile ¶
func NewClientConfigFromFile(path string) (config ClientConfig, err error)
NewClientConfigFromFile reads the client configuration from a file.
func (*ClientConfig) Init ¶
func (conf *ClientConfig) Init()
type ECDSASigner ¶
ECDSASigner represents a handler that signs a message using ecdsa private key.
type EthBackend ¶
type EthBackend interface {
ethereum.ChainReader
ethereum.ChainStateReader
ethereum.TransactionReader
ethereum.TransactionSender
ethereum.ContractCaller
ChainID(ctx context.Context) (*big.Int, error)
BlockNumber(ctx context.Context) (uint64, error)
WaitMinedPeriod() time.Duration
RPC() *rpc.Client
bind.ContractBackend
}
func NewEthBackend ¶
func NewEthBackend(rpcURL url.URL) (EthBackend, error)
type GasConfig ¶
type GasConfig struct {
MaxPriorityFeePerGasMultiplier decimal.Decimal `yaml:"max_priority_fee_per_gas_multiplier" env:"GAS_CONFIG_MAX_PRIORITY_FEE_PER_GAS_MULTIPLIER"` // percentage, 2.42 means 242% increase
MaxFeePerGasMultiplier decimal.Decimal `yaml:"max_fee_per_gas_multiplier" env:"GAS_CONFIG_MAX_FEE_PER_GAS_MULTIPLIER"` // percentage
}
GasConfig represents the configuration for the userop transaction gas fees.
type GasLimitOverrides ¶ added in v0.0.32
type GasLimitOverrides struct {
CallGasLimit *big.Int
VerificationGasLimit *big.Int
PreVerificationGas *big.Int
}
These override the bundler's estimation. NOTE: if all are supplied, bundler's estimation is NOT performed.
type GasPriceOverrides ¶ added in v0.0.44
These override provider's estimation. NOTE: if all are supplied, provider's estimation is NOT performed.
type MockUserOperationClient ¶
func (*MockUserOperationClient) NewUserOp ¶
func (c *MockUserOperationClient) NewUserOp(ctx context.Context, sender common.Address, calls smart_wallet.Calls) (UserOperation, error)
func (*MockUserOperationClient) SendUserOp ¶
func (c *MockUserOperationClient) SendUserOp(ctx context.Context, op UserOperation) (<-chan struct{}, error)
type NonceKeyRotator ¶ added in v0.0.54
type NonceKeyRotator struct {
// contains filtered or unexported fields
}
Implements a nonce key rotation for 2d nonces. https://docs.stackup.sh/docs/useroperation-nonce
func NewNonceKeyRotator ¶ added in v0.0.54
func NewNonceKeyRotator() NonceKeyRotator
func (*NonceKeyRotator) Next ¶ added in v0.0.54
func (r *NonceKeyRotator) Next() *big.Int
type Overrides ¶ added in v0.0.44
type Overrides struct {
Nonce *big.Int
InitCode []byte
GasPrices *GasPriceOverrides
GasLimits *GasLimitOverrides
}
Each field overrides the corresponding middleware during the user operation creation.
type PaymasterConfig ¶
type PaymasterConfig struct {
Type *PaymasterType `yaml:"type" env:"PAYMASTER_CONFIG_TYPE"` // nil is equivalent to PaymasterDisabled
URL string `yaml:"url" env:"PAYMASTER_CONFIG_URL"`
Address common.Address `yaml:"address" env:"PAYMASTER_CONFIG_ADDRESS"`
PimlicoERC20 PimlicoERC20Config `yaml:"pimlico_erc20" env-prefix:"PAYMASTER_CONFIG_PIMLICO_ERC20_"`
PimlicoVerifying PimlicoVerifyingConfig `yaml:"pimlico_verifying" env-prefix:"PAYMASTER_CONFIG_PIMLICO_VERIFYING_"`
BiconomyERC20 BiconomyERC20Config `yaml:"biconomy_erc20" env-prefix:"PAYMASTER_CONFIG_BICONOMY_ERC20_"`
BiconomySponsoring BiconomySponsoringConfig `yaml:"biconomy_sponsoring" env-prefix:"PAYMASTER_CONFIG_BICONOMY_SPONSORING_"`
}
PaymasterConfig represents the configuration for the paymaster to be used with the client.
func (*PaymasterConfig) Init ¶
func (c *PaymasterConfig) Init()
Init initializes the PaymasterConfig with default values.
type PaymasterType ¶
type PaymasterType struct {
// contains filtered or unexported fields
}
PaymasterType represents an enum for supported ERC-4337 paymaster that can be used with the client to sponsor user operations.
func (*PaymasterType) SetValue ¶
func (t *PaymasterType) SetValue(s string) error
SetValue implements the cleanenv.Setter interface.
func (PaymasterType) String ¶
func (t PaymasterType) String() string
func (*PaymasterType) UnmarshalJSON ¶
func (t *PaymasterType) UnmarshalJSON(b []byte) error
UnmarshalJSON unmarshalls the JSON representation of a PaymasterType.
func (*PaymasterType) UnmarshalYAML ¶
func (t *PaymasterType) UnmarshalYAML(unmarshal func(interface{}) error) error
UnmarshalYAML unmarshalls the YAML representation of a PaymasterType.
type PimlicoERC20Config ¶
type PimlicoERC20Config struct {
// MaxTokenCost specifies the limit for tokens to spend.
// Operations requiring user to pay more
// than specified amount of tokens for gas will fail.
MaxTokenCost decimal.Decimal `json:"maxTokenCost" env:"MAX_TOKEN_COST"` // unused for now
VerificationGasOverhead decimal.Decimal `yaml:"verification_gas_overhead" env:"VERIFICATION_GAS_OVERHEAD"`
}
PimlicoERC20Config represents the configuration for the Pimlico ERC20 paymaster.
func (*PimlicoERC20Config) Init ¶
func (config *PimlicoERC20Config) Init()
type PimlicoVerifyingConfig ¶
type PimlicoVerifyingConfig struct {
SponsorshipPolicyID string `json:"sponsorshipPolicyId" yaml:"sponsorship_policy_id" env:"SPONSORSHIP_POLICY_ID"`
}
PimlicoVerifyingConfig represents the configuration for the Pimlico Verifying paymaster. See the RPC endpoint docs at https://docs.pimlico.io/paymaster/verifying-paymaster/reference/endpoints#pm_sponsoruseroperation-v2
func (*PimlicoVerifyingConfig) Init ¶
func (config *PimlicoVerifyingConfig) Init()
type RPCBackend ¶
type RPCBackend interface {
CallContext(ctx context.Context, result interface{}, method string, args ...interface{}) error
}
func NewRPCBackend ¶
func NewRPCBackend(rpcURL url.URL) (RPCBackend, error)
type Signer ¶
Signer represents a handler that signs a user operation. The handler DOES NOT modify the operation itself, but rather builds and returns the signature.
func SignerForBiconomy ¶
func SignerForKernel ¶
type UserOperation ¶
type UserOperation struct {
Sender common.Address `json:"sender"`
Nonce decimal.Decimal `json:"nonce"`
InitCode []byte `json:"initCode"`
CallData []byte `json:"callData"`
CallGasLimit decimal.Decimal `json:"callGasLimit"`
VerificationGasLimit decimal.Decimal `json:"verificationGasLimit"`
PreVerificationGas decimal.Decimal `json:"preVerificationGas"`
MaxFeePerGas decimal.Decimal `json:"maxFeePerGas"`
MaxPriorityFeePerGas decimal.Decimal `json:"maxPriorityFeePerGas"`
PaymasterAndData []byte `json:"paymasterAndData"`
Signature []byte `json:"signature,omitempty"`
}
UserOperation represents an EIP-4337 style transaction for a smart contract account.
func (*UserOperation) GetFactory ¶
func (op *UserOperation) GetFactory() common.Address
GetFactory returns the address portion of InitCode if applicable. Otherwise, it returns the zero address.
func (*UserOperation) GetFactoryData ¶
func (op *UserOperation) GetFactoryData() []byte
GetFactoryData returns the data portion of InitCode if applicable. Otherwise, it returns an empty byte array.
func (UserOperation) MarshalJSON ¶
func (op UserOperation) MarshalJSON() ([]byte, error)
MarshalJSON returns a JSON encoding of the UserOperation.
func (*UserOperation) UserOpHash ¶
func (op *UserOperation) UserOpHash(entryPoint common.Address, chainID *big.Int) (common.Hash, error)
UserOpHash returns the hash of the userOp + entryPoint address + chainID.