diff --git a/README.md b/README.md index d6cb576..0d32ac9 100644 --- a/README.md +++ b/README.md @@ -87,7 +87,7 @@ This will create an executable file called `ownable-erc-721` (on Windows, you ma Try running it: -``` +```bash $ ./ownable-erc-721 -h Interact with the OwnableERC721 contract @@ -130,6 +130,34 @@ Flags: Use "ownable-erc-721 [command] --help" for more information about a command. ``` +```bash +$ ./ownable-erc-721 approve -h +Execute the Approve method on a OwnableERC721 contract + +Usage: + ownable-erc-721 approve [flags] + +Flags: + --contract string Address of the contract to interact with + --gas-limit uint Gas limit for the transaction + --gas-price string Gas price to use for the transaction + -h, --help help for approve + --keyfile string Path to the keystore file to use for the transaction + --max-fee-per-gas string Maximum fee per gas to use for the (EIP-1559) transaction + --max-priority-fee-per-gas string Maximum priority fee per gas to use for the (EIP-1559) transaction + --nonce string Nonce to use for the transaction + --password string Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes) + --rpc string URL of the JSONRPC API to use + --safe string Address of the Safe contract + --safe-api string Safe API for the Safe Transaction Service (optional) + --safe-operation uint8 Safe operation type: 0 (Call) or 1 (DelegateCall) + --simulate Simulate the transaction without sending it + --timeout uint Timeout (in seconds) for interactions with the JSONRPC API (default 60) + --to-0 string to-0 argument (common.Address) + --token-id string token-id argument + --value string Value to send with the transaction +``` + # Crawler That part of seer responsible for crawling raw blocks,tx_calls and events from the blockchain. diff --git a/bindings/CreateCall/CreateCall.go b/bindings/CreateCall/CreateCall.go new file mode 100644 index 0000000..6220e07 --- /dev/null +++ b/bindings/CreateCall/CreateCall.go @@ -0,0 +1,931 @@ +// This file was generated by seer: https://github.com/moonstream-to/seer. +// seer version: 0.1.20 +// seer command: seer evm generate --package CreateCall --cli --struct CreateCall --output bindings/CreateCall/CreateCall.go +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package CreateCall + +import ( + "errors" + "math/big" + "strings" + + "context" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + + // Reference imports to suppress errors if they are not otherwise used. + "encoding/hex" + "fmt" + "os" + "time" + + "github.com/ethereum/go-ethereum/accounts/keystore" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/spf13/cobra" + "golang.org/x/term" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// CreateCallMetaData contains all meta data concerning the CreateCall contract. +var CreateCallMetaData = &bind.MetaData{ + ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newContract\",\"type\":\"address\"}],\"name\":\"ContractCreation\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"deploymentData\",\"type\":\"bytes\"}],\"name\":\"performCreate\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"newContract\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"deploymentData\",\"type\":\"bytes\"},{\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"}],\"name\":\"performCreate2\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"newContract\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x608060405234801561001057600080fd5b5061044b806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80634847be6f1461003b5780634c8c9ea114610134575b600080fd5b6101086004803603606081101561005157600080fd5b81019080803590602001909291908035906020019064010000000081111561007857600080fd5b82018360208201111561008a57600080fd5b803590602001918460018302840111640100000000831117156100ac57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190929190505050610223565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6101f76004803603604081101561014a57600080fd5b81019080803590602001909291908035906020019064010000000081111561017157600080fd5b82018360208201111561018357600080fd5b803590602001918460018302840111640100000000831117156101a557600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929050505061031d565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b60008183518460200186f59050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156102d3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f436f756c64206e6f74206465706c6f7920636f6e74726163740000000000000081525060200191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff167f4db17dd5e4732fb6da34a148104a592783ca119a1e7bb8829eba6cbadef0b51160405160405180910390a29392505050565b600081516020830184f09050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156103cc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f436f756c64206e6f74206465706c6f7920636f6e74726163740000000000000081525060200191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff167f4db17dd5e4732fb6da34a148104a592783ca119a1e7bb8829eba6cbadef0b51160405160405180910390a29291505056fea2646970667358221220153dfbb31f5824b1a17183b88443b5d0771b935e8acd92186d58555a02e4b41f64736f6c63430007060033", +} + +// CreateCallABI is the input ABI used to generate the binding from. +// Deprecated: Use CreateCallMetaData.ABI instead. +var CreateCallABI = CreateCallMetaData.ABI + +// CreateCallBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use CreateCallMetaData.Bin instead. +var CreateCallBin = CreateCallMetaData.Bin + +// DeployCreateCall deploys a new Ethereum contract, binding an instance of CreateCall to it. +func DeployCreateCall(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *CreateCall, error) { + parsed, err := CreateCallMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(CreateCallBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &CreateCall{CreateCallCaller: CreateCallCaller{contract: contract}, CreateCallTransactor: CreateCallTransactor{contract: contract}, CreateCallFilterer: CreateCallFilterer{contract: contract}}, nil +} + +// CreateCall is an auto generated Go binding around an Ethereum contract. +type CreateCall struct { + CreateCallCaller // Read-only binding to the contract + CreateCallTransactor // Write-only binding to the contract + CreateCallFilterer // Log filterer for contract events +} + +// CreateCallCaller is an auto generated read-only Go binding around an Ethereum contract. +type CreateCallCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// CreateCallTransactor is an auto generated write-only Go binding around an Ethereum contract. +type CreateCallTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// CreateCallFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type CreateCallFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// CreateCallSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type CreateCallSession struct { + Contract *CreateCall // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// CreateCallCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type CreateCallCallerSession struct { + Contract *CreateCallCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// CreateCallTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type CreateCallTransactorSession struct { + Contract *CreateCallTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// CreateCallRaw is an auto generated low-level Go binding around an Ethereum contract. +type CreateCallRaw struct { + Contract *CreateCall // Generic contract binding to access the raw methods on +} + +// CreateCallCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type CreateCallCallerRaw struct { + Contract *CreateCallCaller // Generic read-only contract binding to access the raw methods on +} + +// CreateCallTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type CreateCallTransactorRaw struct { + Contract *CreateCallTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewCreateCall creates a new instance of CreateCall, bound to a specific deployed contract. +func NewCreateCall(address common.Address, backend bind.ContractBackend) (*CreateCall, error) { + contract, err := bindCreateCall(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &CreateCall{CreateCallCaller: CreateCallCaller{contract: contract}, CreateCallTransactor: CreateCallTransactor{contract: contract}, CreateCallFilterer: CreateCallFilterer{contract: contract}}, nil +} + +// NewCreateCallCaller creates a new read-only instance of CreateCall, bound to a specific deployed contract. +func NewCreateCallCaller(address common.Address, caller bind.ContractCaller) (*CreateCallCaller, error) { + contract, err := bindCreateCall(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &CreateCallCaller{contract: contract}, nil +} + +// NewCreateCallTransactor creates a new write-only instance of CreateCall, bound to a specific deployed contract. +func NewCreateCallTransactor(address common.Address, transactor bind.ContractTransactor) (*CreateCallTransactor, error) { + contract, err := bindCreateCall(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &CreateCallTransactor{contract: contract}, nil +} + +// NewCreateCallFilterer creates a new log filterer instance of CreateCall, bound to a specific deployed contract. +func NewCreateCallFilterer(address common.Address, filterer bind.ContractFilterer) (*CreateCallFilterer, error) { + contract, err := bindCreateCall(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &CreateCallFilterer{contract: contract}, nil +} + +// bindCreateCall binds a generic wrapper to an already deployed contract. +func bindCreateCall(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := CreateCallMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_CreateCall *CreateCallRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _CreateCall.Contract.CreateCallCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_CreateCall *CreateCallRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _CreateCall.Contract.CreateCallTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_CreateCall *CreateCallRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _CreateCall.Contract.CreateCallTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_CreateCall *CreateCallCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _CreateCall.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_CreateCall *CreateCallTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _CreateCall.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_CreateCall *CreateCallTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _CreateCall.Contract.contract.Transact(opts, method, params...) +} + +// PerformCreate is a paid mutator transaction binding the contract method 0x4c8c9ea1. +// +// Solidity: function performCreate(uint256 value, bytes deploymentData) returns(address newContract) +func (_CreateCall *CreateCallTransactor) PerformCreate(opts *bind.TransactOpts, value *big.Int, deploymentData []byte) (*types.Transaction, error) { + return _CreateCall.contract.Transact(opts, "performCreate", value, deploymentData) +} + +// PerformCreate is a paid mutator transaction binding the contract method 0x4c8c9ea1. +// +// Solidity: function performCreate(uint256 value, bytes deploymentData) returns(address newContract) +func (_CreateCall *CreateCallSession) PerformCreate(value *big.Int, deploymentData []byte) (*types.Transaction, error) { + return _CreateCall.Contract.PerformCreate(&_CreateCall.TransactOpts, value, deploymentData) +} + +// PerformCreate is a paid mutator transaction binding the contract method 0x4c8c9ea1. +// +// Solidity: function performCreate(uint256 value, bytes deploymentData) returns(address newContract) +func (_CreateCall *CreateCallTransactorSession) PerformCreate(value *big.Int, deploymentData []byte) (*types.Transaction, error) { + return _CreateCall.Contract.PerformCreate(&_CreateCall.TransactOpts, value, deploymentData) +} + +// PerformCreate2 is a paid mutator transaction binding the contract method 0x4847be6f. +// +// Solidity: function performCreate2(uint256 value, bytes deploymentData, bytes32 salt) returns(address newContract) +func (_CreateCall *CreateCallTransactor) PerformCreate2(opts *bind.TransactOpts, value *big.Int, deploymentData []byte, salt [32]byte) (*types.Transaction, error) { + return _CreateCall.contract.Transact(opts, "performCreate2", value, deploymentData, salt) +} + +// PerformCreate2 is a paid mutator transaction binding the contract method 0x4847be6f. +// +// Solidity: function performCreate2(uint256 value, bytes deploymentData, bytes32 salt) returns(address newContract) +func (_CreateCall *CreateCallSession) PerformCreate2(value *big.Int, deploymentData []byte, salt [32]byte) (*types.Transaction, error) { + return _CreateCall.Contract.PerformCreate2(&_CreateCall.TransactOpts, value, deploymentData, salt) +} + +// PerformCreate2 is a paid mutator transaction binding the contract method 0x4847be6f. +// +// Solidity: function performCreate2(uint256 value, bytes deploymentData, bytes32 salt) returns(address newContract) +func (_CreateCall *CreateCallTransactorSession) PerformCreate2(value *big.Int, deploymentData []byte, salt [32]byte) (*types.Transaction, error) { + return _CreateCall.Contract.PerformCreate2(&_CreateCall.TransactOpts, value, deploymentData, salt) +} + +// CreateCallContractCreationIterator is returned from FilterContractCreation and is used to iterate over the raw logs and unpacked data for ContractCreation events raised by the CreateCall contract. +type CreateCallContractCreationIterator struct { + Event *CreateCallContractCreation // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *CreateCallContractCreationIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(CreateCallContractCreation) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(CreateCallContractCreation) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *CreateCallContractCreationIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *CreateCallContractCreationIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// CreateCallContractCreation represents a ContractCreation event raised by the CreateCall contract. +type CreateCallContractCreation struct { + NewContract common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterContractCreation is a free log retrieval operation binding the contract event 0x4db17dd5e4732fb6da34a148104a592783ca119a1e7bb8829eba6cbadef0b511. +// +// Solidity: event ContractCreation(address indexed newContract) +func (_CreateCall *CreateCallFilterer) FilterContractCreation(opts *bind.FilterOpts, newContract []common.Address) (*CreateCallContractCreationIterator, error) { + + var newContractRule []interface{} + for _, newContractItem := range newContract { + newContractRule = append(newContractRule, newContractItem) + } + + logs, sub, err := _CreateCall.contract.FilterLogs(opts, "ContractCreation", newContractRule) + if err != nil { + return nil, err + } + return &CreateCallContractCreationIterator{contract: _CreateCall.contract, event: "ContractCreation", logs: logs, sub: sub}, nil +} + +// WatchContractCreation is a free log subscription operation binding the contract event 0x4db17dd5e4732fb6da34a148104a592783ca119a1e7bb8829eba6cbadef0b511. +// +// Solidity: event ContractCreation(address indexed newContract) +func (_CreateCall *CreateCallFilterer) WatchContractCreation(opts *bind.WatchOpts, sink chan<- *CreateCallContractCreation, newContract []common.Address) (event.Subscription, error) { + + var newContractRule []interface{} + for _, newContractItem := range newContract { + newContractRule = append(newContractRule, newContractItem) + } + + logs, sub, err := _CreateCall.contract.WatchLogs(opts, "ContractCreation", newContractRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(CreateCallContractCreation) + if err := _CreateCall.contract.UnpackLog(event, "ContractCreation", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseContractCreation is a log parse operation binding the contract event 0x4db17dd5e4732fb6da34a148104a592783ca119a1e7bb8829eba6cbadef0b511. +// +// Solidity: event ContractCreation(address indexed newContract) +func (_CreateCall *CreateCallFilterer) ParseContractCreation(log types.Log) (*CreateCallContractCreation, error) { + event := new(CreateCallContractCreation) + if err := _CreateCall.contract.UnpackLog(event, "ContractCreation", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func CreateCreateCallDeploymentCommand() *cobra.Command { + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc string + var gasLimit uint64 + var simulate bool + var timeout uint + + cmd := &cobra.Command{ + Use: "deploy", + Short: "Deploy a new CreateCall contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if keyfile == "" { + return fmt.Errorf("--keystore not specified (this should be a path to an Ethereum account keystore file)") + } + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + key, keyErr := KeyFromFile(keyfile, password) + if keyErr != nil { + return keyErr + } + + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + + transactionOpts, transactionOptsErr := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID) + if transactionOptsErr != nil { + return transactionOptsErr + } + + SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) + + address, deploymentTransaction, _, deploymentErr := DeployCreateCall( + transactionOpts, + client, + ) + if deploymentErr != nil { + return deploymentErr + } + + cmd.Printf("Transaction hash: %s\nContract address: %s\n", deploymentTransaction.Hash().Hex(), address.Hex()) + if transactionOpts.NoSend { + estimationMessage := ethereum.CallMsg{ + From: transactionOpts.From, + Data: deploymentTransaction.Data(), + } + + gasEstimationCtx, cancelGasEstimationCtx := NewChainContext(timeout) + defer cancelGasEstimationCtx() + + gasEstimate, gasEstimateErr := client.EstimateGas(gasEstimationCtx, estimationMessage) + if gasEstimateErr != nil { + return gasEstimateErr + } + + transactionBinary, transactionBinaryErr := deploymentTransaction.MarshalBinary() + if transactionBinaryErr != nil { + return transactionBinaryErr + } + transactionBinaryHex := hex.EncodeToString(transactionBinary) + + cmd.Printf("Transaction: %s\nEstimated gas: %d\n", transactionBinaryHex, gasEstimate) + } else { + cmd.Println("Transaction submitted") + } + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&keyfile, "keyfile", "", "Path to the keystore file to use for the transaction") + cmd.Flags().StringVar(&password, "password", "", "Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes)") + cmd.Flags().StringVar(&nonce, "nonce", "", "Nonce to use for the transaction") + cmd.Flags().StringVar(&value, "value", "", "Value to send with the transaction") + cmd.Flags().StringVar(&gasPrice, "gas-price", "", "Gas price to use for the transaction") + cmd.Flags().StringVar(&maxFeePerGas, "max-fee-per-gas", "", "Maximum fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().StringVar(&maxPriorityFeePerGas, "max-priority-fee-per-gas", "", "Maximum priority fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") + cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + + return cmd +} + +func CreatePerformCreateCommand() *cobra.Command { + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw string + var gasLimit uint64 + var simulate bool + var timeout uint + var contractAddress common.Address + + var value0 *big.Int + var value0Raw string + var deploymentData []byte + var deploymentDataRaw string + + cmd := &cobra.Command{ + Use: "perform-create", + Short: "Execute the PerformCreate method on a CreateCall contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if keyfile == "" { + return fmt.Errorf("--keystore not specified") + } + + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + if value0Raw == "" { + return fmt.Errorf("--value-0 argument not specified") + } + value0 = new(big.Int) + value0.SetString(value0Raw, 0) + + var deploymentDataIntermediate []byte + + var deploymentDataIntermediateHexDecodeErr error + deploymentDataIntermediate, deploymentDataIntermediateHexDecodeErr = hex.DecodeString(deploymentDataRaw) + if deploymentDataIntermediateHexDecodeErr != nil { + return deploymentDataIntermediateHexDecodeErr + } + + copy(deploymentData[:], deploymentDataIntermediate) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + key, keyErr := KeyFromFile(keyfile, password) + if keyErr != nil { + return keyErr + } + + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + + transactionOpts, transactionOptsErr := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID) + if transactionOptsErr != nil { + return transactionOptsErr + } + + SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) + + contract, contractErr := NewCreateCall(contractAddress, client) + if contractErr != nil { + return contractErr + } + + session := CreateCallTransactorSession{ + Contract: &contract.CreateCallTransactor, + TransactOpts: *transactionOpts, + } + + transaction, transactionErr := session.PerformCreate( + value0, + deploymentData, + ) + if transactionErr != nil { + return transactionErr + } + + cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) + if transactionOpts.NoSend { + estimationMessage := ethereum.CallMsg{ + From: transactionOpts.From, + To: &contractAddress, + Data: transaction.Data(), + } + + gasEstimationCtx, cancelGasEstimationCtx := NewChainContext(timeout) + defer cancelGasEstimationCtx() + + gasEstimate, gasEstimateErr := client.EstimateGas(gasEstimationCtx, estimationMessage) + if gasEstimateErr != nil { + return gasEstimateErr + } + + transactionBinary, transactionBinaryErr := transaction.MarshalBinary() + if transactionBinaryErr != nil { + return transactionBinaryErr + } + transactionBinaryHex := hex.EncodeToString(transactionBinary) + + cmd.Printf("Transaction: %s\nEstimated gas: %d\n", transactionBinaryHex, gasEstimate) + } else { + cmd.Println("Transaction submitted") + } + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&keyfile, "keyfile", "", "Path to the keystore file to use for the transaction") + cmd.Flags().StringVar(&password, "password", "", "Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes)") + cmd.Flags().StringVar(&nonce, "nonce", "", "Nonce to use for the transaction") + cmd.Flags().StringVar(&value, "value", "", "Value to send with the transaction") + cmd.Flags().StringVar(&gasPrice, "gas-price", "", "Gas price to use for the transaction") + cmd.Flags().StringVar(&maxFeePerGas, "max-fee-per-gas", "", "Maximum fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().StringVar(&maxPriorityFeePerGas, "max-priority-fee-per-gas", "", "Maximum priority fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") + cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + + cmd.Flags().StringVar(&value0Raw, "value-0", "", "value-0 argument") + cmd.Flags().StringVar(&deploymentDataRaw, "deployment-data", "", "deployment-data argument ([]byte)") + + return cmd +} +func CreatePerformCreate2Command() *cobra.Command { + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw string + var gasLimit uint64 + var simulate bool + var timeout uint + var contractAddress common.Address + + var value0 *big.Int + var value0Raw string + var deploymentData []byte + var deploymentDataRaw string + var salt [32]byte + var saltRaw string + + cmd := &cobra.Command{ + Use: "perform-create-2", + Short: "Execute the PerformCreate2 method on a CreateCall contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if keyfile == "" { + return fmt.Errorf("--keystore not specified") + } + + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + if value0Raw == "" { + return fmt.Errorf("--value-0 argument not specified") + } + value0 = new(big.Int) + value0.SetString(value0Raw, 0) + + var deploymentDataIntermediate []byte + + var deploymentDataIntermediateHexDecodeErr error + deploymentDataIntermediate, deploymentDataIntermediateHexDecodeErr = hex.DecodeString(deploymentDataRaw) + if deploymentDataIntermediateHexDecodeErr != nil { + return deploymentDataIntermediateHexDecodeErr + } + + copy(deploymentData[:], deploymentDataIntermediate) + + var saltIntermediate []byte + + var saltIntermediateHexDecodeErr error + saltIntermediate, saltIntermediateHexDecodeErr = hex.DecodeString(saltRaw) + if saltIntermediateHexDecodeErr != nil { + return saltIntermediateHexDecodeErr + } + + copy(salt[:], saltIntermediate) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + key, keyErr := KeyFromFile(keyfile, password) + if keyErr != nil { + return keyErr + } + + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + + transactionOpts, transactionOptsErr := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID) + if transactionOptsErr != nil { + return transactionOptsErr + } + + SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) + + contract, contractErr := NewCreateCall(contractAddress, client) + if contractErr != nil { + return contractErr + } + + session := CreateCallTransactorSession{ + Contract: &contract.CreateCallTransactor, + TransactOpts: *transactionOpts, + } + + transaction, transactionErr := session.PerformCreate2( + value0, + deploymentData, + salt, + ) + if transactionErr != nil { + return transactionErr + } + + cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) + if transactionOpts.NoSend { + estimationMessage := ethereum.CallMsg{ + From: transactionOpts.From, + To: &contractAddress, + Data: transaction.Data(), + } + + gasEstimationCtx, cancelGasEstimationCtx := NewChainContext(timeout) + defer cancelGasEstimationCtx() + + gasEstimate, gasEstimateErr := client.EstimateGas(gasEstimationCtx, estimationMessage) + if gasEstimateErr != nil { + return gasEstimateErr + } + + transactionBinary, transactionBinaryErr := transaction.MarshalBinary() + if transactionBinaryErr != nil { + return transactionBinaryErr + } + transactionBinaryHex := hex.EncodeToString(transactionBinary) + + cmd.Printf("Transaction: %s\nEstimated gas: %d\n", transactionBinaryHex, gasEstimate) + } else { + cmd.Println("Transaction submitted") + } + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&keyfile, "keyfile", "", "Path to the keystore file to use for the transaction") + cmd.Flags().StringVar(&password, "password", "", "Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes)") + cmd.Flags().StringVar(&nonce, "nonce", "", "Nonce to use for the transaction") + cmd.Flags().StringVar(&value, "value", "", "Value to send with the transaction") + cmd.Flags().StringVar(&gasPrice, "gas-price", "", "Gas price to use for the transaction") + cmd.Flags().StringVar(&maxFeePerGas, "max-fee-per-gas", "", "Maximum fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().StringVar(&maxPriorityFeePerGas, "max-priority-fee-per-gas", "", "Maximum priority fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") + cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + + cmd.Flags().StringVar(&value0Raw, "value-0", "", "value-0 argument") + cmd.Flags().StringVar(&deploymentDataRaw, "deployment-data", "", "deployment-data argument ([]byte)") + cmd.Flags().StringVar(&saltRaw, "salt", "", "salt argument ([32]byte)") + + return cmd +} + +var ErrNoRPCURL error = errors.New("no RPC URL provided -- please pass an RPC URL from the command line or set the CREATE_CALL_RPC_URL environment variable") + +// Generates an Ethereum client to the JSONRPC API at the given URL. If rpcURL is empty, then it +// attempts to read the RPC URL from the CREATE_CALL_RPC_URL environment variable. If that is empty, +// too, then it returns an error. +func NewClient(rpcURL string) (*ethclient.Client, error) { + if rpcURL == "" { + rpcURL = os.Getenv("CREATE_CALL_RPC_URL") + } + + if rpcURL == "" { + return nil, ErrNoRPCURL + } + + client, err := ethclient.Dial(rpcURL) + return client, err +} + +// Creates a new context to be used when interacting with the chain client. +func NewChainContext(timeout uint) (context.Context, context.CancelFunc) { + baseCtx := context.Background() + parsedTimeout := time.Duration(timeout) * time.Second + ctx, cancel := context.WithTimeout(baseCtx, parsedTimeout) + return ctx, cancel +} + +// Unlocks a key from a keystore (byte contents of a keystore file) with the given password. +func UnlockKeystore(keystoreData []byte, password string) (*keystore.Key, error) { + key, err := keystore.DecryptKey(keystoreData, password) + return key, err +} + +// Loads a key from file, prompting the user for the password if it is not provided as a function argument. +func KeyFromFile(keystoreFile string, password string) (*keystore.Key, error) { + var emptyKey *keystore.Key + keystoreContent, readErr := os.ReadFile(keystoreFile) + if readErr != nil { + return emptyKey, readErr + } + + // If password is "", prompt user for password. + if password == "" { + fmt.Printf("Please provide a password for keystore (%s): ", keystoreFile) + passwordRaw, inputErr := term.ReadPassword(int(os.Stdin.Fd())) + if inputErr != nil { + return emptyKey, fmt.Errorf("error reading password: %s", inputErr.Error()) + } + fmt.Print("\n") + password = string(passwordRaw) + } + + key, err := UnlockKeystore(keystoreContent, password) + return key, err +} + +// This method is used to set the parameters on a view call from command line arguments (represented mostly as +// strings). +func SetCallParametersFromArgs(opts *bind.CallOpts, pending bool, fromAddress, blockNumber string) { + if pending { + opts.Pending = true + } + + if fromAddress != "" { + opts.From = common.HexToAddress(fromAddress) + } + + if blockNumber != "" { + opts.BlockNumber = new(big.Int) + opts.BlockNumber.SetString(blockNumber, 0) + } +} + +// This method is used to set the parameters on a transaction from command line arguments (represented mostly as +// strings). +func SetTransactionParametersFromArgs(opts *bind.TransactOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas string, gasLimit uint64, noSend bool) { + if nonce != "" { + opts.Nonce = new(big.Int) + opts.Nonce.SetString(nonce, 0) + } + + if value != "" { + opts.Value = new(big.Int) + opts.Value.SetString(value, 0) + } + + if gasPrice != "" { + opts.GasPrice = new(big.Int) + opts.GasPrice.SetString(gasPrice, 0) + } + + if maxFeePerGas != "" { + opts.GasFeeCap = new(big.Int) + opts.GasFeeCap.SetString(maxFeePerGas, 0) + } + + if maxPriorityFeePerGas != "" { + opts.GasTipCap = new(big.Int) + opts.GasTipCap.SetString(maxPriorityFeePerGas, 0) + } + + if gasLimit != 0 { + opts.GasLimit = gasLimit + } + + opts.NoSend = noSend +} + +func CreateCreateCallCommand() *cobra.Command { + cmd := &cobra.Command{ + Use: "create-call", + Short: "Interact with the CreateCall contract", + Run: func(cmd *cobra.Command, args []string) { + cmd.Help() + }, + } + + cmd.SetOut(os.Stdout) + + DeployGroup := &cobra.Group{ + ID: "deploy", Title: "Commands which deploy contracts", + } + cmd.AddGroup(DeployGroup) + ViewGroup := &cobra.Group{ + ID: "view", Title: "Commands which view contract state", + } + TransactGroup := &cobra.Group{ + ID: "transact", Title: "Commands which submit transactions", + } + cmd.AddGroup(ViewGroup, TransactGroup) + + cmdDeployCreateCall := CreateCreateCallDeploymentCommand() + cmdDeployCreateCall.GroupID = DeployGroup.ID + cmd.AddCommand(cmdDeployCreateCall) + + cmdTransactPerformCreate := CreatePerformCreateCommand() + cmdTransactPerformCreate.GroupID = TransactGroup.ID + cmd.AddCommand(cmdTransactPerformCreate) + cmdTransactPerformCreate2 := CreatePerformCreate2Command() + cmdTransactPerformCreate2.GroupID = TransactGroup.ID + cmd.AddCommand(cmdTransactPerformCreate2) + + return cmd +} diff --git a/bindings/GnosisSafe/GnosisSafe.go b/bindings/GnosisSafe/GnosisSafe.go new file mode 100644 index 0000000..ec513c3 --- /dev/null +++ b/bindings/GnosisSafe/GnosisSafe.go @@ -0,0 +1,6777 @@ +// This file was generated by seer: https://github.com/moonstream-to/seer. +// seer version: 0.1.20 +// seer command: seer evm generate --package GnosisSafe --cli --struct GnosisSafe --output bindings/GnosisSafe/GnosisSafe.go +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package GnosisSafe + +import ( + "errors" + "math/big" + "strings" + + "context" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + + // Reference imports to suppress errors if they are not otherwise used. + "encoding/hex" + "encoding/json" + "fmt" + "os" + "time" + + "github.com/ethereum/go-ethereum/accounts/keystore" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/spf13/cobra" + "golang.org/x/term" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// GnosisSafeMetaData contains all meta data concerning the GnosisSafe contract. +var GnosisSafeMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"AddedOwner\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"approvedHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"ApproveHash\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"masterCopy\",\"type\":\"address\"}],\"name\":\"ChangedMasterCopy\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"}],\"name\":\"ChangedThreshold\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contractModule\",\"name\":\"module\",\"type\":\"address\"}],\"name\":\"DisabledModule\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contractModule\",\"name\":\"module\",\"type\":\"address\"}],\"name\":\"EnabledModule\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"txHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"payment\",\"type\":\"uint256\"}],\"name\":\"ExecutionFailure\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"module\",\"type\":\"address\"}],\"name\":\"ExecutionFromModuleFailure\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"module\",\"type\":\"address\"}],\"name\":\"ExecutionFromModuleSuccess\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"txHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"payment\",\"type\":\"uint256\"}],\"name\":\"ExecutionSuccess\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"RemovedOwner\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"msgHash\",\"type\":\"bytes32\"}],\"name\":\"SignMsg\",\"type\":\"event\"},{\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"constant\":true,\"inputs\":[],\"name\":\"NAME\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"VERSION\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_threshold\",\"type\":\"uint256\"}],\"name\":\"addOwnerWithThreshold\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hashToApprove\",\"type\":\"bytes32\"}],\"name\":\"approveHash\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"approvedHashes\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_masterCopy\",\"type\":\"address\"}],\"name\":\"changeMasterCopy\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_threshold\",\"type\":\"uint256\"}],\"name\":\"changeThreshold\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"contractModule\",\"name\":\"prevModule\",\"type\":\"address\"},{\"internalType\":\"contractModule\",\"name\":\"module\",\"type\":\"address\"}],\"name\":\"disableModule\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"domainSeparator\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"contractModule\",\"name\":\"module\",\"type\":\"address\"}],\"name\":\"enableModule\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"enumEnum.Operation\",\"name\":\"operation\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"safeTxGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"baseGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasPrice\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"gasToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"refundReceiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_nonce\",\"type\":\"uint256\"}],\"name\":\"encodeTransactionData\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"enumEnum.Operation\",\"name\":\"operation\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"safeTxGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"baseGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasPrice\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"gasToken\",\"type\":\"address\"},{\"internalType\":\"addresspayable\",\"name\":\"refundReceiver\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"signatures\",\"type\":\"bytes\"}],\"name\":\"execTransaction\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"enumEnum.Operation\",\"name\":\"operation\",\"type\":\"uint8\"}],\"name\":\"execTransactionFromModule\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"enumEnum.Operation\",\"name\":\"operation\",\"type\":\"uint8\"}],\"name\":\"execTransactionFromModuleReturnData\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"}],\"name\":\"getMessageHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getModules\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"start\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"pageSize\",\"type\":\"uint256\"}],\"name\":\"getModulesPaginated\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"array\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"next\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getOwners\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getThreshold\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"enumEnum.Operation\",\"name\":\"operation\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"safeTxGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"baseGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasPrice\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"gasToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"refundReceiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_nonce\",\"type\":\"uint256\"}],\"name\":\"getTransactionHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"contractModule\",\"name\":\"module\",\"type\":\"address\"}],\"name\":\"isModuleEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"isOwner\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"_signature\",\"type\":\"bytes\"}],\"name\":\"isValidSignature\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"nonce\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"prevOwner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_threshold\",\"type\":\"uint256\"}],\"name\":\"removeOwner\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"enumEnum.Operation\",\"name\":\"operation\",\"type\":\"uint8\"}],\"name\":\"requiredTxGas\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"handler\",\"type\":\"address\"}],\"name\":\"setFallbackHandler\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_owners\",\"type\":\"address[]\"},{\"internalType\":\"uint256\",\"name\":\"_threshold\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"fallbackHandler\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"paymentToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"payment\",\"type\":\"uint256\"},{\"internalType\":\"addresspayable\",\"name\":\"paymentReceiver\",\"type\":\"address\"}],\"name\":\"setup\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"signMessage\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"signedMessages\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"prevOwner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"oldOwner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"swapOwner\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x608060405234801561001057600080fd5b506001600481905550615f5a80620000296000396000f3fe6080604052600436106101d85760003560e01c8063a3f4df7e11610102578063e009cfde11610095578063f08a032311610064578063f08a03231461156b578063f698da25146115bc578063f8dc5dd9146115e7578063ffa1ad7414611662576101d8565b8063e009cfde1461125d578063e318b52b146112ce578063e75235b81461135f578063e86637db1461138a576101d8565b8063c4ca3a9c116100d1578063c4ca3a9c14610ef2578063cc2f845214610fc3578063d4d9bdcd146110a6578063d8d11f78146110e1576101d8565b8063a3f4df7e14610c5b578063affed0e014610ceb578063b2494df314610d16578063b63e800d14610d82576101d8565b80635ae6bd371161017a5780637d832974116101495780637d83297414610aa95780637de7edef14610b1857806385a5affe14610b69578063a0e67e2b14610bef576101d8565b80635ae6bd3714610852578063610b5925146108a1578063694e80c3146108f25780636a7612021461092d576101d8565b80632d9ad53d116101b65780632d9ad53d146104e65780632f54bf6e1461054f578063468721a7146105b85780635229073f146106cf576101d8565b80630a1028c4146102825780630d582f131461035e57806320c13b0b146103b9575b60003411806101ea5750600080369050145b156101f457610280565b60007f6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d560001b9050600081549050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461027d57366000803760008036600080855af13d6000803e6000811415610278573d6000fd5b3d6000f35b50505b005b34801561028e57600080fd5b50610348600480360360208110156102a557600080fd5b81019080803590602001906401000000008111156102c257600080fd5b8201836020820111156102d457600080fd5b803590602001918460018302840111640100000000831117156102f657600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192905050506116f2565b6040518082815260200191505060405180910390f35b34801561036a57600080fd5b506103b76004803603604081101561038157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611829565b005b3480156103c557600080fd5b50610492600480360360408110156103dc57600080fd5b81019080803590602001906401000000008111156103f957600080fd5b82018360208201111561040b57600080fd5b8035906020019184600183028401116401000000008311171561042d57600080fd5b90919293919293908035906020019064010000000081111561044e57600080fd5b82018360208201111561046057600080fd5b8035906020019184600183028401116401000000008311171561048257600080fd5b9091929391929390505050611c73565b60405180827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200191505060405180910390f35b3480156104f257600080fd5b506105356004803603602081101561050957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611e09565b604051808215151515815260200191505060405180910390f35b34801561055b57600080fd5b5061059e6004803603602081101561057257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611edb565b604051808215151515815260200191505060405180910390f35b3480156105c457600080fd5b506106b5600480360360808110156105db57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561062257600080fd5b82018360208201111561063457600080fd5b8035906020019184600183028401116401000000008311171561065657600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803560ff169060200190929190505050611fad565b604051808215151515815260200191505060405180910390f35b3480156106db57600080fd5b506107cc600480360360808110156106f257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561073957600080fd5b82018360208201111561074b57600080fd5b8035906020019184600183028401116401000000008311171561076d57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803560ff169060200190929190505050612176565b604051808315151515815260200180602001828103825283818151815260200191508051906020019080838360005b838110156108165780820151818401526020810190506107fb565b50505050905090810190601f1680156108435780820380516001836020036101000a031916815260200191505b50935050505060405180910390f35b34801561085e57600080fd5b5061088b6004803603602081101561087557600080fd5b81019080803590602001909291905050506121ac565b6040518082815260200191505060405180910390f35b3480156108ad57600080fd5b506108f0600480360360208110156108c457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506121c4565b005b3480156108fe57600080fd5b5061092b6004803603602081101561091557600080fd5b81019080803590602001909291905050506125e8565b005b610a8f600480360361014081101561094457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561098b57600080fd5b82018360208201111561099d57600080fd5b803590602001918460018302840111640100000000831117156109bf57600080fd5b9091929391929390803560ff169060200190929190803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190640100000000811115610a4b57600080fd5b820183602082011115610a5d57600080fd5b80359060200191846001830284011164010000000083111715610a7f57600080fd5b9091929391929390505050612764565b604051808215151515815260200191505060405180910390f35b348015610ab557600080fd5b50610b0260048036036040811015610acc57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506129ec565b6040518082815260200191505060405180910390f35b348015610b2457600080fd5b50610b6760048036036020811015610b3b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612a11565b005b348015610b7557600080fd5b50610bed60048036036020811015610b8c57600080fd5b8101908080359060200190640100000000811115610ba957600080fd5b820183602082011115610bbb57600080fd5b80359060200191846001830284011164010000000083111715610bdd57600080fd5b9091929391929390505050612bc1565b005b348015610bfb57600080fd5b50610c04612ce1565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b83811015610c47578082015181840152602081019050610c2c565b505050509050019250505060405180910390f35b348015610c6757600080fd5b50610c70612e76565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610cb0578082015181840152602081019050610c95565b50505050905090810190601f168015610cdd5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b348015610cf757600080fd5b50610d00612eaf565b6040518082815260200191505060405180910390f35b348015610d2257600080fd5b50610d2b612eb5565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b83811015610d6e578082015181840152602081019050610d53565b505050509050019250505060405180910390f35b348015610d8e57600080fd5b50610ef06004803603610100811015610da657600080fd5b8101908080359060200190640100000000811115610dc357600080fd5b820183602082011115610dd557600080fd5b80359060200191846020830284011164010000000083111715610df757600080fd5b909192939192939080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190640100000000811115610e4257600080fd5b820183602082011115610e5457600080fd5b80359060200191846001830284011164010000000083111715610e7657600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612ece565b005b348015610efe57600080fd5b50610fad60048036036080811015610f1557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190640100000000811115610f5c57600080fd5b820183602082011115610f6e57600080fd5b80359060200191846001830284011164010000000083111715610f9057600080fd5b9091929391929390803560ff1690602001909291905050506130c9565b6040518082815260200191505060405180910390f35b348015610fcf57600080fd5b5061101c60048036036040811015610fe657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050613276565b60405180806020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828103825284818151815260200191508051906020019060200280838360005b83811015611091578082015181840152602081019050611076565b50505050905001935050505060405180910390f35b3480156110b257600080fd5b506110df600480360360208110156110c957600080fd5b8101908080359060200190929190505050613455565b005b3480156110ed57600080fd5b50611247600480360361014081101561110557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561114c57600080fd5b82018360208201111561115e57600080fd5b8035906020019184600183028401116401000000008311171561118057600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803560ff169060200190929190803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506135f4565b6040518082815260200191505060405180910390f35b34801561126957600080fd5b506112cc6004803603604081101561128057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061361f565b005b3480156112da57600080fd5b5061135d600480360360608110156112f157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613a25565b005b34801561136b57600080fd5b506113746140ea565b6040518082815260200191505060405180910390f35b34801561139657600080fd5b506114f060048036036101408110156113ae57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156113f557600080fd5b82018360208201111561140757600080fd5b8035906020019184600183028401116401000000008311171561142957600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803560ff169060200190929190803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506140f4565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015611530578082015181840152602081019050611515565b50505050905090810190601f16801561155d5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561157757600080fd5b506115ba6004803603602081101561158e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050614308565b005b3480156115c857600080fd5b506115d1614398565b6040518082815260200191505060405180910390f35b3480156115f357600080fd5b506116606004803603606081101561160a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061439e565b005b34801561166e57600080fd5b50611677614829565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156116b757808201518184015260208101905061169c565b50505050905090810190601f1680156116e45780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6000807f60b3cbf8b4a223d68d641b3b6ddf9a298e7f33710cf3d3a9d1146b5a6150fbca60001b83805190602001206040516020018083815260200182815260200192505050604051602081830303815290604052805190602001209050601960f81b600160f81b6006548360405160200180857effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152600101847effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260010183815260200182815260200194505050505060405160208183030381529060405280519060200120915050919050565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146118ad576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180615e47602c913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141580156119175750600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b611989576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f496e76616c6964206f776e657220616464726573732070726f7669646564000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611a8a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f4164647265737320697320616c726561647920616e206f776e6572000000000081525060200191505060405180910390fd5b60026000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508160026000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506003600081548092919060010191905055507f9465fa0c962cc76958e6373a993326400c1c94f8be2fe3a952adfa7f60b2ea2682604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a18060045414611c6f57611c6e816125e8565b5b5050565b600080611cc386868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506116f2565b90506000848490501415611d6057600060076000838152602001908152602001600020541415611d5b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260118152602001807f48617368206e6f7420617070726f76656400000000000000000000000000000081525060200191505060405180910390fd5b611df6565b611df58187878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505086868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506000614862565b5b6320c13b0b60e01b915050949350505050565b60008173ffffffffffffffffffffffffffffffffffffffff16600173ffffffffffffffffffffffffffffffffffffffff1614158015611ed45750600073ffffffffffffffffffffffffffffffffffffffff16600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b9050919050565b6000600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614158015611fa65750600073ffffffffffffffffffffffffffffffffffffffff16600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b9050919050565b6000600173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141580156120785750600073ffffffffffffffffffffffffffffffffffffffff16600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b6120cd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526030815260200180615e736030913960400191505060405180910390fd5b6120da858585855a615190565b9050801561212a573373ffffffffffffffffffffffffffffffffffffffff167f6895c13664aa4f67288b25d7a21d7aaa34916e355fb9b6fae0a139a9085becb860405160405180910390a261216e565b3373ffffffffffffffffffffffffffffffffffffffff167facd2c8702804128fdb0db2bb49f6d127dd0181c13fd45dbfe16de0930e2bd37560405160405180910390a25b949350505050565b6000606061218686868686611fad565b915060405160203d0181016040523d81523d6000602083013e8091505094509492505050565b60076020528060005260406000206000915090505481565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612248576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180615e47602c913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141580156122b25750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b612324576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f496e76616c6964206d6f64756c6520616464726573732070726f76696465640081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612425576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f4d6f64756c652068617320616c7265616479206265656e20616464656400000081525060200191505060405180910390fd5b60016000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508060016000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fecdf3a3effea5783a3c4c2140e677577666428d44ed9d474a0b3a4c9943f844081604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461266c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180615e47602c913960400191505060405180910390fd5b6003548111156126c7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180615d166023913960400191505060405180910390fd5b6001811015612721576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526024815260200180615dec6024913960400191505060405180910390fd5b806004819055507f610f7ff2b304ae8903c3de74c60c6ab1f7d6226b3f52c5161905bb5ad4039c936004546040518082815260200191505060405180910390a150565b60008060606127c18f8f8f8f8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508e8e8e8e8e8e6005546140f4565b905060056000815480929190600101919050555080805190602001209150612830828287878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506001614862565b506101f46128586109c48b01603f60408d028161284957fe5b0461520290919063ffffffff16565b015a10156128b1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180615efc602a913960400191505060405180910390fd5b60005a905061291a8f8f8f8f8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508e60008d1461290f578e612915565b6109c45a035b615190565b925061292f5a8261521c90919063ffffffff16565b90506000809050600089111561294f5761294c828b8b8b8b61523c565b90505b8315612999577f442e715f626346e8c54381002da614f62bee8d27386535b2521ec8540898556e8382604051808381526020018281526020019250505060405180910390a16129d9565b7f23428b18acfb3ea64b08dc0c1d296ea9c09702c09083ca5272e64d115b687d238382604051808381526020018281526020019250505060405180910390a15b5050509c9b505050505050505050505050565b6008602052816000526040600020602052806000526040600020600091509150505481565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612a95576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180615e47602c913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415612b1b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526024815260200180615c826024913960400191505060405180910390fd5b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f75e41bc35ff1bf14d81d1d2f649c0084a0f974f9289c803ec9898eeec4c8d0b881604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612c45576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180615e47602c913960400191505060405180910390fd5b6000612c9483838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506116f2565b905060016007600083815260200190815260200160002081905550807fe7f4675038f4f6034dfcbbb24c4dc08e4ebf10eb9d257d3d02c0f38d122ac6e460405160405180910390a2505050565b606080600354604051908082528060200260200182016040528015612d155781602001602082028038833980820191505090505b5090506000809050600060026000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505b600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614612e6d5780838381518110612dc457fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508180600101925050612d83565b82935050505090565b6040518060400160405280600b81526020017f476e6f736973205361666500000000000000000000000000000000000000000081525081565b60055481565b606080612ec46001600a613276565b5090508091505090565b6000801b60065414612f48576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f446f6d61696e20536570617261746f7220616c7265616479207365742100000081525060200191505060405180910390fd5b7f035aff83d86937d35b32e04f0ddc6ff469290eef2f1b692d8a815c89404d474960001b30604051602001808381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200192505050604051602081830303815290604052805190602001206006819055506130178a8a80806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f8201169050808301925050505050505089615408565b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16146130555761305484615861565b5b6130a38787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050615890565b60008211156130bd576130bb8260006001868561523c565b505b50505050505050505050565b60003073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461314f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180615e47602c913960400191505060405180910390fd5b60005a90506131a5878787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050865a615190565b6131ae57600080fd5b60005a8203905080604051602001808281526020019150506040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561323b578082015181840152602081019050613220565b50505050905090810190601f1680156132685780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b60606000826040519080825280602002602001820160405280156132a95781602001602082028038833980820191505090505b50915060008090506000600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141580156133805750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b801561338b57508482105b15613446578084838151811061339d57fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050600160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508180600101925050613316565b80925081845250509250929050565b600073ffffffffffffffffffffffffffffffffffffffff16600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415613557576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f4f6e6c79206f776e6572732063616e20617070726f766520612068617368000081525060200191505060405180910390fd5b6001600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000838152602001908152602001600020819055503373ffffffffffffffffffffffffffffffffffffffff16817ff2a0eb156472d1440255b0d7c1e19cc07115d1051fe605b0dce69acfec884d9c60405160405180910390a350565b60006136088b8b8b8b8b8b8b8b8b8b6140f4565b8051906020012090509a9950505050505050505050565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146136a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180615e47602c913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415801561370d5750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b61377f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f496e76616c6964206d6f64756c6520616464726573732070726f76696465640081525060200191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614613862576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180615cee6028913960400191505060405180910390fd5b600160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507faab4fa2b463f581b2b32cb3b7e3b704b9ce37cc209b5fb4d77e593ace405427681604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a15050565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614613aa9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180615e47602c913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614158015613b135750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b613b85576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f496e76616c6964206f776e657220616464726573732070726f7669646564000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614613c86576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f4164647265737320697320616c726561647920616e206f776e6572000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614158015613cf05750600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b613d62576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f496e76616c6964206f776e657220616464726573732070726f7669646564000081525060200191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff16600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614613e45576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180615d906026913960400191505060405180910390fd5b600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507ff8d49fc529812e9a7c5c50e69c20f0dccc0db8fa95c98bc58cc9a4f1c1299eaf82604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a17f9465fa0c962cc76958e6373a993326400c1c94f8be2fe3a952adfa7f60b2ea2681604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a1505050565b6000600454905090565b606060007fbb8310d486368db6bd6f849402fdd73ad53d316b5a4b2644ad6efe0f941286d860001b8c8c8c805190602001208c8c8c8c8c8c8c604051602001808c81526020018b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018a815260200189815260200188600181111561418457fe5b60ff1681526020018781526020018681526020018581526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019b505050505050505050505050604051602081830303815290604052805190602001209050601960f81b600160f81b6006548360405160200180857effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152600101847effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526001018381526020018281526020019450505050506040516020818303038152906040529150509a9950505050505050505050565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461438c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180615e47602c913960400191505060405180910390fd5b61439581615861565b50565b60065481565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614614422576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180615e47602c913960400191505060405180910390fd5b806001600354031015614480576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526035815260200180615d396035913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141580156144ea5750600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b61455c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f496e76616c6964206f776e657220616464726573732070726f7669646564000081525060200191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff16600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461463f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180615d906026913960400191505060405180910390fd5b600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600360008154809291906001900391905055507ff8d49fc529812e9a7c5c50e69c20f0dccc0db8fa95c98bc58cc9a4f1c1299eaf82604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a1806004541461482457614823816125e8565b5b505050565b6040518060400160405280600581526020017f312e322e3000000000000000000000000000000000000000000000000000000081525081565b60006004549050600081116148df576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f5468726573686f6c64206e6565647320746f20626520646566696e656421000081525060200191505060405180910390fd5b6148f3604182615aaa90919063ffffffff16565b83511015614969576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f5369676e617475726573206461746120746f6f2073686f72740000000000000081525060200191505060405180910390fd5b600080905060008060008060008090505b868110156151835761498c8982615ae4565b80945081955082965050505060008460ff161415614d21578260001c94506149be604188615aaa90919063ffffffff16565b8260001c1015614a19576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526037815260200180615e106037913960400191505060405180910390fd5b8851614a3260208460001c615b1390919063ffffffff16565b1115614a89576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526037815260200180615ea36037913960400191505060405180910390fd5b60006020838b01015190508951614abf82614ab160208760001c615b1390919063ffffffff16565b615b1390919063ffffffff16565b1115614b16576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526036815260200180615db66036913960400191505060405180910390fd5b60606020848c010190506320c13b0b60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168773ffffffffffffffffffffffffffffffffffffffff166320c13b0b8e846040518363ffffffff1660e01b8152600401808060200180602001838103835285818151815260200191508051906020019080838360005b83811015614bb8578082015181840152602081019050614b9d565b50505050905090810190601f168015614be55780820380516001836020036101000a031916815260200191505b50838103825284818151815260200191508051906020019080838360005b83811015614c1e578082015181840152602081019050614c03565b50505050905090810190601f168015614c4b5780820380516001836020036101000a031916815260200191505b5094505050505060206040518083038186803b158015614c6a57600080fd5b505afa158015614c7e573d6000803e3d6000fd5b505050506040513d6020811015614c9457600080fd5b81019080805190602001909291905050507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614614d1a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180615ccb6023913960400191505060405180910390fd5b5050615001565b60018460ff161415614eca578260001c94508473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480614dbe57506000600860008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008d81526020019081526020016000205414155b614e30576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f4861736820686173206e6f74206265656e20617070726f76656400000000000081525060200191505060405180910390fd5b878015614e6957508473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614155b15614ec5576000600860008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008d8152602001908152602001600020819055505b615000565b601e8460ff161115614f955760018b60405160200180807f19457468657265756d205369676e6564204d6573736167653a0a333200000000815250601c018281526020019150506040516020818303038152906040528051906020012060048603858560405160008152602001604052604051808581526020018460ff1660ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa158015614f84573d6000803e3d6000fd5b505050602060405103519450614fff565b60018b85858560405160008152602001604052604051808581526020018460ff1660ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa158015614ff2573d6000803e3d6000fd5b5050506020604051035194505b5b5b8573ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161180156150c85750600073ffffffffffffffffffffffffffffffffffffffff16600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b80156151015750600173ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614155b615173576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f496e76616c6964206f776e65722070726f76696465640000000000000000000081525060200191505060405180910390fd5b849550808060010191505061497a565b5050505050505050505050565b600080600181111561519e57fe5b8360018111156151aa57fe5b14156151c3576151bc86868685615b32565b90506151f9565b6001808111156151cf57fe5b8360018111156151db57fe5b14156151f3576151ec868584615b4b565b90506151f8565b600090505b5b95945050505050565b6000818310156152125781615214565b825b905092915050565b60008282111561522b57600080fd5b600082840390508091505092915050565b600080600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614615279578261527b565b325b9050600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415615376576152e53a86106152c2573a6152c4565b855b6152d7888a615b1390919063ffffffff16565b615aaa90919063ffffffff16565b91508073ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050615371576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180615eda6022913960400191505060405180910390fd5b6153fe565b61539b8561538d888a615b1390919063ffffffff16565b615aaa90919063ffffffff16565b91506153a8848284615b62565b6153fd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180615d6e6022913960400191505060405180910390fd5b5b5095945050505050565b600060045414615480576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f4f776e657273206861766520616c7265616479206265656e207365747570000081525060200191505060405180910390fd5b81518111156154da576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180615d166023913960400191505060405180910390fd5b6001811015615534576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526024815260200180615dec6024913960400191505060405180910390fd5b60006001905060008090505b83518110156157cd57600084828151811061555757fe5b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141580156155cb5750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b61563d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f496e76616c6964206f776e657220616464726573732070726f7669646564000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461573e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4475706c6963617465206f776e657220616464726573732070726f766964656481525060200191505060405180910390fd5b80600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550809250508080600101915050615540565b506001600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550825160038190555081600481905550505050565b60007f6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d560001b90508181555050565b600073ffffffffffffffffffffffffffffffffffffffff1660016000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614615975576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526025815260200180615ca66025913960400191505060405180910390fd5b6001806000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614615aa657615a3382825a615b4b565b615aa5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f436f756c64206e6f742066696e69736820696e697469616c697a6174696f6e0081525060200191505060405180910390fd5b5b5050565b600080831415615abd5760009050615ade565b6000828402905082848281615ace57fe5b0414615ad957600080fd5b809150505b92915050565b60008060008360410260208101860151925060408101860151915060ff60418201870151169350509250925092565b600080828401905083811015615b2857600080fd5b8091505092915050565b6000806000845160208601878987f19050949350505050565b60008060008451602086018786f490509392505050565b600060608383604051602401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828152602001925050506040516020818303038152906040527fa9059cbb000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090506000808251602084016000896127105a03f16040513d81016040523d6000823e3d60008114615c645760208114615c6c5760009450615c76565b829450615c76565b8151158315171594505b50505050939250505056fe496e76616c6964206d617374657220636f707920616464726573732070726f76696465644d6f64756c6573206861766520616c7265616479206265656e20696e697469616c697a6564496e76616c696420636f6e7472616374207369676e61747572652070726f7669646564496e76616c696420707265764d6f64756c652c206d6f64756c6520706169722070726f76696465645468726573686f6c642063616e6e6f7420657863656564206f776e657220636f756e744e6577206f776e657220636f756e74206e6565647320746f206265206c6172676572207468616e206e6577207468726573686f6c64436f756c64206e6f74207061792067617320636f737473207769746820746f6b656e496e76616c696420707265764f776e65722c206f776e657220706169722070726f7669646564496e76616c696420636f6e7472616374207369676e6174757265206c6f636174696f6e3a2064617461206e6f7420636f6d706c6574655468726573686f6c64206e6565647320746f2062652067726561746572207468616e2030496e76616c696420636f6e7472616374207369676e6174757265206c6f636174696f6e3a20696e736964652073746174696320706172744d6574686f642063616e206f6e6c792062652063616c6c65642066726f6d207468697320636f6e74726163744d6574686f642063616e206f6e6c792062652063616c6c65642066726f6d20616e20656e61626c6564206d6f64756c65496e76616c696420636f6e7472616374207369676e6174757265206c6f636174696f6e3a206c656e677468206e6f742070726573656e74436f756c64206e6f74207061792067617320636f73747320776974682065746865724e6f7420656e6f7567682067617320746f20657865637574652073616665207472616e73616374696f6ea265627a7a72315820da2029b344faa0acf527c9aacdbb26d18ce3a0599d09b320dfe387081b8e392264736f6c63430005110032", +} + +// GnosisSafeABI is the input ABI used to generate the binding from. +// Deprecated: Use GnosisSafeMetaData.ABI instead. +var GnosisSafeABI = GnosisSafeMetaData.ABI + +// GnosisSafeBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use GnosisSafeMetaData.Bin instead. +var GnosisSafeBin = GnosisSafeMetaData.Bin + +// DeployGnosisSafe deploys a new Ethereum contract, binding an instance of GnosisSafe to it. +func DeployGnosisSafe(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *GnosisSafe, error) { + parsed, err := GnosisSafeMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(GnosisSafeBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &GnosisSafe{GnosisSafeCaller: GnosisSafeCaller{contract: contract}, GnosisSafeTransactor: GnosisSafeTransactor{contract: contract}, GnosisSafeFilterer: GnosisSafeFilterer{contract: contract}}, nil +} + +// GnosisSafe is an auto generated Go binding around an Ethereum contract. +type GnosisSafe struct { + GnosisSafeCaller // Read-only binding to the contract + GnosisSafeTransactor // Write-only binding to the contract + GnosisSafeFilterer // Log filterer for contract events +} + +// GnosisSafeCaller is an auto generated read-only Go binding around an Ethereum contract. +type GnosisSafeCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// GnosisSafeTransactor is an auto generated write-only Go binding around an Ethereum contract. +type GnosisSafeTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// GnosisSafeFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type GnosisSafeFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// GnosisSafeSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type GnosisSafeSession struct { + Contract *GnosisSafe // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// GnosisSafeCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type GnosisSafeCallerSession struct { + Contract *GnosisSafeCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// GnosisSafeTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type GnosisSafeTransactorSession struct { + Contract *GnosisSafeTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// GnosisSafeRaw is an auto generated low-level Go binding around an Ethereum contract. +type GnosisSafeRaw struct { + Contract *GnosisSafe // Generic contract binding to access the raw methods on +} + +// GnosisSafeCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type GnosisSafeCallerRaw struct { + Contract *GnosisSafeCaller // Generic read-only contract binding to access the raw methods on +} + +// GnosisSafeTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type GnosisSafeTransactorRaw struct { + Contract *GnosisSafeTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewGnosisSafe creates a new instance of GnosisSafe, bound to a specific deployed contract. +func NewGnosisSafe(address common.Address, backend bind.ContractBackend) (*GnosisSafe, error) { + contract, err := bindGnosisSafe(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &GnosisSafe{GnosisSafeCaller: GnosisSafeCaller{contract: contract}, GnosisSafeTransactor: GnosisSafeTransactor{contract: contract}, GnosisSafeFilterer: GnosisSafeFilterer{contract: contract}}, nil +} + +// NewGnosisSafeCaller creates a new read-only instance of GnosisSafe, bound to a specific deployed contract. +func NewGnosisSafeCaller(address common.Address, caller bind.ContractCaller) (*GnosisSafeCaller, error) { + contract, err := bindGnosisSafe(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &GnosisSafeCaller{contract: contract}, nil +} + +// NewGnosisSafeTransactor creates a new write-only instance of GnosisSafe, bound to a specific deployed contract. +func NewGnosisSafeTransactor(address common.Address, transactor bind.ContractTransactor) (*GnosisSafeTransactor, error) { + contract, err := bindGnosisSafe(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &GnosisSafeTransactor{contract: contract}, nil +} + +// NewGnosisSafeFilterer creates a new log filterer instance of GnosisSafe, bound to a specific deployed contract. +func NewGnosisSafeFilterer(address common.Address, filterer bind.ContractFilterer) (*GnosisSafeFilterer, error) { + contract, err := bindGnosisSafe(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &GnosisSafeFilterer{contract: contract}, nil +} + +// bindGnosisSafe binds a generic wrapper to an already deployed contract. +func bindGnosisSafe(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := GnosisSafeMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_GnosisSafe *GnosisSafeRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _GnosisSafe.Contract.GnosisSafeCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_GnosisSafe *GnosisSafeRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _GnosisSafe.Contract.GnosisSafeTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_GnosisSafe *GnosisSafeRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _GnosisSafe.Contract.GnosisSafeTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_GnosisSafe *GnosisSafeCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _GnosisSafe.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_GnosisSafe *GnosisSafeTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _GnosisSafe.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_GnosisSafe *GnosisSafeTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _GnosisSafe.Contract.contract.Transact(opts, method, params...) +} + +// NAME is a free data retrieval call binding the contract method 0xa3f4df7e. +// +// Solidity: function NAME() view returns(string) +func (_GnosisSafe *GnosisSafeCaller) NAME(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _GnosisSafe.contract.Call(opts, &out, "NAME") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +// NAME is a free data retrieval call binding the contract method 0xa3f4df7e. +// +// Solidity: function NAME() view returns(string) +func (_GnosisSafe *GnosisSafeSession) NAME() (string, error) { + return _GnosisSafe.Contract.NAME(&_GnosisSafe.CallOpts) +} + +// NAME is a free data retrieval call binding the contract method 0xa3f4df7e. +// +// Solidity: function NAME() view returns(string) +func (_GnosisSafe *GnosisSafeCallerSession) NAME() (string, error) { + return _GnosisSafe.Contract.NAME(&_GnosisSafe.CallOpts) +} + +// VERSION is a free data retrieval call binding the contract method 0xffa1ad74. +// +// Solidity: function VERSION() view returns(string) +func (_GnosisSafe *GnosisSafeCaller) VERSION(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _GnosisSafe.contract.Call(opts, &out, "VERSION") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +// VERSION is a free data retrieval call binding the contract method 0xffa1ad74. +// +// Solidity: function VERSION() view returns(string) +func (_GnosisSafe *GnosisSafeSession) VERSION() (string, error) { + return _GnosisSafe.Contract.VERSION(&_GnosisSafe.CallOpts) +} + +// VERSION is a free data retrieval call binding the contract method 0xffa1ad74. +// +// Solidity: function VERSION() view returns(string) +func (_GnosisSafe *GnosisSafeCallerSession) VERSION() (string, error) { + return _GnosisSafe.Contract.VERSION(&_GnosisSafe.CallOpts) +} + +// ApprovedHashes is a free data retrieval call binding the contract method 0x7d832974. +// +// Solidity: function approvedHashes(address , bytes32 ) view returns(uint256) +func (_GnosisSafe *GnosisSafeCaller) ApprovedHashes(opts *bind.CallOpts, arg0 common.Address, arg1 [32]byte) (*big.Int, error) { + var out []interface{} + err := _GnosisSafe.contract.Call(opts, &out, "approvedHashes", arg0, arg1) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// ApprovedHashes is a free data retrieval call binding the contract method 0x7d832974. +// +// Solidity: function approvedHashes(address , bytes32 ) view returns(uint256) +func (_GnosisSafe *GnosisSafeSession) ApprovedHashes(arg0 common.Address, arg1 [32]byte) (*big.Int, error) { + return _GnosisSafe.Contract.ApprovedHashes(&_GnosisSafe.CallOpts, arg0, arg1) +} + +// ApprovedHashes is a free data retrieval call binding the contract method 0x7d832974. +// +// Solidity: function approvedHashes(address , bytes32 ) view returns(uint256) +func (_GnosisSafe *GnosisSafeCallerSession) ApprovedHashes(arg0 common.Address, arg1 [32]byte) (*big.Int, error) { + return _GnosisSafe.Contract.ApprovedHashes(&_GnosisSafe.CallOpts, arg0, arg1) +} + +// DomainSeparator is a free data retrieval call binding the contract method 0xf698da25. +// +// Solidity: function domainSeparator() view returns(bytes32) +func (_GnosisSafe *GnosisSafeCaller) DomainSeparator(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _GnosisSafe.contract.Call(opts, &out, "domainSeparator") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// DomainSeparator is a free data retrieval call binding the contract method 0xf698da25. +// +// Solidity: function domainSeparator() view returns(bytes32) +func (_GnosisSafe *GnosisSafeSession) DomainSeparator() ([32]byte, error) { + return _GnosisSafe.Contract.DomainSeparator(&_GnosisSafe.CallOpts) +} + +// DomainSeparator is a free data retrieval call binding the contract method 0xf698da25. +// +// Solidity: function domainSeparator() view returns(bytes32) +func (_GnosisSafe *GnosisSafeCallerSession) DomainSeparator() ([32]byte, error) { + return _GnosisSafe.Contract.DomainSeparator(&_GnosisSafe.CallOpts) +} + +// EncodeTransactionData is a free data retrieval call binding the contract method 0xe86637db. +// +// Solidity: function encodeTransactionData(address to, uint256 value, bytes data, uint8 operation, uint256 safeTxGas, uint256 baseGas, uint256 gasPrice, address gasToken, address refundReceiver, uint256 _nonce) view returns(bytes) +func (_GnosisSafe *GnosisSafeCaller) EncodeTransactionData(opts *bind.CallOpts, to common.Address, value *big.Int, data []byte, operation uint8, safeTxGas *big.Int, baseGas *big.Int, gasPrice *big.Int, gasToken common.Address, refundReceiver common.Address, _nonce *big.Int) ([]byte, error) { + var out []interface{} + err := _GnosisSafe.contract.Call(opts, &out, "encodeTransactionData", to, value, data, operation, safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, _nonce) + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +// EncodeTransactionData is a free data retrieval call binding the contract method 0xe86637db. +// +// Solidity: function encodeTransactionData(address to, uint256 value, bytes data, uint8 operation, uint256 safeTxGas, uint256 baseGas, uint256 gasPrice, address gasToken, address refundReceiver, uint256 _nonce) view returns(bytes) +func (_GnosisSafe *GnosisSafeSession) EncodeTransactionData(to common.Address, value *big.Int, data []byte, operation uint8, safeTxGas *big.Int, baseGas *big.Int, gasPrice *big.Int, gasToken common.Address, refundReceiver common.Address, _nonce *big.Int) ([]byte, error) { + return _GnosisSafe.Contract.EncodeTransactionData(&_GnosisSafe.CallOpts, to, value, data, operation, safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, _nonce) +} + +// EncodeTransactionData is a free data retrieval call binding the contract method 0xe86637db. +// +// Solidity: function encodeTransactionData(address to, uint256 value, bytes data, uint8 operation, uint256 safeTxGas, uint256 baseGas, uint256 gasPrice, address gasToken, address refundReceiver, uint256 _nonce) view returns(bytes) +func (_GnosisSafe *GnosisSafeCallerSession) EncodeTransactionData(to common.Address, value *big.Int, data []byte, operation uint8, safeTxGas *big.Int, baseGas *big.Int, gasPrice *big.Int, gasToken common.Address, refundReceiver common.Address, _nonce *big.Int) ([]byte, error) { + return _GnosisSafe.Contract.EncodeTransactionData(&_GnosisSafe.CallOpts, to, value, data, operation, safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, _nonce) +} + +// GetMessageHash is a free data retrieval call binding the contract method 0x0a1028c4. +// +// Solidity: function getMessageHash(bytes message) view returns(bytes32) +func (_GnosisSafe *GnosisSafeCaller) GetMessageHash(opts *bind.CallOpts, message []byte) ([32]byte, error) { + var out []interface{} + err := _GnosisSafe.contract.Call(opts, &out, "getMessageHash", message) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// GetMessageHash is a free data retrieval call binding the contract method 0x0a1028c4. +// +// Solidity: function getMessageHash(bytes message) view returns(bytes32) +func (_GnosisSafe *GnosisSafeSession) GetMessageHash(message []byte) ([32]byte, error) { + return _GnosisSafe.Contract.GetMessageHash(&_GnosisSafe.CallOpts, message) +} + +// GetMessageHash is a free data retrieval call binding the contract method 0x0a1028c4. +// +// Solidity: function getMessageHash(bytes message) view returns(bytes32) +func (_GnosisSafe *GnosisSafeCallerSession) GetMessageHash(message []byte) ([32]byte, error) { + return _GnosisSafe.Contract.GetMessageHash(&_GnosisSafe.CallOpts, message) +} + +// GetModules is a free data retrieval call binding the contract method 0xb2494df3. +// +// Solidity: function getModules() view returns(address[]) +func (_GnosisSafe *GnosisSafeCaller) GetModules(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _GnosisSafe.contract.Call(opts, &out, "getModules") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +// GetModules is a free data retrieval call binding the contract method 0xb2494df3. +// +// Solidity: function getModules() view returns(address[]) +func (_GnosisSafe *GnosisSafeSession) GetModules() ([]common.Address, error) { + return _GnosisSafe.Contract.GetModules(&_GnosisSafe.CallOpts) +} + +// GetModules is a free data retrieval call binding the contract method 0xb2494df3. +// +// Solidity: function getModules() view returns(address[]) +func (_GnosisSafe *GnosisSafeCallerSession) GetModules() ([]common.Address, error) { + return _GnosisSafe.Contract.GetModules(&_GnosisSafe.CallOpts) +} + +// GetModulesPaginated is a free data retrieval call binding the contract method 0xcc2f8452. +// +// Solidity: function getModulesPaginated(address start, uint256 pageSize) view returns(address[] array, address next) +func (_GnosisSafe *GnosisSafeCaller) GetModulesPaginated(opts *bind.CallOpts, start common.Address, pageSize *big.Int) (struct { + Array []common.Address + Next common.Address +}, error) { + var out []interface{} + err := _GnosisSafe.contract.Call(opts, &out, "getModulesPaginated", start, pageSize) + + outstruct := new(struct { + Array []common.Address + Next common.Address + }) + if err != nil { + return *outstruct, err + } + + outstruct.Array = *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + outstruct.Next = *abi.ConvertType(out[1], new(common.Address)).(*common.Address) + + return *outstruct, err + +} + +// GetModulesPaginated is a free data retrieval call binding the contract method 0xcc2f8452. +// +// Solidity: function getModulesPaginated(address start, uint256 pageSize) view returns(address[] array, address next) +func (_GnosisSafe *GnosisSafeSession) GetModulesPaginated(start common.Address, pageSize *big.Int) (struct { + Array []common.Address + Next common.Address +}, error) { + return _GnosisSafe.Contract.GetModulesPaginated(&_GnosisSafe.CallOpts, start, pageSize) +} + +// GetModulesPaginated is a free data retrieval call binding the contract method 0xcc2f8452. +// +// Solidity: function getModulesPaginated(address start, uint256 pageSize) view returns(address[] array, address next) +func (_GnosisSafe *GnosisSafeCallerSession) GetModulesPaginated(start common.Address, pageSize *big.Int) (struct { + Array []common.Address + Next common.Address +}, error) { + return _GnosisSafe.Contract.GetModulesPaginated(&_GnosisSafe.CallOpts, start, pageSize) +} + +// GetOwners is a free data retrieval call binding the contract method 0xa0e67e2b. +// +// Solidity: function getOwners() view returns(address[]) +func (_GnosisSafe *GnosisSafeCaller) GetOwners(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _GnosisSafe.contract.Call(opts, &out, "getOwners") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +// GetOwners is a free data retrieval call binding the contract method 0xa0e67e2b. +// +// Solidity: function getOwners() view returns(address[]) +func (_GnosisSafe *GnosisSafeSession) GetOwners() ([]common.Address, error) { + return _GnosisSafe.Contract.GetOwners(&_GnosisSafe.CallOpts) +} + +// GetOwners is a free data retrieval call binding the contract method 0xa0e67e2b. +// +// Solidity: function getOwners() view returns(address[]) +func (_GnosisSafe *GnosisSafeCallerSession) GetOwners() ([]common.Address, error) { + return _GnosisSafe.Contract.GetOwners(&_GnosisSafe.CallOpts) +} + +// GetThreshold is a free data retrieval call binding the contract method 0xe75235b8. +// +// Solidity: function getThreshold() view returns(uint256) +func (_GnosisSafe *GnosisSafeCaller) GetThreshold(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _GnosisSafe.contract.Call(opts, &out, "getThreshold") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetThreshold is a free data retrieval call binding the contract method 0xe75235b8. +// +// Solidity: function getThreshold() view returns(uint256) +func (_GnosisSafe *GnosisSafeSession) GetThreshold() (*big.Int, error) { + return _GnosisSafe.Contract.GetThreshold(&_GnosisSafe.CallOpts) +} + +// GetThreshold is a free data retrieval call binding the contract method 0xe75235b8. +// +// Solidity: function getThreshold() view returns(uint256) +func (_GnosisSafe *GnosisSafeCallerSession) GetThreshold() (*big.Int, error) { + return _GnosisSafe.Contract.GetThreshold(&_GnosisSafe.CallOpts) +} + +// GetTransactionHash is a free data retrieval call binding the contract method 0xd8d11f78. +// +// Solidity: function getTransactionHash(address to, uint256 value, bytes data, uint8 operation, uint256 safeTxGas, uint256 baseGas, uint256 gasPrice, address gasToken, address refundReceiver, uint256 _nonce) view returns(bytes32) +func (_GnosisSafe *GnosisSafeCaller) GetTransactionHash(opts *bind.CallOpts, to common.Address, value *big.Int, data []byte, operation uint8, safeTxGas *big.Int, baseGas *big.Int, gasPrice *big.Int, gasToken common.Address, refundReceiver common.Address, _nonce *big.Int) ([32]byte, error) { + var out []interface{} + err := _GnosisSafe.contract.Call(opts, &out, "getTransactionHash", to, value, data, operation, safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, _nonce) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// GetTransactionHash is a free data retrieval call binding the contract method 0xd8d11f78. +// +// Solidity: function getTransactionHash(address to, uint256 value, bytes data, uint8 operation, uint256 safeTxGas, uint256 baseGas, uint256 gasPrice, address gasToken, address refundReceiver, uint256 _nonce) view returns(bytes32) +func (_GnosisSafe *GnosisSafeSession) GetTransactionHash(to common.Address, value *big.Int, data []byte, operation uint8, safeTxGas *big.Int, baseGas *big.Int, gasPrice *big.Int, gasToken common.Address, refundReceiver common.Address, _nonce *big.Int) ([32]byte, error) { + return _GnosisSafe.Contract.GetTransactionHash(&_GnosisSafe.CallOpts, to, value, data, operation, safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, _nonce) +} + +// GetTransactionHash is a free data retrieval call binding the contract method 0xd8d11f78. +// +// Solidity: function getTransactionHash(address to, uint256 value, bytes data, uint8 operation, uint256 safeTxGas, uint256 baseGas, uint256 gasPrice, address gasToken, address refundReceiver, uint256 _nonce) view returns(bytes32) +func (_GnosisSafe *GnosisSafeCallerSession) GetTransactionHash(to common.Address, value *big.Int, data []byte, operation uint8, safeTxGas *big.Int, baseGas *big.Int, gasPrice *big.Int, gasToken common.Address, refundReceiver common.Address, _nonce *big.Int) ([32]byte, error) { + return _GnosisSafe.Contract.GetTransactionHash(&_GnosisSafe.CallOpts, to, value, data, operation, safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, _nonce) +} + +// IsModuleEnabled is a free data retrieval call binding the contract method 0x2d9ad53d. +// +// Solidity: function isModuleEnabled(address module) view returns(bool) +func (_GnosisSafe *GnosisSafeCaller) IsModuleEnabled(opts *bind.CallOpts, module common.Address) (bool, error) { + var out []interface{} + err := _GnosisSafe.contract.Call(opts, &out, "isModuleEnabled", module) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// IsModuleEnabled is a free data retrieval call binding the contract method 0x2d9ad53d. +// +// Solidity: function isModuleEnabled(address module) view returns(bool) +func (_GnosisSafe *GnosisSafeSession) IsModuleEnabled(module common.Address) (bool, error) { + return _GnosisSafe.Contract.IsModuleEnabled(&_GnosisSafe.CallOpts, module) +} + +// IsModuleEnabled is a free data retrieval call binding the contract method 0x2d9ad53d. +// +// Solidity: function isModuleEnabled(address module) view returns(bool) +func (_GnosisSafe *GnosisSafeCallerSession) IsModuleEnabled(module common.Address) (bool, error) { + return _GnosisSafe.Contract.IsModuleEnabled(&_GnosisSafe.CallOpts, module) +} + +// IsOwner is a free data retrieval call binding the contract method 0x2f54bf6e. +// +// Solidity: function isOwner(address owner) view returns(bool) +func (_GnosisSafe *GnosisSafeCaller) IsOwner(opts *bind.CallOpts, owner common.Address) (bool, error) { + var out []interface{} + err := _GnosisSafe.contract.Call(opts, &out, "isOwner", owner) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// IsOwner is a free data retrieval call binding the contract method 0x2f54bf6e. +// +// Solidity: function isOwner(address owner) view returns(bool) +func (_GnosisSafe *GnosisSafeSession) IsOwner(owner common.Address) (bool, error) { + return _GnosisSafe.Contract.IsOwner(&_GnosisSafe.CallOpts, owner) +} + +// IsOwner is a free data retrieval call binding the contract method 0x2f54bf6e. +// +// Solidity: function isOwner(address owner) view returns(bool) +func (_GnosisSafe *GnosisSafeCallerSession) IsOwner(owner common.Address) (bool, error) { + return _GnosisSafe.Contract.IsOwner(&_GnosisSafe.CallOpts, owner) +} + +// Nonce is a free data retrieval call binding the contract method 0xaffed0e0. +// +// Solidity: function nonce() view returns(uint256) +func (_GnosisSafe *GnosisSafeCaller) Nonce(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _GnosisSafe.contract.Call(opts, &out, "nonce") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Nonce is a free data retrieval call binding the contract method 0xaffed0e0. +// +// Solidity: function nonce() view returns(uint256) +func (_GnosisSafe *GnosisSafeSession) Nonce() (*big.Int, error) { + return _GnosisSafe.Contract.Nonce(&_GnosisSafe.CallOpts) +} + +// Nonce is a free data retrieval call binding the contract method 0xaffed0e0. +// +// Solidity: function nonce() view returns(uint256) +func (_GnosisSafe *GnosisSafeCallerSession) Nonce() (*big.Int, error) { + return _GnosisSafe.Contract.Nonce(&_GnosisSafe.CallOpts) +} + +// SignedMessages is a free data retrieval call binding the contract method 0x5ae6bd37. +// +// Solidity: function signedMessages(bytes32 ) view returns(uint256) +func (_GnosisSafe *GnosisSafeCaller) SignedMessages(opts *bind.CallOpts, arg0 [32]byte) (*big.Int, error) { + var out []interface{} + err := _GnosisSafe.contract.Call(opts, &out, "signedMessages", arg0) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// SignedMessages is a free data retrieval call binding the contract method 0x5ae6bd37. +// +// Solidity: function signedMessages(bytes32 ) view returns(uint256) +func (_GnosisSafe *GnosisSafeSession) SignedMessages(arg0 [32]byte) (*big.Int, error) { + return _GnosisSafe.Contract.SignedMessages(&_GnosisSafe.CallOpts, arg0) +} + +// SignedMessages is a free data retrieval call binding the contract method 0x5ae6bd37. +// +// Solidity: function signedMessages(bytes32 ) view returns(uint256) +func (_GnosisSafe *GnosisSafeCallerSession) SignedMessages(arg0 [32]byte) (*big.Int, error) { + return _GnosisSafe.Contract.SignedMessages(&_GnosisSafe.CallOpts, arg0) +} + +// AddOwnerWithThreshold is a paid mutator transaction binding the contract method 0x0d582f13. +// +// Solidity: function addOwnerWithThreshold(address owner, uint256 _threshold) returns() +func (_GnosisSafe *GnosisSafeTransactor) AddOwnerWithThreshold(opts *bind.TransactOpts, owner common.Address, _threshold *big.Int) (*types.Transaction, error) { + return _GnosisSafe.contract.Transact(opts, "addOwnerWithThreshold", owner, _threshold) +} + +// AddOwnerWithThreshold is a paid mutator transaction binding the contract method 0x0d582f13. +// +// Solidity: function addOwnerWithThreshold(address owner, uint256 _threshold) returns() +func (_GnosisSafe *GnosisSafeSession) AddOwnerWithThreshold(owner common.Address, _threshold *big.Int) (*types.Transaction, error) { + return _GnosisSafe.Contract.AddOwnerWithThreshold(&_GnosisSafe.TransactOpts, owner, _threshold) +} + +// AddOwnerWithThreshold is a paid mutator transaction binding the contract method 0x0d582f13. +// +// Solidity: function addOwnerWithThreshold(address owner, uint256 _threshold) returns() +func (_GnosisSafe *GnosisSafeTransactorSession) AddOwnerWithThreshold(owner common.Address, _threshold *big.Int) (*types.Transaction, error) { + return _GnosisSafe.Contract.AddOwnerWithThreshold(&_GnosisSafe.TransactOpts, owner, _threshold) +} + +// ApproveHash is a paid mutator transaction binding the contract method 0xd4d9bdcd. +// +// Solidity: function approveHash(bytes32 hashToApprove) returns() +func (_GnosisSafe *GnosisSafeTransactor) ApproveHash(opts *bind.TransactOpts, hashToApprove [32]byte) (*types.Transaction, error) { + return _GnosisSafe.contract.Transact(opts, "approveHash", hashToApprove) +} + +// ApproveHash is a paid mutator transaction binding the contract method 0xd4d9bdcd. +// +// Solidity: function approveHash(bytes32 hashToApprove) returns() +func (_GnosisSafe *GnosisSafeSession) ApproveHash(hashToApprove [32]byte) (*types.Transaction, error) { + return _GnosisSafe.Contract.ApproveHash(&_GnosisSafe.TransactOpts, hashToApprove) +} + +// ApproveHash is a paid mutator transaction binding the contract method 0xd4d9bdcd. +// +// Solidity: function approveHash(bytes32 hashToApprove) returns() +func (_GnosisSafe *GnosisSafeTransactorSession) ApproveHash(hashToApprove [32]byte) (*types.Transaction, error) { + return _GnosisSafe.Contract.ApproveHash(&_GnosisSafe.TransactOpts, hashToApprove) +} + +// ChangeMasterCopy is a paid mutator transaction binding the contract method 0x7de7edef. +// +// Solidity: function changeMasterCopy(address _masterCopy) returns() +func (_GnosisSafe *GnosisSafeTransactor) ChangeMasterCopy(opts *bind.TransactOpts, _masterCopy common.Address) (*types.Transaction, error) { + return _GnosisSafe.contract.Transact(opts, "changeMasterCopy", _masterCopy) +} + +// ChangeMasterCopy is a paid mutator transaction binding the contract method 0x7de7edef. +// +// Solidity: function changeMasterCopy(address _masterCopy) returns() +func (_GnosisSafe *GnosisSafeSession) ChangeMasterCopy(_masterCopy common.Address) (*types.Transaction, error) { + return _GnosisSafe.Contract.ChangeMasterCopy(&_GnosisSafe.TransactOpts, _masterCopy) +} + +// ChangeMasterCopy is a paid mutator transaction binding the contract method 0x7de7edef. +// +// Solidity: function changeMasterCopy(address _masterCopy) returns() +func (_GnosisSafe *GnosisSafeTransactorSession) ChangeMasterCopy(_masterCopy common.Address) (*types.Transaction, error) { + return _GnosisSafe.Contract.ChangeMasterCopy(&_GnosisSafe.TransactOpts, _masterCopy) +} + +// ChangeThreshold is a paid mutator transaction binding the contract method 0x694e80c3. +// +// Solidity: function changeThreshold(uint256 _threshold) returns() +func (_GnosisSafe *GnosisSafeTransactor) ChangeThreshold(opts *bind.TransactOpts, _threshold *big.Int) (*types.Transaction, error) { + return _GnosisSafe.contract.Transact(opts, "changeThreshold", _threshold) +} + +// ChangeThreshold is a paid mutator transaction binding the contract method 0x694e80c3. +// +// Solidity: function changeThreshold(uint256 _threshold) returns() +func (_GnosisSafe *GnosisSafeSession) ChangeThreshold(_threshold *big.Int) (*types.Transaction, error) { + return _GnosisSafe.Contract.ChangeThreshold(&_GnosisSafe.TransactOpts, _threshold) +} + +// ChangeThreshold is a paid mutator transaction binding the contract method 0x694e80c3. +// +// Solidity: function changeThreshold(uint256 _threshold) returns() +func (_GnosisSafe *GnosisSafeTransactorSession) ChangeThreshold(_threshold *big.Int) (*types.Transaction, error) { + return _GnosisSafe.Contract.ChangeThreshold(&_GnosisSafe.TransactOpts, _threshold) +} + +// DisableModule is a paid mutator transaction binding the contract method 0xe009cfde. +// +// Solidity: function disableModule(address prevModule, address module) returns() +func (_GnosisSafe *GnosisSafeTransactor) DisableModule(opts *bind.TransactOpts, prevModule common.Address, module common.Address) (*types.Transaction, error) { + return _GnosisSafe.contract.Transact(opts, "disableModule", prevModule, module) +} + +// DisableModule is a paid mutator transaction binding the contract method 0xe009cfde. +// +// Solidity: function disableModule(address prevModule, address module) returns() +func (_GnosisSafe *GnosisSafeSession) DisableModule(prevModule common.Address, module common.Address) (*types.Transaction, error) { + return _GnosisSafe.Contract.DisableModule(&_GnosisSafe.TransactOpts, prevModule, module) +} + +// DisableModule is a paid mutator transaction binding the contract method 0xe009cfde. +// +// Solidity: function disableModule(address prevModule, address module) returns() +func (_GnosisSafe *GnosisSafeTransactorSession) DisableModule(prevModule common.Address, module common.Address) (*types.Transaction, error) { + return _GnosisSafe.Contract.DisableModule(&_GnosisSafe.TransactOpts, prevModule, module) +} + +// EnableModule is a paid mutator transaction binding the contract method 0x610b5925. +// +// Solidity: function enableModule(address module) returns() +func (_GnosisSafe *GnosisSafeTransactor) EnableModule(opts *bind.TransactOpts, module common.Address) (*types.Transaction, error) { + return _GnosisSafe.contract.Transact(opts, "enableModule", module) +} + +// EnableModule is a paid mutator transaction binding the contract method 0x610b5925. +// +// Solidity: function enableModule(address module) returns() +func (_GnosisSafe *GnosisSafeSession) EnableModule(module common.Address) (*types.Transaction, error) { + return _GnosisSafe.Contract.EnableModule(&_GnosisSafe.TransactOpts, module) +} + +// EnableModule is a paid mutator transaction binding the contract method 0x610b5925. +// +// Solidity: function enableModule(address module) returns() +func (_GnosisSafe *GnosisSafeTransactorSession) EnableModule(module common.Address) (*types.Transaction, error) { + return _GnosisSafe.Contract.EnableModule(&_GnosisSafe.TransactOpts, module) +} + +// ExecTransaction is a paid mutator transaction binding the contract method 0x6a761202. +// +// Solidity: function execTransaction(address to, uint256 value, bytes data, uint8 operation, uint256 safeTxGas, uint256 baseGas, uint256 gasPrice, address gasToken, address refundReceiver, bytes signatures) payable returns(bool success) +func (_GnosisSafe *GnosisSafeTransactor) ExecTransaction(opts *bind.TransactOpts, to common.Address, value *big.Int, data []byte, operation uint8, safeTxGas *big.Int, baseGas *big.Int, gasPrice *big.Int, gasToken common.Address, refundReceiver common.Address, signatures []byte) (*types.Transaction, error) { + return _GnosisSafe.contract.Transact(opts, "execTransaction", to, value, data, operation, safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, signatures) +} + +// ExecTransaction is a paid mutator transaction binding the contract method 0x6a761202. +// +// Solidity: function execTransaction(address to, uint256 value, bytes data, uint8 operation, uint256 safeTxGas, uint256 baseGas, uint256 gasPrice, address gasToken, address refundReceiver, bytes signatures) payable returns(bool success) +func (_GnosisSafe *GnosisSafeSession) ExecTransaction(to common.Address, value *big.Int, data []byte, operation uint8, safeTxGas *big.Int, baseGas *big.Int, gasPrice *big.Int, gasToken common.Address, refundReceiver common.Address, signatures []byte) (*types.Transaction, error) { + return _GnosisSafe.Contract.ExecTransaction(&_GnosisSafe.TransactOpts, to, value, data, operation, safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, signatures) +} + +// ExecTransaction is a paid mutator transaction binding the contract method 0x6a761202. +// +// Solidity: function execTransaction(address to, uint256 value, bytes data, uint8 operation, uint256 safeTxGas, uint256 baseGas, uint256 gasPrice, address gasToken, address refundReceiver, bytes signatures) payable returns(bool success) +func (_GnosisSafe *GnosisSafeTransactorSession) ExecTransaction(to common.Address, value *big.Int, data []byte, operation uint8, safeTxGas *big.Int, baseGas *big.Int, gasPrice *big.Int, gasToken common.Address, refundReceiver common.Address, signatures []byte) (*types.Transaction, error) { + return _GnosisSafe.Contract.ExecTransaction(&_GnosisSafe.TransactOpts, to, value, data, operation, safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, signatures) +} + +// ExecTransactionFromModule is a paid mutator transaction binding the contract method 0x468721a7. +// +// Solidity: function execTransactionFromModule(address to, uint256 value, bytes data, uint8 operation) returns(bool success) +func (_GnosisSafe *GnosisSafeTransactor) ExecTransactionFromModule(opts *bind.TransactOpts, to common.Address, value *big.Int, data []byte, operation uint8) (*types.Transaction, error) { + return _GnosisSafe.contract.Transact(opts, "execTransactionFromModule", to, value, data, operation) +} + +// ExecTransactionFromModule is a paid mutator transaction binding the contract method 0x468721a7. +// +// Solidity: function execTransactionFromModule(address to, uint256 value, bytes data, uint8 operation) returns(bool success) +func (_GnosisSafe *GnosisSafeSession) ExecTransactionFromModule(to common.Address, value *big.Int, data []byte, operation uint8) (*types.Transaction, error) { + return _GnosisSafe.Contract.ExecTransactionFromModule(&_GnosisSafe.TransactOpts, to, value, data, operation) +} + +// ExecTransactionFromModule is a paid mutator transaction binding the contract method 0x468721a7. +// +// Solidity: function execTransactionFromModule(address to, uint256 value, bytes data, uint8 operation) returns(bool success) +func (_GnosisSafe *GnosisSafeTransactorSession) ExecTransactionFromModule(to common.Address, value *big.Int, data []byte, operation uint8) (*types.Transaction, error) { + return _GnosisSafe.Contract.ExecTransactionFromModule(&_GnosisSafe.TransactOpts, to, value, data, operation) +} + +// ExecTransactionFromModuleReturnData is a paid mutator transaction binding the contract method 0x5229073f. +// +// Solidity: function execTransactionFromModuleReturnData(address to, uint256 value, bytes data, uint8 operation) returns(bool success, bytes returnData) +func (_GnosisSafe *GnosisSafeTransactor) ExecTransactionFromModuleReturnData(opts *bind.TransactOpts, to common.Address, value *big.Int, data []byte, operation uint8) (*types.Transaction, error) { + return _GnosisSafe.contract.Transact(opts, "execTransactionFromModuleReturnData", to, value, data, operation) +} + +// ExecTransactionFromModuleReturnData is a paid mutator transaction binding the contract method 0x5229073f. +// +// Solidity: function execTransactionFromModuleReturnData(address to, uint256 value, bytes data, uint8 operation) returns(bool success, bytes returnData) +func (_GnosisSafe *GnosisSafeSession) ExecTransactionFromModuleReturnData(to common.Address, value *big.Int, data []byte, operation uint8) (*types.Transaction, error) { + return _GnosisSafe.Contract.ExecTransactionFromModuleReturnData(&_GnosisSafe.TransactOpts, to, value, data, operation) +} + +// ExecTransactionFromModuleReturnData is a paid mutator transaction binding the contract method 0x5229073f. +// +// Solidity: function execTransactionFromModuleReturnData(address to, uint256 value, bytes data, uint8 operation) returns(bool success, bytes returnData) +func (_GnosisSafe *GnosisSafeTransactorSession) ExecTransactionFromModuleReturnData(to common.Address, value *big.Int, data []byte, operation uint8) (*types.Transaction, error) { + return _GnosisSafe.Contract.ExecTransactionFromModuleReturnData(&_GnosisSafe.TransactOpts, to, value, data, operation) +} + +// IsValidSignature is a paid mutator transaction binding the contract method 0x20c13b0b. +// +// Solidity: function isValidSignature(bytes _data, bytes _signature) returns(bytes4) +func (_GnosisSafe *GnosisSafeTransactor) IsValidSignature(opts *bind.TransactOpts, _data []byte, _signature []byte) (*types.Transaction, error) { + return _GnosisSafe.contract.Transact(opts, "isValidSignature", _data, _signature) +} + +// IsValidSignature is a paid mutator transaction binding the contract method 0x20c13b0b. +// +// Solidity: function isValidSignature(bytes _data, bytes _signature) returns(bytes4) +func (_GnosisSafe *GnosisSafeSession) IsValidSignature(_data []byte, _signature []byte) (*types.Transaction, error) { + return _GnosisSafe.Contract.IsValidSignature(&_GnosisSafe.TransactOpts, _data, _signature) +} + +// IsValidSignature is a paid mutator transaction binding the contract method 0x20c13b0b. +// +// Solidity: function isValidSignature(bytes _data, bytes _signature) returns(bytes4) +func (_GnosisSafe *GnosisSafeTransactorSession) IsValidSignature(_data []byte, _signature []byte) (*types.Transaction, error) { + return _GnosisSafe.Contract.IsValidSignature(&_GnosisSafe.TransactOpts, _data, _signature) +} + +// RemoveOwner is a paid mutator transaction binding the contract method 0xf8dc5dd9. +// +// Solidity: function removeOwner(address prevOwner, address owner, uint256 _threshold) returns() +func (_GnosisSafe *GnosisSafeTransactor) RemoveOwner(opts *bind.TransactOpts, prevOwner common.Address, owner common.Address, _threshold *big.Int) (*types.Transaction, error) { + return _GnosisSafe.contract.Transact(opts, "removeOwner", prevOwner, owner, _threshold) +} + +// RemoveOwner is a paid mutator transaction binding the contract method 0xf8dc5dd9. +// +// Solidity: function removeOwner(address prevOwner, address owner, uint256 _threshold) returns() +func (_GnosisSafe *GnosisSafeSession) RemoveOwner(prevOwner common.Address, owner common.Address, _threshold *big.Int) (*types.Transaction, error) { + return _GnosisSafe.Contract.RemoveOwner(&_GnosisSafe.TransactOpts, prevOwner, owner, _threshold) +} + +// RemoveOwner is a paid mutator transaction binding the contract method 0xf8dc5dd9. +// +// Solidity: function removeOwner(address prevOwner, address owner, uint256 _threshold) returns() +func (_GnosisSafe *GnosisSafeTransactorSession) RemoveOwner(prevOwner common.Address, owner common.Address, _threshold *big.Int) (*types.Transaction, error) { + return _GnosisSafe.Contract.RemoveOwner(&_GnosisSafe.TransactOpts, prevOwner, owner, _threshold) +} + +// RequiredTxGas is a paid mutator transaction binding the contract method 0xc4ca3a9c. +// +// Solidity: function requiredTxGas(address to, uint256 value, bytes data, uint8 operation) returns(uint256) +func (_GnosisSafe *GnosisSafeTransactor) RequiredTxGas(opts *bind.TransactOpts, to common.Address, value *big.Int, data []byte, operation uint8) (*types.Transaction, error) { + return _GnosisSafe.contract.Transact(opts, "requiredTxGas", to, value, data, operation) +} + +// RequiredTxGas is a paid mutator transaction binding the contract method 0xc4ca3a9c. +// +// Solidity: function requiredTxGas(address to, uint256 value, bytes data, uint8 operation) returns(uint256) +func (_GnosisSafe *GnosisSafeSession) RequiredTxGas(to common.Address, value *big.Int, data []byte, operation uint8) (*types.Transaction, error) { + return _GnosisSafe.Contract.RequiredTxGas(&_GnosisSafe.TransactOpts, to, value, data, operation) +} + +// RequiredTxGas is a paid mutator transaction binding the contract method 0xc4ca3a9c. +// +// Solidity: function requiredTxGas(address to, uint256 value, bytes data, uint8 operation) returns(uint256) +func (_GnosisSafe *GnosisSafeTransactorSession) RequiredTxGas(to common.Address, value *big.Int, data []byte, operation uint8) (*types.Transaction, error) { + return _GnosisSafe.Contract.RequiredTxGas(&_GnosisSafe.TransactOpts, to, value, data, operation) +} + +// SetFallbackHandler is a paid mutator transaction binding the contract method 0xf08a0323. +// +// Solidity: function setFallbackHandler(address handler) returns() +func (_GnosisSafe *GnosisSafeTransactor) SetFallbackHandler(opts *bind.TransactOpts, handler common.Address) (*types.Transaction, error) { + return _GnosisSafe.contract.Transact(opts, "setFallbackHandler", handler) +} + +// SetFallbackHandler is a paid mutator transaction binding the contract method 0xf08a0323. +// +// Solidity: function setFallbackHandler(address handler) returns() +func (_GnosisSafe *GnosisSafeSession) SetFallbackHandler(handler common.Address) (*types.Transaction, error) { + return _GnosisSafe.Contract.SetFallbackHandler(&_GnosisSafe.TransactOpts, handler) +} + +// SetFallbackHandler is a paid mutator transaction binding the contract method 0xf08a0323. +// +// Solidity: function setFallbackHandler(address handler) returns() +func (_GnosisSafe *GnosisSafeTransactorSession) SetFallbackHandler(handler common.Address) (*types.Transaction, error) { + return _GnosisSafe.Contract.SetFallbackHandler(&_GnosisSafe.TransactOpts, handler) +} + +// Setup is a paid mutator transaction binding the contract method 0xb63e800d. +// +// Solidity: function setup(address[] _owners, uint256 _threshold, address to, bytes data, address fallbackHandler, address paymentToken, uint256 payment, address paymentReceiver) returns() +func (_GnosisSafe *GnosisSafeTransactor) Setup(opts *bind.TransactOpts, _owners []common.Address, _threshold *big.Int, to common.Address, data []byte, fallbackHandler common.Address, paymentToken common.Address, payment *big.Int, paymentReceiver common.Address) (*types.Transaction, error) { + return _GnosisSafe.contract.Transact(opts, "setup", _owners, _threshold, to, data, fallbackHandler, paymentToken, payment, paymentReceiver) +} + +// Setup is a paid mutator transaction binding the contract method 0xb63e800d. +// +// Solidity: function setup(address[] _owners, uint256 _threshold, address to, bytes data, address fallbackHandler, address paymentToken, uint256 payment, address paymentReceiver) returns() +func (_GnosisSafe *GnosisSafeSession) Setup(_owners []common.Address, _threshold *big.Int, to common.Address, data []byte, fallbackHandler common.Address, paymentToken common.Address, payment *big.Int, paymentReceiver common.Address) (*types.Transaction, error) { + return _GnosisSafe.Contract.Setup(&_GnosisSafe.TransactOpts, _owners, _threshold, to, data, fallbackHandler, paymentToken, payment, paymentReceiver) +} + +// Setup is a paid mutator transaction binding the contract method 0xb63e800d. +// +// Solidity: function setup(address[] _owners, uint256 _threshold, address to, bytes data, address fallbackHandler, address paymentToken, uint256 payment, address paymentReceiver) returns() +func (_GnosisSafe *GnosisSafeTransactorSession) Setup(_owners []common.Address, _threshold *big.Int, to common.Address, data []byte, fallbackHandler common.Address, paymentToken common.Address, payment *big.Int, paymentReceiver common.Address) (*types.Transaction, error) { + return _GnosisSafe.Contract.Setup(&_GnosisSafe.TransactOpts, _owners, _threshold, to, data, fallbackHandler, paymentToken, payment, paymentReceiver) +} + +// SignMessage is a paid mutator transaction binding the contract method 0x85a5affe. +// +// Solidity: function signMessage(bytes _data) returns() +func (_GnosisSafe *GnosisSafeTransactor) SignMessage(opts *bind.TransactOpts, _data []byte) (*types.Transaction, error) { + return _GnosisSafe.contract.Transact(opts, "signMessage", _data) +} + +// SignMessage is a paid mutator transaction binding the contract method 0x85a5affe. +// +// Solidity: function signMessage(bytes _data) returns() +func (_GnosisSafe *GnosisSafeSession) SignMessage(_data []byte) (*types.Transaction, error) { + return _GnosisSafe.Contract.SignMessage(&_GnosisSafe.TransactOpts, _data) +} + +// SignMessage is a paid mutator transaction binding the contract method 0x85a5affe. +// +// Solidity: function signMessage(bytes _data) returns() +func (_GnosisSafe *GnosisSafeTransactorSession) SignMessage(_data []byte) (*types.Transaction, error) { + return _GnosisSafe.Contract.SignMessage(&_GnosisSafe.TransactOpts, _data) +} + +// SwapOwner is a paid mutator transaction binding the contract method 0xe318b52b. +// +// Solidity: function swapOwner(address prevOwner, address oldOwner, address newOwner) returns() +func (_GnosisSafe *GnosisSafeTransactor) SwapOwner(opts *bind.TransactOpts, prevOwner common.Address, oldOwner common.Address, newOwner common.Address) (*types.Transaction, error) { + return _GnosisSafe.contract.Transact(opts, "swapOwner", prevOwner, oldOwner, newOwner) +} + +// SwapOwner is a paid mutator transaction binding the contract method 0xe318b52b. +// +// Solidity: function swapOwner(address prevOwner, address oldOwner, address newOwner) returns() +func (_GnosisSafe *GnosisSafeSession) SwapOwner(prevOwner common.Address, oldOwner common.Address, newOwner common.Address) (*types.Transaction, error) { + return _GnosisSafe.Contract.SwapOwner(&_GnosisSafe.TransactOpts, prevOwner, oldOwner, newOwner) +} + +// SwapOwner is a paid mutator transaction binding the contract method 0xe318b52b. +// +// Solidity: function swapOwner(address prevOwner, address oldOwner, address newOwner) returns() +func (_GnosisSafe *GnosisSafeTransactorSession) SwapOwner(prevOwner common.Address, oldOwner common.Address, newOwner common.Address) (*types.Transaction, error) { + return _GnosisSafe.Contract.SwapOwner(&_GnosisSafe.TransactOpts, prevOwner, oldOwner, newOwner) +} + +// Fallback is a paid mutator transaction binding the contract fallback function. +// +// Solidity: fallback() payable returns() +func (_GnosisSafe *GnosisSafeTransactor) Fallback(opts *bind.TransactOpts, calldata []byte) (*types.Transaction, error) { + return _GnosisSafe.contract.RawTransact(opts, calldata) +} + +// Fallback is a paid mutator transaction binding the contract fallback function. +// +// Solidity: fallback() payable returns() +func (_GnosisSafe *GnosisSafeSession) Fallback(calldata []byte) (*types.Transaction, error) { + return _GnosisSafe.Contract.Fallback(&_GnosisSafe.TransactOpts, calldata) +} + +// Fallback is a paid mutator transaction binding the contract fallback function. +// +// Solidity: fallback() payable returns() +func (_GnosisSafe *GnosisSafeTransactorSession) Fallback(calldata []byte) (*types.Transaction, error) { + return _GnosisSafe.Contract.Fallback(&_GnosisSafe.TransactOpts, calldata) +} + +// GnosisSafeAddedOwnerIterator is returned from FilterAddedOwner and is used to iterate over the raw logs and unpacked data for AddedOwner events raised by the GnosisSafe contract. +type GnosisSafeAddedOwnerIterator struct { + Event *GnosisSafeAddedOwner // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *GnosisSafeAddedOwnerIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(GnosisSafeAddedOwner) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(GnosisSafeAddedOwner) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *GnosisSafeAddedOwnerIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *GnosisSafeAddedOwnerIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// GnosisSafeAddedOwner represents a AddedOwner event raised by the GnosisSafe contract. +type GnosisSafeAddedOwner struct { + Owner common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterAddedOwner is a free log retrieval operation binding the contract event 0x9465fa0c962cc76958e6373a993326400c1c94f8be2fe3a952adfa7f60b2ea26. +// +// Solidity: event AddedOwner(address owner) +func (_GnosisSafe *GnosisSafeFilterer) FilterAddedOwner(opts *bind.FilterOpts) (*GnosisSafeAddedOwnerIterator, error) { + + logs, sub, err := _GnosisSafe.contract.FilterLogs(opts, "AddedOwner") + if err != nil { + return nil, err + } + return &GnosisSafeAddedOwnerIterator{contract: _GnosisSafe.contract, event: "AddedOwner", logs: logs, sub: sub}, nil +} + +// WatchAddedOwner is a free log subscription operation binding the contract event 0x9465fa0c962cc76958e6373a993326400c1c94f8be2fe3a952adfa7f60b2ea26. +// +// Solidity: event AddedOwner(address owner) +func (_GnosisSafe *GnosisSafeFilterer) WatchAddedOwner(opts *bind.WatchOpts, sink chan<- *GnosisSafeAddedOwner) (event.Subscription, error) { + + logs, sub, err := _GnosisSafe.contract.WatchLogs(opts, "AddedOwner") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(GnosisSafeAddedOwner) + if err := _GnosisSafe.contract.UnpackLog(event, "AddedOwner", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseAddedOwner is a log parse operation binding the contract event 0x9465fa0c962cc76958e6373a993326400c1c94f8be2fe3a952adfa7f60b2ea26. +// +// Solidity: event AddedOwner(address owner) +func (_GnosisSafe *GnosisSafeFilterer) ParseAddedOwner(log types.Log) (*GnosisSafeAddedOwner, error) { + event := new(GnosisSafeAddedOwner) + if err := _GnosisSafe.contract.UnpackLog(event, "AddedOwner", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// GnosisSafeApproveHashIterator is returned from FilterApproveHash and is used to iterate over the raw logs and unpacked data for ApproveHash events raised by the GnosisSafe contract. +type GnosisSafeApproveHashIterator struct { + Event *GnosisSafeApproveHash // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *GnosisSafeApproveHashIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(GnosisSafeApproveHash) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(GnosisSafeApproveHash) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *GnosisSafeApproveHashIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *GnosisSafeApproveHashIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// GnosisSafeApproveHash represents a ApproveHash event raised by the GnosisSafe contract. +type GnosisSafeApproveHash struct { + ApprovedHash [32]byte + Owner common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterApproveHash is a free log retrieval operation binding the contract event 0xf2a0eb156472d1440255b0d7c1e19cc07115d1051fe605b0dce69acfec884d9c. +// +// Solidity: event ApproveHash(bytes32 indexed approvedHash, address indexed owner) +func (_GnosisSafe *GnosisSafeFilterer) FilterApproveHash(opts *bind.FilterOpts, approvedHash [][32]byte, owner []common.Address) (*GnosisSafeApproveHashIterator, error) { + + var approvedHashRule []interface{} + for _, approvedHashItem := range approvedHash { + approvedHashRule = append(approvedHashRule, approvedHashItem) + } + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + + logs, sub, err := _GnosisSafe.contract.FilterLogs(opts, "ApproveHash", approvedHashRule, ownerRule) + if err != nil { + return nil, err + } + return &GnosisSafeApproveHashIterator{contract: _GnosisSafe.contract, event: "ApproveHash", logs: logs, sub: sub}, nil +} + +// WatchApproveHash is a free log subscription operation binding the contract event 0xf2a0eb156472d1440255b0d7c1e19cc07115d1051fe605b0dce69acfec884d9c. +// +// Solidity: event ApproveHash(bytes32 indexed approvedHash, address indexed owner) +func (_GnosisSafe *GnosisSafeFilterer) WatchApproveHash(opts *bind.WatchOpts, sink chan<- *GnosisSafeApproveHash, approvedHash [][32]byte, owner []common.Address) (event.Subscription, error) { + + var approvedHashRule []interface{} + for _, approvedHashItem := range approvedHash { + approvedHashRule = append(approvedHashRule, approvedHashItem) + } + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + + logs, sub, err := _GnosisSafe.contract.WatchLogs(opts, "ApproveHash", approvedHashRule, ownerRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(GnosisSafeApproveHash) + if err := _GnosisSafe.contract.UnpackLog(event, "ApproveHash", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseApproveHash is a log parse operation binding the contract event 0xf2a0eb156472d1440255b0d7c1e19cc07115d1051fe605b0dce69acfec884d9c. +// +// Solidity: event ApproveHash(bytes32 indexed approvedHash, address indexed owner) +func (_GnosisSafe *GnosisSafeFilterer) ParseApproveHash(log types.Log) (*GnosisSafeApproveHash, error) { + event := new(GnosisSafeApproveHash) + if err := _GnosisSafe.contract.UnpackLog(event, "ApproveHash", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// GnosisSafeChangedMasterCopyIterator is returned from FilterChangedMasterCopy and is used to iterate over the raw logs and unpacked data for ChangedMasterCopy events raised by the GnosisSafe contract. +type GnosisSafeChangedMasterCopyIterator struct { + Event *GnosisSafeChangedMasterCopy // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *GnosisSafeChangedMasterCopyIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(GnosisSafeChangedMasterCopy) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(GnosisSafeChangedMasterCopy) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *GnosisSafeChangedMasterCopyIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *GnosisSafeChangedMasterCopyIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// GnosisSafeChangedMasterCopy represents a ChangedMasterCopy event raised by the GnosisSafe contract. +type GnosisSafeChangedMasterCopy struct { + MasterCopy common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterChangedMasterCopy is a free log retrieval operation binding the contract event 0x75e41bc35ff1bf14d81d1d2f649c0084a0f974f9289c803ec9898eeec4c8d0b8. +// +// Solidity: event ChangedMasterCopy(address masterCopy) +func (_GnosisSafe *GnosisSafeFilterer) FilterChangedMasterCopy(opts *bind.FilterOpts) (*GnosisSafeChangedMasterCopyIterator, error) { + + logs, sub, err := _GnosisSafe.contract.FilterLogs(opts, "ChangedMasterCopy") + if err != nil { + return nil, err + } + return &GnosisSafeChangedMasterCopyIterator{contract: _GnosisSafe.contract, event: "ChangedMasterCopy", logs: logs, sub: sub}, nil +} + +// WatchChangedMasterCopy is a free log subscription operation binding the contract event 0x75e41bc35ff1bf14d81d1d2f649c0084a0f974f9289c803ec9898eeec4c8d0b8. +// +// Solidity: event ChangedMasterCopy(address masterCopy) +func (_GnosisSafe *GnosisSafeFilterer) WatchChangedMasterCopy(opts *bind.WatchOpts, sink chan<- *GnosisSafeChangedMasterCopy) (event.Subscription, error) { + + logs, sub, err := _GnosisSafe.contract.WatchLogs(opts, "ChangedMasterCopy") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(GnosisSafeChangedMasterCopy) + if err := _GnosisSafe.contract.UnpackLog(event, "ChangedMasterCopy", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseChangedMasterCopy is a log parse operation binding the contract event 0x75e41bc35ff1bf14d81d1d2f649c0084a0f974f9289c803ec9898eeec4c8d0b8. +// +// Solidity: event ChangedMasterCopy(address masterCopy) +func (_GnosisSafe *GnosisSafeFilterer) ParseChangedMasterCopy(log types.Log) (*GnosisSafeChangedMasterCopy, error) { + event := new(GnosisSafeChangedMasterCopy) + if err := _GnosisSafe.contract.UnpackLog(event, "ChangedMasterCopy", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// GnosisSafeChangedThresholdIterator is returned from FilterChangedThreshold and is used to iterate over the raw logs and unpacked data for ChangedThreshold events raised by the GnosisSafe contract. +type GnosisSafeChangedThresholdIterator struct { + Event *GnosisSafeChangedThreshold // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *GnosisSafeChangedThresholdIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(GnosisSafeChangedThreshold) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(GnosisSafeChangedThreshold) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *GnosisSafeChangedThresholdIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *GnosisSafeChangedThresholdIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// GnosisSafeChangedThreshold represents a ChangedThreshold event raised by the GnosisSafe contract. +type GnosisSafeChangedThreshold struct { + Threshold *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterChangedThreshold is a free log retrieval operation binding the contract event 0x610f7ff2b304ae8903c3de74c60c6ab1f7d6226b3f52c5161905bb5ad4039c93. +// +// Solidity: event ChangedThreshold(uint256 threshold) +func (_GnosisSafe *GnosisSafeFilterer) FilterChangedThreshold(opts *bind.FilterOpts) (*GnosisSafeChangedThresholdIterator, error) { + + logs, sub, err := _GnosisSafe.contract.FilterLogs(opts, "ChangedThreshold") + if err != nil { + return nil, err + } + return &GnosisSafeChangedThresholdIterator{contract: _GnosisSafe.contract, event: "ChangedThreshold", logs: logs, sub: sub}, nil +} + +// WatchChangedThreshold is a free log subscription operation binding the contract event 0x610f7ff2b304ae8903c3de74c60c6ab1f7d6226b3f52c5161905bb5ad4039c93. +// +// Solidity: event ChangedThreshold(uint256 threshold) +func (_GnosisSafe *GnosisSafeFilterer) WatchChangedThreshold(opts *bind.WatchOpts, sink chan<- *GnosisSafeChangedThreshold) (event.Subscription, error) { + + logs, sub, err := _GnosisSafe.contract.WatchLogs(opts, "ChangedThreshold") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(GnosisSafeChangedThreshold) + if err := _GnosisSafe.contract.UnpackLog(event, "ChangedThreshold", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseChangedThreshold is a log parse operation binding the contract event 0x610f7ff2b304ae8903c3de74c60c6ab1f7d6226b3f52c5161905bb5ad4039c93. +// +// Solidity: event ChangedThreshold(uint256 threshold) +func (_GnosisSafe *GnosisSafeFilterer) ParseChangedThreshold(log types.Log) (*GnosisSafeChangedThreshold, error) { + event := new(GnosisSafeChangedThreshold) + if err := _GnosisSafe.contract.UnpackLog(event, "ChangedThreshold", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// GnosisSafeDisabledModuleIterator is returned from FilterDisabledModule and is used to iterate over the raw logs and unpacked data for DisabledModule events raised by the GnosisSafe contract. +type GnosisSafeDisabledModuleIterator struct { + Event *GnosisSafeDisabledModule // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *GnosisSafeDisabledModuleIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(GnosisSafeDisabledModule) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(GnosisSafeDisabledModule) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *GnosisSafeDisabledModuleIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *GnosisSafeDisabledModuleIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// GnosisSafeDisabledModule represents a DisabledModule event raised by the GnosisSafe contract. +type GnosisSafeDisabledModule struct { + Module common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterDisabledModule is a free log retrieval operation binding the contract event 0xaab4fa2b463f581b2b32cb3b7e3b704b9ce37cc209b5fb4d77e593ace4054276. +// +// Solidity: event DisabledModule(address module) +func (_GnosisSafe *GnosisSafeFilterer) FilterDisabledModule(opts *bind.FilterOpts) (*GnosisSafeDisabledModuleIterator, error) { + + logs, sub, err := _GnosisSafe.contract.FilterLogs(opts, "DisabledModule") + if err != nil { + return nil, err + } + return &GnosisSafeDisabledModuleIterator{contract: _GnosisSafe.contract, event: "DisabledModule", logs: logs, sub: sub}, nil +} + +// WatchDisabledModule is a free log subscription operation binding the contract event 0xaab4fa2b463f581b2b32cb3b7e3b704b9ce37cc209b5fb4d77e593ace4054276. +// +// Solidity: event DisabledModule(address module) +func (_GnosisSafe *GnosisSafeFilterer) WatchDisabledModule(opts *bind.WatchOpts, sink chan<- *GnosisSafeDisabledModule) (event.Subscription, error) { + + logs, sub, err := _GnosisSafe.contract.WatchLogs(opts, "DisabledModule") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(GnosisSafeDisabledModule) + if err := _GnosisSafe.contract.UnpackLog(event, "DisabledModule", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseDisabledModule is a log parse operation binding the contract event 0xaab4fa2b463f581b2b32cb3b7e3b704b9ce37cc209b5fb4d77e593ace4054276. +// +// Solidity: event DisabledModule(address module) +func (_GnosisSafe *GnosisSafeFilterer) ParseDisabledModule(log types.Log) (*GnosisSafeDisabledModule, error) { + event := new(GnosisSafeDisabledModule) + if err := _GnosisSafe.contract.UnpackLog(event, "DisabledModule", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// GnosisSafeEnabledModuleIterator is returned from FilterEnabledModule and is used to iterate over the raw logs and unpacked data for EnabledModule events raised by the GnosisSafe contract. +type GnosisSafeEnabledModuleIterator struct { + Event *GnosisSafeEnabledModule // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *GnosisSafeEnabledModuleIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(GnosisSafeEnabledModule) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(GnosisSafeEnabledModule) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *GnosisSafeEnabledModuleIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *GnosisSafeEnabledModuleIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// GnosisSafeEnabledModule represents a EnabledModule event raised by the GnosisSafe contract. +type GnosisSafeEnabledModule struct { + Module common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterEnabledModule is a free log retrieval operation binding the contract event 0xecdf3a3effea5783a3c4c2140e677577666428d44ed9d474a0b3a4c9943f8440. +// +// Solidity: event EnabledModule(address module) +func (_GnosisSafe *GnosisSafeFilterer) FilterEnabledModule(opts *bind.FilterOpts) (*GnosisSafeEnabledModuleIterator, error) { + + logs, sub, err := _GnosisSafe.contract.FilterLogs(opts, "EnabledModule") + if err != nil { + return nil, err + } + return &GnosisSafeEnabledModuleIterator{contract: _GnosisSafe.contract, event: "EnabledModule", logs: logs, sub: sub}, nil +} + +// WatchEnabledModule is a free log subscription operation binding the contract event 0xecdf3a3effea5783a3c4c2140e677577666428d44ed9d474a0b3a4c9943f8440. +// +// Solidity: event EnabledModule(address module) +func (_GnosisSafe *GnosisSafeFilterer) WatchEnabledModule(opts *bind.WatchOpts, sink chan<- *GnosisSafeEnabledModule) (event.Subscription, error) { + + logs, sub, err := _GnosisSafe.contract.WatchLogs(opts, "EnabledModule") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(GnosisSafeEnabledModule) + if err := _GnosisSafe.contract.UnpackLog(event, "EnabledModule", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseEnabledModule is a log parse operation binding the contract event 0xecdf3a3effea5783a3c4c2140e677577666428d44ed9d474a0b3a4c9943f8440. +// +// Solidity: event EnabledModule(address module) +func (_GnosisSafe *GnosisSafeFilterer) ParseEnabledModule(log types.Log) (*GnosisSafeEnabledModule, error) { + event := new(GnosisSafeEnabledModule) + if err := _GnosisSafe.contract.UnpackLog(event, "EnabledModule", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// GnosisSafeExecutionFailureIterator is returned from FilterExecutionFailure and is used to iterate over the raw logs and unpacked data for ExecutionFailure events raised by the GnosisSafe contract. +type GnosisSafeExecutionFailureIterator struct { + Event *GnosisSafeExecutionFailure // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *GnosisSafeExecutionFailureIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(GnosisSafeExecutionFailure) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(GnosisSafeExecutionFailure) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *GnosisSafeExecutionFailureIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *GnosisSafeExecutionFailureIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// GnosisSafeExecutionFailure represents a ExecutionFailure event raised by the GnosisSafe contract. +type GnosisSafeExecutionFailure struct { + TxHash [32]byte + Payment *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterExecutionFailure is a free log retrieval operation binding the contract event 0x23428b18acfb3ea64b08dc0c1d296ea9c09702c09083ca5272e64d115b687d23. +// +// Solidity: event ExecutionFailure(bytes32 txHash, uint256 payment) +func (_GnosisSafe *GnosisSafeFilterer) FilterExecutionFailure(opts *bind.FilterOpts) (*GnosisSafeExecutionFailureIterator, error) { + + logs, sub, err := _GnosisSafe.contract.FilterLogs(opts, "ExecutionFailure") + if err != nil { + return nil, err + } + return &GnosisSafeExecutionFailureIterator{contract: _GnosisSafe.contract, event: "ExecutionFailure", logs: logs, sub: sub}, nil +} + +// WatchExecutionFailure is a free log subscription operation binding the contract event 0x23428b18acfb3ea64b08dc0c1d296ea9c09702c09083ca5272e64d115b687d23. +// +// Solidity: event ExecutionFailure(bytes32 txHash, uint256 payment) +func (_GnosisSafe *GnosisSafeFilterer) WatchExecutionFailure(opts *bind.WatchOpts, sink chan<- *GnosisSafeExecutionFailure) (event.Subscription, error) { + + logs, sub, err := _GnosisSafe.contract.WatchLogs(opts, "ExecutionFailure") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(GnosisSafeExecutionFailure) + if err := _GnosisSafe.contract.UnpackLog(event, "ExecutionFailure", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseExecutionFailure is a log parse operation binding the contract event 0x23428b18acfb3ea64b08dc0c1d296ea9c09702c09083ca5272e64d115b687d23. +// +// Solidity: event ExecutionFailure(bytes32 txHash, uint256 payment) +func (_GnosisSafe *GnosisSafeFilterer) ParseExecutionFailure(log types.Log) (*GnosisSafeExecutionFailure, error) { + event := new(GnosisSafeExecutionFailure) + if err := _GnosisSafe.contract.UnpackLog(event, "ExecutionFailure", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// GnosisSafeExecutionFromModuleFailureIterator is returned from FilterExecutionFromModuleFailure and is used to iterate over the raw logs and unpacked data for ExecutionFromModuleFailure events raised by the GnosisSafe contract. +type GnosisSafeExecutionFromModuleFailureIterator struct { + Event *GnosisSafeExecutionFromModuleFailure // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *GnosisSafeExecutionFromModuleFailureIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(GnosisSafeExecutionFromModuleFailure) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(GnosisSafeExecutionFromModuleFailure) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *GnosisSafeExecutionFromModuleFailureIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *GnosisSafeExecutionFromModuleFailureIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// GnosisSafeExecutionFromModuleFailure represents a ExecutionFromModuleFailure event raised by the GnosisSafe contract. +type GnosisSafeExecutionFromModuleFailure struct { + Module common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterExecutionFromModuleFailure is a free log retrieval operation binding the contract event 0xacd2c8702804128fdb0db2bb49f6d127dd0181c13fd45dbfe16de0930e2bd375. +// +// Solidity: event ExecutionFromModuleFailure(address indexed module) +func (_GnosisSafe *GnosisSafeFilterer) FilterExecutionFromModuleFailure(opts *bind.FilterOpts, module []common.Address) (*GnosisSafeExecutionFromModuleFailureIterator, error) { + + var moduleRule []interface{} + for _, moduleItem := range module { + moduleRule = append(moduleRule, moduleItem) + } + + logs, sub, err := _GnosisSafe.contract.FilterLogs(opts, "ExecutionFromModuleFailure", moduleRule) + if err != nil { + return nil, err + } + return &GnosisSafeExecutionFromModuleFailureIterator{contract: _GnosisSafe.contract, event: "ExecutionFromModuleFailure", logs: logs, sub: sub}, nil +} + +// WatchExecutionFromModuleFailure is a free log subscription operation binding the contract event 0xacd2c8702804128fdb0db2bb49f6d127dd0181c13fd45dbfe16de0930e2bd375. +// +// Solidity: event ExecutionFromModuleFailure(address indexed module) +func (_GnosisSafe *GnosisSafeFilterer) WatchExecutionFromModuleFailure(opts *bind.WatchOpts, sink chan<- *GnosisSafeExecutionFromModuleFailure, module []common.Address) (event.Subscription, error) { + + var moduleRule []interface{} + for _, moduleItem := range module { + moduleRule = append(moduleRule, moduleItem) + } + + logs, sub, err := _GnosisSafe.contract.WatchLogs(opts, "ExecutionFromModuleFailure", moduleRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(GnosisSafeExecutionFromModuleFailure) + if err := _GnosisSafe.contract.UnpackLog(event, "ExecutionFromModuleFailure", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseExecutionFromModuleFailure is a log parse operation binding the contract event 0xacd2c8702804128fdb0db2bb49f6d127dd0181c13fd45dbfe16de0930e2bd375. +// +// Solidity: event ExecutionFromModuleFailure(address indexed module) +func (_GnosisSafe *GnosisSafeFilterer) ParseExecutionFromModuleFailure(log types.Log) (*GnosisSafeExecutionFromModuleFailure, error) { + event := new(GnosisSafeExecutionFromModuleFailure) + if err := _GnosisSafe.contract.UnpackLog(event, "ExecutionFromModuleFailure", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// GnosisSafeExecutionFromModuleSuccessIterator is returned from FilterExecutionFromModuleSuccess and is used to iterate over the raw logs and unpacked data for ExecutionFromModuleSuccess events raised by the GnosisSafe contract. +type GnosisSafeExecutionFromModuleSuccessIterator struct { + Event *GnosisSafeExecutionFromModuleSuccess // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *GnosisSafeExecutionFromModuleSuccessIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(GnosisSafeExecutionFromModuleSuccess) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(GnosisSafeExecutionFromModuleSuccess) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *GnosisSafeExecutionFromModuleSuccessIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *GnosisSafeExecutionFromModuleSuccessIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// GnosisSafeExecutionFromModuleSuccess represents a ExecutionFromModuleSuccess event raised by the GnosisSafe contract. +type GnosisSafeExecutionFromModuleSuccess struct { + Module common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterExecutionFromModuleSuccess is a free log retrieval operation binding the contract event 0x6895c13664aa4f67288b25d7a21d7aaa34916e355fb9b6fae0a139a9085becb8. +// +// Solidity: event ExecutionFromModuleSuccess(address indexed module) +func (_GnosisSafe *GnosisSafeFilterer) FilterExecutionFromModuleSuccess(opts *bind.FilterOpts, module []common.Address) (*GnosisSafeExecutionFromModuleSuccessIterator, error) { + + var moduleRule []interface{} + for _, moduleItem := range module { + moduleRule = append(moduleRule, moduleItem) + } + + logs, sub, err := _GnosisSafe.contract.FilterLogs(opts, "ExecutionFromModuleSuccess", moduleRule) + if err != nil { + return nil, err + } + return &GnosisSafeExecutionFromModuleSuccessIterator{contract: _GnosisSafe.contract, event: "ExecutionFromModuleSuccess", logs: logs, sub: sub}, nil +} + +// WatchExecutionFromModuleSuccess is a free log subscription operation binding the contract event 0x6895c13664aa4f67288b25d7a21d7aaa34916e355fb9b6fae0a139a9085becb8. +// +// Solidity: event ExecutionFromModuleSuccess(address indexed module) +func (_GnosisSafe *GnosisSafeFilterer) WatchExecutionFromModuleSuccess(opts *bind.WatchOpts, sink chan<- *GnosisSafeExecutionFromModuleSuccess, module []common.Address) (event.Subscription, error) { + + var moduleRule []interface{} + for _, moduleItem := range module { + moduleRule = append(moduleRule, moduleItem) + } + + logs, sub, err := _GnosisSafe.contract.WatchLogs(opts, "ExecutionFromModuleSuccess", moduleRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(GnosisSafeExecutionFromModuleSuccess) + if err := _GnosisSafe.contract.UnpackLog(event, "ExecutionFromModuleSuccess", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseExecutionFromModuleSuccess is a log parse operation binding the contract event 0x6895c13664aa4f67288b25d7a21d7aaa34916e355fb9b6fae0a139a9085becb8. +// +// Solidity: event ExecutionFromModuleSuccess(address indexed module) +func (_GnosisSafe *GnosisSafeFilterer) ParseExecutionFromModuleSuccess(log types.Log) (*GnosisSafeExecutionFromModuleSuccess, error) { + event := new(GnosisSafeExecutionFromModuleSuccess) + if err := _GnosisSafe.contract.UnpackLog(event, "ExecutionFromModuleSuccess", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// GnosisSafeExecutionSuccessIterator is returned from FilterExecutionSuccess and is used to iterate over the raw logs and unpacked data for ExecutionSuccess events raised by the GnosisSafe contract. +type GnosisSafeExecutionSuccessIterator struct { + Event *GnosisSafeExecutionSuccess // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *GnosisSafeExecutionSuccessIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(GnosisSafeExecutionSuccess) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(GnosisSafeExecutionSuccess) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *GnosisSafeExecutionSuccessIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *GnosisSafeExecutionSuccessIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// GnosisSafeExecutionSuccess represents a ExecutionSuccess event raised by the GnosisSafe contract. +type GnosisSafeExecutionSuccess struct { + TxHash [32]byte + Payment *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterExecutionSuccess is a free log retrieval operation binding the contract event 0x442e715f626346e8c54381002da614f62bee8d27386535b2521ec8540898556e. +// +// Solidity: event ExecutionSuccess(bytes32 txHash, uint256 payment) +func (_GnosisSafe *GnosisSafeFilterer) FilterExecutionSuccess(opts *bind.FilterOpts) (*GnosisSafeExecutionSuccessIterator, error) { + + logs, sub, err := _GnosisSafe.contract.FilterLogs(opts, "ExecutionSuccess") + if err != nil { + return nil, err + } + return &GnosisSafeExecutionSuccessIterator{contract: _GnosisSafe.contract, event: "ExecutionSuccess", logs: logs, sub: sub}, nil +} + +// WatchExecutionSuccess is a free log subscription operation binding the contract event 0x442e715f626346e8c54381002da614f62bee8d27386535b2521ec8540898556e. +// +// Solidity: event ExecutionSuccess(bytes32 txHash, uint256 payment) +func (_GnosisSafe *GnosisSafeFilterer) WatchExecutionSuccess(opts *bind.WatchOpts, sink chan<- *GnosisSafeExecutionSuccess) (event.Subscription, error) { + + logs, sub, err := _GnosisSafe.contract.WatchLogs(opts, "ExecutionSuccess") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(GnosisSafeExecutionSuccess) + if err := _GnosisSafe.contract.UnpackLog(event, "ExecutionSuccess", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseExecutionSuccess is a log parse operation binding the contract event 0x442e715f626346e8c54381002da614f62bee8d27386535b2521ec8540898556e. +// +// Solidity: event ExecutionSuccess(bytes32 txHash, uint256 payment) +func (_GnosisSafe *GnosisSafeFilterer) ParseExecutionSuccess(log types.Log) (*GnosisSafeExecutionSuccess, error) { + event := new(GnosisSafeExecutionSuccess) + if err := _GnosisSafe.contract.UnpackLog(event, "ExecutionSuccess", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// GnosisSafeRemovedOwnerIterator is returned from FilterRemovedOwner and is used to iterate over the raw logs and unpacked data for RemovedOwner events raised by the GnosisSafe contract. +type GnosisSafeRemovedOwnerIterator struct { + Event *GnosisSafeRemovedOwner // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *GnosisSafeRemovedOwnerIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(GnosisSafeRemovedOwner) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(GnosisSafeRemovedOwner) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *GnosisSafeRemovedOwnerIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *GnosisSafeRemovedOwnerIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// GnosisSafeRemovedOwner represents a RemovedOwner event raised by the GnosisSafe contract. +type GnosisSafeRemovedOwner struct { + Owner common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterRemovedOwner is a free log retrieval operation binding the contract event 0xf8d49fc529812e9a7c5c50e69c20f0dccc0db8fa95c98bc58cc9a4f1c1299eaf. +// +// Solidity: event RemovedOwner(address owner) +func (_GnosisSafe *GnosisSafeFilterer) FilterRemovedOwner(opts *bind.FilterOpts) (*GnosisSafeRemovedOwnerIterator, error) { + + logs, sub, err := _GnosisSafe.contract.FilterLogs(opts, "RemovedOwner") + if err != nil { + return nil, err + } + return &GnosisSafeRemovedOwnerIterator{contract: _GnosisSafe.contract, event: "RemovedOwner", logs: logs, sub: sub}, nil +} + +// WatchRemovedOwner is a free log subscription operation binding the contract event 0xf8d49fc529812e9a7c5c50e69c20f0dccc0db8fa95c98bc58cc9a4f1c1299eaf. +// +// Solidity: event RemovedOwner(address owner) +func (_GnosisSafe *GnosisSafeFilterer) WatchRemovedOwner(opts *bind.WatchOpts, sink chan<- *GnosisSafeRemovedOwner) (event.Subscription, error) { + + logs, sub, err := _GnosisSafe.contract.WatchLogs(opts, "RemovedOwner") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(GnosisSafeRemovedOwner) + if err := _GnosisSafe.contract.UnpackLog(event, "RemovedOwner", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseRemovedOwner is a log parse operation binding the contract event 0xf8d49fc529812e9a7c5c50e69c20f0dccc0db8fa95c98bc58cc9a4f1c1299eaf. +// +// Solidity: event RemovedOwner(address owner) +func (_GnosisSafe *GnosisSafeFilterer) ParseRemovedOwner(log types.Log) (*GnosisSafeRemovedOwner, error) { + event := new(GnosisSafeRemovedOwner) + if err := _GnosisSafe.contract.UnpackLog(event, "RemovedOwner", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// GnosisSafeSignMsgIterator is returned from FilterSignMsg and is used to iterate over the raw logs and unpacked data for SignMsg events raised by the GnosisSafe contract. +type GnosisSafeSignMsgIterator struct { + Event *GnosisSafeSignMsg // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *GnosisSafeSignMsgIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(GnosisSafeSignMsg) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(GnosisSafeSignMsg) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *GnosisSafeSignMsgIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *GnosisSafeSignMsgIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// GnosisSafeSignMsg represents a SignMsg event raised by the GnosisSafe contract. +type GnosisSafeSignMsg struct { + MsgHash [32]byte + Raw types.Log // Blockchain specific contextual infos +} + +// FilterSignMsg is a free log retrieval operation binding the contract event 0xe7f4675038f4f6034dfcbbb24c4dc08e4ebf10eb9d257d3d02c0f38d122ac6e4. +// +// Solidity: event SignMsg(bytes32 indexed msgHash) +func (_GnosisSafe *GnosisSafeFilterer) FilterSignMsg(opts *bind.FilterOpts, msgHash [][32]byte) (*GnosisSafeSignMsgIterator, error) { + + var msgHashRule []interface{} + for _, msgHashItem := range msgHash { + msgHashRule = append(msgHashRule, msgHashItem) + } + + logs, sub, err := _GnosisSafe.contract.FilterLogs(opts, "SignMsg", msgHashRule) + if err != nil { + return nil, err + } + return &GnosisSafeSignMsgIterator{contract: _GnosisSafe.contract, event: "SignMsg", logs: logs, sub: sub}, nil +} + +// WatchSignMsg is a free log subscription operation binding the contract event 0xe7f4675038f4f6034dfcbbb24c4dc08e4ebf10eb9d257d3d02c0f38d122ac6e4. +// +// Solidity: event SignMsg(bytes32 indexed msgHash) +func (_GnosisSafe *GnosisSafeFilterer) WatchSignMsg(opts *bind.WatchOpts, sink chan<- *GnosisSafeSignMsg, msgHash [][32]byte) (event.Subscription, error) { + + var msgHashRule []interface{} + for _, msgHashItem := range msgHash { + msgHashRule = append(msgHashRule, msgHashItem) + } + + logs, sub, err := _GnosisSafe.contract.WatchLogs(opts, "SignMsg", msgHashRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(GnosisSafeSignMsg) + if err := _GnosisSafe.contract.UnpackLog(event, "SignMsg", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseSignMsg is a log parse operation binding the contract event 0xe7f4675038f4f6034dfcbbb24c4dc08e4ebf10eb9d257d3d02c0f38d122ac6e4. +// +// Solidity: event SignMsg(bytes32 indexed msgHash) +func (_GnosisSafe *GnosisSafeFilterer) ParseSignMsg(log types.Log) (*GnosisSafeSignMsg, error) { + event := new(GnosisSafeSignMsg) + if err := _GnosisSafe.contract.UnpackLog(event, "SignMsg", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func CreateGnosisSafeDeploymentCommand() *cobra.Command { + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc string + var gasLimit uint64 + var simulate bool + var timeout uint + + cmd := &cobra.Command{ + Use: "deploy", + Short: "Deploy a new GnosisSafe contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if keyfile == "" { + return fmt.Errorf("--keystore not specified (this should be a path to an Ethereum account keystore file)") + } + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + key, keyErr := KeyFromFile(keyfile, password) + if keyErr != nil { + return keyErr + } + + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + + transactionOpts, transactionOptsErr := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID) + if transactionOptsErr != nil { + return transactionOptsErr + } + + SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) + + address, deploymentTransaction, _, deploymentErr := DeployGnosisSafe( + transactionOpts, + client, + ) + if deploymentErr != nil { + return deploymentErr + } + + cmd.Printf("Transaction hash: %s\nContract address: %s\n", deploymentTransaction.Hash().Hex(), address.Hex()) + if transactionOpts.NoSend { + estimationMessage := ethereum.CallMsg{ + From: transactionOpts.From, + Data: deploymentTransaction.Data(), + } + + gasEstimationCtx, cancelGasEstimationCtx := NewChainContext(timeout) + defer cancelGasEstimationCtx() + + gasEstimate, gasEstimateErr := client.EstimateGas(gasEstimationCtx, estimationMessage) + if gasEstimateErr != nil { + return gasEstimateErr + } + + transactionBinary, transactionBinaryErr := deploymentTransaction.MarshalBinary() + if transactionBinaryErr != nil { + return transactionBinaryErr + } + transactionBinaryHex := hex.EncodeToString(transactionBinary) + + cmd.Printf("Transaction: %s\nEstimated gas: %d\n", transactionBinaryHex, gasEstimate) + } else { + cmd.Println("Transaction submitted") + } + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&keyfile, "keyfile", "", "Path to the keystore file to use for the transaction") + cmd.Flags().StringVar(&password, "password", "", "Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes)") + cmd.Flags().StringVar(&nonce, "nonce", "", "Nonce to use for the transaction") + cmd.Flags().StringVar(&value, "value", "", "Value to send with the transaction") + cmd.Flags().StringVar(&gasPrice, "gas-price", "", "Gas price to use for the transaction") + cmd.Flags().StringVar(&maxFeePerGas, "max-fee-per-gas", "", "Maximum fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().StringVar(&maxPriorityFeePerGas, "max-priority-fee-per-gas", "", "Maximum priority fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") + cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + + return cmd +} + +func CreateApprovedHashesCommand() *cobra.Command { + var contractAddressRaw, rpc string + var contractAddress common.Address + var timeout uint + + var blockNumberRaw, fromAddressRaw string + var pending bool + + var arg0 common.Address + var arg0Raw string + var arg1 [32]byte + var arg1Raw string + + var capture0 *big.Int + + cmd := &cobra.Command{ + Use: "approved-hashes", + Short: "Call the ApprovedHashes view method on a GnosisSafe contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + if arg0Raw == "" { + return fmt.Errorf("--arg-0 argument not specified") + } else if !common.IsHexAddress(arg0Raw) { + return fmt.Errorf("--arg-0 argument is not a valid Ethereum address") + } + arg0 = common.HexToAddress(arg0Raw) + + var arg1Intermediate []byte + + var arg1IntermediateHexDecodeErr error + arg1Intermediate, arg1IntermediateHexDecodeErr = hex.DecodeString(arg1Raw) + if arg1IntermediateHexDecodeErr != nil { + return arg1IntermediateHexDecodeErr + } + + copy(arg1[:], arg1Intermediate) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + contract, contractErr := NewGnosisSafe(contractAddress, client) + if contractErr != nil { + return contractErr + } + + callOpts := bind.CallOpts{} + SetCallParametersFromArgs(&callOpts, pending, fromAddressRaw, blockNumberRaw) + + session := GnosisSafeCallerSession{ + Contract: &contract.GnosisSafeCaller, + CallOpts: callOpts, + } + + var callErr error + capture0, callErr = session.ApprovedHashes( + arg0, + arg1, + ) + if callErr != nil { + return callErr + } + + cmd.Printf("0: %s\n", capture0.String()) + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&blockNumberRaw, "block", "", "Block number at which to call the view method") + cmd.Flags().BoolVar(&pending, "pending", false, "Set this flag if it's ok to call the view method against pending state") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&fromAddressRaw, "from", "", "Optional address for caller of the view method") + + cmd.Flags().StringVar(&arg0Raw, "arg-0", "", "arg-0 argument (common.Address)") + cmd.Flags().StringVar(&arg1Raw, "arg-1", "", "arg-1 argument ([32]byte)") + + return cmd +} +func CreateDomainSeparatorCommand() *cobra.Command { + var contractAddressRaw, rpc string + var contractAddress common.Address + var timeout uint + + var blockNumberRaw, fromAddressRaw string + var pending bool + + var capture0 [32]byte + + cmd := &cobra.Command{ + Use: "domain-separator", + Short: "Call the DomainSeparator view method on a GnosisSafe contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + contract, contractErr := NewGnosisSafe(contractAddress, client) + if contractErr != nil { + return contractErr + } + + callOpts := bind.CallOpts{} + SetCallParametersFromArgs(&callOpts, pending, fromAddressRaw, blockNumberRaw) + + session := GnosisSafeCallerSession{ + Contract: &contract.GnosisSafeCaller, + CallOpts: callOpts, + } + + var callErr error + capture0, callErr = session.DomainSeparator() + if callErr != nil { + return callErr + } + + cmd.Printf("0: %v\n", capture0) + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&blockNumberRaw, "block", "", "Block number at which to call the view method") + cmd.Flags().BoolVar(&pending, "pending", false, "Set this flag if it's ok to call the view method against pending state") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&fromAddressRaw, "from", "", "Optional address for caller of the view method") + + return cmd +} +func CreateEncodeTransactionDataCommand() *cobra.Command { + var contractAddressRaw, rpc string + var contractAddress common.Address + var timeout uint + + var blockNumberRaw, fromAddressRaw string + var pending bool + + var to0 common.Address + var to0Raw string + var value0 *big.Int + var value0Raw string + var data []byte + var dataRaw string + var operation uint8 + + var safeTxGas *big.Int + var safeTxGasRaw string + var baseGas *big.Int + var baseGasRaw string + var gasPrice0 *big.Int + var gasPrice0Raw string + var gasToken common.Address + var gasTokenRaw string + var refundReceiver common.Address + var refundReceiverRaw string + var _nonce0 *big.Int + var _nonce0Raw string + + var capture0 []byte + + cmd := &cobra.Command{ + Use: "encode-transaction-data", + Short: "Call the EncodeTransactionData view method on a GnosisSafe contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + if to0Raw == "" { + return fmt.Errorf("--to-0 argument not specified") + } else if !common.IsHexAddress(to0Raw) { + return fmt.Errorf("--to-0 argument is not a valid Ethereum address") + } + to0 = common.HexToAddress(to0Raw) + + if value0Raw == "" { + return fmt.Errorf("--value-0 argument not specified") + } + value0 = new(big.Int) + value0.SetString(value0Raw, 0) + + var dataIntermediate []byte + + var dataIntermediateHexDecodeErr error + dataIntermediate, dataIntermediateHexDecodeErr = hex.DecodeString(dataRaw) + if dataIntermediateHexDecodeErr != nil { + return dataIntermediateHexDecodeErr + } + + copy(data[:], dataIntermediate) + + if safeTxGasRaw == "" { + return fmt.Errorf("--safe-tx-gas argument not specified") + } + safeTxGas = new(big.Int) + safeTxGas.SetString(safeTxGasRaw, 0) + + if baseGasRaw == "" { + return fmt.Errorf("--base-gas argument not specified") + } + baseGas = new(big.Int) + baseGas.SetString(baseGasRaw, 0) + + if gasPrice0Raw == "" { + return fmt.Errorf("--gas-price-0 argument not specified") + } + gasPrice0 = new(big.Int) + gasPrice0.SetString(gasPrice0Raw, 0) + + if gasTokenRaw == "" { + return fmt.Errorf("--gas-token argument not specified") + } else if !common.IsHexAddress(gasTokenRaw) { + return fmt.Errorf("--gas-token argument is not a valid Ethereum address") + } + gasToken = common.HexToAddress(gasTokenRaw) + + if refundReceiverRaw == "" { + return fmt.Errorf("--refund-receiver argument not specified") + } else if !common.IsHexAddress(refundReceiverRaw) { + return fmt.Errorf("--refund-receiver argument is not a valid Ethereum address") + } + refundReceiver = common.HexToAddress(refundReceiverRaw) + + if _nonce0Raw == "" { + return fmt.Errorf("---nonce-0 argument not specified") + } + _nonce0 = new(big.Int) + _nonce0.SetString(_nonce0Raw, 0) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + contract, contractErr := NewGnosisSafe(contractAddress, client) + if contractErr != nil { + return contractErr + } + + callOpts := bind.CallOpts{} + SetCallParametersFromArgs(&callOpts, pending, fromAddressRaw, blockNumberRaw) + + session := GnosisSafeCallerSession{ + Contract: &contract.GnosisSafeCaller, + CallOpts: callOpts, + } + + var callErr error + capture0, callErr = session.EncodeTransactionData( + to0, + value0, + data, + operation, + safeTxGas, + baseGas, + gasPrice0, + gasToken, + refundReceiver, + _nonce0, + ) + if callErr != nil { + return callErr + } + + cmd.Printf("0: %v\n", capture0) + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&blockNumberRaw, "block", "", "Block number at which to call the view method") + cmd.Flags().BoolVar(&pending, "pending", false, "Set this flag if it's ok to call the view method against pending state") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&fromAddressRaw, "from", "", "Optional address for caller of the view method") + + cmd.Flags().StringVar(&to0Raw, "to-0", "", "to-0 argument (common.Address)") + cmd.Flags().StringVar(&value0Raw, "value-0", "", "value-0 argument") + cmd.Flags().StringVar(&dataRaw, "data", "", "data argument ([]byte)") + cmd.Flags().Uint8Var(&operation, "operation", 0, "operation argument") + cmd.Flags().StringVar(&safeTxGasRaw, "safe-tx-gas", "", "safe-tx-gas argument") + cmd.Flags().StringVar(&baseGasRaw, "base-gas", "", "base-gas argument") + cmd.Flags().StringVar(&gasPrice0Raw, "gas-price-0", "", "gas-price-0 argument") + cmd.Flags().StringVar(&gasTokenRaw, "gas-token", "", "gas-token argument (common.Address)") + cmd.Flags().StringVar(&refundReceiverRaw, "refund-receiver", "", "refund-receiver argument (common.Address)") + cmd.Flags().StringVar(&_nonce0Raw, "-nonce-0", "", "-nonce-0 argument") + + return cmd +} +func CreateGetMessageHashCommand() *cobra.Command { + var contractAddressRaw, rpc string + var contractAddress common.Address + var timeout uint + + var blockNumberRaw, fromAddressRaw string + var pending bool + + var message []byte + var messageRaw string + + var capture0 [32]byte + + cmd := &cobra.Command{ + Use: "get-message-hash", + Short: "Call the GetMessageHash view method on a GnosisSafe contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + var messageIntermediate []byte + + var messageIntermediateHexDecodeErr error + messageIntermediate, messageIntermediateHexDecodeErr = hex.DecodeString(messageRaw) + if messageIntermediateHexDecodeErr != nil { + return messageIntermediateHexDecodeErr + } + + copy(message[:], messageIntermediate) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + contract, contractErr := NewGnosisSafe(contractAddress, client) + if contractErr != nil { + return contractErr + } + + callOpts := bind.CallOpts{} + SetCallParametersFromArgs(&callOpts, pending, fromAddressRaw, blockNumberRaw) + + session := GnosisSafeCallerSession{ + Contract: &contract.GnosisSafeCaller, + CallOpts: callOpts, + } + + var callErr error + capture0, callErr = session.GetMessageHash( + message, + ) + if callErr != nil { + return callErr + } + + cmd.Printf("0: %v\n", capture0) + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&blockNumberRaw, "block", "", "Block number at which to call the view method") + cmd.Flags().BoolVar(&pending, "pending", false, "Set this flag if it's ok to call the view method against pending state") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&fromAddressRaw, "from", "", "Optional address for caller of the view method") + + cmd.Flags().StringVar(&messageRaw, "message", "", "message argument ([]byte)") + + return cmd +} +func CreateGetModulesCommand() *cobra.Command { + var contractAddressRaw, rpc string + var contractAddress common.Address + var timeout uint + + var blockNumberRaw, fromAddressRaw string + var pending bool + + var capture0 []common.Address + + cmd := &cobra.Command{ + Use: "get-modules", + Short: "Call the GetModules view method on a GnosisSafe contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + contract, contractErr := NewGnosisSafe(contractAddress, client) + if contractErr != nil { + return contractErr + } + + callOpts := bind.CallOpts{} + SetCallParametersFromArgs(&callOpts, pending, fromAddressRaw, blockNumberRaw) + + session := GnosisSafeCallerSession{ + Contract: &contract.GnosisSafeCaller, + CallOpts: callOpts, + } + + var callErr error + capture0, callErr = session.GetModules() + if callErr != nil { + return callErr + } + + cmd.Printf("0: %v\n", capture0) + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&blockNumberRaw, "block", "", "Block number at which to call the view method") + cmd.Flags().BoolVar(&pending, "pending", false, "Set this flag if it's ok to call the view method against pending state") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&fromAddressRaw, "from", "", "Optional address for caller of the view method") + + return cmd +} +func CreateGetModulesPaginatedCommand() *cobra.Command { + var contractAddressRaw, rpc string + var contractAddress common.Address + var timeout uint + + var blockNumberRaw, fromAddressRaw string + var pending bool + + var start common.Address + var startRaw string + var pageSize *big.Int + var pageSizeRaw string + + var capture0 struct { + Array []common.Address + Next common.Address + } + + cmd := &cobra.Command{ + Use: "get-modules-paginated", + Short: "Call the GetModulesPaginated view method on a GnosisSafe contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + if startRaw == "" { + return fmt.Errorf("--start argument not specified") + } else if !common.IsHexAddress(startRaw) { + return fmt.Errorf("--start argument is not a valid Ethereum address") + } + start = common.HexToAddress(startRaw) + + if pageSizeRaw == "" { + return fmt.Errorf("--page-size argument not specified") + } + pageSize = new(big.Int) + pageSize.SetString(pageSizeRaw, 0) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + contract, contractErr := NewGnosisSafe(contractAddress, client) + if contractErr != nil { + return contractErr + } + + callOpts := bind.CallOpts{} + SetCallParametersFromArgs(&callOpts, pending, fromAddressRaw, blockNumberRaw) + + session := GnosisSafeCallerSession{ + Contract: &contract.GnosisSafeCaller, + CallOpts: callOpts, + } + + var callErr error + capture0, callErr = session.GetModulesPaginated( + start, + pageSize, + ) + if callErr != nil { + return callErr + } + + cmd.Printf("0: %v\n", capture0) + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&blockNumberRaw, "block", "", "Block number at which to call the view method") + cmd.Flags().BoolVar(&pending, "pending", false, "Set this flag if it's ok to call the view method against pending state") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&fromAddressRaw, "from", "", "Optional address for caller of the view method") + + cmd.Flags().StringVar(&startRaw, "start", "", "start argument (common.Address)") + cmd.Flags().StringVar(&pageSizeRaw, "page-size", "", "page-size argument") + + return cmd +} +func CreateGetOwnersCommand() *cobra.Command { + var contractAddressRaw, rpc string + var contractAddress common.Address + var timeout uint + + var blockNumberRaw, fromAddressRaw string + var pending bool + + var capture0 []common.Address + + cmd := &cobra.Command{ + Use: "get-owners", + Short: "Call the GetOwners view method on a GnosisSafe contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + contract, contractErr := NewGnosisSafe(contractAddress, client) + if contractErr != nil { + return contractErr + } + + callOpts := bind.CallOpts{} + SetCallParametersFromArgs(&callOpts, pending, fromAddressRaw, blockNumberRaw) + + session := GnosisSafeCallerSession{ + Contract: &contract.GnosisSafeCaller, + CallOpts: callOpts, + } + + var callErr error + capture0, callErr = session.GetOwners() + if callErr != nil { + return callErr + } + + cmd.Printf("0: %v\n", capture0) + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&blockNumberRaw, "block", "", "Block number at which to call the view method") + cmd.Flags().BoolVar(&pending, "pending", false, "Set this flag if it's ok to call the view method against pending state") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&fromAddressRaw, "from", "", "Optional address for caller of the view method") + + return cmd +} +func CreateGetThresholdCommand() *cobra.Command { + var contractAddressRaw, rpc string + var contractAddress common.Address + var timeout uint + + var blockNumberRaw, fromAddressRaw string + var pending bool + + var capture0 *big.Int + + cmd := &cobra.Command{ + Use: "get-threshold", + Short: "Call the GetThreshold view method on a GnosisSafe contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + contract, contractErr := NewGnosisSafe(contractAddress, client) + if contractErr != nil { + return contractErr + } + + callOpts := bind.CallOpts{} + SetCallParametersFromArgs(&callOpts, pending, fromAddressRaw, blockNumberRaw) + + session := GnosisSafeCallerSession{ + Contract: &contract.GnosisSafeCaller, + CallOpts: callOpts, + } + + var callErr error + capture0, callErr = session.GetThreshold() + if callErr != nil { + return callErr + } + + cmd.Printf("0: %s\n", capture0.String()) + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&blockNumberRaw, "block", "", "Block number at which to call the view method") + cmd.Flags().BoolVar(&pending, "pending", false, "Set this flag if it's ok to call the view method against pending state") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&fromAddressRaw, "from", "", "Optional address for caller of the view method") + + return cmd +} +func CreateGetTransactionHashCommand() *cobra.Command { + var contractAddressRaw, rpc string + var contractAddress common.Address + var timeout uint + + var blockNumberRaw, fromAddressRaw string + var pending bool + + var to0 common.Address + var to0Raw string + var value0 *big.Int + var value0Raw string + var data []byte + var dataRaw string + var operation uint8 + + var safeTxGas *big.Int + var safeTxGasRaw string + var baseGas *big.Int + var baseGasRaw string + var gasPrice0 *big.Int + var gasPrice0Raw string + var gasToken common.Address + var gasTokenRaw string + var refundReceiver common.Address + var refundReceiverRaw string + var _nonce0 *big.Int + var _nonce0Raw string + + var capture0 [32]byte + + cmd := &cobra.Command{ + Use: "get-transaction-hash", + Short: "Call the GetTransactionHash view method on a GnosisSafe contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + if to0Raw == "" { + return fmt.Errorf("--to-0 argument not specified") + } else if !common.IsHexAddress(to0Raw) { + return fmt.Errorf("--to-0 argument is not a valid Ethereum address") + } + to0 = common.HexToAddress(to0Raw) + + if value0Raw == "" { + return fmt.Errorf("--value-0 argument not specified") + } + value0 = new(big.Int) + value0.SetString(value0Raw, 0) + + var dataIntermediate []byte + + var dataIntermediateHexDecodeErr error + dataIntermediate, dataIntermediateHexDecodeErr = hex.DecodeString(dataRaw) + if dataIntermediateHexDecodeErr != nil { + return dataIntermediateHexDecodeErr + } + + copy(data[:], dataIntermediate) + + if safeTxGasRaw == "" { + return fmt.Errorf("--safe-tx-gas argument not specified") + } + safeTxGas = new(big.Int) + safeTxGas.SetString(safeTxGasRaw, 0) + + if baseGasRaw == "" { + return fmt.Errorf("--base-gas argument not specified") + } + baseGas = new(big.Int) + baseGas.SetString(baseGasRaw, 0) + + if gasPrice0Raw == "" { + return fmt.Errorf("--gas-price-0 argument not specified") + } + gasPrice0 = new(big.Int) + gasPrice0.SetString(gasPrice0Raw, 0) + + if gasTokenRaw == "" { + return fmt.Errorf("--gas-token argument not specified") + } else if !common.IsHexAddress(gasTokenRaw) { + return fmt.Errorf("--gas-token argument is not a valid Ethereum address") + } + gasToken = common.HexToAddress(gasTokenRaw) + + if refundReceiverRaw == "" { + return fmt.Errorf("--refund-receiver argument not specified") + } else if !common.IsHexAddress(refundReceiverRaw) { + return fmt.Errorf("--refund-receiver argument is not a valid Ethereum address") + } + refundReceiver = common.HexToAddress(refundReceiverRaw) + + if _nonce0Raw == "" { + return fmt.Errorf("---nonce-0 argument not specified") + } + _nonce0 = new(big.Int) + _nonce0.SetString(_nonce0Raw, 0) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + contract, contractErr := NewGnosisSafe(contractAddress, client) + if contractErr != nil { + return contractErr + } + + callOpts := bind.CallOpts{} + SetCallParametersFromArgs(&callOpts, pending, fromAddressRaw, blockNumberRaw) + + session := GnosisSafeCallerSession{ + Contract: &contract.GnosisSafeCaller, + CallOpts: callOpts, + } + + var callErr error + capture0, callErr = session.GetTransactionHash( + to0, + value0, + data, + operation, + safeTxGas, + baseGas, + gasPrice0, + gasToken, + refundReceiver, + _nonce0, + ) + if callErr != nil { + return callErr + } + + cmd.Printf("0: %v\n", capture0) + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&blockNumberRaw, "block", "", "Block number at which to call the view method") + cmd.Flags().BoolVar(&pending, "pending", false, "Set this flag if it's ok to call the view method against pending state") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&fromAddressRaw, "from", "", "Optional address for caller of the view method") + + cmd.Flags().StringVar(&to0Raw, "to-0", "", "to-0 argument (common.Address)") + cmd.Flags().StringVar(&value0Raw, "value-0", "", "value-0 argument") + cmd.Flags().StringVar(&dataRaw, "data", "", "data argument ([]byte)") + cmd.Flags().Uint8Var(&operation, "operation", 0, "operation argument") + cmd.Flags().StringVar(&safeTxGasRaw, "safe-tx-gas", "", "safe-tx-gas argument") + cmd.Flags().StringVar(&baseGasRaw, "base-gas", "", "base-gas argument") + cmd.Flags().StringVar(&gasPrice0Raw, "gas-price-0", "", "gas-price-0 argument") + cmd.Flags().StringVar(&gasTokenRaw, "gas-token", "", "gas-token argument (common.Address)") + cmd.Flags().StringVar(&refundReceiverRaw, "refund-receiver", "", "refund-receiver argument (common.Address)") + cmd.Flags().StringVar(&_nonce0Raw, "-nonce-0", "", "-nonce-0 argument") + + return cmd +} +func CreateIsModuleEnabledCommand() *cobra.Command { + var contractAddressRaw, rpc string + var contractAddress common.Address + var timeout uint + + var blockNumberRaw, fromAddressRaw string + var pending bool + + var module common.Address + var moduleRaw string + + var capture0 bool + + cmd := &cobra.Command{ + Use: "is-module-enabled", + Short: "Call the IsModuleEnabled view method on a GnosisSafe contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + if moduleRaw == "" { + return fmt.Errorf("--module argument not specified") + } else if !common.IsHexAddress(moduleRaw) { + return fmt.Errorf("--module argument is not a valid Ethereum address") + } + module = common.HexToAddress(moduleRaw) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + contract, contractErr := NewGnosisSafe(contractAddress, client) + if contractErr != nil { + return contractErr + } + + callOpts := bind.CallOpts{} + SetCallParametersFromArgs(&callOpts, pending, fromAddressRaw, blockNumberRaw) + + session := GnosisSafeCallerSession{ + Contract: &contract.GnosisSafeCaller, + CallOpts: callOpts, + } + + var callErr error + capture0, callErr = session.IsModuleEnabled( + module, + ) + if callErr != nil { + return callErr + } + + cmd.Printf("0: %t\n", capture0) + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&blockNumberRaw, "block", "", "Block number at which to call the view method") + cmd.Flags().BoolVar(&pending, "pending", false, "Set this flag if it's ok to call the view method against pending state") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&fromAddressRaw, "from", "", "Optional address for caller of the view method") + + cmd.Flags().StringVar(&moduleRaw, "module", "", "module argument (common.Address)") + + return cmd +} +func CreateIsOwnerCommand() *cobra.Command { + var contractAddressRaw, rpc string + var contractAddress common.Address + var timeout uint + + var blockNumberRaw, fromAddressRaw string + var pending bool + + var owner common.Address + var ownerRaw string + + var capture0 bool + + cmd := &cobra.Command{ + Use: "is-owner", + Short: "Call the IsOwner view method on a GnosisSafe contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + if ownerRaw == "" { + return fmt.Errorf("--owner argument not specified") + } else if !common.IsHexAddress(ownerRaw) { + return fmt.Errorf("--owner argument is not a valid Ethereum address") + } + owner = common.HexToAddress(ownerRaw) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + contract, contractErr := NewGnosisSafe(contractAddress, client) + if contractErr != nil { + return contractErr + } + + callOpts := bind.CallOpts{} + SetCallParametersFromArgs(&callOpts, pending, fromAddressRaw, blockNumberRaw) + + session := GnosisSafeCallerSession{ + Contract: &contract.GnosisSafeCaller, + CallOpts: callOpts, + } + + var callErr error + capture0, callErr = session.IsOwner( + owner, + ) + if callErr != nil { + return callErr + } + + cmd.Printf("0: %t\n", capture0) + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&blockNumberRaw, "block", "", "Block number at which to call the view method") + cmd.Flags().BoolVar(&pending, "pending", false, "Set this flag if it's ok to call the view method against pending state") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&fromAddressRaw, "from", "", "Optional address for caller of the view method") + + cmd.Flags().StringVar(&ownerRaw, "owner", "", "owner argument (common.Address)") + + return cmd +} +func CreateNameCommand() *cobra.Command { + var contractAddressRaw, rpc string + var contractAddress common.Address + var timeout uint + + var blockNumberRaw, fromAddressRaw string + var pending bool + + var capture0 string + + cmd := &cobra.Command{ + Use: "name", + Short: "Call the NAME view method on a GnosisSafe contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + contract, contractErr := NewGnosisSafe(contractAddress, client) + if contractErr != nil { + return contractErr + } + + callOpts := bind.CallOpts{} + SetCallParametersFromArgs(&callOpts, pending, fromAddressRaw, blockNumberRaw) + + session := GnosisSafeCallerSession{ + Contract: &contract.GnosisSafeCaller, + CallOpts: callOpts, + } + + var callErr error + capture0, callErr = session.NAME() + if callErr != nil { + return callErr + } + + cmd.Printf("0: %s\n", capture0) + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&blockNumberRaw, "block", "", "Block number at which to call the view method") + cmd.Flags().BoolVar(&pending, "pending", false, "Set this flag if it's ok to call the view method against pending state") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&fromAddressRaw, "from", "", "Optional address for caller of the view method") + + return cmd +} +func CreateNonceCommand() *cobra.Command { + var contractAddressRaw, rpc string + var contractAddress common.Address + var timeout uint + + var blockNumberRaw, fromAddressRaw string + var pending bool + + var capture0 *big.Int + + cmd := &cobra.Command{ + Use: "nonce", + Short: "Call the Nonce view method on a GnosisSafe contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + contract, contractErr := NewGnosisSafe(contractAddress, client) + if contractErr != nil { + return contractErr + } + + callOpts := bind.CallOpts{} + SetCallParametersFromArgs(&callOpts, pending, fromAddressRaw, blockNumberRaw) + + session := GnosisSafeCallerSession{ + Contract: &contract.GnosisSafeCaller, + CallOpts: callOpts, + } + + var callErr error + capture0, callErr = session.Nonce() + if callErr != nil { + return callErr + } + + cmd.Printf("0: %s\n", capture0.String()) + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&blockNumberRaw, "block", "", "Block number at which to call the view method") + cmd.Flags().BoolVar(&pending, "pending", false, "Set this flag if it's ok to call the view method against pending state") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&fromAddressRaw, "from", "", "Optional address for caller of the view method") + + return cmd +} +func CreateSignedMessagesCommand() *cobra.Command { + var contractAddressRaw, rpc string + var contractAddress common.Address + var timeout uint + + var blockNumberRaw, fromAddressRaw string + var pending bool + + var arg0 [32]byte + var arg0Raw string + + var capture0 *big.Int + + cmd := &cobra.Command{ + Use: "signed-messages", + Short: "Call the SignedMessages view method on a GnosisSafe contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + var arg0Intermediate []byte + + var arg0IntermediateHexDecodeErr error + arg0Intermediate, arg0IntermediateHexDecodeErr = hex.DecodeString(arg0Raw) + if arg0IntermediateHexDecodeErr != nil { + return arg0IntermediateHexDecodeErr + } + + copy(arg0[:], arg0Intermediate) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + contract, contractErr := NewGnosisSafe(contractAddress, client) + if contractErr != nil { + return contractErr + } + + callOpts := bind.CallOpts{} + SetCallParametersFromArgs(&callOpts, pending, fromAddressRaw, blockNumberRaw) + + session := GnosisSafeCallerSession{ + Contract: &contract.GnosisSafeCaller, + CallOpts: callOpts, + } + + var callErr error + capture0, callErr = session.SignedMessages( + arg0, + ) + if callErr != nil { + return callErr + } + + cmd.Printf("0: %s\n", capture0.String()) + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&blockNumberRaw, "block", "", "Block number at which to call the view method") + cmd.Flags().BoolVar(&pending, "pending", false, "Set this flag if it's ok to call the view method against pending state") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&fromAddressRaw, "from", "", "Optional address for caller of the view method") + + cmd.Flags().StringVar(&arg0Raw, "arg-0", "", "arg-0 argument ([32]byte)") + + return cmd +} +func CreateVersionCommand() *cobra.Command { + var contractAddressRaw, rpc string + var contractAddress common.Address + var timeout uint + + var blockNumberRaw, fromAddressRaw string + var pending bool + + var capture0 string + + cmd := &cobra.Command{ + Use: "version", + Short: "Call the VERSION view method on a GnosisSafe contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + contract, contractErr := NewGnosisSafe(contractAddress, client) + if contractErr != nil { + return contractErr + } + + callOpts := bind.CallOpts{} + SetCallParametersFromArgs(&callOpts, pending, fromAddressRaw, blockNumberRaw) + + session := GnosisSafeCallerSession{ + Contract: &contract.GnosisSafeCaller, + CallOpts: callOpts, + } + + var callErr error + capture0, callErr = session.VERSION() + if callErr != nil { + return callErr + } + + cmd.Printf("0: %s\n", capture0) + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&blockNumberRaw, "block", "", "Block number at which to call the view method") + cmd.Flags().BoolVar(&pending, "pending", false, "Set this flag if it's ok to call the view method against pending state") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&fromAddressRaw, "from", "", "Optional address for caller of the view method") + + return cmd +} + +func CreateAddOwnerWithThresholdCommand() *cobra.Command { + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw string + var gasLimit uint64 + var simulate bool + var timeout uint + var contractAddress common.Address + + var owner common.Address + var ownerRaw string + var threshold *big.Int + var thresholdRaw string + + cmd := &cobra.Command{ + Use: "add-owner-with-threshold", + Short: "Execute the AddOwnerWithThreshold method on a GnosisSafe contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if keyfile == "" { + return fmt.Errorf("--keystore not specified") + } + + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + if ownerRaw == "" { + return fmt.Errorf("--owner argument not specified") + } else if !common.IsHexAddress(ownerRaw) { + return fmt.Errorf("--owner argument is not a valid Ethereum address") + } + owner = common.HexToAddress(ownerRaw) + + if thresholdRaw == "" { + return fmt.Errorf("--threshold argument not specified") + } + threshold = new(big.Int) + threshold.SetString(thresholdRaw, 0) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + key, keyErr := KeyFromFile(keyfile, password) + if keyErr != nil { + return keyErr + } + + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + + transactionOpts, transactionOptsErr := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID) + if transactionOptsErr != nil { + return transactionOptsErr + } + + SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) + + contract, contractErr := NewGnosisSafe(contractAddress, client) + if contractErr != nil { + return contractErr + } + + session := GnosisSafeTransactorSession{ + Contract: &contract.GnosisSafeTransactor, + TransactOpts: *transactionOpts, + } + + transaction, transactionErr := session.AddOwnerWithThreshold( + owner, + threshold, + ) + if transactionErr != nil { + return transactionErr + } + + cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) + if transactionOpts.NoSend { + estimationMessage := ethereum.CallMsg{ + From: transactionOpts.From, + To: &contractAddress, + Data: transaction.Data(), + } + + gasEstimationCtx, cancelGasEstimationCtx := NewChainContext(timeout) + defer cancelGasEstimationCtx() + + gasEstimate, gasEstimateErr := client.EstimateGas(gasEstimationCtx, estimationMessage) + if gasEstimateErr != nil { + return gasEstimateErr + } + + transactionBinary, transactionBinaryErr := transaction.MarshalBinary() + if transactionBinaryErr != nil { + return transactionBinaryErr + } + transactionBinaryHex := hex.EncodeToString(transactionBinary) + + cmd.Printf("Transaction: %s\nEstimated gas: %d\n", transactionBinaryHex, gasEstimate) + } else { + cmd.Println("Transaction submitted") + } + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&keyfile, "keyfile", "", "Path to the keystore file to use for the transaction") + cmd.Flags().StringVar(&password, "password", "", "Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes)") + cmd.Flags().StringVar(&nonce, "nonce", "", "Nonce to use for the transaction") + cmd.Flags().StringVar(&value, "value", "", "Value to send with the transaction") + cmd.Flags().StringVar(&gasPrice, "gas-price", "", "Gas price to use for the transaction") + cmd.Flags().StringVar(&maxFeePerGas, "max-fee-per-gas", "", "Maximum fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().StringVar(&maxPriorityFeePerGas, "max-priority-fee-per-gas", "", "Maximum priority fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") + cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + + cmd.Flags().StringVar(&ownerRaw, "owner", "", "owner argument (common.Address)") + cmd.Flags().StringVar(&thresholdRaw, "threshold", "", "threshold argument") + + return cmd +} +func CreateApproveHashCommand() *cobra.Command { + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw string + var gasLimit uint64 + var simulate bool + var timeout uint + var contractAddress common.Address + + var hashToApprove [32]byte + var hashToApproveRaw string + + cmd := &cobra.Command{ + Use: "approve-hash", + Short: "Execute the ApproveHash method on a GnosisSafe contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if keyfile == "" { + return fmt.Errorf("--keystore not specified") + } + + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + var hashToApproveIntermediate []byte + + var hashToApproveIntermediateHexDecodeErr error + hashToApproveIntermediate, hashToApproveIntermediateHexDecodeErr = hex.DecodeString(hashToApproveRaw) + if hashToApproveIntermediateHexDecodeErr != nil { + return hashToApproveIntermediateHexDecodeErr + } + + copy(hashToApprove[:], hashToApproveIntermediate) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + key, keyErr := KeyFromFile(keyfile, password) + if keyErr != nil { + return keyErr + } + + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + + transactionOpts, transactionOptsErr := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID) + if transactionOptsErr != nil { + return transactionOptsErr + } + + SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) + + contract, contractErr := NewGnosisSafe(contractAddress, client) + if contractErr != nil { + return contractErr + } + + session := GnosisSafeTransactorSession{ + Contract: &contract.GnosisSafeTransactor, + TransactOpts: *transactionOpts, + } + + transaction, transactionErr := session.ApproveHash( + hashToApprove, + ) + if transactionErr != nil { + return transactionErr + } + + cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) + if transactionOpts.NoSend { + estimationMessage := ethereum.CallMsg{ + From: transactionOpts.From, + To: &contractAddress, + Data: transaction.Data(), + } + + gasEstimationCtx, cancelGasEstimationCtx := NewChainContext(timeout) + defer cancelGasEstimationCtx() + + gasEstimate, gasEstimateErr := client.EstimateGas(gasEstimationCtx, estimationMessage) + if gasEstimateErr != nil { + return gasEstimateErr + } + + transactionBinary, transactionBinaryErr := transaction.MarshalBinary() + if transactionBinaryErr != nil { + return transactionBinaryErr + } + transactionBinaryHex := hex.EncodeToString(transactionBinary) + + cmd.Printf("Transaction: %s\nEstimated gas: %d\n", transactionBinaryHex, gasEstimate) + } else { + cmd.Println("Transaction submitted") + } + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&keyfile, "keyfile", "", "Path to the keystore file to use for the transaction") + cmd.Flags().StringVar(&password, "password", "", "Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes)") + cmd.Flags().StringVar(&nonce, "nonce", "", "Nonce to use for the transaction") + cmd.Flags().StringVar(&value, "value", "", "Value to send with the transaction") + cmd.Flags().StringVar(&gasPrice, "gas-price", "", "Gas price to use for the transaction") + cmd.Flags().StringVar(&maxFeePerGas, "max-fee-per-gas", "", "Maximum fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().StringVar(&maxPriorityFeePerGas, "max-priority-fee-per-gas", "", "Maximum priority fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") + cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + + cmd.Flags().StringVar(&hashToApproveRaw, "hash-to-approve", "", "hash-to-approve argument ([32]byte)") + + return cmd +} +func CreateChangeMasterCopyCommand() *cobra.Command { + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw string + var gasLimit uint64 + var simulate bool + var timeout uint + var contractAddress common.Address + + var masterCopy common.Address + var masterCopyRaw string + + cmd := &cobra.Command{ + Use: "change-master-copy", + Short: "Execute the ChangeMasterCopy method on a GnosisSafe contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if keyfile == "" { + return fmt.Errorf("--keystore not specified") + } + + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + if masterCopyRaw == "" { + return fmt.Errorf("--master-copy argument not specified") + } else if !common.IsHexAddress(masterCopyRaw) { + return fmt.Errorf("--master-copy argument is not a valid Ethereum address") + } + masterCopy = common.HexToAddress(masterCopyRaw) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + key, keyErr := KeyFromFile(keyfile, password) + if keyErr != nil { + return keyErr + } + + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + + transactionOpts, transactionOptsErr := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID) + if transactionOptsErr != nil { + return transactionOptsErr + } + + SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) + + contract, contractErr := NewGnosisSafe(contractAddress, client) + if contractErr != nil { + return contractErr + } + + session := GnosisSafeTransactorSession{ + Contract: &contract.GnosisSafeTransactor, + TransactOpts: *transactionOpts, + } + + transaction, transactionErr := session.ChangeMasterCopy( + masterCopy, + ) + if transactionErr != nil { + return transactionErr + } + + cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) + if transactionOpts.NoSend { + estimationMessage := ethereum.CallMsg{ + From: transactionOpts.From, + To: &contractAddress, + Data: transaction.Data(), + } + + gasEstimationCtx, cancelGasEstimationCtx := NewChainContext(timeout) + defer cancelGasEstimationCtx() + + gasEstimate, gasEstimateErr := client.EstimateGas(gasEstimationCtx, estimationMessage) + if gasEstimateErr != nil { + return gasEstimateErr + } + + transactionBinary, transactionBinaryErr := transaction.MarshalBinary() + if transactionBinaryErr != nil { + return transactionBinaryErr + } + transactionBinaryHex := hex.EncodeToString(transactionBinary) + + cmd.Printf("Transaction: %s\nEstimated gas: %d\n", transactionBinaryHex, gasEstimate) + } else { + cmd.Println("Transaction submitted") + } + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&keyfile, "keyfile", "", "Path to the keystore file to use for the transaction") + cmd.Flags().StringVar(&password, "password", "", "Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes)") + cmd.Flags().StringVar(&nonce, "nonce", "", "Nonce to use for the transaction") + cmd.Flags().StringVar(&value, "value", "", "Value to send with the transaction") + cmd.Flags().StringVar(&gasPrice, "gas-price", "", "Gas price to use for the transaction") + cmd.Flags().StringVar(&maxFeePerGas, "max-fee-per-gas", "", "Maximum fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().StringVar(&maxPriorityFeePerGas, "max-priority-fee-per-gas", "", "Maximum priority fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") + cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + + cmd.Flags().StringVar(&masterCopyRaw, "master-copy", "", "master-copy argument (common.Address)") + + return cmd +} +func CreateChangeThresholdCommand() *cobra.Command { + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw string + var gasLimit uint64 + var simulate bool + var timeout uint + var contractAddress common.Address + + var threshold *big.Int + var thresholdRaw string + + cmd := &cobra.Command{ + Use: "change-threshold", + Short: "Execute the ChangeThreshold method on a GnosisSafe contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if keyfile == "" { + return fmt.Errorf("--keystore not specified") + } + + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + if thresholdRaw == "" { + return fmt.Errorf("--threshold argument not specified") + } + threshold = new(big.Int) + threshold.SetString(thresholdRaw, 0) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + key, keyErr := KeyFromFile(keyfile, password) + if keyErr != nil { + return keyErr + } + + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + + transactionOpts, transactionOptsErr := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID) + if transactionOptsErr != nil { + return transactionOptsErr + } + + SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) + + contract, contractErr := NewGnosisSafe(contractAddress, client) + if contractErr != nil { + return contractErr + } + + session := GnosisSafeTransactorSession{ + Contract: &contract.GnosisSafeTransactor, + TransactOpts: *transactionOpts, + } + + transaction, transactionErr := session.ChangeThreshold( + threshold, + ) + if transactionErr != nil { + return transactionErr + } + + cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) + if transactionOpts.NoSend { + estimationMessage := ethereum.CallMsg{ + From: transactionOpts.From, + To: &contractAddress, + Data: transaction.Data(), + } + + gasEstimationCtx, cancelGasEstimationCtx := NewChainContext(timeout) + defer cancelGasEstimationCtx() + + gasEstimate, gasEstimateErr := client.EstimateGas(gasEstimationCtx, estimationMessage) + if gasEstimateErr != nil { + return gasEstimateErr + } + + transactionBinary, transactionBinaryErr := transaction.MarshalBinary() + if transactionBinaryErr != nil { + return transactionBinaryErr + } + transactionBinaryHex := hex.EncodeToString(transactionBinary) + + cmd.Printf("Transaction: %s\nEstimated gas: %d\n", transactionBinaryHex, gasEstimate) + } else { + cmd.Println("Transaction submitted") + } + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&keyfile, "keyfile", "", "Path to the keystore file to use for the transaction") + cmd.Flags().StringVar(&password, "password", "", "Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes)") + cmd.Flags().StringVar(&nonce, "nonce", "", "Nonce to use for the transaction") + cmd.Flags().StringVar(&value, "value", "", "Value to send with the transaction") + cmd.Flags().StringVar(&gasPrice, "gas-price", "", "Gas price to use for the transaction") + cmd.Flags().StringVar(&maxFeePerGas, "max-fee-per-gas", "", "Maximum fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().StringVar(&maxPriorityFeePerGas, "max-priority-fee-per-gas", "", "Maximum priority fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") + cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + + cmd.Flags().StringVar(&thresholdRaw, "threshold", "", "threshold argument") + + return cmd +} +func CreateDisableModuleCommand() *cobra.Command { + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw string + var gasLimit uint64 + var simulate bool + var timeout uint + var contractAddress common.Address + + var prevModule common.Address + var prevModuleRaw string + var module common.Address + var moduleRaw string + + cmd := &cobra.Command{ + Use: "disable-module", + Short: "Execute the DisableModule method on a GnosisSafe contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if keyfile == "" { + return fmt.Errorf("--keystore not specified") + } + + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + if prevModuleRaw == "" { + return fmt.Errorf("--prev-module argument not specified") + } else if !common.IsHexAddress(prevModuleRaw) { + return fmt.Errorf("--prev-module argument is not a valid Ethereum address") + } + prevModule = common.HexToAddress(prevModuleRaw) + + if moduleRaw == "" { + return fmt.Errorf("--module argument not specified") + } else if !common.IsHexAddress(moduleRaw) { + return fmt.Errorf("--module argument is not a valid Ethereum address") + } + module = common.HexToAddress(moduleRaw) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + key, keyErr := KeyFromFile(keyfile, password) + if keyErr != nil { + return keyErr + } + + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + + transactionOpts, transactionOptsErr := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID) + if transactionOptsErr != nil { + return transactionOptsErr + } + + SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) + + contract, contractErr := NewGnosisSafe(contractAddress, client) + if contractErr != nil { + return contractErr + } + + session := GnosisSafeTransactorSession{ + Contract: &contract.GnosisSafeTransactor, + TransactOpts: *transactionOpts, + } + + transaction, transactionErr := session.DisableModule( + prevModule, + module, + ) + if transactionErr != nil { + return transactionErr + } + + cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) + if transactionOpts.NoSend { + estimationMessage := ethereum.CallMsg{ + From: transactionOpts.From, + To: &contractAddress, + Data: transaction.Data(), + } + + gasEstimationCtx, cancelGasEstimationCtx := NewChainContext(timeout) + defer cancelGasEstimationCtx() + + gasEstimate, gasEstimateErr := client.EstimateGas(gasEstimationCtx, estimationMessage) + if gasEstimateErr != nil { + return gasEstimateErr + } + + transactionBinary, transactionBinaryErr := transaction.MarshalBinary() + if transactionBinaryErr != nil { + return transactionBinaryErr + } + transactionBinaryHex := hex.EncodeToString(transactionBinary) + + cmd.Printf("Transaction: %s\nEstimated gas: %d\n", transactionBinaryHex, gasEstimate) + } else { + cmd.Println("Transaction submitted") + } + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&keyfile, "keyfile", "", "Path to the keystore file to use for the transaction") + cmd.Flags().StringVar(&password, "password", "", "Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes)") + cmd.Flags().StringVar(&nonce, "nonce", "", "Nonce to use for the transaction") + cmd.Flags().StringVar(&value, "value", "", "Value to send with the transaction") + cmd.Flags().StringVar(&gasPrice, "gas-price", "", "Gas price to use for the transaction") + cmd.Flags().StringVar(&maxFeePerGas, "max-fee-per-gas", "", "Maximum fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().StringVar(&maxPriorityFeePerGas, "max-priority-fee-per-gas", "", "Maximum priority fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") + cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + + cmd.Flags().StringVar(&prevModuleRaw, "prev-module", "", "prev-module argument (common.Address)") + cmd.Flags().StringVar(&moduleRaw, "module", "", "module argument (common.Address)") + + return cmd +} +func CreateEnableModuleCommand() *cobra.Command { + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw string + var gasLimit uint64 + var simulate bool + var timeout uint + var contractAddress common.Address + + var module common.Address + var moduleRaw string + + cmd := &cobra.Command{ + Use: "enable-module", + Short: "Execute the EnableModule method on a GnosisSafe contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if keyfile == "" { + return fmt.Errorf("--keystore not specified") + } + + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + if moduleRaw == "" { + return fmt.Errorf("--module argument not specified") + } else if !common.IsHexAddress(moduleRaw) { + return fmt.Errorf("--module argument is not a valid Ethereum address") + } + module = common.HexToAddress(moduleRaw) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + key, keyErr := KeyFromFile(keyfile, password) + if keyErr != nil { + return keyErr + } + + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + + transactionOpts, transactionOptsErr := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID) + if transactionOptsErr != nil { + return transactionOptsErr + } + + SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) + + contract, contractErr := NewGnosisSafe(contractAddress, client) + if contractErr != nil { + return contractErr + } + + session := GnosisSafeTransactorSession{ + Contract: &contract.GnosisSafeTransactor, + TransactOpts: *transactionOpts, + } + + transaction, transactionErr := session.EnableModule( + module, + ) + if transactionErr != nil { + return transactionErr + } + + cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) + if transactionOpts.NoSend { + estimationMessage := ethereum.CallMsg{ + From: transactionOpts.From, + To: &contractAddress, + Data: transaction.Data(), + } + + gasEstimationCtx, cancelGasEstimationCtx := NewChainContext(timeout) + defer cancelGasEstimationCtx() + + gasEstimate, gasEstimateErr := client.EstimateGas(gasEstimationCtx, estimationMessage) + if gasEstimateErr != nil { + return gasEstimateErr + } + + transactionBinary, transactionBinaryErr := transaction.MarshalBinary() + if transactionBinaryErr != nil { + return transactionBinaryErr + } + transactionBinaryHex := hex.EncodeToString(transactionBinary) + + cmd.Printf("Transaction: %s\nEstimated gas: %d\n", transactionBinaryHex, gasEstimate) + } else { + cmd.Println("Transaction submitted") + } + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&keyfile, "keyfile", "", "Path to the keystore file to use for the transaction") + cmd.Flags().StringVar(&password, "password", "", "Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes)") + cmd.Flags().StringVar(&nonce, "nonce", "", "Nonce to use for the transaction") + cmd.Flags().StringVar(&value, "value", "", "Value to send with the transaction") + cmd.Flags().StringVar(&gasPrice, "gas-price", "", "Gas price to use for the transaction") + cmd.Flags().StringVar(&maxFeePerGas, "max-fee-per-gas", "", "Maximum fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().StringVar(&maxPriorityFeePerGas, "max-priority-fee-per-gas", "", "Maximum priority fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") + cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + + cmd.Flags().StringVar(&moduleRaw, "module", "", "module argument (common.Address)") + + return cmd +} +func CreateExecTransactionCommand() *cobra.Command { + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw string + var gasLimit uint64 + var simulate bool + var timeout uint + var contractAddress common.Address + + var to0 common.Address + var to0Raw string + var value0 *big.Int + var value0Raw string + var data []byte + var dataRaw string + var operation uint8 + + var safeTxGas *big.Int + var safeTxGasRaw string + var baseGas *big.Int + var baseGasRaw string + var gasPrice0 *big.Int + var gasPrice0Raw string + var gasToken common.Address + var gasTokenRaw string + var refundReceiver common.Address + var refundReceiverRaw string + var signatures []byte + var signaturesRaw string + + cmd := &cobra.Command{ + Use: "exec-transaction", + Short: "Execute the ExecTransaction method on a GnosisSafe contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if keyfile == "" { + return fmt.Errorf("--keystore not specified") + } + + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + if to0Raw == "" { + return fmt.Errorf("--to-0 argument not specified") + } else if !common.IsHexAddress(to0Raw) { + return fmt.Errorf("--to-0 argument is not a valid Ethereum address") + } + to0 = common.HexToAddress(to0Raw) + + if value0Raw == "" { + return fmt.Errorf("--value-0 argument not specified") + } + value0 = new(big.Int) + value0.SetString(value0Raw, 0) + + var dataIntermediate []byte + + var dataIntermediateHexDecodeErr error + dataIntermediate, dataIntermediateHexDecodeErr = hex.DecodeString(dataRaw) + if dataIntermediateHexDecodeErr != nil { + return dataIntermediateHexDecodeErr + } + + copy(data[:], dataIntermediate) + + if safeTxGasRaw == "" { + return fmt.Errorf("--safe-tx-gas argument not specified") + } + safeTxGas = new(big.Int) + safeTxGas.SetString(safeTxGasRaw, 0) + + if baseGasRaw == "" { + return fmt.Errorf("--base-gas argument not specified") + } + baseGas = new(big.Int) + baseGas.SetString(baseGasRaw, 0) + + if gasPrice0Raw == "" { + return fmt.Errorf("--gas-price-0 argument not specified") + } + gasPrice0 = new(big.Int) + gasPrice0.SetString(gasPrice0Raw, 0) + + if gasTokenRaw == "" { + return fmt.Errorf("--gas-token argument not specified") + } else if !common.IsHexAddress(gasTokenRaw) { + return fmt.Errorf("--gas-token argument is not a valid Ethereum address") + } + gasToken = common.HexToAddress(gasTokenRaw) + + if refundReceiverRaw == "" { + return fmt.Errorf("--refund-receiver argument not specified") + } else if !common.IsHexAddress(refundReceiverRaw) { + return fmt.Errorf("--refund-receiver argument is not a valid Ethereum address") + } + refundReceiver = common.HexToAddress(refundReceiverRaw) + + var signaturesIntermediate []byte + + var signaturesIntermediateHexDecodeErr error + signaturesIntermediate, signaturesIntermediateHexDecodeErr = hex.DecodeString(signaturesRaw) + if signaturesIntermediateHexDecodeErr != nil { + return signaturesIntermediateHexDecodeErr + } + + copy(signatures[:], signaturesIntermediate) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + key, keyErr := KeyFromFile(keyfile, password) + if keyErr != nil { + return keyErr + } + + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + + transactionOpts, transactionOptsErr := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID) + if transactionOptsErr != nil { + return transactionOptsErr + } + + SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) + + contract, contractErr := NewGnosisSafe(contractAddress, client) + if contractErr != nil { + return contractErr + } + + session := GnosisSafeTransactorSession{ + Contract: &contract.GnosisSafeTransactor, + TransactOpts: *transactionOpts, + } + + transaction, transactionErr := session.ExecTransaction( + to0, + value0, + data, + operation, + safeTxGas, + baseGas, + gasPrice0, + gasToken, + refundReceiver, + signatures, + ) + if transactionErr != nil { + return transactionErr + } + + cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) + if transactionOpts.NoSend { + estimationMessage := ethereum.CallMsg{ + From: transactionOpts.From, + To: &contractAddress, + Data: transaction.Data(), + } + + gasEstimationCtx, cancelGasEstimationCtx := NewChainContext(timeout) + defer cancelGasEstimationCtx() + + gasEstimate, gasEstimateErr := client.EstimateGas(gasEstimationCtx, estimationMessage) + if gasEstimateErr != nil { + return gasEstimateErr + } + + transactionBinary, transactionBinaryErr := transaction.MarshalBinary() + if transactionBinaryErr != nil { + return transactionBinaryErr + } + transactionBinaryHex := hex.EncodeToString(transactionBinary) + + cmd.Printf("Transaction: %s\nEstimated gas: %d\n", transactionBinaryHex, gasEstimate) + } else { + cmd.Println("Transaction submitted") + } + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&keyfile, "keyfile", "", "Path to the keystore file to use for the transaction") + cmd.Flags().StringVar(&password, "password", "", "Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes)") + cmd.Flags().StringVar(&nonce, "nonce", "", "Nonce to use for the transaction") + cmd.Flags().StringVar(&value, "value", "", "Value to send with the transaction") + cmd.Flags().StringVar(&gasPrice, "gas-price", "", "Gas price to use for the transaction") + cmd.Flags().StringVar(&maxFeePerGas, "max-fee-per-gas", "", "Maximum fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().StringVar(&maxPriorityFeePerGas, "max-priority-fee-per-gas", "", "Maximum priority fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") + cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + + cmd.Flags().StringVar(&to0Raw, "to-0", "", "to-0 argument (common.Address)") + cmd.Flags().StringVar(&value0Raw, "value-0", "", "value-0 argument") + cmd.Flags().StringVar(&dataRaw, "data", "", "data argument ([]byte)") + cmd.Flags().Uint8Var(&operation, "operation", 0, "operation argument") + cmd.Flags().StringVar(&safeTxGasRaw, "safe-tx-gas", "", "safe-tx-gas argument") + cmd.Flags().StringVar(&baseGasRaw, "base-gas", "", "base-gas argument") + cmd.Flags().StringVar(&gasPrice0Raw, "gas-price-0", "", "gas-price-0 argument") + cmd.Flags().StringVar(&gasTokenRaw, "gas-token", "", "gas-token argument (common.Address)") + cmd.Flags().StringVar(&refundReceiverRaw, "refund-receiver", "", "refund-receiver argument (common.Address)") + cmd.Flags().StringVar(&signaturesRaw, "signatures", "", "signatures argument ([]byte)") + + return cmd +} +func CreateExecTransactionFromModuleCommand() *cobra.Command { + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw string + var gasLimit uint64 + var simulate bool + var timeout uint + var contractAddress common.Address + + var to0 common.Address + var to0Raw string + var value0 *big.Int + var value0Raw string + var data []byte + var dataRaw string + var operation uint8 + + cmd := &cobra.Command{ + Use: "exec-transaction-from-module", + Short: "Execute the ExecTransactionFromModule method on a GnosisSafe contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if keyfile == "" { + return fmt.Errorf("--keystore not specified") + } + + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + if to0Raw == "" { + return fmt.Errorf("--to-0 argument not specified") + } else if !common.IsHexAddress(to0Raw) { + return fmt.Errorf("--to-0 argument is not a valid Ethereum address") + } + to0 = common.HexToAddress(to0Raw) + + if value0Raw == "" { + return fmt.Errorf("--value-0 argument not specified") + } + value0 = new(big.Int) + value0.SetString(value0Raw, 0) + + var dataIntermediate []byte + + var dataIntermediateHexDecodeErr error + dataIntermediate, dataIntermediateHexDecodeErr = hex.DecodeString(dataRaw) + if dataIntermediateHexDecodeErr != nil { + return dataIntermediateHexDecodeErr + } + + copy(data[:], dataIntermediate) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + key, keyErr := KeyFromFile(keyfile, password) + if keyErr != nil { + return keyErr + } + + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + + transactionOpts, transactionOptsErr := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID) + if transactionOptsErr != nil { + return transactionOptsErr + } + + SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) + + contract, contractErr := NewGnosisSafe(contractAddress, client) + if contractErr != nil { + return contractErr + } + + session := GnosisSafeTransactorSession{ + Contract: &contract.GnosisSafeTransactor, + TransactOpts: *transactionOpts, + } + + transaction, transactionErr := session.ExecTransactionFromModule( + to0, + value0, + data, + operation, + ) + if transactionErr != nil { + return transactionErr + } + + cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) + if transactionOpts.NoSend { + estimationMessage := ethereum.CallMsg{ + From: transactionOpts.From, + To: &contractAddress, + Data: transaction.Data(), + } + + gasEstimationCtx, cancelGasEstimationCtx := NewChainContext(timeout) + defer cancelGasEstimationCtx() + + gasEstimate, gasEstimateErr := client.EstimateGas(gasEstimationCtx, estimationMessage) + if gasEstimateErr != nil { + return gasEstimateErr + } + + transactionBinary, transactionBinaryErr := transaction.MarshalBinary() + if transactionBinaryErr != nil { + return transactionBinaryErr + } + transactionBinaryHex := hex.EncodeToString(transactionBinary) + + cmd.Printf("Transaction: %s\nEstimated gas: %d\n", transactionBinaryHex, gasEstimate) + } else { + cmd.Println("Transaction submitted") + } + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&keyfile, "keyfile", "", "Path to the keystore file to use for the transaction") + cmd.Flags().StringVar(&password, "password", "", "Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes)") + cmd.Flags().StringVar(&nonce, "nonce", "", "Nonce to use for the transaction") + cmd.Flags().StringVar(&value, "value", "", "Value to send with the transaction") + cmd.Flags().StringVar(&gasPrice, "gas-price", "", "Gas price to use for the transaction") + cmd.Flags().StringVar(&maxFeePerGas, "max-fee-per-gas", "", "Maximum fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().StringVar(&maxPriorityFeePerGas, "max-priority-fee-per-gas", "", "Maximum priority fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") + cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + + cmd.Flags().StringVar(&to0Raw, "to-0", "", "to-0 argument (common.Address)") + cmd.Flags().StringVar(&value0Raw, "value-0", "", "value-0 argument") + cmd.Flags().StringVar(&dataRaw, "data", "", "data argument ([]byte)") + cmd.Flags().Uint8Var(&operation, "operation", 0, "operation argument") + + return cmd +} +func CreateExecTransactionFromModuleReturnDataCommand() *cobra.Command { + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw string + var gasLimit uint64 + var simulate bool + var timeout uint + var contractAddress common.Address + + var to0 common.Address + var to0Raw string + var value0 *big.Int + var value0Raw string + var data []byte + var dataRaw string + var operation uint8 + + cmd := &cobra.Command{ + Use: "exec-transaction-from-module-return-data", + Short: "Execute the ExecTransactionFromModuleReturnData method on a GnosisSafe contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if keyfile == "" { + return fmt.Errorf("--keystore not specified") + } + + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + if to0Raw == "" { + return fmt.Errorf("--to-0 argument not specified") + } else if !common.IsHexAddress(to0Raw) { + return fmt.Errorf("--to-0 argument is not a valid Ethereum address") + } + to0 = common.HexToAddress(to0Raw) + + if value0Raw == "" { + return fmt.Errorf("--value-0 argument not specified") + } + value0 = new(big.Int) + value0.SetString(value0Raw, 0) + + var dataIntermediate []byte + + var dataIntermediateHexDecodeErr error + dataIntermediate, dataIntermediateHexDecodeErr = hex.DecodeString(dataRaw) + if dataIntermediateHexDecodeErr != nil { + return dataIntermediateHexDecodeErr + } + + copy(data[:], dataIntermediate) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + key, keyErr := KeyFromFile(keyfile, password) + if keyErr != nil { + return keyErr + } + + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + + transactionOpts, transactionOptsErr := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID) + if transactionOptsErr != nil { + return transactionOptsErr + } + + SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) + + contract, contractErr := NewGnosisSafe(contractAddress, client) + if contractErr != nil { + return contractErr + } + + session := GnosisSafeTransactorSession{ + Contract: &contract.GnosisSafeTransactor, + TransactOpts: *transactionOpts, + } + + transaction, transactionErr := session.ExecTransactionFromModuleReturnData( + to0, + value0, + data, + operation, + ) + if transactionErr != nil { + return transactionErr + } + + cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) + if transactionOpts.NoSend { + estimationMessage := ethereum.CallMsg{ + From: transactionOpts.From, + To: &contractAddress, + Data: transaction.Data(), + } + + gasEstimationCtx, cancelGasEstimationCtx := NewChainContext(timeout) + defer cancelGasEstimationCtx() + + gasEstimate, gasEstimateErr := client.EstimateGas(gasEstimationCtx, estimationMessage) + if gasEstimateErr != nil { + return gasEstimateErr + } + + transactionBinary, transactionBinaryErr := transaction.MarshalBinary() + if transactionBinaryErr != nil { + return transactionBinaryErr + } + transactionBinaryHex := hex.EncodeToString(transactionBinary) + + cmd.Printf("Transaction: %s\nEstimated gas: %d\n", transactionBinaryHex, gasEstimate) + } else { + cmd.Println("Transaction submitted") + } + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&keyfile, "keyfile", "", "Path to the keystore file to use for the transaction") + cmd.Flags().StringVar(&password, "password", "", "Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes)") + cmd.Flags().StringVar(&nonce, "nonce", "", "Nonce to use for the transaction") + cmd.Flags().StringVar(&value, "value", "", "Value to send with the transaction") + cmd.Flags().StringVar(&gasPrice, "gas-price", "", "Gas price to use for the transaction") + cmd.Flags().StringVar(&maxFeePerGas, "max-fee-per-gas", "", "Maximum fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().StringVar(&maxPriorityFeePerGas, "max-priority-fee-per-gas", "", "Maximum priority fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") + cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + + cmd.Flags().StringVar(&to0Raw, "to-0", "", "to-0 argument (common.Address)") + cmd.Flags().StringVar(&value0Raw, "value-0", "", "value-0 argument") + cmd.Flags().StringVar(&dataRaw, "data", "", "data argument ([]byte)") + cmd.Flags().Uint8Var(&operation, "operation", 0, "operation argument") + + return cmd +} +func CreateFallbackCommand() *cobra.Command { + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw string + var gasLimit uint64 + var simulate bool + var timeout uint + var contractAddress common.Address + + var calldata []byte + var calldataRaw string + + cmd := &cobra.Command{ + Use: "fallback", + Short: "Execute the Fallback method on a GnosisSafe contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if keyfile == "" { + return fmt.Errorf("--keystore not specified") + } + + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + var calldataIntermediate []byte + + var calldataIntermediateHexDecodeErr error + calldataIntermediate, calldataIntermediateHexDecodeErr = hex.DecodeString(calldataRaw) + if calldataIntermediateHexDecodeErr != nil { + return calldataIntermediateHexDecodeErr + } + + copy(calldata[:], calldataIntermediate) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + key, keyErr := KeyFromFile(keyfile, password) + if keyErr != nil { + return keyErr + } + + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + + transactionOpts, transactionOptsErr := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID) + if transactionOptsErr != nil { + return transactionOptsErr + } + + SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) + + contract, contractErr := NewGnosisSafe(contractAddress, client) + if contractErr != nil { + return contractErr + } + + session := GnosisSafeTransactorSession{ + Contract: &contract.GnosisSafeTransactor, + TransactOpts: *transactionOpts, + } + + transaction, transactionErr := session.Fallback( + calldata, + ) + if transactionErr != nil { + return transactionErr + } + + cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) + if transactionOpts.NoSend { + estimationMessage := ethereum.CallMsg{ + From: transactionOpts.From, + To: &contractAddress, + Data: transaction.Data(), + } + + gasEstimationCtx, cancelGasEstimationCtx := NewChainContext(timeout) + defer cancelGasEstimationCtx() + + gasEstimate, gasEstimateErr := client.EstimateGas(gasEstimationCtx, estimationMessage) + if gasEstimateErr != nil { + return gasEstimateErr + } + + transactionBinary, transactionBinaryErr := transaction.MarshalBinary() + if transactionBinaryErr != nil { + return transactionBinaryErr + } + transactionBinaryHex := hex.EncodeToString(transactionBinary) + + cmd.Printf("Transaction: %s\nEstimated gas: %d\n", transactionBinaryHex, gasEstimate) + } else { + cmd.Println("Transaction submitted") + } + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&keyfile, "keyfile", "", "Path to the keystore file to use for the transaction") + cmd.Flags().StringVar(&password, "password", "", "Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes)") + cmd.Flags().StringVar(&nonce, "nonce", "", "Nonce to use for the transaction") + cmd.Flags().StringVar(&value, "value", "", "Value to send with the transaction") + cmd.Flags().StringVar(&gasPrice, "gas-price", "", "Gas price to use for the transaction") + cmd.Flags().StringVar(&maxFeePerGas, "max-fee-per-gas", "", "Maximum fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().StringVar(&maxPriorityFeePerGas, "max-priority-fee-per-gas", "", "Maximum priority fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") + cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + + cmd.Flags().StringVar(&calldataRaw, "calldata", "", "calldata argument ([]byte)") + + return cmd +} +func CreateIsValidSignatureCommand() *cobra.Command { + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw string + var gasLimit uint64 + var simulate bool + var timeout uint + var contractAddress common.Address + + var data []byte + var dataRaw string + var signature []byte + var signatureRaw string + + cmd := &cobra.Command{ + Use: "is-valid-signature", + Short: "Execute the IsValidSignature method on a GnosisSafe contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if keyfile == "" { + return fmt.Errorf("--keystore not specified") + } + + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + var dataIntermediate []byte + + var dataIntermediateHexDecodeErr error + dataIntermediate, dataIntermediateHexDecodeErr = hex.DecodeString(dataRaw) + if dataIntermediateHexDecodeErr != nil { + return dataIntermediateHexDecodeErr + } + + copy(data[:], dataIntermediate) + + var signatureIntermediate []byte + + var signatureIntermediateHexDecodeErr error + signatureIntermediate, signatureIntermediateHexDecodeErr = hex.DecodeString(signatureRaw) + if signatureIntermediateHexDecodeErr != nil { + return signatureIntermediateHexDecodeErr + } + + copy(signature[:], signatureIntermediate) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + key, keyErr := KeyFromFile(keyfile, password) + if keyErr != nil { + return keyErr + } + + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + + transactionOpts, transactionOptsErr := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID) + if transactionOptsErr != nil { + return transactionOptsErr + } + + SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) + + contract, contractErr := NewGnosisSafe(contractAddress, client) + if contractErr != nil { + return contractErr + } + + session := GnosisSafeTransactorSession{ + Contract: &contract.GnosisSafeTransactor, + TransactOpts: *transactionOpts, + } + + transaction, transactionErr := session.IsValidSignature( + data, + signature, + ) + if transactionErr != nil { + return transactionErr + } + + cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) + if transactionOpts.NoSend { + estimationMessage := ethereum.CallMsg{ + From: transactionOpts.From, + To: &contractAddress, + Data: transaction.Data(), + } + + gasEstimationCtx, cancelGasEstimationCtx := NewChainContext(timeout) + defer cancelGasEstimationCtx() + + gasEstimate, gasEstimateErr := client.EstimateGas(gasEstimationCtx, estimationMessage) + if gasEstimateErr != nil { + return gasEstimateErr + } + + transactionBinary, transactionBinaryErr := transaction.MarshalBinary() + if transactionBinaryErr != nil { + return transactionBinaryErr + } + transactionBinaryHex := hex.EncodeToString(transactionBinary) + + cmd.Printf("Transaction: %s\nEstimated gas: %d\n", transactionBinaryHex, gasEstimate) + } else { + cmd.Println("Transaction submitted") + } + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&keyfile, "keyfile", "", "Path to the keystore file to use for the transaction") + cmd.Flags().StringVar(&password, "password", "", "Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes)") + cmd.Flags().StringVar(&nonce, "nonce", "", "Nonce to use for the transaction") + cmd.Flags().StringVar(&value, "value", "", "Value to send with the transaction") + cmd.Flags().StringVar(&gasPrice, "gas-price", "", "Gas price to use for the transaction") + cmd.Flags().StringVar(&maxFeePerGas, "max-fee-per-gas", "", "Maximum fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().StringVar(&maxPriorityFeePerGas, "max-priority-fee-per-gas", "", "Maximum priority fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") + cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + + cmd.Flags().StringVar(&dataRaw, "data", "", "data argument ([]byte)") + cmd.Flags().StringVar(&signatureRaw, "signature", "", "signature argument ([]byte)") + + return cmd +} +func CreateRemoveOwnerCommand() *cobra.Command { + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw string + var gasLimit uint64 + var simulate bool + var timeout uint + var contractAddress common.Address + + var prevOwner common.Address + var prevOwnerRaw string + var owner common.Address + var ownerRaw string + var threshold *big.Int + var thresholdRaw string + + cmd := &cobra.Command{ + Use: "remove-owner", + Short: "Execute the RemoveOwner method on a GnosisSafe contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if keyfile == "" { + return fmt.Errorf("--keystore not specified") + } + + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + if prevOwnerRaw == "" { + return fmt.Errorf("--prev-owner argument not specified") + } else if !common.IsHexAddress(prevOwnerRaw) { + return fmt.Errorf("--prev-owner argument is not a valid Ethereum address") + } + prevOwner = common.HexToAddress(prevOwnerRaw) + + if ownerRaw == "" { + return fmt.Errorf("--owner argument not specified") + } else if !common.IsHexAddress(ownerRaw) { + return fmt.Errorf("--owner argument is not a valid Ethereum address") + } + owner = common.HexToAddress(ownerRaw) + + if thresholdRaw == "" { + return fmt.Errorf("--threshold argument not specified") + } + threshold = new(big.Int) + threshold.SetString(thresholdRaw, 0) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + key, keyErr := KeyFromFile(keyfile, password) + if keyErr != nil { + return keyErr + } + + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + + transactionOpts, transactionOptsErr := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID) + if transactionOptsErr != nil { + return transactionOptsErr + } + + SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) + + contract, contractErr := NewGnosisSafe(contractAddress, client) + if contractErr != nil { + return contractErr + } + + session := GnosisSafeTransactorSession{ + Contract: &contract.GnosisSafeTransactor, + TransactOpts: *transactionOpts, + } + + transaction, transactionErr := session.RemoveOwner( + prevOwner, + owner, + threshold, + ) + if transactionErr != nil { + return transactionErr + } + + cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) + if transactionOpts.NoSend { + estimationMessage := ethereum.CallMsg{ + From: transactionOpts.From, + To: &contractAddress, + Data: transaction.Data(), + } + + gasEstimationCtx, cancelGasEstimationCtx := NewChainContext(timeout) + defer cancelGasEstimationCtx() + + gasEstimate, gasEstimateErr := client.EstimateGas(gasEstimationCtx, estimationMessage) + if gasEstimateErr != nil { + return gasEstimateErr + } + + transactionBinary, transactionBinaryErr := transaction.MarshalBinary() + if transactionBinaryErr != nil { + return transactionBinaryErr + } + transactionBinaryHex := hex.EncodeToString(transactionBinary) + + cmd.Printf("Transaction: %s\nEstimated gas: %d\n", transactionBinaryHex, gasEstimate) + } else { + cmd.Println("Transaction submitted") + } + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&keyfile, "keyfile", "", "Path to the keystore file to use for the transaction") + cmd.Flags().StringVar(&password, "password", "", "Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes)") + cmd.Flags().StringVar(&nonce, "nonce", "", "Nonce to use for the transaction") + cmd.Flags().StringVar(&value, "value", "", "Value to send with the transaction") + cmd.Flags().StringVar(&gasPrice, "gas-price", "", "Gas price to use for the transaction") + cmd.Flags().StringVar(&maxFeePerGas, "max-fee-per-gas", "", "Maximum fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().StringVar(&maxPriorityFeePerGas, "max-priority-fee-per-gas", "", "Maximum priority fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") + cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + + cmd.Flags().StringVar(&prevOwnerRaw, "prev-owner", "", "prev-owner argument (common.Address)") + cmd.Flags().StringVar(&ownerRaw, "owner", "", "owner argument (common.Address)") + cmd.Flags().StringVar(&thresholdRaw, "threshold", "", "threshold argument") + + return cmd +} +func CreateRequiredTxGasCommand() *cobra.Command { + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw string + var gasLimit uint64 + var simulate bool + var timeout uint + var contractAddress common.Address + + var to0 common.Address + var to0Raw string + var value0 *big.Int + var value0Raw string + var data []byte + var dataRaw string + var operation uint8 + + cmd := &cobra.Command{ + Use: "required-tx-gas", + Short: "Execute the RequiredTxGas method on a GnosisSafe contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if keyfile == "" { + return fmt.Errorf("--keystore not specified") + } + + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + if to0Raw == "" { + return fmt.Errorf("--to-0 argument not specified") + } else if !common.IsHexAddress(to0Raw) { + return fmt.Errorf("--to-0 argument is not a valid Ethereum address") + } + to0 = common.HexToAddress(to0Raw) + + if value0Raw == "" { + return fmt.Errorf("--value-0 argument not specified") + } + value0 = new(big.Int) + value0.SetString(value0Raw, 0) + + var dataIntermediate []byte + + var dataIntermediateHexDecodeErr error + dataIntermediate, dataIntermediateHexDecodeErr = hex.DecodeString(dataRaw) + if dataIntermediateHexDecodeErr != nil { + return dataIntermediateHexDecodeErr + } + + copy(data[:], dataIntermediate) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + key, keyErr := KeyFromFile(keyfile, password) + if keyErr != nil { + return keyErr + } + + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + + transactionOpts, transactionOptsErr := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID) + if transactionOptsErr != nil { + return transactionOptsErr + } + + SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) + + contract, contractErr := NewGnosisSafe(contractAddress, client) + if contractErr != nil { + return contractErr + } + + session := GnosisSafeTransactorSession{ + Contract: &contract.GnosisSafeTransactor, + TransactOpts: *transactionOpts, + } + + transaction, transactionErr := session.RequiredTxGas( + to0, + value0, + data, + operation, + ) + if transactionErr != nil { + return transactionErr + } + + cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) + if transactionOpts.NoSend { + estimationMessage := ethereum.CallMsg{ + From: transactionOpts.From, + To: &contractAddress, + Data: transaction.Data(), + } + + gasEstimationCtx, cancelGasEstimationCtx := NewChainContext(timeout) + defer cancelGasEstimationCtx() + + gasEstimate, gasEstimateErr := client.EstimateGas(gasEstimationCtx, estimationMessage) + if gasEstimateErr != nil { + return gasEstimateErr + } + + transactionBinary, transactionBinaryErr := transaction.MarshalBinary() + if transactionBinaryErr != nil { + return transactionBinaryErr + } + transactionBinaryHex := hex.EncodeToString(transactionBinary) + + cmd.Printf("Transaction: %s\nEstimated gas: %d\n", transactionBinaryHex, gasEstimate) + } else { + cmd.Println("Transaction submitted") + } + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&keyfile, "keyfile", "", "Path to the keystore file to use for the transaction") + cmd.Flags().StringVar(&password, "password", "", "Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes)") + cmd.Flags().StringVar(&nonce, "nonce", "", "Nonce to use for the transaction") + cmd.Flags().StringVar(&value, "value", "", "Value to send with the transaction") + cmd.Flags().StringVar(&gasPrice, "gas-price", "", "Gas price to use for the transaction") + cmd.Flags().StringVar(&maxFeePerGas, "max-fee-per-gas", "", "Maximum fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().StringVar(&maxPriorityFeePerGas, "max-priority-fee-per-gas", "", "Maximum priority fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") + cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + + cmd.Flags().StringVar(&to0Raw, "to-0", "", "to-0 argument (common.Address)") + cmd.Flags().StringVar(&value0Raw, "value-0", "", "value-0 argument") + cmd.Flags().StringVar(&dataRaw, "data", "", "data argument ([]byte)") + cmd.Flags().Uint8Var(&operation, "operation", 0, "operation argument") + + return cmd +} +func CreateSetFallbackHandlerCommand() *cobra.Command { + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw string + var gasLimit uint64 + var simulate bool + var timeout uint + var contractAddress common.Address + + var handler common.Address + var handlerRaw string + + cmd := &cobra.Command{ + Use: "set-fallback-handler", + Short: "Execute the SetFallbackHandler method on a GnosisSafe contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if keyfile == "" { + return fmt.Errorf("--keystore not specified") + } + + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + if handlerRaw == "" { + return fmt.Errorf("--handler argument not specified") + } else if !common.IsHexAddress(handlerRaw) { + return fmt.Errorf("--handler argument is not a valid Ethereum address") + } + handler = common.HexToAddress(handlerRaw) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + key, keyErr := KeyFromFile(keyfile, password) + if keyErr != nil { + return keyErr + } + + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + + transactionOpts, transactionOptsErr := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID) + if transactionOptsErr != nil { + return transactionOptsErr + } + + SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) + + contract, contractErr := NewGnosisSafe(contractAddress, client) + if contractErr != nil { + return contractErr + } + + session := GnosisSafeTransactorSession{ + Contract: &contract.GnosisSafeTransactor, + TransactOpts: *transactionOpts, + } + + transaction, transactionErr := session.SetFallbackHandler( + handler, + ) + if transactionErr != nil { + return transactionErr + } + + cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) + if transactionOpts.NoSend { + estimationMessage := ethereum.CallMsg{ + From: transactionOpts.From, + To: &contractAddress, + Data: transaction.Data(), + } + + gasEstimationCtx, cancelGasEstimationCtx := NewChainContext(timeout) + defer cancelGasEstimationCtx() + + gasEstimate, gasEstimateErr := client.EstimateGas(gasEstimationCtx, estimationMessage) + if gasEstimateErr != nil { + return gasEstimateErr + } + + transactionBinary, transactionBinaryErr := transaction.MarshalBinary() + if transactionBinaryErr != nil { + return transactionBinaryErr + } + transactionBinaryHex := hex.EncodeToString(transactionBinary) + + cmd.Printf("Transaction: %s\nEstimated gas: %d\n", transactionBinaryHex, gasEstimate) + } else { + cmd.Println("Transaction submitted") + } + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&keyfile, "keyfile", "", "Path to the keystore file to use for the transaction") + cmd.Flags().StringVar(&password, "password", "", "Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes)") + cmd.Flags().StringVar(&nonce, "nonce", "", "Nonce to use for the transaction") + cmd.Flags().StringVar(&value, "value", "", "Value to send with the transaction") + cmd.Flags().StringVar(&gasPrice, "gas-price", "", "Gas price to use for the transaction") + cmd.Flags().StringVar(&maxFeePerGas, "max-fee-per-gas", "", "Maximum fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().StringVar(&maxPriorityFeePerGas, "max-priority-fee-per-gas", "", "Maximum priority fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") + cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + + cmd.Flags().StringVar(&handlerRaw, "handler", "", "handler argument (common.Address)") + + return cmd +} +func CreateSetupCommand() *cobra.Command { + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw string + var gasLimit uint64 + var simulate bool + var timeout uint + var contractAddress common.Address + + var owners []common.Address + var ownersRaw string + var threshold *big.Int + var thresholdRaw string + var to0 common.Address + var to0Raw string + var data []byte + var dataRaw string + var fallbackHandler common.Address + var fallbackHandlerRaw string + var paymentToken common.Address + var paymentTokenRaw string + var payment *big.Int + var paymentRaw string + var paymentReceiver common.Address + var paymentReceiverRaw string + + cmd := &cobra.Command{ + Use: "setup", + Short: "Execute the Setup method on a GnosisSafe contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if keyfile == "" { + return fmt.Errorf("--keystore not specified") + } + + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + if ownersRaw == "" { + return fmt.Errorf("--owners argument not specified") + } else if strings.HasPrefix(ownersRaw, "@") { + filename := strings.TrimPrefix(ownersRaw, "@") + contents, readErr := os.ReadFile(filename) + if readErr != nil { + return readErr + } + unmarshalErr := json.Unmarshal(contents, &owners) + if unmarshalErr != nil { + return unmarshalErr + } + } else { + unmarshalErr := json.Unmarshal([]byte(ownersRaw), &owners) + if unmarshalErr != nil { + return unmarshalErr + } + } + + if thresholdRaw == "" { + return fmt.Errorf("--threshold argument not specified") + } + threshold = new(big.Int) + threshold.SetString(thresholdRaw, 0) + + if to0Raw == "" { + return fmt.Errorf("--to-0 argument not specified") + } else if !common.IsHexAddress(to0Raw) { + return fmt.Errorf("--to-0 argument is not a valid Ethereum address") + } + to0 = common.HexToAddress(to0Raw) + + var dataIntermediate []byte + + var dataIntermediateHexDecodeErr error + dataIntermediate, dataIntermediateHexDecodeErr = hex.DecodeString(dataRaw) + if dataIntermediateHexDecodeErr != nil { + return dataIntermediateHexDecodeErr + } + + copy(data[:], dataIntermediate) + + if fallbackHandlerRaw == "" { + return fmt.Errorf("--fallback-handler argument not specified") + } else if !common.IsHexAddress(fallbackHandlerRaw) { + return fmt.Errorf("--fallback-handler argument is not a valid Ethereum address") + } + fallbackHandler = common.HexToAddress(fallbackHandlerRaw) + + if paymentTokenRaw == "" { + return fmt.Errorf("--payment-token argument not specified") + } else if !common.IsHexAddress(paymentTokenRaw) { + return fmt.Errorf("--payment-token argument is not a valid Ethereum address") + } + paymentToken = common.HexToAddress(paymentTokenRaw) + + if paymentRaw == "" { + return fmt.Errorf("--payment argument not specified") + } + payment = new(big.Int) + payment.SetString(paymentRaw, 0) + + if paymentReceiverRaw == "" { + return fmt.Errorf("--payment-receiver argument not specified") + } else if !common.IsHexAddress(paymentReceiverRaw) { + return fmt.Errorf("--payment-receiver argument is not a valid Ethereum address") + } + paymentReceiver = common.HexToAddress(paymentReceiverRaw) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + key, keyErr := KeyFromFile(keyfile, password) + if keyErr != nil { + return keyErr + } + + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + + transactionOpts, transactionOptsErr := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID) + if transactionOptsErr != nil { + return transactionOptsErr + } + + SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) + + contract, contractErr := NewGnosisSafe(contractAddress, client) + if contractErr != nil { + return contractErr + } + + session := GnosisSafeTransactorSession{ + Contract: &contract.GnosisSafeTransactor, + TransactOpts: *transactionOpts, + } + + transaction, transactionErr := session.Setup( + owners, + threshold, + to0, + data, + fallbackHandler, + paymentToken, + payment, + paymentReceiver, + ) + if transactionErr != nil { + return transactionErr + } + + cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) + if transactionOpts.NoSend { + estimationMessage := ethereum.CallMsg{ + From: transactionOpts.From, + To: &contractAddress, + Data: transaction.Data(), + } + + gasEstimationCtx, cancelGasEstimationCtx := NewChainContext(timeout) + defer cancelGasEstimationCtx() + + gasEstimate, gasEstimateErr := client.EstimateGas(gasEstimationCtx, estimationMessage) + if gasEstimateErr != nil { + return gasEstimateErr + } + + transactionBinary, transactionBinaryErr := transaction.MarshalBinary() + if transactionBinaryErr != nil { + return transactionBinaryErr + } + transactionBinaryHex := hex.EncodeToString(transactionBinary) + + cmd.Printf("Transaction: %s\nEstimated gas: %d\n", transactionBinaryHex, gasEstimate) + } else { + cmd.Println("Transaction submitted") + } + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&keyfile, "keyfile", "", "Path to the keystore file to use for the transaction") + cmd.Flags().StringVar(&password, "password", "", "Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes)") + cmd.Flags().StringVar(&nonce, "nonce", "", "Nonce to use for the transaction") + cmd.Flags().StringVar(&value, "value", "", "Value to send with the transaction") + cmd.Flags().StringVar(&gasPrice, "gas-price", "", "Gas price to use for the transaction") + cmd.Flags().StringVar(&maxFeePerGas, "max-fee-per-gas", "", "Maximum fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().StringVar(&maxPriorityFeePerGas, "max-priority-fee-per-gas", "", "Maximum priority fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") + cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + + cmd.Flags().StringVar(&ownersRaw, "owners", "", "owners argument ([]common.Address)") + cmd.Flags().StringVar(&thresholdRaw, "threshold", "", "threshold argument") + cmd.Flags().StringVar(&to0Raw, "to-0", "", "to-0 argument (common.Address)") + cmd.Flags().StringVar(&dataRaw, "data", "", "data argument ([]byte)") + cmd.Flags().StringVar(&fallbackHandlerRaw, "fallback-handler", "", "fallback-handler argument (common.Address)") + cmd.Flags().StringVar(&paymentTokenRaw, "payment-token", "", "payment-token argument (common.Address)") + cmd.Flags().StringVar(&paymentRaw, "payment", "", "payment argument") + cmd.Flags().StringVar(&paymentReceiverRaw, "payment-receiver", "", "payment-receiver argument (common.Address)") + + return cmd +} +func CreateSignMessageCommand() *cobra.Command { + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw string + var gasLimit uint64 + var simulate bool + var timeout uint + var contractAddress common.Address + + var data []byte + var dataRaw string + + cmd := &cobra.Command{ + Use: "sign-message", + Short: "Execute the SignMessage method on a GnosisSafe contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if keyfile == "" { + return fmt.Errorf("--keystore not specified") + } + + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + var dataIntermediate []byte + + var dataIntermediateHexDecodeErr error + dataIntermediate, dataIntermediateHexDecodeErr = hex.DecodeString(dataRaw) + if dataIntermediateHexDecodeErr != nil { + return dataIntermediateHexDecodeErr + } + + copy(data[:], dataIntermediate) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + key, keyErr := KeyFromFile(keyfile, password) + if keyErr != nil { + return keyErr + } + + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + + transactionOpts, transactionOptsErr := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID) + if transactionOptsErr != nil { + return transactionOptsErr + } + + SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) + + contract, contractErr := NewGnosisSafe(contractAddress, client) + if contractErr != nil { + return contractErr + } + + session := GnosisSafeTransactorSession{ + Contract: &contract.GnosisSafeTransactor, + TransactOpts: *transactionOpts, + } + + transaction, transactionErr := session.SignMessage( + data, + ) + if transactionErr != nil { + return transactionErr + } + + cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) + if transactionOpts.NoSend { + estimationMessage := ethereum.CallMsg{ + From: transactionOpts.From, + To: &contractAddress, + Data: transaction.Data(), + } + + gasEstimationCtx, cancelGasEstimationCtx := NewChainContext(timeout) + defer cancelGasEstimationCtx() + + gasEstimate, gasEstimateErr := client.EstimateGas(gasEstimationCtx, estimationMessage) + if gasEstimateErr != nil { + return gasEstimateErr + } + + transactionBinary, transactionBinaryErr := transaction.MarshalBinary() + if transactionBinaryErr != nil { + return transactionBinaryErr + } + transactionBinaryHex := hex.EncodeToString(transactionBinary) + + cmd.Printf("Transaction: %s\nEstimated gas: %d\n", transactionBinaryHex, gasEstimate) + } else { + cmd.Println("Transaction submitted") + } + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&keyfile, "keyfile", "", "Path to the keystore file to use for the transaction") + cmd.Flags().StringVar(&password, "password", "", "Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes)") + cmd.Flags().StringVar(&nonce, "nonce", "", "Nonce to use for the transaction") + cmd.Flags().StringVar(&value, "value", "", "Value to send with the transaction") + cmd.Flags().StringVar(&gasPrice, "gas-price", "", "Gas price to use for the transaction") + cmd.Flags().StringVar(&maxFeePerGas, "max-fee-per-gas", "", "Maximum fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().StringVar(&maxPriorityFeePerGas, "max-priority-fee-per-gas", "", "Maximum priority fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") + cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + + cmd.Flags().StringVar(&dataRaw, "data", "", "data argument ([]byte)") + + return cmd +} +func CreateSwapOwnerCommand() *cobra.Command { + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw string + var gasLimit uint64 + var simulate bool + var timeout uint + var contractAddress common.Address + + var prevOwner common.Address + var prevOwnerRaw string + var oldOwner common.Address + var oldOwnerRaw string + var newOwner common.Address + var newOwnerRaw string + + cmd := &cobra.Command{ + Use: "swap-owner", + Short: "Execute the SwapOwner method on a GnosisSafe contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if keyfile == "" { + return fmt.Errorf("--keystore not specified") + } + + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + if prevOwnerRaw == "" { + return fmt.Errorf("--prev-owner argument not specified") + } else if !common.IsHexAddress(prevOwnerRaw) { + return fmt.Errorf("--prev-owner argument is not a valid Ethereum address") + } + prevOwner = common.HexToAddress(prevOwnerRaw) + + if oldOwnerRaw == "" { + return fmt.Errorf("--old-owner argument not specified") + } else if !common.IsHexAddress(oldOwnerRaw) { + return fmt.Errorf("--old-owner argument is not a valid Ethereum address") + } + oldOwner = common.HexToAddress(oldOwnerRaw) + + if newOwnerRaw == "" { + return fmt.Errorf("--new-owner argument not specified") + } else if !common.IsHexAddress(newOwnerRaw) { + return fmt.Errorf("--new-owner argument is not a valid Ethereum address") + } + newOwner = common.HexToAddress(newOwnerRaw) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + key, keyErr := KeyFromFile(keyfile, password) + if keyErr != nil { + return keyErr + } + + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + + transactionOpts, transactionOptsErr := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID) + if transactionOptsErr != nil { + return transactionOptsErr + } + + SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) + + contract, contractErr := NewGnosisSafe(contractAddress, client) + if contractErr != nil { + return contractErr + } + + session := GnosisSafeTransactorSession{ + Contract: &contract.GnosisSafeTransactor, + TransactOpts: *transactionOpts, + } + + transaction, transactionErr := session.SwapOwner( + prevOwner, + oldOwner, + newOwner, + ) + if transactionErr != nil { + return transactionErr + } + + cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) + if transactionOpts.NoSend { + estimationMessage := ethereum.CallMsg{ + From: transactionOpts.From, + To: &contractAddress, + Data: transaction.Data(), + } + + gasEstimationCtx, cancelGasEstimationCtx := NewChainContext(timeout) + defer cancelGasEstimationCtx() + + gasEstimate, gasEstimateErr := client.EstimateGas(gasEstimationCtx, estimationMessage) + if gasEstimateErr != nil { + return gasEstimateErr + } + + transactionBinary, transactionBinaryErr := transaction.MarshalBinary() + if transactionBinaryErr != nil { + return transactionBinaryErr + } + transactionBinaryHex := hex.EncodeToString(transactionBinary) + + cmd.Printf("Transaction: %s\nEstimated gas: %d\n", transactionBinaryHex, gasEstimate) + } else { + cmd.Println("Transaction submitted") + } + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&keyfile, "keyfile", "", "Path to the keystore file to use for the transaction") + cmd.Flags().StringVar(&password, "password", "", "Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes)") + cmd.Flags().StringVar(&nonce, "nonce", "", "Nonce to use for the transaction") + cmd.Flags().StringVar(&value, "value", "", "Value to send with the transaction") + cmd.Flags().StringVar(&gasPrice, "gas-price", "", "Gas price to use for the transaction") + cmd.Flags().StringVar(&maxFeePerGas, "max-fee-per-gas", "", "Maximum fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().StringVar(&maxPriorityFeePerGas, "max-priority-fee-per-gas", "", "Maximum priority fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") + cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + + cmd.Flags().StringVar(&prevOwnerRaw, "prev-owner", "", "prev-owner argument (common.Address)") + cmd.Flags().StringVar(&oldOwnerRaw, "old-owner", "", "old-owner argument (common.Address)") + cmd.Flags().StringVar(&newOwnerRaw, "new-owner", "", "new-owner argument (common.Address)") + + return cmd +} + +var ErrNoRPCURL error = errors.New("no RPC URL provided -- please pass an RPC URL from the command line or set the GNOSIS_SAFE_RPC_URL environment variable") + +// Generates an Ethereum client to the JSONRPC API at the given URL. If rpcURL is empty, then it +// attempts to read the RPC URL from the GNOSIS_SAFE_RPC_URL environment variable. If that is empty, +// too, then it returns an error. +func NewClient(rpcURL string) (*ethclient.Client, error) { + if rpcURL == "" { + rpcURL = os.Getenv("GNOSIS_SAFE_RPC_URL") + } + + if rpcURL == "" { + return nil, ErrNoRPCURL + } + + client, err := ethclient.Dial(rpcURL) + return client, err +} + +// Creates a new context to be used when interacting with the chain client. +func NewChainContext(timeout uint) (context.Context, context.CancelFunc) { + baseCtx := context.Background() + parsedTimeout := time.Duration(timeout) * time.Second + ctx, cancel := context.WithTimeout(baseCtx, parsedTimeout) + return ctx, cancel +} + +// Unlocks a key from a keystore (byte contents of a keystore file) with the given password. +func UnlockKeystore(keystoreData []byte, password string) (*keystore.Key, error) { + key, err := keystore.DecryptKey(keystoreData, password) + return key, err +} + +// Loads a key from file, prompting the user for the password if it is not provided as a function argument. +func KeyFromFile(keystoreFile string, password string) (*keystore.Key, error) { + var emptyKey *keystore.Key + keystoreContent, readErr := os.ReadFile(keystoreFile) + if readErr != nil { + return emptyKey, readErr + } + + // If password is "", prompt user for password. + if password == "" { + fmt.Printf("Please provide a password for keystore (%s): ", keystoreFile) + passwordRaw, inputErr := term.ReadPassword(int(os.Stdin.Fd())) + if inputErr != nil { + return emptyKey, fmt.Errorf("error reading password: %s", inputErr.Error()) + } + fmt.Print("\n") + password = string(passwordRaw) + } + + key, err := UnlockKeystore(keystoreContent, password) + return key, err +} + +// This method is used to set the parameters on a view call from command line arguments (represented mostly as +// strings). +func SetCallParametersFromArgs(opts *bind.CallOpts, pending bool, fromAddress, blockNumber string) { + if pending { + opts.Pending = true + } + + if fromAddress != "" { + opts.From = common.HexToAddress(fromAddress) + } + + if blockNumber != "" { + opts.BlockNumber = new(big.Int) + opts.BlockNumber.SetString(blockNumber, 0) + } +} + +// This method is used to set the parameters on a transaction from command line arguments (represented mostly as +// strings). +func SetTransactionParametersFromArgs(opts *bind.TransactOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas string, gasLimit uint64, noSend bool) { + if nonce != "" { + opts.Nonce = new(big.Int) + opts.Nonce.SetString(nonce, 0) + } + + if value != "" { + opts.Value = new(big.Int) + opts.Value.SetString(value, 0) + } + + if gasPrice != "" { + opts.GasPrice = new(big.Int) + opts.GasPrice.SetString(gasPrice, 0) + } + + if maxFeePerGas != "" { + opts.GasFeeCap = new(big.Int) + opts.GasFeeCap.SetString(maxFeePerGas, 0) + } + + if maxPriorityFeePerGas != "" { + opts.GasTipCap = new(big.Int) + opts.GasTipCap.SetString(maxPriorityFeePerGas, 0) + } + + if gasLimit != 0 { + opts.GasLimit = gasLimit + } + + opts.NoSend = noSend +} + +func CreateGnosisSafeCommand() *cobra.Command { + cmd := &cobra.Command{ + Use: "gnosis-safe", + Short: "Interact with the GnosisSafe contract", + Run: func(cmd *cobra.Command, args []string) { + cmd.Help() + }, + } + + cmd.SetOut(os.Stdout) + + DeployGroup := &cobra.Group{ + ID: "deploy", Title: "Commands which deploy contracts", + } + cmd.AddGroup(DeployGroup) + ViewGroup := &cobra.Group{ + ID: "view", Title: "Commands which view contract state", + } + TransactGroup := &cobra.Group{ + ID: "transact", Title: "Commands which submit transactions", + } + cmd.AddGroup(ViewGroup, TransactGroup) + + cmdDeployGnosisSafe := CreateGnosisSafeDeploymentCommand() + cmdDeployGnosisSafe.GroupID = DeployGroup.ID + cmd.AddCommand(cmdDeployGnosisSafe) + + cmdViewApprovedHashes := CreateApprovedHashesCommand() + cmdViewApprovedHashes.GroupID = ViewGroup.ID + cmd.AddCommand(cmdViewApprovedHashes) + cmdViewDomainSeparator := CreateDomainSeparatorCommand() + cmdViewDomainSeparator.GroupID = ViewGroup.ID + cmd.AddCommand(cmdViewDomainSeparator) + cmdViewEncodeTransactionData := CreateEncodeTransactionDataCommand() + cmdViewEncodeTransactionData.GroupID = ViewGroup.ID + cmd.AddCommand(cmdViewEncodeTransactionData) + cmdViewGetMessageHash := CreateGetMessageHashCommand() + cmdViewGetMessageHash.GroupID = ViewGroup.ID + cmd.AddCommand(cmdViewGetMessageHash) + cmdViewGetModules := CreateGetModulesCommand() + cmdViewGetModules.GroupID = ViewGroup.ID + cmd.AddCommand(cmdViewGetModules) + cmdViewGetModulesPaginated := CreateGetModulesPaginatedCommand() + cmdViewGetModulesPaginated.GroupID = ViewGroup.ID + cmd.AddCommand(cmdViewGetModulesPaginated) + cmdViewGetOwners := CreateGetOwnersCommand() + cmdViewGetOwners.GroupID = ViewGroup.ID + cmd.AddCommand(cmdViewGetOwners) + cmdViewGetThreshold := CreateGetThresholdCommand() + cmdViewGetThreshold.GroupID = ViewGroup.ID + cmd.AddCommand(cmdViewGetThreshold) + cmdViewGetTransactionHash := CreateGetTransactionHashCommand() + cmdViewGetTransactionHash.GroupID = ViewGroup.ID + cmd.AddCommand(cmdViewGetTransactionHash) + cmdViewIsModuleEnabled := CreateIsModuleEnabledCommand() + cmdViewIsModuleEnabled.GroupID = ViewGroup.ID + cmd.AddCommand(cmdViewIsModuleEnabled) + cmdViewIsOwner := CreateIsOwnerCommand() + cmdViewIsOwner.GroupID = ViewGroup.ID + cmd.AddCommand(cmdViewIsOwner) + cmdViewNAME := CreateNameCommand() + cmdViewNAME.GroupID = ViewGroup.ID + cmd.AddCommand(cmdViewNAME) + cmdViewNonce := CreateNonceCommand() + cmdViewNonce.GroupID = ViewGroup.ID + cmd.AddCommand(cmdViewNonce) + cmdViewSignedMessages := CreateSignedMessagesCommand() + cmdViewSignedMessages.GroupID = ViewGroup.ID + cmd.AddCommand(cmdViewSignedMessages) + cmdViewVERSION := CreateVersionCommand() + cmdViewVERSION.GroupID = ViewGroup.ID + cmd.AddCommand(cmdViewVERSION) + + cmdTransactAddOwnerWithThreshold := CreateAddOwnerWithThresholdCommand() + cmdTransactAddOwnerWithThreshold.GroupID = TransactGroup.ID + cmd.AddCommand(cmdTransactAddOwnerWithThreshold) + cmdTransactApproveHash := CreateApproveHashCommand() + cmdTransactApproveHash.GroupID = TransactGroup.ID + cmd.AddCommand(cmdTransactApproveHash) + cmdTransactChangeMasterCopy := CreateChangeMasterCopyCommand() + cmdTransactChangeMasterCopy.GroupID = TransactGroup.ID + cmd.AddCommand(cmdTransactChangeMasterCopy) + cmdTransactChangeThreshold := CreateChangeThresholdCommand() + cmdTransactChangeThreshold.GroupID = TransactGroup.ID + cmd.AddCommand(cmdTransactChangeThreshold) + cmdTransactDisableModule := CreateDisableModuleCommand() + cmdTransactDisableModule.GroupID = TransactGroup.ID + cmd.AddCommand(cmdTransactDisableModule) + cmdTransactEnableModule := CreateEnableModuleCommand() + cmdTransactEnableModule.GroupID = TransactGroup.ID + cmd.AddCommand(cmdTransactEnableModule) + cmdTransactExecTransaction := CreateExecTransactionCommand() + cmdTransactExecTransaction.GroupID = TransactGroup.ID + cmd.AddCommand(cmdTransactExecTransaction) + cmdTransactExecTransactionFromModule := CreateExecTransactionFromModuleCommand() + cmdTransactExecTransactionFromModule.GroupID = TransactGroup.ID + cmd.AddCommand(cmdTransactExecTransactionFromModule) + cmdTransactExecTransactionFromModuleReturnData := CreateExecTransactionFromModuleReturnDataCommand() + cmdTransactExecTransactionFromModuleReturnData.GroupID = TransactGroup.ID + cmd.AddCommand(cmdTransactExecTransactionFromModuleReturnData) + cmdTransactFallback := CreateFallbackCommand() + cmdTransactFallback.GroupID = TransactGroup.ID + cmd.AddCommand(cmdTransactFallback) + cmdTransactIsValidSignature := CreateIsValidSignatureCommand() + cmdTransactIsValidSignature.GroupID = TransactGroup.ID + cmd.AddCommand(cmdTransactIsValidSignature) + cmdTransactRemoveOwner := CreateRemoveOwnerCommand() + cmdTransactRemoveOwner.GroupID = TransactGroup.ID + cmd.AddCommand(cmdTransactRemoveOwner) + cmdTransactRequiredTxGas := CreateRequiredTxGasCommand() + cmdTransactRequiredTxGas.GroupID = TransactGroup.ID + cmd.AddCommand(cmdTransactRequiredTxGas) + cmdTransactSetFallbackHandler := CreateSetFallbackHandlerCommand() + cmdTransactSetFallbackHandler.GroupID = TransactGroup.ID + cmd.AddCommand(cmdTransactSetFallbackHandler) + cmdTransactSetup := CreateSetupCommand() + cmdTransactSetup.GroupID = TransactGroup.ID + cmd.AddCommand(cmdTransactSetup) + cmdTransactSignMessage := CreateSignMessageCommand() + cmdTransactSignMessage.GroupID = TransactGroup.ID + cmd.AddCommand(cmdTransactSignMessage) + cmdTransactSwapOwner := CreateSwapOwnerCommand() + cmdTransactSwapOwner.GroupID = TransactGroup.ID + cmd.AddCommand(cmdTransactSwapOwner) + + return cmd +} diff --git a/evm/generators.go b/evm/generators.go index c33c983..6759baa 100644 --- a/evm/generators.go +++ b/evm/generators.go @@ -780,6 +780,10 @@ func AddCLI(sourceCode, structName string, noformat, includemain bool) (string, // - github.com/ethereum/go-ethereum/accounts/keystore // - github.com/ethereum/go-ethereum/ethclient // - golang.org/x/term + // - github.com/moonstream-to/seer/bindings/GnosisSafe + // - github.com/moonstream-to/seer/bindings/CreateCall + // - github.com/ethereum/go-ethereum/common/math + // - github.com/ethereum/go-ethereum/crypto if t.Tok == token.IMPORT { t.Specs = append( t.Specs, @@ -793,6 +797,10 @@ func AddCLI(sourceCode, structName string, noformat, includemain bool) (string, &ast.ImportSpec{Path: &ast.BasicLit{Value: `"github.com/ethereum/go-ethereum/accounts/keystore"`}}, &ast.ImportSpec{Path: &ast.BasicLit{Value: `"github.com/ethereum/go-ethereum/ethclient"`}}, &ast.ImportSpec{Path: &ast.BasicLit{Value: `"golang.org/x/term"`}}, + &ast.ImportSpec{Path: &ast.BasicLit{Value: `"github.com/moonstream-to/seer/bindings/GnosisSafe"`}}, + &ast.ImportSpec{Path: &ast.BasicLit{Value: `"github.com/moonstream-to/seer/bindings/CreateCall"`}}, + &ast.ImportSpec{Path: &ast.BasicLit{Value: `"github.com/ethereum/go-ethereum/common/math"`}}, + &ast.ImportSpec{Path: &ast.BasicLit{Value: `"github.com/ethereum/go-ethereum/crypto"`}}, ) } return true @@ -822,6 +830,7 @@ func AddCLI(sourceCode, structName string, noformat, includemain bool) (string, templateFuncs := map[string]any{ "KebabCase": strcase.ToKebab, "ScreamingSnake": strcase.ToScreamingSnake, + "ToLowerCamel": strcase.ToLowerCamel, } cliTemplate, cliTemplateParseErr := template.New("cli").Funcs(templateFuncs).Parse(CLICodeTemplate) @@ -905,9 +914,9 @@ func AddCLI(sourceCode, structName string, noformat, includemain bool) (string, if formattingErr != nil { return code, formattingErr } + code = string(generatedCode) } - return code, nil } @@ -1066,6 +1075,208 @@ func Create{{.StructName}}Command() *cobra.Command { return cmd } + +// SafeOperationType represents the type of operation for a Safe transaction +type SafeOperationType uint8 + +const ( + Call SafeOperationType = 0 + DelegateCall SafeOperationType = 1 +) + +// String returns the string representation of the SafeOperationType +func (o SafeOperationType) String() string { + switch o { + case Call: + return "Call" + case DelegateCall: + return "DelegateCall" + default: + return "Unknown" + } +} + +// SafeTransactionData represents the data for a Safe transaction +type SafeTransactionData struct { + To string ` + "`" + `json:"to"` + "`" + ` + Value string ` + "`" + `json:"value"` + "`" + ` + Data string ` + "`" + `json:"data"` + "`" + ` + Operation SafeOperationType ` + "`" + `json:"operation"` + "`" + ` + SafeTxGas uint64 ` + "`" + `json:"safeTxGas"` + "`" + ` + BaseGas uint64 ` + "`" + `json:"baseGas"` + "`" + ` + GasPrice string ` + "`" + `json:"gasPrice"` + "`" + ` + GasToken string ` + "`" + `json:"gasToken"` + "`" + ` + RefundReceiver string ` + "`" + `json:"refundReceiver"` + "`" + ` + Nonce uint64 ` + "`" + `json:"nonce"` + "`" + ` + SafeTxHash string ` + "`" + `json:"safeTxHash"` + "`" + ` + Sender string ` + "`" + `json:"sender"` + "`" + ` + Signature string ` + "`" + `json:"signature"` + "`" + ` + Origin string ` + "`" + `json:"origin"` + "`" + ` +} + +const ( + NativeTokenAddress = "0x0000000000000000000000000000000000000000" +) + + +func DeployWithSafe(client *ethclient.Client, key *keystore.Key, safeAddress common.Address, factoryAddress common.Address, value *big.Int, safeApi string, deployBytecode []byte, safeOperationType SafeOperationType, salt [32]byte) error { + abi, err := CreateCall.CreateCallMetaData.GetAbi() + if err != nil { + return fmt.Errorf("failed to get ABI: %v", err) + } + + safeCreateCallTxData, err := abi.Pack("performCreate2", value, deployBytecode, salt) + if err != nil { + return fmt.Errorf("failed to pack performCreate2 transaction: %v", err) + } + + return CreateSafeProposal(client, key, safeAddress, factoryAddress, safeCreateCallTxData, value, safeApi, SafeOperationType(safeOperationType)) +} + +func CreateSafeProposal(client *ethclient.Client, key *keystore.Key, safeAddress common.Address, to common.Address, data []byte, value *big.Int, safeApi string, safeOperationType SafeOperationType) error { + chainID, err := client.ChainID(context.Background()) + if err != nil { + return fmt.Errorf("failed to get chain ID: %v", err) + } + + // Create a new instance of the GnosisSafe contract + safeInstance, err := GnosisSafe.NewGnosisSafe(safeAddress, client) + if err != nil { + return fmt.Errorf("failed to create GnosisSafe instance: %v", err) + } + + // Fetch the current nonce from the Safe contract + nonce, err := safeInstance.Nonce(&bind.CallOpts{}) + if err != nil { + return fmt.Errorf("failed to fetch nonce from Safe contract: %v", err) + } + + safeTransactionData := SafeTransactionData{ + To: to.Hex(), + Value: value.String(), + Data: common.Bytes2Hex(data), + Operation: safeOperationType, + SafeTxGas: 0, + BaseGas: 0, + GasPrice: "0", + GasToken: NativeTokenAddress, + RefundReceiver: NativeTokenAddress, + Nonce: nonce.Uint64(), + } + + // Calculate SafeTxHash + safeTxHash, err := CalculateSafeTxHash(safeAddress, safeTransactionData, chainID) + if err != nil { + return fmt.Errorf("failed to calculate SafeTxHash: %v", err) + } + + // Sign the SafeTxHash + signature, err := crypto.Sign(safeTxHash.Bytes(), key.PrivateKey) + if err != nil { + return fmt.Errorf("failed to sign SafeTxHash: %v", err) + } + + // Adjust V value for Ethereum's replay protection + signature[64] += 27 + + // Convert signature to hex + senderSignature := "0x" + common.Bytes2Hex(signature) + + // Prepare the request body + requestBody := map[string]interface{}{ + "to": safeTransactionData.To, + "value": safeTransactionData.Value, + "data": "0x" + safeTransactionData.Data, + "operation": int(safeTransactionData.Operation), + "safeTxGas": fmt.Sprintf("%d", safeTransactionData.SafeTxGas), + "baseGas": fmt.Sprintf("%d", safeTransactionData.BaseGas), + "gasPrice": safeTransactionData.GasPrice, + "gasToken": safeTransactionData.GasToken, + "refundReceiver": safeTransactionData.RefundReceiver, + "nonce": fmt.Sprintf("%d", safeTransactionData.Nonce), + "safeTxHash": safeTxHash.Hex(), + "sender": key.Address.Hex(), + "signature": senderSignature, + "origin": fmt.Sprintf("{\"url\":\"%s\",\"name\":\"TokenSender Deployment\"}", safeApi), + } + + // Marshal the request body to JSON + jsonBody, err := json.Marshal(requestBody) + if err != nil { + return fmt.Errorf("failed to marshal request body: %v", err) + } + + // Send the request to the Safe Transaction Service + req, err := http.NewRequest("POST", safeApi, bytes.NewBuffer(jsonBody)) + if err != nil { + return fmt.Errorf("failed to create request: %v", err) + } + + req.Header.Set("Content-Type", "application/json") + + httpClient := &http.Client{} + resp, err := httpClient.Do(req) + if err != nil { + return fmt.Errorf("failed to send request: %v", err) + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusCreated { + return fmt.Errorf("unexpected status code: %d", resp.StatusCode) + } + + fmt.Println("Safe proposal created successfully") + return nil +} + +func CalculateSafeTxHash(safeAddress common.Address, txData SafeTransactionData, chainID *big.Int) (common.Hash, error) { + domainSeparator := apitypes.TypedDataDomain{ + ChainId: (*math.HexOrDecimal256)(chainID), + VerifyingContract: safeAddress.Hex(), + } + + typedData := apitypes.TypedData{ + Types: apitypes.Types{ + "EIP712Domain": []apitypes.Type{ + {Name: "chainId", Type: "uint256"}, + {Name: "verifyingContract", Type: "address"}, + }, + "SafeTx": []apitypes.Type{ + {Name: "to", Type: "address"}, + {Name: "value", Type: "uint256"}, + {Name: "data", Type: "bytes"}, + {Name: "operation", Type: "uint8"}, + {Name: "safeTxGas", Type: "uint256"}, + {Name: "baseGas", Type: "uint256"}, + {Name: "gasPrice", Type: "uint256"}, + {Name: "gasToken", Type: "address"}, + {Name: "refundReceiver", Type: "address"}, + {Name: "nonce", Type: "uint256"}, + }, + }, + Domain: domainSeparator, + PrimaryType: "SafeTx", + Message: apitypes.TypedDataMessage{ + "to": txData.To, + "value": txData.Value, + "data": "0x" + txData.Data, + "operation": fmt.Sprintf("%d", txData.Operation), + "safeTxGas": fmt.Sprintf("%d", txData.SafeTxGas), + "baseGas": fmt.Sprintf("%d", txData.BaseGas), + "gasPrice": txData.GasPrice, + "gasToken": txData.GasToken, + "refundReceiver": txData.RefundReceiver, + "nonce": fmt.Sprintf("%d", txData.Nonce), + }, + } + + typedDataHash, _, err := apitypes.TypedDataAndHash(typedData) + if err != nil { + return common.Hash{}, fmt.Errorf("failed to hash typed data: %v", err) + } + + return common.BytesToHash(typedDataHash), nil +} ` // This template generates the handler for smart contract deployment. It is intended to be used with a @@ -1077,6 +1288,9 @@ func {{.DeployHandler.HandlerName}}() *cobra.Command { var gasLimit uint64 var simulate bool var timeout uint + var safeAddress, safeApi, safeCreateCall, safeSaltRaw string + var safeOperationType uint8 + var salt [32]byte {{range .DeployHandler.MethodArgs}} var {{.CLIVar}} {{.CLIType}} @@ -1091,6 +1305,60 @@ func {{.DeployHandler.HandlerName}}() *cobra.Command { return fmt.Errorf("--keystore not specified (this should be a path to an Ethereum account keystore file)") } + if rpc == "" { + return fmt.Errorf("--rpc not specified (this should be a URL to an Ethereum JSONRPC API)") + } + + if safeAddress != "" { + if !common.IsHexAddress(safeAddress) { + return fmt.Errorf("--safe is not a valid Ethereum address") + } + if safeApi == "" { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + safeApi = fmt.Sprintf("https://safe-client.safe.global/v1/chains/%s/transactions/%s/propose", chainID.String(), safeAddress) + fmt.Println("--safe-api not specified, using default (", safeApi, ")") + } + + if safeCreateCall == "" { + fmt.Println("--safe-create-call not specified, using default (0x7cbB62EaA69F79e6873cD1ecB2392971036cFAa4)") + safeCreateCall = "0x7cbB62EaA69F79e6873cD1ecB2392971036cFAa4" + } + if !common.IsHexAddress(safeCreateCall) { + return fmt.Errorf("--safe-create-call is not a valid Ethereum address") + } + + if SafeOperationType(safeOperationType).String() == "Unknown" { + return fmt.Errorf("--safe-operation must be 0 (Call) or 1 (DelegateCall)") + } + + if safeSaltRaw == "" { + fmt.Println("--safe-salt not specified, generating random salt") + _, err := rand.Read(salt[:]) + if err != nil { + return fmt.Errorf("failed to generate random salt: %v", err) + } + // prompt user to accept random salt + fmt.Println("Generated salt:", common.Bytes2Hex(salt[:])) + fmt.Println("Please check the salt and confirm (y/n)") + var confirm string + fmt.Scanln(&confirm) + if confirm != "y" && confirm != "Y" && confirm != "\n" && confirm != "" { + return fmt.Errorf("salt not accepted, please specify a valid salt") + } + } else { + copy(salt[:], safeSaltRaw) + } + } + {{range .DeployHandler.MethodArgs}} {{.PreRunE}} {{- end}} @@ -1122,6 +1390,31 @@ func {{.DeployHandler.HandlerName}}() *cobra.Command { SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) + if safeAddress != "" { + // Generate deploy bytecode with constructor arguments + deployBytecode, err := generate{{.StructName}}DeployBytecode( + {{- range .DeployHandler.MethodArgs}} + {{.CLIVar}}, + {{- end}} + ) + if err != nil { + return fmt.Errorf("failed to generate deploy bytecode: %v", err) + } + + // Create Safe proposal for deployment + value := transactionOpts.Value + if value == nil { + value = big.NewInt(0) + } + + err = DeployWithSafe(client, key, common.HexToAddress(safeAddress), common.HexToAddress(safeCreateCall), value, safeApi, deployBytecode, SafeOperationType(safeOperationType), salt) + if err != nil { + return fmt.Errorf("failed to create Safe proposal: %v", err) + } + + return nil + } + address, deploymentTransaction, _, deploymentErr := {{.DeployHandler.MethodName}}( transactionOpts, client, @@ -1175,13 +1468,41 @@ func {{.DeployHandler.HandlerName}}() *cobra.Command { cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") - + cmd.Flags().StringVar(&safeAddress, "safe", "", "Address of the Safe contract") + cmd.Flags().StringVar(&safeApi, "safe-api", "", "Safe API for the Safe Transaction Service (optional)") + cmd.Flags().StringVar(&safeCreateCall, "safe-create-call", "", "Address of the CreateCall contract (optional)") + cmd.Flags().Uint8Var(&safeOperationType, "safe-operation", 1, "Safe operation type: 0 (Call) or 1 (DelegateCall) - default is 1") + cmd.Flags().StringVar(&safeSaltRaw, "safe-salt", "", "Salt to use for the Safe transaction") + {{range .DeployHandler.MethodArgs}} cmd.Flags().{{.Flag}} {{- end}} return cmd } + +func generate{{.StructName}}DeployBytecode( + {{- range .DeployHandler.MethodArgs}} + {{.CLIVar}} {{.CLIType}}, + {{- end}} +) ([]byte, error) { + abiPacked, err := {{.StructName}}MetaData.GetAbi() + if err != nil { + return nil, fmt.Errorf("failed to get ABI: %v", err) + } + + constructorArguments, err := abiPacked.Pack("", + {{- range .DeployHandler.MethodArgs}} + {{.CLIVar}}, + {{- end}} + ) + if err != nil { + return nil, fmt.Errorf("failed to pack constructor arguments: %v", err) + } + + deployBytecode := append(common.FromHex({{.StructName}}MetaData.Bin), constructorArguments...) + return deployBytecode, nil +} {{end}} ` @@ -1281,131 +1602,189 @@ func {{.HandlerName}}() *cobra.Command { var TransactMethodCommandsTemplate string = `{{$structName := .StructName}} {{range .TransactHandlers}} func {{.HandlerName}}() *cobra.Command { - var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw string - var gasLimit uint64 - var simulate bool - var timeout uint - var contractAddress common.Address - - {{range .MethodArgs}} - var {{.CLIVar}} {{.CLIType}} - {{if (ne .CLIRawVar .CLIVar)}}var {{.CLIRawVar}} {{.CLIRawType}}{{end}} - {{- end}} - - cmd := &cobra.Command{ - Use: "{{(KebabCase .MethodName)}}", - Short: "Execute the {{.MethodName}} method on a {{$structName}} contract", - PreRunE: func(cmd *cobra.Command, args []string) error { - if keyfile == "" { - return fmt.Errorf("--keystore not specified") + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw string + var gasLimit uint64 + var simulate bool + var timeout uint + var contractAddress common.Address + var safeAddress, safeApi string + var safeOperationType uint8 + + {{range .MethodArgs}} + var {{.CLIVar}} {{.CLIType}} + {{if (ne .CLIRawVar .CLIVar)}}var {{.CLIRawVar}} {{.CLIRawType}}{{end}} + {{- end}} + + cmd := &cobra.Command{ + Use: "{{(KebabCase .MethodName)}}", + Short: "Execute the {{.MethodName}} method on a {{$structName}} contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + if keyfile == "" { + return fmt.Errorf("--keystore not specified (this should be a path to an Ethereum account keystore file)") + } + + if rpc == "" { + return fmt.Errorf("--rpc not specified (this should be a URL to an Ethereum JSONRPC API)") } - if contractAddressRaw == "" { - return fmt.Errorf("--contract not specified") - } else if !common.IsHexAddress(contractAddressRaw) { - return fmt.Errorf("--contract is not a valid Ethereum address") - } - contractAddress = common.HexToAddress(contractAddressRaw) - - {{range .MethodArgs}} - {{.PreRunE}} - {{- end}} - - return nil - }, - RunE: func(cmd *cobra.Command, args []string) error { - client, clientErr := NewClient(rpc) - if clientErr != nil { - return clientErr - } - - key, keyErr := KeyFromFile(keyfile, password) - if keyErr != nil { - return keyErr - } - - chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) - defer cancelChainIDCtx() - chainID, chainIDErr := client.ChainID(chainIDCtx) - if chainIDErr != nil { - return chainIDErr - } - - transactionOpts, transactionOptsErr := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID) - if transactionOptsErr != nil { - return transactionOptsErr - } - - SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) - - contract, contractErr := New{{$structName}}(contractAddress, client) - if contractErr != nil { - return contractErr - } - - session := {{$structName}}TransactorSession{ - Contract: &contract.{{$structName}}Transactor, - TransactOpts: *transactionOpts, - } - - transaction, transactionErr := session.{{.MethodName}}( - {{- range .MethodArgs}} - {{.CLIVar}}, - {{- end}} - ) - if transactionErr != nil { - return transactionErr - } - - cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) - if transactionOpts.NoSend { - estimationMessage := ethereum.CallMsg{ - From: transactionOpts.From, - To: &contractAddress, - Data: transaction.Data(), + if safeAddress != "" { + if !common.IsHexAddress(safeAddress) { + return fmt.Errorf("--safe is not a valid Ethereum address") + } + if safeApi == "" { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + safeApi = fmt.Sprintf("https://safe-client.safe.global/v1/chains/%s/transactions/%s/propose", chainID.String(), safeAddress) + fmt.Println("--safe-api not specified, using default (", safeApi, ")") } - gasEstimationCtx, cancelGasEstimationCtx := NewChainContext(timeout) - defer cancelGasEstimationCtx() - - gasEstimate, gasEstimateErr := client.EstimateGas(gasEstimationCtx, estimationMessage) - if gasEstimateErr != nil { - return gasEstimateErr + if SafeOperationType(safeOperationType).String() == "Unknown" { + return fmt.Errorf("--safe-operation must be 0 (Call) or 1 (DelegateCall)") } + } + + {{range .MethodArgs}} + {{.PreRunE}} + {{- end}} + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + key, keyErr := KeyFromFile(keyfile, password) + if keyErr != nil { + return keyErr + } + + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + + transactionOpts, transactionOptsErr := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID) + if transactionOptsErr != nil { + return transactionOptsErr + } + + SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) + + contract, contractErr := New{{$structName}}(contractAddress, client) + if contractErr != nil { + return contractErr + } + + session := {{$structName}}TransactorSession{ + Contract: &contract.{{$structName}}Transactor, + TransactOpts: *transactionOpts, + } + + if safeAddress != "" { + // Generate transaction data + transaction, err := session.{{.MethodName}}( + {{range .MethodArgs}} + {{.CLIVar}}, + {{- end}} + ) - transactionBinary, transactionBinaryErr := transaction.MarshalBinary() - if transactionBinaryErr != nil { - return transactionBinaryErr + if err != nil { + return err } - transactionBinaryHex := hex.EncodeToString(transactionBinary) - - cmd.Printf("Transaction: %s\nEstimated gas: %d\n", transactionBinaryHex, gasEstimate) - } else { - cmd.Println("Transaction submitted") - } - - return nil - }, - } - - cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") - cmd.Flags().StringVar(&keyfile, "keyfile", "", "Path to the keystore file to use for the transaction") - cmd.Flags().StringVar(&password, "password", "", "Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes)") - cmd.Flags().StringVar(&nonce, "nonce", "", "Nonce to use for the transaction") - cmd.Flags().StringVar(&value, "value", "", "Value to send with the transaction") - cmd.Flags().StringVar(&gasPrice, "gas-price", "", "Gas price to use for the transaction") - cmd.Flags().StringVar(&maxFeePerGas, "max-fee-per-gas", "", "Maximum fee per gas to use for the (EIP-1559) transaction") - cmd.Flags().StringVar(&maxPriorityFeePerGas, "max-priority-fee-per-gas", "", "Maximum priority fee per gas to use for the (EIP-1559) transaction") - cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") - cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") - cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + + // Create Safe proposal for transaction + value := transactionOpts.Value + if value == nil { + value = big.NewInt(0) + } + err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, transaction.Data(), value, safeApi, SafeOperationType(safeOperationType)) + if err != nil { + return fmt.Errorf("failed to create Safe proposal: %v", err) + } + + return nil + } + + transaction, err := session.{{.MethodName}}( + {{range .MethodArgs}} + {{.CLIVar}}, + {{- end}} + ) + if err != nil { + return err + } + + cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) + if transactionOpts.NoSend { + estimationMessage := ethereum.CallMsg{ + From: transactionOpts.From, + To: &contractAddress, + Data: transaction.Data(), + } + + gasEstimationCtx, cancelGasEstimationCtx := NewChainContext(timeout) + defer cancelGasEstimationCtx() + + gasEstimate, gasEstimateErr := client.EstimateGas(gasEstimationCtx, estimationMessage) + if gasEstimateErr != nil { + return gasEstimateErr + } + + transactionBinary, transactionBinaryErr := transaction.MarshalBinary() + if transactionBinaryErr != nil { + return transactionBinaryErr + } + transactionBinaryHex := hex.EncodeToString(transactionBinary) + + cmd.Printf("Transaction: %s\nEstimated gas: %d\n", transactionBinaryHex, gasEstimate) + } else { + cmd.Println("Transaction submitted") + } + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&keyfile, "keyfile", "", "Path to the keystore file to use for the transaction") + cmd.Flags().StringVar(&password, "password", "", "Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes)") + cmd.Flags().StringVar(&nonce, "nonce", "", "Nonce to use for the transaction") + cmd.Flags().StringVar(&value, "value", "", "Value to send with the transaction") + cmd.Flags().StringVar(&gasPrice, "gas-price", "", "Gas price to use for the transaction") + cmd.Flags().StringVar(&maxFeePerGas, "max-fee-per-gas", "", "Maximum fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().StringVar(&maxPriorityFeePerGas, "max-priority-fee-per-gas", "", "Maximum priority fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") + cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&safeAddress, "safe", "", "Address of the Safe contract") + cmd.Flags().StringVar(&safeApi, "safe-api", "", "Safe API for the Safe Transaction Service (optional)") + cmd.Flags().Uint8Var(&safeOperationType, "safe-operation", 0, "Safe operation type: 0 (Call) or 1 (DelegateCall)") - {{range .MethodArgs}} - cmd.Flags().{{.Flag}} - {{- end}} + {{range .MethodArgs}} + cmd.Flags().{{.Flag}} + {{- end}} - return cmd + return cmd } {{- end}} ` diff --git a/examples/ownable-erc-721/OwnableERC721.go b/examples/ownable-erc-721/OwnableERC721.go index 7dd4604..6e0151f 100644 --- a/examples/ownable-erc-721/OwnableERC721.go +++ b/examples/ownable-erc-721/OwnableERC721.go @@ -1,5 +1,5 @@ // This file was generated by seer: https://github.com/moonstream-to/seer. -// seer version: 0.1.19 +// seer version: 0.2.0 // seer command: seer evm generate --package main --cli --includemain --abi fixtures/OwnableERC721.json --bytecode fixtures/OwnableERC721.bin --struct OwnableERC721 --output examples/ownable-erc-721/OwnableERC721.go // Code generated - DO NOT EDIT. // This file is a generated binding and any manual changes will be lost. @@ -7,8 +7,10 @@ package main import ( + "bytes" "errors" "math/big" + "net/http" "strings" "context" @@ -19,17 +21,25 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/event" + "github.com/ethereum/go-ethereum/signer/core/apitypes" // Reference imports to suppress errors if they are not otherwise used. "encoding/hex" + "encoding/json" "fmt" "os" "time" "github.com/ethereum/go-ethereum/accounts/keystore" "github.com/ethereum/go-ethereum/ethclient" + "github.com/moonstream-to/seer/bindings/CreateCall" + "github.com/moonstream-to/seer/bindings/GnosisSafe" "github.com/spf13/cobra" "golang.org/x/term" + + // OwnableERC721MetaData contains all meta data concerning the OwnableERC721 contract. + "github.com/ethereum/go-ethereum/common/math" + "github.com/ethereum/go-ethereum/crypto" ) var ( @@ -44,7 +54,6 @@ var ( _ = abi.ConvertType ) -// OwnableERC721MetaData contains all meta data concerning the OwnableERC721 contract. var OwnableERC721MetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name_\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol_\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"approved\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"}],\"name\":\"ApprovalForAll\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"getApproved\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"isApprovedForAll\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"ownerOf\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"safeTransferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"safeTransferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"}],\"name\":\"setApprovalForAll\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"tokenURI\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", Bin: "0x60806040523480156200001157600080fd5b50604051620019fe380380620019fe833981016040819052620000349162000332565b8251839083906200004d906000906020850190620001bf565b50805162000063906001906020840190620001bf565b505050620000806200007a6200009460201b60201c565b62000098565b6200008b81620000ea565b505050620003fc565b3390565b600680546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6006546001600160a01b031633146200014a5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064015b60405180910390fd5b6001600160a01b038116620001b15760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840162000141565b620001bc8162000098565b50565b828054620001cd90620003bf565b90600052602060002090601f016020900481019282620001f157600085556200023c565b82601f106200020c57805160ff19168380011785556200023c565b828001600101855582156200023c579182015b828111156200023c5782518255916020019190600101906200021f565b506200024a9291506200024e565b5090565b5b808211156200024a57600081556001016200024f565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200028d57600080fd5b81516001600160401b0380821115620002aa57620002aa62000265565b604051601f8301601f19908116603f01168101908282118183101715620002d557620002d562000265565b81604052838152602092508683858801011115620002f257600080fd5b600091505b83821015620003165785820183015181830184015290820190620002f7565b83821115620003285760008385830101525b9695505050505050565b6000806000606084860312156200034857600080fd5b83516001600160401b03808211156200036057600080fd5b6200036e878388016200027b565b945060208601519150808211156200038557600080fd5b5062000394868287016200027b565b604086015190935090506001600160a01b0381168114620003b457600080fd5b809150509250925092565b600181811c90821680620003d457607f821691505b60208210811415620003f657634e487b7160e01b600052602260045260246000fd5b50919050565b6115f2806200040c6000396000f3fe608060405234801561001057600080fd5b506004361061010b5760003560e01c806370a08231116100a2578063a22cb46511610071578063a22cb4651461021b578063b88d4fde1461022e578063c87b56dd14610241578063e985e9c514610254578063f2fde38b1461029057600080fd5b806370a08231146101d9578063715018a6146101fa5780638da5cb5b1461020257806395d89b411461021357600080fd5b806323b872dd116100de57806323b872dd1461018d57806340c10f19146101a057806342842e0e146101b35780636352211e146101c657600080fd5b806301ffc9a71461011057806306fdde0314610138578063081812fc1461014d578063095ea7b314610178575b600080fd5b61012361011e3660046110cd565b6102a3565b60405190151581526020015b60405180910390f35b6101406102f5565b60405161012f9190611142565b61016061015b366004611155565b610387565b6040516001600160a01b03909116815260200161012f565b61018b61018636600461118a565b610421565b005b61018b61019b3660046111b4565b610537565b61018b6101ae36600461118a565b610568565b61018b6101c13660046111b4565b6105a0565b6101606101d4366004611155565b6105bb565b6101ec6101e73660046111f0565b610632565b60405190815260200161012f565b61018b6106b9565b6006546001600160a01b0316610160565b6101406106ef565b61018b61022936600461120b565b6106fe565b61018b61023c36600461125d565b610709565b61014061024f366004611155565b610741565b610123610262366004611339565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b61018b61029e3660046111f0565b610829565b60006001600160e01b031982166380ac58cd60e01b14806102d457506001600160e01b03198216635b5e139f60e01b145b806102ef57506301ffc9a760e01b6001600160e01b03198316145b92915050565b6060600080546103049061136c565b80601f01602080910402602001604051908101604052809291908181526020018280546103309061136c565b801561037d5780601f106103525761010080835404028352916020019161037d565b820191906000526020600020905b81548152906001019060200180831161036057829003601f168201915b5050505050905090565b6000818152600260205260408120546001600160a01b03166104055760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b600061042c826105bb565b9050806001600160a01b0316836001600160a01b0316141561049a5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084016103fc565b336001600160a01b03821614806104b657506104b68133610262565b6105285760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c000000000000000060648201526084016103fc565b61053283836108c4565b505050565b6105413382610932565b61055d5760405162461bcd60e51b81526004016103fc906113a7565b610532838383610a29565b6006546001600160a01b031633146105925760405162461bcd60e51b81526004016103fc906113f8565b61059c8282610bc9565b5050565b61053283838360405180602001604052806000815250610709565b6000818152600260205260408120546001600160a01b0316806102ef5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b60648201526084016103fc565b60006001600160a01b03821661069d5760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b60648201526084016103fc565b506001600160a01b031660009081526003602052604090205490565b6006546001600160a01b031633146106e35760405162461bcd60e51b81526004016103fc906113f8565b6106ed6000610be3565b565b6060600180546103049061136c565b61059c338383610c35565b6107133383610932565b61072f5760405162461bcd60e51b81526004016103fc906113a7565b61073b84848484610d04565b50505050565b6000818152600260205260409020546060906001600160a01b03166107c05760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b60648201526084016103fc565b60006107d760408051602081019091526000815290565b905060008151116107f75760405180602001604052806000815250610822565b8061080184610d37565b60405160200161081292919061142d565b6040516020818303038152906040525b9392505050565b6006546001600160a01b031633146108535760405162461bcd60e51b81526004016103fc906113f8565b6001600160a01b0381166108b85760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016103fc565b6108c181610be3565b50565b600081815260046020526040902080546001600160a01b0319166001600160a01b03841690811790915581906108f9826105bb565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000818152600260205260408120546001600160a01b03166109ab5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084016103fc565b60006109b6836105bb565b9050806001600160a01b0316846001600160a01b031614806109f15750836001600160a01b03166109e684610387565b6001600160a01b0316145b80610a2157506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b949350505050565b826001600160a01b0316610a3c826105bb565b6001600160a01b031614610aa45760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b60648201526084016103fc565b6001600160a01b038216610b065760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b60648201526084016103fc565b610b116000826108c4565b6001600160a01b0383166000908152600360205260408120805460019290610b3a908490611472565b90915550506001600160a01b0382166000908152600360205260408120805460019290610b68908490611489565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b61059c828260405180602001604052806000815250610e35565b600680546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b816001600160a01b0316836001600160a01b03161415610c975760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c65720000000000000060448201526064016103fc565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b610d0f848484610a29565b610d1b84848484610e68565b61073b5760405162461bcd60e51b81526004016103fc906114a1565b606081610d5b5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115610d855780610d6f816114f3565b9150610d7e9050600a83611524565b9150610d5f565b60008167ffffffffffffffff811115610da057610da0611247565b6040519080825280601f01601f191660200182016040528015610dca576020820181803683370190505b5090505b8415610a2157610ddf600183611472565b9150610dec600a86611538565b610df7906030611489565b60f81b818381518110610e0c57610e0c61154c565b60200101906001600160f81b031916908160001a905350610e2e600a86611524565b9450610dce565b610e3f8383610f75565b610e4c6000848484610e68565b6105325760405162461bcd60e51b81526004016103fc906114a1565b60006001600160a01b0384163b15610f6a57604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290610eac903390899088908890600401611562565b602060405180830381600087803b158015610ec657600080fd5b505af1925050508015610ef6575060408051601f3d908101601f19168201909252610ef39181019061159f565b60015b610f50573d808015610f24576040519150601f19603f3d011682016040523d82523d6000602084013e610f29565b606091505b508051610f485760405162461bcd60e51b81526004016103fc906114a1565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050610a21565b506001949350505050565b6001600160a01b038216610fcb5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f206164647265737360448201526064016103fc565b6000818152600260205260409020546001600160a01b0316156110305760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000060448201526064016103fc565b6001600160a01b0382166000908152600360205260408120805460019290611059908490611489565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6001600160e01b0319811681146108c157600080fd5b6000602082840312156110df57600080fd5b8135610822816110b7565b60005b838110156111055781810151838201526020016110ed565b8381111561073b5750506000910152565b6000815180845261112e8160208601602086016110ea565b601f01601f19169290920160200192915050565b6020815260006108226020830184611116565b60006020828403121561116757600080fd5b5035919050565b80356001600160a01b038116811461118557600080fd5b919050565b6000806040838503121561119d57600080fd5b6111a68361116e565b946020939093013593505050565b6000806000606084860312156111c957600080fd5b6111d28461116e565b92506111e06020850161116e565b9150604084013590509250925092565b60006020828403121561120257600080fd5b6108228261116e565b6000806040838503121561121e57600080fd5b6112278361116e565b91506020830135801515811461123c57600080fd5b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b6000806000806080858703121561127357600080fd5b61127c8561116e565b935061128a6020860161116e565b925060408501359150606085013567ffffffffffffffff808211156112ae57600080fd5b818701915087601f8301126112c257600080fd5b8135818111156112d4576112d4611247565b604051601f8201601f19908116603f011681019083821181831017156112fc576112fc611247565b816040528281528a602084870101111561131557600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b6000806040838503121561134c57600080fd5b6113558361116e565b91506113636020840161116e565b90509250929050565b600181811c9082168061138057607f821691505b602082108114156113a157634e487b7160e01b600052602260045260246000fd5b50919050565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6000835161143f8184602088016110ea565b8351908301906114538183602088016110ea565b01949350505050565b634e487b7160e01b600052601160045260246000fd5b6000828210156114845761148461145c565b500390565b6000821982111561149c5761149c61145c565b500190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b60006000198214156115075761150761145c565b5060010190565b634e487b7160e01b600052601260045260246000fd5b6000826115335761153361150e565b500490565b6000826115475761154761150e565b500690565b634e487b7160e01b600052603260045260246000fd5b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061159590830184611116565b9695505050505050565b6000602082840312156115b157600080fd5b8151610822816110b756fea264697066735822122061bd7069fbe4cf9497a08868a69ed81fec10d620962d72d34b6772153fc0186364736f6c63430008090033", @@ -1300,6 +1309,9 @@ func CreateOwnableERC721DeploymentCommand() *cobra.Command { var gasLimit uint64 var simulate bool var timeout uint + var safeAddress, safeApi, safeCreateCall, safeSaltRaw string + var safeOperationType uint8 + var safeSalt []byte var name_0 string @@ -1316,6 +1328,47 @@ func CreateOwnableERC721DeploymentCommand() *cobra.Command { return fmt.Errorf("--keystore not specified (this should be a path to an Ethereum account keystore file)") } + if rpc == "" { + return fmt.Errorf("--rpc not specified (this should be a URL to an Ethereum JSONRPC API)") + } + + if safeAddress != "" { + if !common.IsHexAddress(safeAddress) { + return fmt.Errorf("--safe is not a valid Ethereum address") + } + if safeApi == "" { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + safeApi = fmt.Sprintf("https://safe-client.safe.global/v1/chains/%s/transactions/%s/propose", chainID.String(), safeAddress) + fmt.Println("--safe-api not specified, using default (", safeApi, ")") + } + + if safeCreateCall == "" { + fmt.Println("--safe-create-call not specified, using default (0x7cbB62EaA69F79e6873cD1ecB2392971036cFAa4)") + safeCreateCall = "0x7cbB62EaA69F79e6873cD1ecB2392971036cFAa4" + } + if !common.IsHexAddress(safeCreateCall) { + return fmt.Errorf("--safe-create-call is not a valid Ethereum address") + } + + if SafeOperationType(safeOperationType).String() == "Unknown" { + return fmt.Errorf("--safe-operation must be 0 (Call) or 1 (DelegateCall)") + } + + if safeSaltRaw == "" { + return fmt.Errorf("--safe-salt not specified") + } + safeSalt = common.Hex2Bytes(safeSaltRaw) + } + if ownerRaw == "" { return fmt.Errorf("--owner argument not specified") } else if !common.IsHexAddress(ownerRaw) { @@ -1350,6 +1403,30 @@ func CreateOwnableERC721DeploymentCommand() *cobra.Command { SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) + if safeAddress != "" { + // Generate deploy bytecode with constructor arguments + deployBytecode, err := generateOwnableERC721DeployBytecode( + name_0, + symbol, + owner, + ) + if err != nil { + return fmt.Errorf("failed to generate deploy bytecode: %v", err) + } + + // Create Safe proposal for deployment + value := transactionOpts.Value + if value == nil { + value = big.NewInt(0) + } + err = DeployWithSafe(client, key, common.HexToAddress(safeAddress), common.HexToAddress(safeCreateCall), value, safeApi, deployBytecode, SafeOperationType(safeOperationType), safeSalt) + if err != nil { + return fmt.Errorf("failed to create Safe proposal: %v", err) + } + + return nil + } + address, deploymentTransaction, _, deploymentErr := DeployOwnableERC721( transactionOpts, client, @@ -1402,6 +1479,11 @@ func CreateOwnableERC721DeploymentCommand() *cobra.Command { cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&safeAddress, "safe", "", "Address of the Safe contract") + cmd.Flags().StringVar(&safeApi, "safe-api", "", "Safe API for the Safe Transaction Service (optional)") + cmd.Flags().StringVar(&safeCreateCall, "safe-create-call", "", "Address of the CreateCall contract (optional)") + cmd.Flags().Uint8Var(&safeOperationType, "safe-operation", 1, "Safe operation type: 0 (Call) or 1 (DelegateCall) - default is 1") + cmd.Flags().StringVar(&safeSaltRaw, "safe-salt", "", "Salt to use for the Safe transaction") cmd.Flags().StringVar(&name_0, "name-0", "", "name-0 argument") cmd.Flags().StringVar(&symbol, "symbol", "", "symbol argument") @@ -1410,6 +1492,29 @@ func CreateOwnableERC721DeploymentCommand() *cobra.Command { return cmd } +func generateOwnableERC721DeployBytecode( + name_0 string, + symbol string, + owner common.Address, +) ([]byte, error) { + abiPacked, err := OwnableERC721MetaData.GetAbi() + if err != nil { + return nil, fmt.Errorf("failed to get ABI: %v", err) + } + + constructorArguments, err := abiPacked.Pack("", + name_0, + symbol, + owner, + ) + if err != nil { + return nil, fmt.Errorf("failed to pack constructor arguments: %v", err) + } + + deployBytecode := append(common.FromHex(OwnableERC721MetaData.Bin), constructorArguments...) + return deployBytecode, nil +} + func CreateBalanceOfCommand() *cobra.Command { var contractAddressRaw, rpc string var contractAddress common.Address @@ -2079,6 +2184,8 @@ func CreateApproveCommand() *cobra.Command { var simulate bool var timeout uint var contractAddress common.Address + var safeAddress, safeApi string + var safeOperationType uint8 var to0 common.Address var to0Raw string @@ -2089,10 +2196,6 @@ func CreateApproveCommand() *cobra.Command { Use: "approve", Short: "Execute the Approve method on a OwnableERC721 contract", PreRunE: func(cmd *cobra.Command, args []string) error { - if keyfile == "" { - return fmt.Errorf("--keystore not specified") - } - if contractAddressRaw == "" { return fmt.Errorf("--contract not specified") } else if !common.IsHexAddress(contractAddressRaw) { @@ -2100,6 +2203,38 @@ func CreateApproveCommand() *cobra.Command { } contractAddress = common.HexToAddress(contractAddressRaw) + if keyfile == "" { + return fmt.Errorf("--keystore not specified (this should be a path to an Ethereum account keystore file)") + } + + if rpc == "" { + return fmt.Errorf("--rpc not specified (this should be a URL to an Ethereum JSONRPC API)") + } + + if safeAddress != "" { + if !common.IsHexAddress(safeAddress) { + return fmt.Errorf("--safe is not a valid Ethereum address") + } + if safeApi == "" { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + safeApi = fmt.Sprintf("https://safe-client.safe.global/v1/chains/%s/transactions/%s/propose", chainID.String(), safeAddress) + fmt.Println("--safe-api not specified, using default (", safeApi, ")") + } + + if SafeOperationType(safeOperationType).String() == "Unknown" { + return fmt.Errorf("--safe-operation must be 0 (Call) or 1 (DelegateCall)") + } + } + if to0Raw == "" { return fmt.Errorf("--to-0 argument not specified") } else if !common.IsHexAddress(to0Raw) { @@ -2150,12 +2285,38 @@ func CreateApproveCommand() *cobra.Command { TransactOpts: *transactionOpts, } - transaction, transactionErr := session.Approve( + if safeAddress != "" { + // Generate transaction data + transaction, err := session.Approve( + + to0, + tokenId, + ) + + if err != nil { + return err + } + + // Create Safe proposal for transaction + value := transactionOpts.Value + if value == nil { + value = big.NewInt(0) + } + err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, transaction.Data(), value, safeApi, SafeOperationType(safeOperationType)) + if err != nil { + return fmt.Errorf("failed to create Safe proposal: %v", err) + } + + return nil + } + + transaction, err := session.Approve( + to0, tokenId, ) - if transactionErr != nil { - return transactionErr + if err != nil { + return err } cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) @@ -2201,6 +2362,9 @@ func CreateApproveCommand() *cobra.Command { cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&safeAddress, "safe", "", "Address of the Safe contract") + cmd.Flags().StringVar(&safeApi, "safe-api", "", "Safe API for the Safe Transaction Service (optional)") + cmd.Flags().Uint8Var(&safeOperationType, "safe-operation", 0, "Safe operation type: 0 (Call) or 1 (DelegateCall)") cmd.Flags().StringVar(&to0Raw, "to-0", "", "to-0 argument (common.Address)") cmd.Flags().StringVar(&tokenIdRaw, "token-id", "", "token-id argument") @@ -2213,6 +2377,8 @@ func CreateMintCommand() *cobra.Command { var simulate bool var timeout uint var contractAddress common.Address + var safeAddress, safeApi string + var safeOperationType uint8 var to0 common.Address var to0Raw string @@ -2223,10 +2389,6 @@ func CreateMintCommand() *cobra.Command { Use: "mint", Short: "Execute the Mint method on a OwnableERC721 contract", PreRunE: func(cmd *cobra.Command, args []string) error { - if keyfile == "" { - return fmt.Errorf("--keystore not specified") - } - if contractAddressRaw == "" { return fmt.Errorf("--contract not specified") } else if !common.IsHexAddress(contractAddressRaw) { @@ -2234,6 +2396,38 @@ func CreateMintCommand() *cobra.Command { } contractAddress = common.HexToAddress(contractAddressRaw) + if keyfile == "" { + return fmt.Errorf("--keystore not specified (this should be a path to an Ethereum account keystore file)") + } + + if rpc == "" { + return fmt.Errorf("--rpc not specified (this should be a URL to an Ethereum JSONRPC API)") + } + + if safeAddress != "" { + if !common.IsHexAddress(safeAddress) { + return fmt.Errorf("--safe is not a valid Ethereum address") + } + if safeApi == "" { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + safeApi = fmt.Sprintf("https://safe-client.safe.global/v1/chains/%s/transactions/%s/propose", chainID.String(), safeAddress) + fmt.Println("--safe-api not specified, using default (", safeApi, ")") + } + + if SafeOperationType(safeOperationType).String() == "Unknown" { + return fmt.Errorf("--safe-operation must be 0 (Call) or 1 (DelegateCall)") + } + } + if to0Raw == "" { return fmt.Errorf("--to-0 argument not specified") } else if !common.IsHexAddress(to0Raw) { @@ -2284,12 +2478,38 @@ func CreateMintCommand() *cobra.Command { TransactOpts: *transactionOpts, } - transaction, transactionErr := session.Mint( + if safeAddress != "" { + // Generate transaction data + transaction, err := session.Mint( + + to0, + tokenId, + ) + + if err != nil { + return err + } + + // Create Safe proposal for transaction + value := transactionOpts.Value + if value == nil { + value = big.NewInt(0) + } + err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, transaction.Data(), value, safeApi, SafeOperationType(safeOperationType)) + if err != nil { + return fmt.Errorf("failed to create Safe proposal: %v", err) + } + + return nil + } + + transaction, err := session.Mint( + to0, tokenId, ) - if transactionErr != nil { - return transactionErr + if err != nil { + return err } cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) @@ -2335,6 +2555,9 @@ func CreateMintCommand() *cobra.Command { cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&safeAddress, "safe", "", "Address of the Safe contract") + cmd.Flags().StringVar(&safeApi, "safe-api", "", "Safe API for the Safe Transaction Service (optional)") + cmd.Flags().Uint8Var(&safeOperationType, "safe-operation", 0, "Safe operation type: 0 (Call) or 1 (DelegateCall)") cmd.Flags().StringVar(&to0Raw, "to-0", "", "to-0 argument (common.Address)") cmd.Flags().StringVar(&tokenIdRaw, "token-id", "", "token-id argument") @@ -2347,15 +2570,13 @@ func CreateRenounceOwnershipCommand() *cobra.Command { var simulate bool var timeout uint var contractAddress common.Address + var safeAddress, safeApi string + var safeOperationType uint8 cmd := &cobra.Command{ Use: "renounce-ownership", Short: "Execute the RenounceOwnership method on a OwnableERC721 contract", PreRunE: func(cmd *cobra.Command, args []string) error { - if keyfile == "" { - return fmt.Errorf("--keystore not specified") - } - if contractAddressRaw == "" { return fmt.Errorf("--contract not specified") } else if !common.IsHexAddress(contractAddressRaw) { @@ -2363,6 +2584,38 @@ func CreateRenounceOwnershipCommand() *cobra.Command { } contractAddress = common.HexToAddress(contractAddressRaw) + if keyfile == "" { + return fmt.Errorf("--keystore not specified (this should be a path to an Ethereum account keystore file)") + } + + if rpc == "" { + return fmt.Errorf("--rpc not specified (this should be a URL to an Ethereum JSONRPC API)") + } + + if safeAddress != "" { + if !common.IsHexAddress(safeAddress) { + return fmt.Errorf("--safe is not a valid Ethereum address") + } + if safeApi == "" { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + safeApi = fmt.Sprintf("https://safe-client.safe.global/v1/chains/%s/transactions/%s/propose", chainID.String(), safeAddress) + fmt.Println("--safe-api not specified, using default (", safeApi, ")") + } + + if SafeOperationType(safeOperationType).String() == "Unknown" { + return fmt.Errorf("--safe-operation must be 0 (Call) or 1 (DelegateCall)") + } + } + return nil }, RunE: func(cmd *cobra.Command, args []string) error { @@ -2400,9 +2653,30 @@ func CreateRenounceOwnershipCommand() *cobra.Command { TransactOpts: *transactionOpts, } - transaction, transactionErr := session.RenounceOwnership() - if transactionErr != nil { - return transactionErr + if safeAddress != "" { + // Generate transaction data + transaction, err := session.RenounceOwnership() + + if err != nil { + return err + } + + // Create Safe proposal for transaction + value := transactionOpts.Value + if value == nil { + value = big.NewInt(0) + } + err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, transaction.Data(), value, safeApi, SafeOperationType(safeOperationType)) + if err != nil { + return fmt.Errorf("failed to create Safe proposal: %v", err) + } + + return nil + } + + transaction, err := session.RenounceOwnership() + if err != nil { + return err } cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) @@ -2448,6 +2722,9 @@ func CreateRenounceOwnershipCommand() *cobra.Command { cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&safeAddress, "safe", "", "Address of the Safe contract") + cmd.Flags().StringVar(&safeApi, "safe-api", "", "Safe API for the Safe Transaction Service (optional)") + cmd.Flags().Uint8Var(&safeOperationType, "safe-operation", 0, "Safe operation type: 0 (Call) or 1 (DelegateCall)") return cmd } @@ -2457,6 +2734,8 @@ func CreateSafeTransferFromCommand() *cobra.Command { var simulate bool var timeout uint var contractAddress common.Address + var safeAddress, safeApi string + var safeOperationType uint8 var from0 common.Address var from0Raw string @@ -2469,10 +2748,6 @@ func CreateSafeTransferFromCommand() *cobra.Command { Use: "safe-transfer-from", Short: "Execute the SafeTransferFrom method on a OwnableERC721 contract", PreRunE: func(cmd *cobra.Command, args []string) error { - if keyfile == "" { - return fmt.Errorf("--keystore not specified") - } - if contractAddressRaw == "" { return fmt.Errorf("--contract not specified") } else if !common.IsHexAddress(contractAddressRaw) { @@ -2480,6 +2755,38 @@ func CreateSafeTransferFromCommand() *cobra.Command { } contractAddress = common.HexToAddress(contractAddressRaw) + if keyfile == "" { + return fmt.Errorf("--keystore not specified (this should be a path to an Ethereum account keystore file)") + } + + if rpc == "" { + return fmt.Errorf("--rpc not specified (this should be a URL to an Ethereum JSONRPC API)") + } + + if safeAddress != "" { + if !common.IsHexAddress(safeAddress) { + return fmt.Errorf("--safe is not a valid Ethereum address") + } + if safeApi == "" { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + safeApi = fmt.Sprintf("https://safe-client.safe.global/v1/chains/%s/transactions/%s/propose", chainID.String(), safeAddress) + fmt.Println("--safe-api not specified, using default (", safeApi, ")") + } + + if SafeOperationType(safeOperationType).String() == "Unknown" { + return fmt.Errorf("--safe-operation must be 0 (Call) or 1 (DelegateCall)") + } + } + if from0Raw == "" { return fmt.Errorf("--from-0 argument not specified") } else if !common.IsHexAddress(from0Raw) { @@ -2537,13 +2844,40 @@ func CreateSafeTransferFromCommand() *cobra.Command { TransactOpts: *transactionOpts, } - transaction, transactionErr := session.SafeTransferFrom( + if safeAddress != "" { + // Generate transaction data + transaction, err := session.SafeTransferFrom( + + from0, + to0, + tokenId, + ) + + if err != nil { + return err + } + + // Create Safe proposal for transaction + value := transactionOpts.Value + if value == nil { + value = big.NewInt(0) + } + err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, transaction.Data(), value, safeApi, SafeOperationType(safeOperationType)) + if err != nil { + return fmt.Errorf("failed to create Safe proposal: %v", err) + } + + return nil + } + + transaction, err := session.SafeTransferFrom( + from0, to0, tokenId, ) - if transactionErr != nil { - return transactionErr + if err != nil { + return err } cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) @@ -2589,6 +2923,9 @@ func CreateSafeTransferFromCommand() *cobra.Command { cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&safeAddress, "safe", "", "Address of the Safe contract") + cmd.Flags().StringVar(&safeApi, "safe-api", "", "Safe API for the Safe Transaction Service (optional)") + cmd.Flags().Uint8Var(&safeOperationType, "safe-operation", 0, "Safe operation type: 0 (Call) or 1 (DelegateCall)") cmd.Flags().StringVar(&from0Raw, "from-0", "", "from-0 argument (common.Address)") cmd.Flags().StringVar(&to0Raw, "to-0", "", "to-0 argument (common.Address)") @@ -2602,6 +2939,8 @@ func CreateSafeTransferFrom0Command() *cobra.Command { var simulate bool var timeout uint var contractAddress common.Address + var safeAddress, safeApi string + var safeOperationType uint8 var from0 common.Address var from0Raw string @@ -2616,10 +2955,6 @@ func CreateSafeTransferFrom0Command() *cobra.Command { Use: "safe-transfer-from-0", Short: "Execute the SafeTransferFrom0 method on a OwnableERC721 contract", PreRunE: func(cmd *cobra.Command, args []string) error { - if keyfile == "" { - return fmt.Errorf("--keystore not specified") - } - if contractAddressRaw == "" { return fmt.Errorf("--contract not specified") } else if !common.IsHexAddress(contractAddressRaw) { @@ -2627,6 +2962,38 @@ func CreateSafeTransferFrom0Command() *cobra.Command { } contractAddress = common.HexToAddress(contractAddressRaw) + if keyfile == "" { + return fmt.Errorf("--keystore not specified (this should be a path to an Ethereum account keystore file)") + } + + if rpc == "" { + return fmt.Errorf("--rpc not specified (this should be a URL to an Ethereum JSONRPC API)") + } + + if safeAddress != "" { + if !common.IsHexAddress(safeAddress) { + return fmt.Errorf("--safe is not a valid Ethereum address") + } + if safeApi == "" { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + safeApi = fmt.Sprintf("https://safe-client.safe.global/v1/chains/%s/transactions/%s/propose", chainID.String(), safeAddress) + fmt.Println("--safe-api not specified, using default (", safeApi, ")") + } + + if SafeOperationType(safeOperationType).String() == "Unknown" { + return fmt.Errorf("--safe-operation must be 0 (Call) or 1 (DelegateCall)") + } + } + if from0Raw == "" { return fmt.Errorf("--from-0 argument not specified") } else if !common.IsHexAddress(from0Raw) { @@ -2694,14 +3061,42 @@ func CreateSafeTransferFrom0Command() *cobra.Command { TransactOpts: *transactionOpts, } - transaction, transactionErr := session.SafeTransferFrom0( + if safeAddress != "" { + // Generate transaction data + transaction, err := session.SafeTransferFrom0( + + from0, + to0, + tokenId, + data, + ) + + if err != nil { + return err + } + + // Create Safe proposal for transaction + value := transactionOpts.Value + if value == nil { + value = big.NewInt(0) + } + err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, transaction.Data(), value, safeApi, SafeOperationType(safeOperationType)) + if err != nil { + return fmt.Errorf("failed to create Safe proposal: %v", err) + } + + return nil + } + + transaction, err := session.SafeTransferFrom0( + from0, to0, tokenId, data, ) - if transactionErr != nil { - return transactionErr + if err != nil { + return err } cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) @@ -2747,6 +3142,9 @@ func CreateSafeTransferFrom0Command() *cobra.Command { cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&safeAddress, "safe", "", "Address of the Safe contract") + cmd.Flags().StringVar(&safeApi, "safe-api", "", "Safe API for the Safe Transaction Service (optional)") + cmd.Flags().Uint8Var(&safeOperationType, "safe-operation", 0, "Safe operation type: 0 (Call) or 1 (DelegateCall)") cmd.Flags().StringVar(&from0Raw, "from-0", "", "from-0 argument (common.Address)") cmd.Flags().StringVar(&to0Raw, "to-0", "", "to-0 argument (common.Address)") @@ -2761,6 +3159,8 @@ func CreateSetApprovalForAllCommand() *cobra.Command { var simulate bool var timeout uint var contractAddress common.Address + var safeAddress, safeApi string + var safeOperationType uint8 var operator common.Address var operatorRaw string @@ -2771,10 +3171,6 @@ func CreateSetApprovalForAllCommand() *cobra.Command { Use: "set-approval-for-all", Short: "Execute the SetApprovalForAll method on a OwnableERC721 contract", PreRunE: func(cmd *cobra.Command, args []string) error { - if keyfile == "" { - return fmt.Errorf("--keystore not specified") - } - if contractAddressRaw == "" { return fmt.Errorf("--contract not specified") } else if !common.IsHexAddress(contractAddressRaw) { @@ -2782,6 +3178,38 @@ func CreateSetApprovalForAllCommand() *cobra.Command { } contractAddress = common.HexToAddress(contractAddressRaw) + if keyfile == "" { + return fmt.Errorf("--keystore not specified (this should be a path to an Ethereum account keystore file)") + } + + if rpc == "" { + return fmt.Errorf("--rpc not specified (this should be a URL to an Ethereum JSONRPC API)") + } + + if safeAddress != "" { + if !common.IsHexAddress(safeAddress) { + return fmt.Errorf("--safe is not a valid Ethereum address") + } + if safeApi == "" { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + safeApi = fmt.Sprintf("https://safe-client.safe.global/v1/chains/%s/transactions/%s/propose", chainID.String(), safeAddress) + fmt.Println("--safe-api not specified, using default (", safeApi, ")") + } + + if SafeOperationType(safeOperationType).String() == "Unknown" { + return fmt.Errorf("--safe-operation must be 0 (Call) or 1 (DelegateCall)") + } + } + if operatorRaw == "" { return fmt.Errorf("--operator argument not specified") } else if !common.IsHexAddress(operatorRaw) { @@ -2836,12 +3264,38 @@ func CreateSetApprovalForAllCommand() *cobra.Command { TransactOpts: *transactionOpts, } - transaction, transactionErr := session.SetApprovalForAll( + if safeAddress != "" { + // Generate transaction data + transaction, err := session.SetApprovalForAll( + + operator, + approved, + ) + + if err != nil { + return err + } + + // Create Safe proposal for transaction + value := transactionOpts.Value + if value == nil { + value = big.NewInt(0) + } + err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, transaction.Data(), value, safeApi, SafeOperationType(safeOperationType)) + if err != nil { + return fmt.Errorf("failed to create Safe proposal: %v", err) + } + + return nil + } + + transaction, err := session.SetApprovalForAll( + operator, approved, ) - if transactionErr != nil { - return transactionErr + if err != nil { + return err } cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) @@ -2887,6 +3341,9 @@ func CreateSetApprovalForAllCommand() *cobra.Command { cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&safeAddress, "safe", "", "Address of the Safe contract") + cmd.Flags().StringVar(&safeApi, "safe-api", "", "Safe API for the Safe Transaction Service (optional)") + cmd.Flags().Uint8Var(&safeOperationType, "safe-operation", 0, "Safe operation type: 0 (Call) or 1 (DelegateCall)") cmd.Flags().StringVar(&operatorRaw, "operator", "", "operator argument (common.Address)") cmd.Flags().StringVar(&approvedRaw, "approved", "", "approved argument (true, t, y, yes, 1 OR false, f, n, no, 0)") @@ -2899,6 +3356,8 @@ func CreateTransferFromCommand() *cobra.Command { var simulate bool var timeout uint var contractAddress common.Address + var safeAddress, safeApi string + var safeOperationType uint8 var from0 common.Address var from0Raw string @@ -2911,10 +3370,6 @@ func CreateTransferFromCommand() *cobra.Command { Use: "transfer-from", Short: "Execute the TransferFrom method on a OwnableERC721 contract", PreRunE: func(cmd *cobra.Command, args []string) error { - if keyfile == "" { - return fmt.Errorf("--keystore not specified") - } - if contractAddressRaw == "" { return fmt.Errorf("--contract not specified") } else if !common.IsHexAddress(contractAddressRaw) { @@ -2922,6 +3377,38 @@ func CreateTransferFromCommand() *cobra.Command { } contractAddress = common.HexToAddress(contractAddressRaw) + if keyfile == "" { + return fmt.Errorf("--keystore not specified (this should be a path to an Ethereum account keystore file)") + } + + if rpc == "" { + return fmt.Errorf("--rpc not specified (this should be a URL to an Ethereum JSONRPC API)") + } + + if safeAddress != "" { + if !common.IsHexAddress(safeAddress) { + return fmt.Errorf("--safe is not a valid Ethereum address") + } + if safeApi == "" { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + safeApi = fmt.Sprintf("https://safe-client.safe.global/v1/chains/%s/transactions/%s/propose", chainID.String(), safeAddress) + fmt.Println("--safe-api not specified, using default (", safeApi, ")") + } + + if SafeOperationType(safeOperationType).String() == "Unknown" { + return fmt.Errorf("--safe-operation must be 0 (Call) or 1 (DelegateCall)") + } + } + if from0Raw == "" { return fmt.Errorf("--from-0 argument not specified") } else if !common.IsHexAddress(from0Raw) { @@ -2979,13 +3466,40 @@ func CreateTransferFromCommand() *cobra.Command { TransactOpts: *transactionOpts, } - transaction, transactionErr := session.TransferFrom( + if safeAddress != "" { + // Generate transaction data + transaction, err := session.TransferFrom( + + from0, + to0, + tokenId, + ) + + if err != nil { + return err + } + + // Create Safe proposal for transaction + value := transactionOpts.Value + if value == nil { + value = big.NewInt(0) + } + err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, transaction.Data(), value, safeApi, SafeOperationType(safeOperationType)) + if err != nil { + return fmt.Errorf("failed to create Safe proposal: %v", err) + } + + return nil + } + + transaction, err := session.TransferFrom( + from0, to0, tokenId, ) - if transactionErr != nil { - return transactionErr + if err != nil { + return err } cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) @@ -3031,6 +3545,9 @@ func CreateTransferFromCommand() *cobra.Command { cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&safeAddress, "safe", "", "Address of the Safe contract") + cmd.Flags().StringVar(&safeApi, "safe-api", "", "Safe API for the Safe Transaction Service (optional)") + cmd.Flags().Uint8Var(&safeOperationType, "safe-operation", 0, "Safe operation type: 0 (Call) or 1 (DelegateCall)") cmd.Flags().StringVar(&from0Raw, "from-0", "", "from-0 argument (common.Address)") cmd.Flags().StringVar(&to0Raw, "to-0", "", "to-0 argument (common.Address)") @@ -3044,6 +3561,8 @@ func CreateTransferOwnershipCommand() *cobra.Command { var simulate bool var timeout uint var contractAddress common.Address + var safeAddress, safeApi string + var safeOperationType uint8 var newOwner common.Address var newOwnerRaw string @@ -3052,10 +3571,6 @@ func CreateTransferOwnershipCommand() *cobra.Command { Use: "transfer-ownership", Short: "Execute the TransferOwnership method on a OwnableERC721 contract", PreRunE: func(cmd *cobra.Command, args []string) error { - if keyfile == "" { - return fmt.Errorf("--keystore not specified") - } - if contractAddressRaw == "" { return fmt.Errorf("--contract not specified") } else if !common.IsHexAddress(contractAddressRaw) { @@ -3063,6 +3578,38 @@ func CreateTransferOwnershipCommand() *cobra.Command { } contractAddress = common.HexToAddress(contractAddressRaw) + if keyfile == "" { + return fmt.Errorf("--keystore not specified (this should be a path to an Ethereum account keystore file)") + } + + if rpc == "" { + return fmt.Errorf("--rpc not specified (this should be a URL to an Ethereum JSONRPC API)") + } + + if safeAddress != "" { + if !common.IsHexAddress(safeAddress) { + return fmt.Errorf("--safe is not a valid Ethereum address") + } + if safeApi == "" { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + safeApi = fmt.Sprintf("https://safe-client.safe.global/v1/chains/%s/transactions/%s/propose", chainID.String(), safeAddress) + fmt.Println("--safe-api not specified, using default (", safeApi, ")") + } + + if SafeOperationType(safeOperationType).String() == "Unknown" { + return fmt.Errorf("--safe-operation must be 0 (Call) or 1 (DelegateCall)") + } + } + if newOwnerRaw == "" { return fmt.Errorf("--new-owner argument not specified") } else if !common.IsHexAddress(newOwnerRaw) { @@ -3107,11 +3654,36 @@ func CreateTransferOwnershipCommand() *cobra.Command { TransactOpts: *transactionOpts, } - transaction, transactionErr := session.TransferOwnership( + if safeAddress != "" { + // Generate transaction data + transaction, err := session.TransferOwnership( + + newOwner, + ) + + if err != nil { + return err + } + + // Create Safe proposal for transaction + value := transactionOpts.Value + if value == nil { + value = big.NewInt(0) + } + err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, transaction.Data(), value, safeApi, SafeOperationType(safeOperationType)) + if err != nil { + return fmt.Errorf("failed to create Safe proposal: %v", err) + } + + return nil + } + + transaction, err := session.TransferOwnership( + newOwner, ) - if transactionErr != nil { - return transactionErr + if err != nil { + return err } cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) @@ -3157,6 +3729,9 @@ func CreateTransferOwnershipCommand() *cobra.Command { cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&safeAddress, "safe", "", "Address of the Safe contract") + cmd.Flags().StringVar(&safeApi, "safe-api", "", "Safe API for the Safe Transaction Service (optional)") + cmd.Flags().Uint8Var(&safeOperationType, "safe-operation", 0, "Safe operation type: 0 (Call) or 1 (DelegateCall)") cmd.Flags().StringVar(&newOwnerRaw, "new-owner", "", "new-owner argument (common.Address)") @@ -3353,6 +3928,207 @@ func CreateOwnableERC721Command() *cobra.Command { return cmd } +// SafeOperationType represents the type of operation for a Safe transaction +type SafeOperationType uint8 + +const ( + Call SafeOperationType = 0 + DelegateCall SafeOperationType = 1 +) + +// String returns the string representation of the SafeOperationType +func (o SafeOperationType) String() string { + switch o { + case Call: + return "Call" + case DelegateCall: + return "DelegateCall" + default: + return "Unknown" + } +} + +// SafeTransactionData represents the data for a Safe transaction +type SafeTransactionData struct { + To string `json:"to"` + Value string `json:"value"` + Data string `json:"data"` + Operation SafeOperationType `json:"operation"` + SafeTxGas uint64 `json:"safeTxGas"` + BaseGas uint64 `json:"baseGas"` + GasPrice string `json:"gasPrice"` + GasToken string `json:"gasToken"` + RefundReceiver string `json:"refundReceiver"` + Nonce uint64 `json:"nonce"` + SafeTxHash string `json:"safeTxHash"` + Sender string `json:"sender"` + Signature string `json:"signature"` + Origin string `json:"origin"` +} + +const ( + NativeTokenAddress = "0x0000000000000000000000000000000000000000" +) + +func DeployWithSafe(client *ethclient.Client, key *keystore.Key, safeAddress common.Address, factoryAddress common.Address, value *big.Int, safeApi string, deployBytecode []byte, safeOperationType SafeOperationType, salt []byte) error { + abi, err := CreateCall.CreateCallMetaData.GetAbi() + if err != nil { + return fmt.Errorf("failed to get ABI: %v", err) + } + + safeCreateCallTxData, err := abi.Pack("performCreate2", value, deployBytecode, salt) + if err != nil { + return fmt.Errorf("failed to pack performCreate2 transaction: %v", err) + } + + return CreateSafeProposal(client, key, safeAddress, factoryAddress, safeCreateCallTxData, value, safeApi, SafeOperationType(safeOperationType)) +} + +func CreateSafeProposal(client *ethclient.Client, key *keystore.Key, safeAddress common.Address, to common.Address, data []byte, value *big.Int, safeApi string, safeOperationType SafeOperationType) error { + chainID, err := client.ChainID(context.Background()) + if err != nil { + return fmt.Errorf("failed to get chain ID: %v", err) + } + + // Create a new instance of the GnosisSafe contract + safeInstance, err := GnosisSafe.NewGnosisSafe(safeAddress, client) + if err != nil { + return fmt.Errorf("failed to create GnosisSafe instance: %v", err) + } + + // Fetch the current nonce from the Safe contract + nonce, err := safeInstance.Nonce(&bind.CallOpts{}) + if err != nil { + return fmt.Errorf("failed to fetch nonce from Safe contract: %v", err) + } + + safeTransactionData := SafeTransactionData{ + To: to.Hex(), + Value: value.String(), + Data: common.Bytes2Hex(data), + Operation: safeOperationType, + SafeTxGas: 0, + BaseGas: 0, + GasPrice: "0", + GasToken: NativeTokenAddress, + RefundReceiver: NativeTokenAddress, + Nonce: nonce.Uint64(), + } + + // Calculate SafeTxHash + safeTxHash, err := CalculateSafeTxHash(safeAddress, safeTransactionData, chainID) + if err != nil { + return fmt.Errorf("failed to calculate SafeTxHash: %v", err) + } + + // Sign the SafeTxHash + signature, err := crypto.Sign(safeTxHash.Bytes(), key.PrivateKey) + if err != nil { + return fmt.Errorf("failed to sign SafeTxHash: %v", err) + } + + // Adjust V value for Ethereum's replay protection + signature[64] += 27 + + // Convert signature to hex + senderSignature := "0x" + common.Bytes2Hex(signature) + + // Prepare the request body + requestBody := map[string]interface{}{ + "to": safeTransactionData.To, + "value": safeTransactionData.Value, + "data": "0x" + safeTransactionData.Data, + "operation": int(safeTransactionData.Operation), + "safeTxGas": fmt.Sprintf("%d", safeTransactionData.SafeTxGas), + "baseGas": fmt.Sprintf("%d", safeTransactionData.BaseGas), + "gasPrice": safeTransactionData.GasPrice, + "gasToken": safeTransactionData.GasToken, + "refundReceiver": safeTransactionData.RefundReceiver, + "nonce": fmt.Sprintf("%d", safeTransactionData.Nonce), + "safeTxHash": safeTxHash.Hex(), + "sender": key.Address.Hex(), + "signature": senderSignature, + "origin": fmt.Sprintf("{\"url\":\"%s\",\"name\":\"TokenSender Deployment\"}", safeApi), + } + + // Marshal the request body to JSON + jsonBody, err := json.Marshal(requestBody) + if err != nil { + return fmt.Errorf("failed to marshal request body: %v", err) + } + + // Send the request to the Safe Transaction Service + req, err := http.NewRequest("POST", safeApi, bytes.NewBuffer(jsonBody)) + if err != nil { + return fmt.Errorf("failed to create request: %v", err) + } + + req.Header.Set("Content-Type", "application/json") + + httpClient := &http.Client{} + resp, err := httpClient.Do(req) + if err != nil { + return fmt.Errorf("failed to send request: %v", err) + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusCreated { + return fmt.Errorf("unexpected status code: %d", resp.StatusCode) + } + + fmt.Println("Safe proposal created successfully") + return nil +} + +func CalculateSafeTxHash(safeAddress common.Address, txData SafeTransactionData, chainID *big.Int) (common.Hash, error) { + domainSeparator := apitypes.TypedDataDomain{ + ChainId: (*math.HexOrDecimal256)(chainID), + VerifyingContract: safeAddress.Hex(), + } + + typedData := apitypes.TypedData{ + Types: apitypes.Types{ + "EIP712Domain": []apitypes.Type{ + {Name: "chainId", Type: "uint256"}, + {Name: "verifyingContract", Type: "address"}, + }, + "SafeTx": []apitypes.Type{ + {Name: "to", Type: "address"}, + {Name: "value", Type: "uint256"}, + {Name: "data", Type: "bytes"}, + {Name: "operation", Type: "uint8"}, + {Name: "safeTxGas", Type: "uint256"}, + {Name: "baseGas", Type: "uint256"}, + {Name: "gasPrice", Type: "uint256"}, + {Name: "gasToken", Type: "address"}, + {Name: "refundReceiver", Type: "address"}, + {Name: "nonce", Type: "uint256"}, + }, + }, + Domain: domainSeparator, + PrimaryType: "SafeTx", + Message: apitypes.TypedDataMessage{ + "to": txData.To, + "value": txData.Value, + "data": "0x" + txData.Data, + "operation": fmt.Sprintf("%d", txData.Operation), + "safeTxGas": fmt.Sprintf("%d", txData.SafeTxGas), + "baseGas": fmt.Sprintf("%d", txData.BaseGas), + "gasPrice": txData.GasPrice, + "gasToken": txData.GasToken, + "refundReceiver": txData.RefundReceiver, + "nonce": fmt.Sprintf("%d", txData.Nonce), + }, + } + + typedDataHash, _, err := apitypes.TypedDataAndHash(typedData) + if err != nil { + return common.Hash{}, fmt.Errorf("failed to hash typed data: %v", err) + } + + return common.BytesToHash(typedDataHash), nil +} + func main() { command := CreateOwnableERC721Command() err := command.Execute() diff --git a/go.mod b/go.mod index 0c7c138..5adb2c5 100644 --- a/go.mod +++ b/go.mod @@ -1,20 +1,22 @@ module github.com/moonstream-to/seer -go 1.21 +go 1.22.0 + +toolchain go1.22.2 require ( cloud.google.com/go/storage v1.39.1 github.com/aws/aws-sdk-go v1.51.4 - github.com/ethereum/go-ethereum v1.13.11 + github.com/ethereum/go-ethereum v1.14.10 github.com/google/uuid v1.6.0 github.com/iancoleman/strcase v0.3.0 github.com/jackc/pgx/v5 v5.5.3 github.com/spf13/cobra v1.8.0 - golang.org/x/crypto v0.20.0 - golang.org/x/term v0.17.0 - golang.org/x/tools v0.15.0 + golang.org/x/crypto v0.23.0 + golang.org/x/term v0.20.0 + golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d google.golang.org/api v0.167.0 - google.golang.org/protobuf v1.34.1 + google.golang.org/protobuf v1.34.2 ) require ( @@ -22,16 +24,18 @@ require ( cloud.google.com/go/compute v1.24.0 // indirect cloud.google.com/go/compute/metadata v0.2.3 // indirect cloud.google.com/go/iam v1.1.6 // indirect - github.com/Microsoft/go-winio v0.6.1 // indirect + github.com/Microsoft/go-winio v0.6.2 // indirect github.com/StackExchange/wmi v1.2.1 // indirect - github.com/bits-and-blooms/bitset v1.10.0 // indirect - github.com/btcsuite/btcd/btcec/v2 v2.2.0 // indirect + github.com/bits-and-blooms/bitset v1.13.0 // indirect + github.com/btcsuite/btcd/btcec/v2 v2.3.4 // indirect github.com/consensys/bavard v0.1.13 // indirect github.com/consensys/gnark-crypto v0.12.1 // indirect - github.com/crate-crypto/go-kzg-4844 v0.7.0 // indirect - github.com/deckarep/golang-set/v2 v2.1.0 // indirect + github.com/crate-crypto/go-ipa v0.0.0-20240223125850-b1e8a79f509c // indirect + github.com/crate-crypto/go-kzg-4844 v1.0.0 // indirect + github.com/deckarep/golang-set/v2 v2.6.0 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect - github.com/ethereum/c-kzg-4844 v0.4.0 // indirect + github.com/ethereum/c-kzg-4844 v1.0.0 // indirect + github.com/ethereum/go-verkle v0.1.1-0.20240829091221-dffa7562dbe9 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/go-logr/logr v1.4.1 // indirect @@ -43,7 +47,7 @@ require ( github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect github.com/googleapis/gax-go/v2 v2.12.2 // indirect github.com/gorilla/websocket v1.4.2 // indirect - github.com/holiman/uint256 v1.2.4 // indirect + github.com/holiman/uint256 v1.3.1 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9 // indirect @@ -52,7 +56,7 @@ require ( github.com/mmcloughlin/addchain v0.4.0 // indirect github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/supranational/blst v0.3.11 // indirect + github.com/supranational/blst v0.3.13 // indirect github.com/tklauser/go-sysconf v0.3.12 // indirect github.com/tklauser/numcpus v0.6.1 // indirect go.opencensus.io v0.24.0 // indirect @@ -62,12 +66,12 @@ require ( go.opentelemetry.io/otel/metric v1.23.0 // indirect go.opentelemetry.io/otel/trace v1.23.0 // indirect golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa // indirect - golang.org/x/mod v0.14.0 // indirect - golang.org/x/net v0.21.0 // indirect + golang.org/x/mod v0.17.0 // indirect + golang.org/x/net v0.25.0 // indirect golang.org/x/oauth2 v0.17.0 // indirect - golang.org/x/sync v0.6.0 // indirect - golang.org/x/sys v0.17.0 // indirect - golang.org/x/text v0.14.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.25.0 // indirect + golang.org/x/text v0.18.0 // indirect golang.org/x/time v0.5.0 // indirect google.golang.org/appengine v1.6.8 // indirect google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 // indirect diff --git a/go.sum b/go.sum index 0ad15c5..e51d5aa 100644 --- a/go.sum +++ b/go.sum @@ -12,41 +12,41 @@ cloud.google.com/go/storage v1.39.1/go.mod h1:xK6xZmxZmo+fyP7+DEF6FhNc24/JAe95OL github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/DataDog/zstd v1.4.5 h1:EndNeuB0l9syBZhut0wns3gV1hL8zX8LIu6ZiVHWLIQ= github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= -github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= -github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= +github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= +github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDOSA= github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8= -github.com/VictoriaMetrics/fastcache v1.12.1 h1:i0mICQuojGDL3KblA7wUNlY5lOK6a4bwt3uRKnkZU40= -github.com/VictoriaMetrics/fastcache v1.12.1/go.mod h1:tX04vaqcNoQeGLD+ra5pU5sWkuxnzWhEzLwhP9w653o= +github.com/VictoriaMetrics/fastcache v1.12.2 h1:N0y9ASrJ0F6h0QaC3o6uJb3NIZ9VKLjCM7NQbSmF7WI= +github.com/VictoriaMetrics/fastcache v1.12.2/go.mod h1:AmC+Nzz1+3G2eCPapF6UcsnkThDcMsQicp4xDukwJYI= github.com/aws/aws-sdk-go v1.51.4 h1:yOVfGhRJyReBrACK0alLosJl8iXhWkNY1vrePYmhHdw= github.com/aws/aws-sdk-go v1.51.4/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/bits-and-blooms/bitset v1.10.0 h1:ePXTeiPEazB5+opbv5fr8umg2R/1NlzgDsyepwsSr88= -github.com/bits-and-blooms/bitset v1.10.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= -github.com/btcsuite/btcd/btcec/v2 v2.2.0 h1:fzn1qaOt32TuLjFlkzYSsBC35Q3KUjT1SwPxiMSCF5k= -github.com/btcsuite/btcd/btcec/v2 v2.2.0/go.mod h1:U7MHm051Al6XmscBQ0BoNydpOTsFAn707034b5nY8zU= +github.com/bits-and-blooms/bitset v1.13.0 h1:bAQ9OPNFYbGHV6Nez0tmNI0RiEu7/hxlYJRUA0wFAVE= +github.com/bits-and-blooms/bitset v1.13.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= +github.com/btcsuite/btcd/btcec/v2 v2.3.4 h1:3EJjcN70HCu/mwqlUsGK8GcNVyLVxFDlWurTXGPFfiQ= +github.com/btcsuite/btcd/btcec/v2 v2.3.4/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U= github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk= github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= -github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= -github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa h1:jQCWAUqqlij9Pgj2i/PB79y4KOPYVyFYdROxgaCwdTQ= github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa/go.mod h1:x/1Gn8zydmfq8dk6e9PdstVsDgu9RuyIIJqAaF//0IM= -github.com/cockroachdb/errors v1.8.1 h1:A5+txlVZfOqFBDa4mGz2bUWSp0aHElvHX2bKkdbQu+Y= -github.com/cockroachdb/errors v1.8.1/go.mod h1:qGwQn6JmZ+oMjuLwjWzUNqblqk0xl4CVV3SQbGwK7Ac= -github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f h1:o/kfcElHqOiXqcou5a3rIlMc7oJbMQkeLk0VQJ7zgqY= -github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI= -github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593 h1:aPEJyR4rPBvDmeyi+l/FS/VtA00IWvjeFvjen1m1l1A= -github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593/go.mod h1:6hk1eMY/u5t+Cf18q5lFMUA1Rc+Sm5I6Ra1QuPyxXCo= -github.com/cockroachdb/redact v1.0.8 h1:8QG/764wK+vmEYoOlfobpe12EQcS81ukx/a4hdVMxNw= -github.com/cockroachdb/redact v1.0.8/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= -github.com/cockroachdb/sentry-go v0.6.1-cockroachdb.2 h1:IKgmqgMQlVJIZj19CdocBeSfSaiCbEBZGKODaixqtHM= -github.com/cockroachdb/sentry-go v0.6.1-cockroachdb.2/go.mod h1:8BT+cPK6xvFOcRlk0R8eg+OTkcqI6baNH4xAkpiYVvQ= +github.com/cockroachdb/errors v1.11.3 h1:5bA+k2Y6r+oz/6Z/RFlNeVCesGARKuC6YymtcDrbC/I= +github.com/cockroachdb/errors v1.11.3/go.mod h1:m4UIW4CDjx+R5cybPsNrRbreomiFqt8o1h1wUVazSd8= +github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce h1:giXvy4KSc/6g/esnpM7Geqxka4WSqI1SZc7sMJFd3y4= +github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce/go.mod h1:9/y3cnZ5GKakj/H4y9r9GTjCvAFta7KLgSHPJJYc52M= +github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE= +github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= +github.com/cockroachdb/pebble v1.1.2 h1:CUh2IPtR4swHlEj48Rhfzw6l/d0qA31fItcIszQVIsA= +github.com/cockroachdb/pebble v1.1.2/go.mod h1:4exszw1r40423ZsmkG/09AFEG83I0uDgfujJdbL6kYU= +github.com/cockroachdb/redact v1.1.5 h1:u1PMllDkdFfPWaNGMyLD1+so+aq3uUItthCFqzwPJ30= +github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo= github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ= github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/YjhQ= @@ -55,15 +55,15 @@ github.com/consensys/gnark-crypto v0.12.1 h1:lHH39WuuFgVHONRl3J0LRBtuYdQTumFSDtJ github.com/consensys/gnark-crypto v0.12.1/go.mod h1:v2Gy7L/4ZRosZ7Ivs+9SfUDr0f5UlG+EM5t7MPHiLuY= github.com/cpuguy83/go-md2man/v2 v2.0.3 h1:qMCsGGgs+MAzDFyp9LpAe1Lqy/fY/qCovCm0qnXZOBM= github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233 h1:d28BXYi+wUpz1KBmiF9bWrjEMacUEREV6MBi2ODnrfQ= -github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233/go.mod h1:geZJZH3SzKCqnz5VT0q/DyIG/tvu/dZk+VIfXicupJs= -github.com/crate-crypto/go-kzg-4844 v0.7.0 h1:C0vgZRk4q4EZ/JgPfzuSoxdCq3C3mOZMBShovmncxvA= -github.com/crate-crypto/go-kzg-4844 v0.7.0/go.mod h1:1kMhvPgI0Ky3yIa+9lFySEBUBXkYxeOi8ZF1sYioxhc= +github.com/crate-crypto/go-ipa v0.0.0-20240223125850-b1e8a79f509c h1:uQYC5Z1mdLRPrZhHjHxufI8+2UG/i25QG92j0Er9p6I= +github.com/crate-crypto/go-ipa v0.0.0-20240223125850-b1e8a79f509c/go.mod h1:geZJZH3SzKCqnz5VT0q/DyIG/tvu/dZk+VIfXicupJs= +github.com/crate-crypto/go-kzg-4844 v1.0.0 h1:TsSgHwrkTKecKJ4kadtHi4b3xHW5dCFUDFnUp1TsawI= +github.com/crate-crypto/go-kzg-4844 v1.0.0/go.mod h1:1kMhvPgI0Ky3yIa+9lFySEBUBXkYxeOi8ZF1sYioxhc= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/deckarep/golang-set/v2 v2.1.0 h1:g47V4Or+DUdzbs8FxCCmgb6VYd+ptPAngjM6dtGktsI= -github.com/deckarep/golang-set/v2 v2.1.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= +github.com/deckarep/golang-set/v2 v2.6.0 h1:XfcQbWM1LlMB8BsJ8N9vW5ehnnPVIw0je80NsVHagjM= +github.com/deckarep/golang-set/v2 v2.6.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 h1:YLtO71vCjJRCBcrPMtQ9nqBsqpA1m5sE92cU+pd5Mcc= @@ -74,20 +74,20 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v1.0.4 h1:gVPz/FMfvh57HdSJQyvBtF00j8JU4zdyUgIUNhlgg0A= github.com/envoyproxy/protoc-gen-validate v1.0.4/go.mod h1:qys6tmnRsYrQqIhm2bvKZH4Blx/1gTIZ2UKVY1M+Yew= -github.com/ethereum/c-kzg-4844 v0.4.0 h1:3MS1s4JtA868KpJxroZoepdV0ZKBp3u/O5HcZ7R3nlY= -github.com/ethereum/c-kzg-4844 v0.4.0/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= -github.com/ethereum/go-ethereum v1.13.11 h1:b51Dsm+rEg7anFRUMGB8hODXHvNfcRKzz9vcj8wSdUs= -github.com/ethereum/go-ethereum v1.13.11/go.mod h1:gFtlVORuUcT+UUIcJ/veCNjkuOSujCi338uSHJrYAew= +github.com/ethereum/c-kzg-4844 v1.0.0 h1:0X1LBXxaEtYD9xsyj9B9ctQEZIpnvVDeoBx8aHEwTNA= +github.com/ethereum/c-kzg-4844 v1.0.0/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= +github.com/ethereum/go-ethereum v1.14.10 h1:kC24WjYeRjDy86LVo6MfF5Xs7nnUu+XG4AjaYIaZYko= +github.com/ethereum/go-ethereum v1.14.10/go.mod h1:+l/fr42Mma+xBnhefL/+z11/hcmJ2egl+ScIVPjhc7E= +github.com/ethereum/go-verkle v0.1.1-0.20240829091221-dffa7562dbe9 h1:8NfxH2iXvJ60YRB8ChToFTUzl8awsc3cJ8CbLjGIl/A= +github.com/ethereum/go-verkle v0.1.1-0.20240829091221-dffa7562dbe9/go.mod h1:M3b90YRnzqKyyzBEWJGqj8Qff4IDeXnzFw0P9bFw3uk= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 h1:FtmdgXiUlNeRsoNMFlKLDt+S+6hbjVMEW6RGQ7aUf7c= -github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff h1:tY80oXqGNY4FhTFhk+o9oFHGINQ/+vhlm8HFzi6znCI= github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= -github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46 h1:BAIP2GihuqhwdILrV+7GJel5lyPV3u1+PgzrWLc0TkE= -github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46/go.mod h1:QNpY22eby74jVhqH4WhDLDwxc/vqsern6pW+u2kbkpc= +github.com/getsentry/sentry-go v0.27.0 h1:Pv98CIbtB3LkMWmXi4Joa5OOcwbmnX88sF5qbK3r3Ps= +github.com/getsentry/sentry-go v0.27.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= @@ -149,12 +149,12 @@ github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0U github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/hashicorp/go-bexpr v0.1.10 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpxn4uE= github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= -github.com/holiman/billy v0.0.0-20230718173358-1c7e68d277a7 h1:3JQNjnMRil1yD0IfZKHF9GxxWKDJGj8I0IqOUol//sw= -github.com/holiman/billy v0.0.0-20230718173358-1c7e68d277a7/go.mod h1:5GuXa7vkL8u9FkFuWdVvfR5ix8hRB7DbOAaYULamFpc= +github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4 h1:X4egAf/gcS1zATw6wn4Ej8vjuVGxeHdan+bRb2ebyv4= +github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4/go.mod h1:5GuXa7vkL8u9FkFuWdVvfR5ix8hRB7DbOAaYULamFpc= github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= -github.com/holiman/uint256 v1.2.4 h1:jUc4Nk8fm9jZabQuqr2JzednajVmBpC+oiTiXZJEApU= -github.com/holiman/uint256 v1.2.4/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E= +github.com/holiman/uint256 v1.3.1 h1:JfTzmih28bittyHM8z360dCjIA9dbPIBlcTI6lmctQs= +github.com/holiman/uint256 v1.3.1/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E= github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI= @@ -175,8 +175,8 @@ github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9Y github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= -github.com/klauspost/compress v1.15.15 h1:EF27CXIuDsYJ6mmvtBRlEuB2UVOqHG1tAXgZ7yIO+lw= -github.com/klauspost/compress v1.15.15/go.mod h1:ZcK2JAFqKOpnBlxcLsJzYfrS9X1akm9fHZNnD9+Vo/4= +github.com/klauspost/compress v1.16.0 h1:iULayQNOReoYUe+1qtKOqw9CwJv3aNQu8ivo7lw1HU4= +github.com/klauspost/compress v1.16.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -187,8 +187,8 @@ github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7 github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= -github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI= @@ -239,10 +239,10 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/supranational/blst v0.3.11 h1:LyU6FolezeWAhvQk0k6O/d49jqgO52MSDDfYgbeoEm4= -github.com/supranational/blst v0.3.11/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/supranational/blst v0.3.13 h1:AYeSxdOMacwu7FBmpfloBz5pbFXDmJL33RuwnKtmTjk= +github.com/supranational/blst v0.3.13/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= @@ -273,8 +273,8 @@ go.opentelemetry.io/otel/trace v1.23.0/go.mod h1:GSGTbIClEsuZrGIzoEHqsVfxgn5Ukgg golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.20.0 h1:jmAMJJZXr5KiCw05dfYK9QnqaqKLYXijU23lsEdcQqg= -golang.org/x/crypto v0.20.0/go.mod h1:Xwo95rrVNIoSMx9wa1JroENMToLWn3RNVrTBpLHgZPQ= +golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= +golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ= golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE= @@ -282,8 +282,8 @@ golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTk golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= -golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= +golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -293,8 +293,8 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= -golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= +golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.17.0 h1:6m3ZPmLEFdVxKKWnKq4VqZ60gutO35zm+zrAHVmHyDQ= golang.org/x/oauth2 v0.17.0/go.mod h1:OzPDGQiuQMguemayvdylqddI7qcD9lnSDb+1FiwQ5HA= @@ -302,8 +302,8 @@ golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= -golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -317,18 +317,18 @@ golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= -golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= +golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.17.0 h1:mkTF7LCd6WGJNL3K1Ad7kwxNfYAW6a8a8QqtMblp/4U= -golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= +golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw= +golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= +golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -338,8 +338,8 @@ golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3 golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.15.0 h1:zdAyfUGbYmuVokhzVmghFl2ZJh5QhcfebBgmVPFYA+8= -golang.org/x/tools v0.15.0/go.mod h1:hpksKq4dtpQWS1uQ61JkdqWM3LscIS6Slf+VVkm+wQk= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU= @@ -377,11 +377,11 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= -google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8= -gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= +gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= +gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= diff --git a/version/version.go b/version/version.go index 6144365..0589ddd 100644 --- a/version/version.go +++ b/version/version.go @@ -1,3 +1,3 @@ package version -var SeerVersion string = "0.1.22" +var SeerVersion string = "0.2.0"