diff --git a/README.md b/README.md index 0d32ac9..612eea0 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,8 @@ # seer -`seer` is Moonstream's second generation blockchain-adjacent tooling for crawling data and performing +`seer` is blockchain-adjacent tooling for crawling data and performing smart contract interactions. -It builds on what we have learned from our first generation of [`crawlers`](https://github.com/moonstream-to/api/tree/e69d81d1fb081cbddb0c8a1983af41e53d5a0f8f/crawlers) and from [`moonworm`](https://github.com/moonstream-to/moonworm). ## Build diff --git a/bindings/CreateCall/CreateCall.go b/bindings/CreateCall/CreateCall.go index 6220e07..a19ce6d 100644 --- a/bindings/CreateCall/CreateCall.go +++ b/bindings/CreateCall/CreateCall.go @@ -1,4 +1,4 @@ -// This file was generated by seer: https://github.com/moonstream-to/seer. +// This file was generated by seer: https://github.com/G7DAO/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. diff --git a/bindings/GnosisSafe/GnosisSafe.go b/bindings/GnosisSafe/GnosisSafe.go index ec513c3..ca58586 100644 --- a/bindings/GnosisSafe/GnosisSafe.go +++ b/bindings/GnosisSafe/GnosisSafe.go @@ -1,4 +1,4 @@ -// This file was generated by seer: https://github.com/moonstream-to/seer. +// This file was generated by seer: https://github.com/G7DAO/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. diff --git a/blockchain/arbitrum_one/arbitrum_one.go b/blockchain/arbitrum_one/arbitrum_one.go index 0af2e50..011bcab 100644 --- a/blockchain/arbitrum_one/arbitrum_one.go +++ b/blockchain/arbitrum_one/arbitrum_one.go @@ -21,9 +21,9 @@ import ( "github.com/ethereum/go-ethereum/rpc" "google.golang.org/protobuf/proto" - seer_common "github.com/moonstream-to/seer/blockchain/common" - "github.com/moonstream-to/seer/indexer" - "github.com/moonstream-to/seer/version" + seer_common "github.com/G7DAO/seer/blockchain/common" + "github.com/G7DAO/seer/indexer" + "github.com/G7DAO/seer/version" ) func NewClient(url string, timeout int) (*Client, error) { diff --git a/blockchain/arbitrum_one/arbitrum_one_index_types.proto b/blockchain/arbitrum_one/arbitrum_one_index_types.proto index 09c1823..1060cfa 100644 --- a/blockchain/arbitrum_one/arbitrum_one_index_types.proto +++ b/blockchain/arbitrum_one/arbitrum_one_index_types.proto @@ -1,6 +1,6 @@ syntax = "proto3"; -option go_package = "github.com/moonstream-to/seer/blockchain/arbitrum_one"; +option go_package = "github.com/G7DAO/seer/blockchain/arbitrum_one"; message ArbitrumOneTransactionAccessList { diff --git a/blockchain/arbitrum_sepolia/arbitrum_sepolia.go b/blockchain/arbitrum_sepolia/arbitrum_sepolia.go index b83b582..bf8423d 100644 --- a/blockchain/arbitrum_sepolia/arbitrum_sepolia.go +++ b/blockchain/arbitrum_sepolia/arbitrum_sepolia.go @@ -21,9 +21,9 @@ import ( "github.com/ethereum/go-ethereum/rpc" "google.golang.org/protobuf/proto" - seer_common "github.com/moonstream-to/seer/blockchain/common" - "github.com/moonstream-to/seer/indexer" - "github.com/moonstream-to/seer/version" + seer_common "github.com/G7DAO/seer/blockchain/common" + "github.com/G7DAO/seer/indexer" + "github.com/G7DAO/seer/version" ) func NewClient(url string, timeout int) (*Client, error) { diff --git a/blockchain/arbitrum_sepolia/arbitrum_sepolia_index_types.proto b/blockchain/arbitrum_sepolia/arbitrum_sepolia_index_types.proto index b880e28..c5176b8 100644 --- a/blockchain/arbitrum_sepolia/arbitrum_sepolia_index_types.proto +++ b/blockchain/arbitrum_sepolia/arbitrum_sepolia_index_types.proto @@ -1,6 +1,6 @@ syntax = "proto3"; -option go_package = "github.com/moonstream-to/seer/blockchain/arbitrum_sepolia"; +option go_package = "github.com/G7DAO/seer/blockchain/arbitrum_sepolia"; message ArbitrumSepoliaTransactionAccessList { diff --git a/blockchain/b3/b3.go b/blockchain/b3/b3.go index 5b1efcf..88bda72 100644 --- a/blockchain/b3/b3.go +++ b/blockchain/b3/b3.go @@ -21,9 +21,9 @@ import ( "github.com/ethereum/go-ethereum/rpc" "google.golang.org/protobuf/proto" - seer_common "github.com/moonstream-to/seer/blockchain/common" - "github.com/moonstream-to/seer/indexer" - "github.com/moonstream-to/seer/version" + seer_common "github.com/G7DAO/seer/blockchain/common" + "github.com/G7DAO/seer/indexer" + "github.com/G7DAO/seer/version" ) func NewClient(url string, timeout int) (*Client, error) { diff --git a/blockchain/b3/b3_index_types.proto b/blockchain/b3/b3_index_types.proto index e68262a..c4657f5 100644 --- a/blockchain/b3/b3_index_types.proto +++ b/blockchain/b3/b3_index_types.proto @@ -1,6 +1,6 @@ syntax = "proto3"; -option go_package = "github.com/moonstream-to/seer/blockchain/b3"; +option go_package = "github.com/G7DAO/seer/blockchain/b3"; message B3TransactionAccessList { diff --git a/blockchain/b3_sepolia/b3_sepolia.go b/blockchain/b3_sepolia/b3_sepolia.go index 9f9d7bf..5710817 100644 --- a/blockchain/b3_sepolia/b3_sepolia.go +++ b/blockchain/b3_sepolia/b3_sepolia.go @@ -21,9 +21,9 @@ import ( "github.com/ethereum/go-ethereum/rpc" "google.golang.org/protobuf/proto" - seer_common "github.com/moonstream-to/seer/blockchain/common" - "github.com/moonstream-to/seer/indexer" - "github.com/moonstream-to/seer/version" + seer_common "github.com/G7DAO/seer/blockchain/common" + "github.com/G7DAO/seer/indexer" + "github.com/G7DAO/seer/version" ) func NewClient(url string, timeout int) (*Client, error) { diff --git a/blockchain/b3_sepolia/b3_sepolia_index_types.proto b/blockchain/b3_sepolia/b3_sepolia_index_types.proto index 6282c16..0b63de9 100644 --- a/blockchain/b3_sepolia/b3_sepolia_index_types.proto +++ b/blockchain/b3_sepolia/b3_sepolia_index_types.proto @@ -1,6 +1,6 @@ syntax = "proto3"; -option go_package = "github.com/moonstream-to/seer/blockchain/b3_sepolia"; +option go_package = "github.com/G7DAO/seer/blockchain/b3_sepolia"; message B3SepoliaTransactionAccessList { diff --git a/blockchain/blockchain.go.tmpl b/blockchain/blockchain.go.tmpl index fce259b..c2360a4 100644 --- a/blockchain/blockchain.go.tmpl +++ b/blockchain/blockchain.go.tmpl @@ -21,9 +21,9 @@ import ( "github.com/ethereum/go-ethereum/rpc" "google.golang.org/protobuf/proto" - seer_common "github.com/moonstream-to/seer/blockchain/common" - "github.com/moonstream-to/seer/indexer" - "github.com/moonstream-to/seer/version" + seer_common "github.com/G7DAO/seer/blockchain/common" + "github.com/G7DAO/seer/indexer" + "github.com/G7DAO/seer/version" ) func NewClient(url string, timeout int) (*Client, error) { diff --git a/blockchain/ethereum/ethereum.go b/blockchain/ethereum/ethereum.go index fb58676..8dee423 100644 --- a/blockchain/ethereum/ethereum.go +++ b/blockchain/ethereum/ethereum.go @@ -21,9 +21,9 @@ import ( "github.com/ethereum/go-ethereum/rpc" "google.golang.org/protobuf/proto" - seer_common "github.com/moonstream-to/seer/blockchain/common" - "github.com/moonstream-to/seer/indexer" - "github.com/moonstream-to/seer/version" + seer_common "github.com/G7DAO/seer/blockchain/common" + "github.com/G7DAO/seer/indexer" + "github.com/G7DAO/seer/version" ) func NewClient(url string, timeout int) (*Client, error) { diff --git a/blockchain/ethereum/ethereum_index_types.proto b/blockchain/ethereum/ethereum_index_types.proto index 758189c..bf7ea4a 100644 --- a/blockchain/ethereum/ethereum_index_types.proto +++ b/blockchain/ethereum/ethereum_index_types.proto @@ -1,6 +1,6 @@ syntax = "proto3"; -option go_package = "github.com/moonstream-to/seer/blockchain/ethereum"; +option go_package = "github.com/G7DAO/seer/blockchain/ethereum"; message EthereumTransactionAccessList { diff --git a/blockchain/game7_orbit_arbitrum_sepolia/game7_orbit_arbitrum_sepolia.go b/blockchain/game7_orbit_arbitrum_sepolia/game7_orbit_arbitrum_sepolia.go index af0e3b1..d254d51 100644 --- a/blockchain/game7_orbit_arbitrum_sepolia/game7_orbit_arbitrum_sepolia.go +++ b/blockchain/game7_orbit_arbitrum_sepolia/game7_orbit_arbitrum_sepolia.go @@ -21,9 +21,9 @@ import ( "github.com/ethereum/go-ethereum/rpc" "google.golang.org/protobuf/proto" - seer_common "github.com/moonstream-to/seer/blockchain/common" - "github.com/moonstream-to/seer/indexer" - "github.com/moonstream-to/seer/version" + seer_common "github.com/G7DAO/seer/blockchain/common" + "github.com/G7DAO/seer/indexer" + "github.com/G7DAO/seer/version" ) func NewClient(url string, timeout int) (*Client, error) { diff --git a/blockchain/game7_orbit_arbitrum_sepolia/game7_orbit_arbitrum_sepolia_index_types.proto b/blockchain/game7_orbit_arbitrum_sepolia/game7_orbit_arbitrum_sepolia_index_types.proto index b963bc1..b066202 100644 --- a/blockchain/game7_orbit_arbitrum_sepolia/game7_orbit_arbitrum_sepolia_index_types.proto +++ b/blockchain/game7_orbit_arbitrum_sepolia/game7_orbit_arbitrum_sepolia_index_types.proto @@ -1,6 +1,6 @@ syntax = "proto3"; -option go_package = "github.com/moonstream-to/seer/blockchain/game7_orbit_arbitrum_sepolia"; +option go_package = "github.com/G7DAO/seer/blockchain/game7_orbit_arbitrum_sepolia"; message Game7OrbitArbitrumSepoliaTransactionAccessList { diff --git a/blockchain/game7_testnet/game7_testnet.go b/blockchain/game7_testnet/game7_testnet.go index e53e90a..735cec4 100644 --- a/blockchain/game7_testnet/game7_testnet.go +++ b/blockchain/game7_testnet/game7_testnet.go @@ -21,9 +21,9 @@ import ( "github.com/ethereum/go-ethereum/rpc" "google.golang.org/protobuf/proto" - seer_common "github.com/moonstream-to/seer/blockchain/common" - "github.com/moonstream-to/seer/indexer" - "github.com/moonstream-to/seer/version" + seer_common "github.com/G7DAO/seer/blockchain/common" + "github.com/G7DAO/seer/indexer" + "github.com/G7DAO/seer/version" ) func NewClient(url string, timeout int) (*Client, error) { diff --git a/blockchain/game7_testnet/game7_testnet_index_types.proto b/blockchain/game7_testnet/game7_testnet_index_types.proto index 2811169..441aada 100644 --- a/blockchain/game7_testnet/game7_testnet_index_types.proto +++ b/blockchain/game7_testnet/game7_testnet_index_types.proto @@ -1,6 +1,6 @@ syntax = "proto3"; -option go_package = "github.com/moonstream-to/seer/blockchain/game7_testnet" ; +option go_package = "github.com/G7DAO/seer/blockchain/game7_testnet" ; message Game7TestnetTransactionAccessList { diff --git a/blockchain/handlers.go b/blockchain/handlers.go index cdef3e6..2ec0c33 100644 --- a/blockchain/handlers.go +++ b/blockchain/handlers.go @@ -10,25 +10,25 @@ import ( "sync" "time" + "github.com/G7DAO/seer/blockchain/arbitrum_one" + "github.com/G7DAO/seer/blockchain/arbitrum_sepolia" + "github.com/G7DAO/seer/blockchain/b3" + "github.com/G7DAO/seer/blockchain/b3_sepolia" + seer_common "github.com/G7DAO/seer/blockchain/common" + "github.com/G7DAO/seer/blockchain/ethereum" + "github.com/G7DAO/seer/blockchain/game7_orbit_arbitrum_sepolia" + "github.com/G7DAO/seer/blockchain/game7_testnet" + "github.com/G7DAO/seer/blockchain/imx_zkevm" + "github.com/G7DAO/seer/blockchain/imx_zkevm_sepolia" + "github.com/G7DAO/seer/blockchain/mantle" + "github.com/G7DAO/seer/blockchain/mantle_sepolia" + "github.com/G7DAO/seer/blockchain/polygon" + "github.com/G7DAO/seer/blockchain/sepolia" + "github.com/G7DAO/seer/blockchain/xai" + "github.com/G7DAO/seer/blockchain/xai_sepolia" + "github.com/G7DAO/seer/indexer" "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" - "github.com/moonstream-to/seer/blockchain/arbitrum_one" - "github.com/moonstream-to/seer/blockchain/arbitrum_sepolia" - "github.com/moonstream-to/seer/blockchain/b3" - "github.com/moonstream-to/seer/blockchain/b3_sepolia" - seer_common "github.com/moonstream-to/seer/blockchain/common" - "github.com/moonstream-to/seer/blockchain/ethereum" - "github.com/moonstream-to/seer/blockchain/game7_orbit_arbitrum_sepolia" - "github.com/moonstream-to/seer/blockchain/game7_testnet" - "github.com/moonstream-to/seer/blockchain/imx_zkevm" - "github.com/moonstream-to/seer/blockchain/imx_zkevm_sepolia" - "github.com/moonstream-to/seer/blockchain/mantle" - "github.com/moonstream-to/seer/blockchain/mantle_sepolia" - "github.com/moonstream-to/seer/blockchain/polygon" - "github.com/moonstream-to/seer/blockchain/sepolia" - "github.com/moonstream-to/seer/blockchain/xai" - "github.com/moonstream-to/seer/blockchain/xai_sepolia" - "github.com/moonstream-to/seer/indexer" "google.golang.org/protobuf/proto" ) diff --git a/blockchain/imx_zkevm/imx_zkevm.go b/blockchain/imx_zkevm/imx_zkevm.go index 641fef3..23c73d2 100644 --- a/blockchain/imx_zkevm/imx_zkevm.go +++ b/blockchain/imx_zkevm/imx_zkevm.go @@ -21,9 +21,9 @@ import ( "github.com/ethereum/go-ethereum/rpc" "google.golang.org/protobuf/proto" - seer_common "github.com/moonstream-to/seer/blockchain/common" - "github.com/moonstream-to/seer/indexer" - "github.com/moonstream-to/seer/version" + seer_common "github.com/G7DAO/seer/blockchain/common" + "github.com/G7DAO/seer/indexer" + "github.com/G7DAO/seer/version" ) func NewClient(url string, timeout int) (*Client, error) { diff --git a/blockchain/imx_zkevm/imx_zkevm_index_types.proto b/blockchain/imx_zkevm/imx_zkevm_index_types.proto index ce7771d..0476ea9 100644 --- a/blockchain/imx_zkevm/imx_zkevm_index_types.proto +++ b/blockchain/imx_zkevm/imx_zkevm_index_types.proto @@ -1,6 +1,6 @@ syntax = "proto3"; -option go_package = "github.com/moonstream-to/seer/blockchain/imx_zkevm"; +option go_package = "github.com/G7DAO/seer/blockchain/imx_zkevm"; message ImxZkevmTransactionAccessList { diff --git a/blockchain/imx_zkevm_sepolia/imx_zkevm_sepolia.go b/blockchain/imx_zkevm_sepolia/imx_zkevm_sepolia.go index 5ae48de..a149d22 100644 --- a/blockchain/imx_zkevm_sepolia/imx_zkevm_sepolia.go +++ b/blockchain/imx_zkevm_sepolia/imx_zkevm_sepolia.go @@ -21,9 +21,9 @@ import ( "github.com/ethereum/go-ethereum/rpc" "google.golang.org/protobuf/proto" - seer_common "github.com/moonstream-to/seer/blockchain/common" - "github.com/moonstream-to/seer/indexer" - "github.com/moonstream-to/seer/version" + seer_common "github.com/G7DAO/seer/blockchain/common" + "github.com/G7DAO/seer/indexer" + "github.com/G7DAO/seer/version" ) func NewClient(url string, timeout int) (*Client, error) { diff --git a/blockchain/imx_zkevm_sepolia/imx_zkevm_sepolia_index_types.proto b/blockchain/imx_zkevm_sepolia/imx_zkevm_sepolia_index_types.proto index 0e27e14..0255f1d 100644 --- a/blockchain/imx_zkevm_sepolia/imx_zkevm_sepolia_index_types.proto +++ b/blockchain/imx_zkevm_sepolia/imx_zkevm_sepolia_index_types.proto @@ -1,6 +1,6 @@ syntax = "proto3"; -option go_package = "github.com/moonstream-to/seer/blockchain/imx_zkevm_sepolia"; +option go_package = "github.com/G7DAO/seer/blockchain/imx_zkevm_sepolia"; message ImxZkevmSepoliaTransactionAccessList { diff --git a/blockchain/mantle/mantle.go b/blockchain/mantle/mantle.go index 3366ba8..47817c0 100644 --- a/blockchain/mantle/mantle.go +++ b/blockchain/mantle/mantle.go @@ -21,9 +21,9 @@ import ( "github.com/ethereum/go-ethereum/rpc" "google.golang.org/protobuf/proto" - seer_common "github.com/moonstream-to/seer/blockchain/common" - "github.com/moonstream-to/seer/indexer" - "github.com/moonstream-to/seer/version" + seer_common "github.com/G7DAO/seer/blockchain/common" + "github.com/G7DAO/seer/indexer" + "github.com/G7DAO/seer/version" ) func NewClient(url string, timeout int) (*Client, error) { diff --git a/blockchain/mantle/mantle_index_types.proto b/blockchain/mantle/mantle_index_types.proto index 866469d..863e224 100644 --- a/blockchain/mantle/mantle_index_types.proto +++ b/blockchain/mantle/mantle_index_types.proto @@ -1,6 +1,6 @@ syntax = "proto3"; -option go_package = "github.com/moonstream-to/seer/blockchain/mantle"; +option go_package = "github.com/G7DAO/seer/blockchain/mantle"; message MantleTransactionAccessList { diff --git a/blockchain/mantle_sepolia/mantle_sepolia.go b/blockchain/mantle_sepolia/mantle_sepolia.go index cdf42b1..6f2f5c4 100644 --- a/blockchain/mantle_sepolia/mantle_sepolia.go +++ b/blockchain/mantle_sepolia/mantle_sepolia.go @@ -21,9 +21,9 @@ import ( "github.com/ethereum/go-ethereum/rpc" "google.golang.org/protobuf/proto" - seer_common "github.com/moonstream-to/seer/blockchain/common" - "github.com/moonstream-to/seer/indexer" - "github.com/moonstream-to/seer/version" + seer_common "github.com/G7DAO/seer/blockchain/common" + "github.com/G7DAO/seer/indexer" + "github.com/G7DAO/seer/version" ) func NewClient(url string, timeout int) (*Client, error) { diff --git a/blockchain/mantle_sepolia/mantle_sepolia_index_types.proto b/blockchain/mantle_sepolia/mantle_sepolia_index_types.proto index 3551b1f..d72db9d 100644 --- a/blockchain/mantle_sepolia/mantle_sepolia_index_types.proto +++ b/blockchain/mantle_sepolia/mantle_sepolia_index_types.proto @@ -1,6 +1,6 @@ syntax = "proto3"; -option go_package = "github.com/moonstream-to/seer/blockchain/mantle_sepolia"; +option go_package = "github.com/G7DAO/seer/blockchain/mantle_sepolia"; message MantleSepoliaTransactionAccessList { diff --git a/blockchain/polygon/polygon.go b/blockchain/polygon/polygon.go index 557eb1b..2480ac9 100644 --- a/blockchain/polygon/polygon.go +++ b/blockchain/polygon/polygon.go @@ -21,9 +21,9 @@ import ( "github.com/ethereum/go-ethereum/rpc" "google.golang.org/protobuf/proto" - seer_common "github.com/moonstream-to/seer/blockchain/common" - "github.com/moonstream-to/seer/indexer" - "github.com/moonstream-to/seer/version" + seer_common "github.com/G7DAO/seer/blockchain/common" + "github.com/G7DAO/seer/indexer" + "github.com/G7DAO/seer/version" ) func NewClient(url string, timeout int) (*Client, error) { diff --git a/blockchain/polygon/polygon_index_types.proto b/blockchain/polygon/polygon_index_types.proto index 30a7d8a..00812eb 100644 --- a/blockchain/polygon/polygon_index_types.proto +++ b/blockchain/polygon/polygon_index_types.proto @@ -1,6 +1,6 @@ syntax = "proto3"; -option go_package = "github.com/moonstream-to/seer/blockchain/polygon"; +option go_package = "github.com/G7DAO/seer/blockchain/polygon"; message PolygonTransactionAccessList { diff --git a/blockchain/sepolia/sepolia.go b/blockchain/sepolia/sepolia.go index e0691c5..3eb41b6 100644 --- a/blockchain/sepolia/sepolia.go +++ b/blockchain/sepolia/sepolia.go @@ -21,9 +21,9 @@ import ( "github.com/ethereum/go-ethereum/rpc" "google.golang.org/protobuf/proto" - seer_common "github.com/moonstream-to/seer/blockchain/common" - "github.com/moonstream-to/seer/indexer" - "github.com/moonstream-to/seer/version" + seer_common "github.com/G7DAO/seer/blockchain/common" + "github.com/G7DAO/seer/indexer" + "github.com/G7DAO/seer/version" ) func NewClient(url string, timeout int) (*Client, error) { diff --git a/blockchain/sepolia/sepolia_index_types.proto b/blockchain/sepolia/sepolia_index_types.proto index c36e9eb..015ee3a 100644 --- a/blockchain/sepolia/sepolia_index_types.proto +++ b/blockchain/sepolia/sepolia_index_types.proto @@ -1,6 +1,6 @@ syntax = "proto3"; -option go_package = "github.com/moonstream-to/seer/blockchain/sepolia"; +option go_package = "github.com/G7DAO/seer/blockchain/sepolia"; message SepoliaTransactionAccessList { diff --git a/blockchain/xai/xai.go b/blockchain/xai/xai.go index c9a640e..8a0a786 100644 --- a/blockchain/xai/xai.go +++ b/blockchain/xai/xai.go @@ -21,9 +21,9 @@ import ( "github.com/ethereum/go-ethereum/rpc" "google.golang.org/protobuf/proto" - seer_common "github.com/moonstream-to/seer/blockchain/common" - "github.com/moonstream-to/seer/indexer" - "github.com/moonstream-to/seer/version" + seer_common "github.com/G7DAO/seer/blockchain/common" + "github.com/G7DAO/seer/indexer" + "github.com/G7DAO/seer/version" ) func NewClient(url string, timeout int) (*Client, error) { diff --git a/blockchain/xai/xai_index_types.proto b/blockchain/xai/xai_index_types.proto index d6998d4..24a023c 100644 --- a/blockchain/xai/xai_index_types.proto +++ b/blockchain/xai/xai_index_types.proto @@ -1,6 +1,6 @@ syntax = "proto3"; -option go_package = "github.com/moonstream-to/seer/blockchain/xai"; +option go_package = "github.com/G7DAO/seer/blockchain/xai"; message XaiTransactionAccessList { diff --git a/blockchain/xai_sepolia/xai_sepolia.go b/blockchain/xai_sepolia/xai_sepolia.go index 23dac7d..fbeb7f5 100644 --- a/blockchain/xai_sepolia/xai_sepolia.go +++ b/blockchain/xai_sepolia/xai_sepolia.go @@ -21,9 +21,9 @@ import ( "github.com/ethereum/go-ethereum/rpc" "google.golang.org/protobuf/proto" - seer_common "github.com/moonstream-to/seer/blockchain/common" - "github.com/moonstream-to/seer/indexer" - "github.com/moonstream-to/seer/version" + seer_common "github.com/G7DAO/seer/blockchain/common" + "github.com/G7DAO/seer/indexer" + "github.com/G7DAO/seer/version" ) func NewClient(url string, timeout int) (*Client, error) { diff --git a/blockchain/xai_sepolia/xai_sepolia_index_types.proto b/blockchain/xai_sepolia/xai_sepolia_index_types.proto index 64c4131..0fc6a7f 100644 --- a/blockchain/xai_sepolia/xai_sepolia_index_types.proto +++ b/blockchain/xai_sepolia/xai_sepolia_index_types.proto @@ -1,6 +1,6 @@ syntax = "proto3"; -option go_package = "github.com/moonstream-to/seer/blockchain/xai_sepolia"; +option go_package = "github.com/G7DAO/seer/blockchain/xai_sepolia"; message XaiSepoliaTransactionAccessList { diff --git a/cmd.go b/cmd.go index c658762..a89654f 100644 --- a/cmd.go +++ b/cmd.go @@ -1,6 +1,7 @@ package main import ( + "bufio" "context" "encoding/json" "errors" @@ -16,14 +17,14 @@ import ( "github.com/spf13/cobra" - seer_blockchain "github.com/moonstream-to/seer/blockchain" - "github.com/moonstream-to/seer/crawler" - "github.com/moonstream-to/seer/evm" - "github.com/moonstream-to/seer/indexer" - "github.com/moonstream-to/seer/starknet" - "github.com/moonstream-to/seer/storage" - "github.com/moonstream-to/seer/synchronizer" - "github.com/moonstream-to/seer/version" + seer_blockchain "github.com/G7DAO/seer/blockchain" + "github.com/G7DAO/seer/crawler" + "github.com/G7DAO/seer/evm" + "github.com/G7DAO/seer/indexer" + "github.com/G7DAO/seer/starknet" + "github.com/G7DAO/seer/storage" + "github.com/G7DAO/seer/synchronizer" + "github.com/G7DAO/seer/version" ) func CreateRootCommand() *cobra.Command { @@ -822,15 +823,14 @@ func CreateDatabaseOperationCommand() *cobra.Command { return blockchainErr } - return nil - }, - RunE: func(cmd *cobra.Command, args []string) error { - - // check if the chain is supported + // Check if the chain is supported if _, ok := seer_blockchain.BlockchainURLs[jobChain]; !ok { return fmt.Errorf("chain %s is not supported", jobChain) } + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { client, clientErr := seer_blockchain.NewClient(jobChain, seer_blockchain.BlockchainURLs[jobChain], 30) if clientErr != nil { return clientErr @@ -856,15 +856,150 @@ func CreateDatabaseOperationCommand() *cobra.Command { }, } - createJobsCommand.Flags().StringVar(&jobChain, "jobChain", "ethereum", "The blockchain to crawl (default: ethereum)") + createJobsCommand.Flags().StringVar(&jobChain, "chain", "", "The blockchain") createJobsCommand.Flags().StringVar(&address, "address", "", "The address to create jobs for") createJobsCommand.Flags().StringVar(&abiFile, "abi-file", "", "The path to the ABI file") createJobsCommand.Flags().StringVar(&customerId, "customer-id", "", "The customer ID to create jobs for (default: '')") createJobsCommand.Flags().StringVar(&userId, "user-id", "00000000-0000-0000-0000-000000000000", "The user ID to create jobs for (default: '00000000-0000-0000-0000-000000000000')") createJobsCommand.Flags().Uint64Var(&deployBlock, "deploy-block", 0, "The block number to deploy contract (default: 0)") + var jobIds, jobAddresses, jobCustomerIds []string + var silentFlag bool + + deleteJobsCommand := &cobra.Command{ + Use: "delete-jobs", + Short: "Delete existing jobs", + PreRunE: func(cmd *cobra.Command, args []string) error { + indexerErr := indexer.CheckVariablesForIndexer() + if indexerErr != nil { + return indexerErr + } + + indexer.InitDBConnection() + + blockchainErr := seer_blockchain.CheckVariablesForBlockchains() + if blockchainErr != nil { + return blockchainErr + } + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + abiJobs, selectJobsErr := indexer.DBConnection.SelectAbiJobs(jobChain, jobAddresses, jobCustomerIds, false, false, []string{}) + if selectJobsErr != nil { + return fmt.Errorf("error selecting ABI jobs: %w", selectJobsErr) + } + + jobIds := indexer.GetJobIds(abiJobs, false) + + output := "no" + if silentFlag { + output = "yes" + } else { + var promptErr error + output, promptErr = StringPrompt("Continue? (y/yes)") + if promptErr != nil { + return promptErr + } + } + + switch output { + case "y": + case "yes": + default: + fmt.Println("Canceled") + return nil + } + + deleteJobsErr := indexer.DBConnection.DeleteJobs(jobIds) + if deleteJobsErr != nil { + return deleteJobsErr + } + + return nil + }, + } + + deleteJobsCommand.Flags().StringVar(&jobChain, "chain", "", "The blockchain") + deleteJobsCommand.Flags().StringSliceVar(&jobIds, "job-ids", []string{}, "The list of job UUIDs separated by coma") + deleteJobsCommand.Flags().StringSliceVar(&jobAddresses, "addresses", []string{}, "The list of addresses created jobs for separated by coma") + deleteJobsCommand.Flags().StringSliceVar(&jobCustomerIds, "customer-ids", []string{}, "The list of customer IDs created jobs for separated by coma") + deleteJobsCommand.Flags().BoolVar(&silentFlag, "silent", false, "Set this flag to run command without prompt") + + var sourceCustomerId, destCustomerId string + + copyJobsCommand := &cobra.Command{ + Use: "copy-jobs", + Short: "Copy jobs between customers", + PreRunE: func(cmd *cobra.Command, args []string) error { + indexerErr := indexer.CheckVariablesForIndexer() + if indexerErr != nil { + return indexerErr + } + + indexer.InitDBConnection() + + blockchainErr := seer_blockchain.CheckVariablesForBlockchains() + if blockchainErr != nil { + return blockchainErr + } + + if sourceCustomerId == "" || destCustomerId == "" { + return fmt.Errorf("values for --source-customer-id and --dest-customer-id should be set") + } + + // Check if the chain is supported + if _, ok := seer_blockchain.BlockchainURLs[jobChain]; !ok { + return fmt.Errorf("chain %s is not supported", jobChain) + } + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + abiJobs, selectJobsErr := indexer.DBConnection.SelectAbiJobs(jobChain, []string{}, []string{sourceCustomerId}, false, false, []string{}) + if selectJobsErr != nil { + return fmt.Errorf("error selecting ABI jobs: %w", selectJobsErr) + } + + indexer.GetJobIds(abiJobs, false) + + output := "no" + if silentFlag { + output = "yes" + } else { + var promptErr error + output, promptErr = StringPrompt("Continue? (y/yes)") + if promptErr != nil { + return promptErr + } + } + + switch output { + case "y": + case "yes": + default: + fmt.Println("Canceled") + return nil + } + + copyErr := indexer.DBConnection.CopyAbiJobs(sourceCustomerId, destCustomerId, abiJobs) + if copyErr != nil { + return copyErr + } + + return nil + }, + } + + copyJobsCommand.Flags().StringVar(&jobChain, "chain", "", "The blockchain to crawl") + copyJobsCommand.Flags().StringVar(&sourceCustomerId, "source-customer-id", "", "Source customer ID with jobs to copy") + copyJobsCommand.Flags().StringVar(&destCustomerId, "dest-customer-id", "", "Destination customer ID where to copy jobs") + copyJobsCommand.Flags().BoolVar(&silentFlag, "silent", false, "Set this flag to run command without prompt") + indexCommand.AddCommand(deploymentBlocksCommand) indexCommand.AddCommand(createJobsCommand) + indexCommand.AddCommand(deleteJobsCommand) + indexCommand.AddCommand(copyJobsCommand) databaseCmd.AddCommand(indexCommand) return databaseCmd @@ -1159,3 +1294,17 @@ func CreateEVMGenerateCommand() *cobra.Command { return evmGenerateCmd } + +func StringPrompt(label string) (string, error) { + var output string + r := bufio.NewReader(os.Stdin) + + fmt.Fprint(os.Stderr, label+" ") + var readErr error + output, readErr = r.ReadString('\n') + if readErr != nil { + return "", readErr + } + + return strings.TrimSpace(output), nil +} diff --git a/crawler/crawler.go b/crawler/crawler.go index b1f4338..0016543 100644 --- a/crawler/crawler.go +++ b/crawler/crawler.go @@ -9,9 +9,9 @@ import ( "sync" "time" - seer_blockchain "github.com/moonstream-to/seer/blockchain" - "github.com/moonstream-to/seer/indexer" - "github.com/moonstream-to/seer/storage" + seer_blockchain "github.com/G7DAO/seer/blockchain" + "github.com/G7DAO/seer/indexer" + "github.com/G7DAO/seer/storage" "google.golang.org/protobuf/proto" ) diff --git a/evm/generators.go b/evm/generators.go index 6759baa..c01da6c 100644 --- a/evm/generators.go +++ b/evm/generators.go @@ -18,9 +18,9 @@ import ( "strings" "text/template" + "github.com/G7DAO/seer/version" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/iancoleman/strcase" - "github.com/moonstream-to/seer/version" "golang.org/x/tools/imports" ) @@ -780,8 +780,8 @@ 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/G7DAO/seer/bindings/GnosisSafe + // - github.com/G7DAO/seer/bindings/CreateCall // - github.com/ethereum/go-ethereum/common/math // - github.com/ethereum/go-ethereum/crypto if t.Tok == token.IMPORT { @@ -797,8 +797,8 @@ 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/G7DAO/seer/bindings/GnosisSafe"`}}, + &ast.ImportSpec{Path: &ast.BasicLit{Value: `"github.com/G7DAO/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"`}}, ) @@ -1107,7 +1107,7 @@ type SafeTransactionData struct { GasPrice string ` + "`" + `json:"gasPrice"` + "`" + ` GasToken string ` + "`" + `json:"gasToken"` + "`" + ` RefundReceiver string ` + "`" + `json:"refundReceiver"` + "`" + ` - Nonce uint64 ` + "`" + `json:"nonce"` + "`" + ` + Nonce *big.Int ` + "`" + `json:"nonce"` + "`" + ` SafeTxHash string ` + "`" + `json:"safeTxHash"` + "`" + ` Sender string ` + "`" + `json:"sender"` + "`" + ` Signature string ` + "`" + `json:"signature"` + "`" + ` @@ -1119,7 +1119,7 @@ const ( ) -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 { +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, safeNonce *big.Int) error { abi, err := CreateCall.CreateCallMetaData.GetAbi() if err != nil { return fmt.Errorf("failed to get ABI: %v", err) @@ -1130,10 +1130,20 @@ func DeployWithSafe(client *ethclient.Client, key *keystore.Key, safeAddress com return fmt.Errorf("failed to pack performCreate2 transaction: %v", err) } - return CreateSafeProposal(client, key, safeAddress, factoryAddress, safeCreateCallTxData, value, safeApi, SafeOperationType(safeOperationType)) + return CreateSafeProposal(client, key, safeAddress, factoryAddress, safeCreateCallTxData, value, safeApi, SafeOperationType(safeOperationType), safeNonce) } -func CreateSafeProposal(client *ethclient.Client, key *keystore.Key, safeAddress common.Address, to common.Address, data []byte, value *big.Int, safeApi string, safeOperationType SafeOperationType) error { +func PredictDeploymentAddressSafe(from common.Address, salt [32]byte, deployBytecode []byte) (common.Address, error) { + // Calculate the hash of the init code (deployment bytecode) + initCodeHash := crypto.Keccak256(deployBytecode) + + // Calculate the CREATE2 address + deployedAddress := crypto.CreateAddress2(from, salt, initCodeHash) + + return deployedAddress, nil +} + +func CreateSafeProposal(client *ethclient.Client, key *keystore.Key, safeAddress common.Address, to common.Address, data []byte, value *big.Int, safeApi string, safeOperationType SafeOperationType, safeNonce *big.Int) error { chainID, err := client.ChainID(context.Background()) if err != nil { return fmt.Errorf("failed to get chain ID: %v", err) @@ -1145,10 +1155,16 @@ func CreateSafeProposal(client *ethclient.Client, key *keystore.Key, safeAddress 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) + nonce := safeNonce + if safeNonce == big.NewInt(0) { + // Fetch the current nonce from the Safe contract + fetchedNonce, err := safeInstance.Nonce(&bind.CallOpts{}) + if err != nil { + return fmt.Errorf("failed to fetch nonce from Safe contract: %v", err) + } + nonce = fetchedNonce + } else { + nonce = safeNonce } safeTransactionData := SafeTransactionData{ @@ -1161,7 +1177,7 @@ func CreateSafeProposal(client *ethclient.Client, key *keystore.Key, safeAddress GasPrice: "0", GasToken: NativeTokenAddress, RefundReceiver: NativeTokenAddress, - Nonce: nonce.Uint64(), + Nonce: nonce, } // Calculate SafeTxHash @@ -1288,10 +1304,11 @@ func {{.DeployHandler.HandlerName}}() *cobra.Command { var gasLimit uint64 var simulate bool var timeout uint - var safeAddress, safeApi, safeCreateCall, safeSaltRaw string + var safeAddress, safeApi, safeCreateCall, safeSaltRaw, safeNonceRaw string var safeOperationType uint8 var salt [32]byte - + var predictAddress bool + var safeNonce *big.Int {{range .DeployHandler.MethodArgs}} var {{.CLIVar}} {{.CLIType}} {{if (ne .CLIRawVar .CLIVar)}}var {{.CLIRawVar}} {{.CLIRawType}}{{end}} @@ -1357,6 +1374,17 @@ func {{.DeployHandler.HandlerName}}() *cobra.Command { } else { copy(salt[:], safeSaltRaw) } + + if safeNonceRaw == "" { + fmt.Println("--safe-nonce not specified, fetching nonce from Safe contract") + safeNonce = big.NewInt(0) + } else { + safeNonce = new(big.Int) + _, ok := safeNonce.SetString(safeNonceRaw, 0) + if !ok { + return fmt.Errorf("--safe-nonce is not a valid big integer") + } + } } {{range .DeployHandler.MethodArgs}} @@ -1407,9 +1435,24 @@ func {{.DeployHandler.HandlerName}}() *cobra.Command { 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) + if predictAddress { + fmt.Println("Predicting deployment address...") + from := common.HexToAddress(safeAddress) + if safeOperationType == 0 { + from = common.HexToAddress(safeCreateCall) + } + deploymentAddress, err := PredictDeploymentAddressSafe(from, salt, deployBytecode) + if err != nil { + return fmt.Errorf("failed to predict deployment address: %v", err) + } + fmt.Println("Predicted deployment address:", deploymentAddress.Hex()) + return nil + } else { + fmt.Println("Creating Safe proposal...") + err = DeployWithSafe(client, key, common.HexToAddress(safeAddress), common.HexToAddress(safeCreateCall), value, safeApi, deployBytecode, SafeOperationType(safeOperationType), salt, safeNonce) + if err != nil { + return fmt.Errorf("failed to create Safe proposal: %v", err) + } } return nil @@ -1473,6 +1516,8 @@ func {{.DeployHandler.HandlerName}}() *cobra.Command { 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().BoolVar(&predictAddress, "safe-predict-address", false, "Predict the deployment address (only works for Safe transactions)") + cmd.Flags().StringVar(&safeNonceRaw, "safe-nonce", "", "Safe nonce overrider for the transaction (optional)") {{range .DeployHandler.MethodArgs}} cmd.Flags().{{.Flag}} @@ -1602,13 +1647,14 @@ 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 keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw, safeFunction, safeNonceRaw string var gasLimit uint64 var simulate bool var timeout uint var contractAddress common.Address var safeAddress, safeApi string var safeOperationType uint8 + var safeNonce *big.Int {{range .MethodArgs}} var {{.CLIVar}} {{.CLIType}} @@ -1656,6 +1702,17 @@ func {{.HandlerName}}() *cobra.Command { if SafeOperationType(safeOperationType).String() == "Unknown" { return fmt.Errorf("--safe-operation must be 0 (Call) or 1 (DelegateCall)") } + + if safeNonceRaw == "" { + fmt.Println("--safe-nonce not specified, fetching nonce from Safe contract") + safeNonce = big.NewInt(0) + } else { + safeNonce = new(big.Int) + _, ok := safeNonce.SetString(safeNonceRaw, 0) + if !ok { + return fmt.Errorf("--safe-nonce is not a valid big integer") + } + } } {{range .MethodArgs}} @@ -1700,11 +1757,22 @@ func {{.HandlerName}}() *cobra.Command { } if safeAddress != "" { - // Generate transaction data - transaction, err := session.{{.MethodName}}( - {{range .MethodArgs}} - {{.CLIVar}}, - {{- end}} + abi, err := {{$structName}}MetaData.GetAbi() + if err != nil { + return fmt.Errorf("failed to get ABI: %v", err) + } + + // Generate transaction data (override method name if safe function is specified) + methodName := "{{ToLowerCamel .MethodName}}" + if safeFunction != "" { + methodName = safeFunction + } + + transaction, err := abi.Pack( + methodName, + {{- range .MethodArgs}} + {{.CLIVar}}, + {{- end}} ) if err != nil { @@ -1716,7 +1784,8 @@ func {{.HandlerName}}() *cobra.Command { if value == nil { value = big.NewInt(0) } - err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, transaction.Data(), value, safeApi, SafeOperationType(safeOperationType)) + + err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, transaction, value, safeApi, SafeOperationType(safeOperationType), safeNonce) if err != nil { return fmt.Errorf("failed to create Safe proposal: %v", err) } @@ -1779,6 +1848,8 @@ func {{.HandlerName}}() *cobra.Command { 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(&safeFunction, "safe-function", "", "Safe function overrider to use for the transaction (optional)") + cmd.Flags().StringVar(&safeNonceRaw, "safe-nonce", "", "Safe nonce overrider for the transaction (optional)") {{range .MethodArgs}} cmd.Flags().{{.Flag}} @@ -1792,7 +1863,7 @@ func {{.HandlerName}}() *cobra.Command { // This is the Go template used to create header information at the top of the generated code. // At a bare minimum, the header specifies the version of seer that was used to generate the code. // This template should be applied to a EVMHeaderParameters struct. -var HeaderTemplate string = `// This file was generated by seer: https://github.com/moonstream-to/seer. +var HeaderTemplate string = `// This file was generated by seer: https://github.com/G7DAO/seer. // seer version: {{.Version}} // seer command: seer evm generate{{if .PackageName}} --package {{.PackageName}}{{end}}{{if .CLI}} --cli{{end}}{{if .IncludeMain}} --includemain{{end}}{{if (ne .Foundry "")}} --foundry {{.Foundry}}{{end}}{{if (ne .ABI "")}} --abi {{.ABI}}{{end}}{{if (ne .Bytecode "")}} --bytecode {{.Bytecode}}{{end}} --struct {{.StructName}}{{if (ne .OutputFile "")}} --output {{.OutputFile}}{{end}}{{if .NoFormat}} --noformat{{end}} ` diff --git a/examples/ownable-erc-721/OwnableERC721.go b/examples/ownable-erc-721/OwnableERC721.go index 6e0151f..57934dd 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.2.0 +// This file was generated by seer: https://github.com/G7DAO/seer. +// seer version: 0.3.1 // 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. @@ -8,6 +8,7 @@ package main import ( "bytes" + "crypto/rand" "errors" "math/big" "net/http" @@ -30,10 +31,10 @@ import ( "os" "time" + "github.com/G7DAO/seer/bindings/CreateCall" + "github.com/G7DAO/seer/bindings/GnosisSafe" "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" @@ -1309,9 +1310,11 @@ func CreateOwnableERC721DeploymentCommand() *cobra.Command { var gasLimit uint64 var simulate bool var timeout uint - var safeAddress, safeApi, safeCreateCall, safeSaltRaw string + var safeAddress, safeApi, safeCreateCall, safeSaltRaw, safeNonceRaw string var safeOperationType uint8 - var safeSalt []byte + var salt [32]byte + var predictAddress bool + var safeNonce *big.Int var name_0 string @@ -1364,9 +1367,33 @@ func CreateOwnableERC721DeploymentCommand() *cobra.Command { } if safeSaltRaw == "" { - return fmt.Errorf("--safe-salt not specified") + 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) + } + + if safeNonceRaw == "" { + fmt.Println("--safe-nonce not specified, fetching nonce from Safe contract") + safeNonce = big.NewInt(0) + } else { + safeNonce = new(big.Int) + _, ok := safeNonce.SetString(safeNonceRaw, 0) + if !ok { + return fmt.Errorf("--safe-nonce is not a valid big integer") + } } - safeSalt = common.Hex2Bytes(safeSaltRaw) } if ownerRaw == "" { @@ -1419,9 +1446,25 @@ func CreateOwnableERC721DeploymentCommand() *cobra.Command { 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) + + if predictAddress { + fmt.Println("Predicting deployment address...") + from := common.HexToAddress(safeAddress) + if safeOperationType == 0 { + from = common.HexToAddress(safeCreateCall) + } + deploymentAddress, err := PredictDeploymentAddressSafe(from, salt, deployBytecode) + if err != nil { + return fmt.Errorf("failed to predict deployment address: %v", err) + } + fmt.Println("Predicted deployment address:", deploymentAddress.Hex()) + return nil + } else { + fmt.Println("Creating Safe proposal...") + err = DeployWithSafe(client, key, common.HexToAddress(safeAddress), common.HexToAddress(safeCreateCall), value, safeApi, deployBytecode, SafeOperationType(safeOperationType), salt, safeNonce) + if err != nil { + return fmt.Errorf("failed to create Safe proposal: %v", err) + } } return nil @@ -1484,6 +1527,8 @@ func CreateOwnableERC721DeploymentCommand() *cobra.Command { 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().BoolVar(&predictAddress, "safe-predict-address", false, "Predict the deployment address (only works for Safe transactions)") + cmd.Flags().StringVar(&safeNonceRaw, "safe-nonce", "", "Safe nonce overrider for the transaction (optional)") cmd.Flags().StringVar(&name_0, "name-0", "", "name-0 argument") cmd.Flags().StringVar(&symbol, "symbol", "", "symbol argument") @@ -2179,13 +2224,14 @@ func CreateTokenUriCommand() *cobra.Command { } func CreateApproveCommand() *cobra.Command { - var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw string + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw, safeFunction, safeNonceRaw string var gasLimit uint64 var simulate bool var timeout uint var contractAddress common.Address var safeAddress, safeApi string var safeOperationType uint8 + var safeNonce *big.Int var to0 common.Address var to0Raw string @@ -2233,6 +2279,17 @@ func CreateApproveCommand() *cobra.Command { if SafeOperationType(safeOperationType).String() == "Unknown" { return fmt.Errorf("--safe-operation must be 0 (Call) or 1 (DelegateCall)") } + + if safeNonceRaw == "" { + fmt.Println("--safe-nonce not specified, fetching nonce from Safe contract") + safeNonce = big.NewInt(0) + } else { + safeNonce = new(big.Int) + _, ok := safeNonce.SetString(safeNonceRaw, 0) + if !ok { + return fmt.Errorf("--safe-nonce is not a valid big integer") + } + } } if to0Raw == "" { @@ -2286,9 +2343,19 @@ func CreateApproveCommand() *cobra.Command { } if safeAddress != "" { - // Generate transaction data - transaction, err := session.Approve( + abi, err := OwnableERC721MetaData.GetAbi() + if err != nil { + return fmt.Errorf("failed to get ABI: %v", err) + } + + // Generate transaction data (override method name if safe function is specified) + methodName := "approve" + if safeFunction != "" { + methodName = safeFunction + } + transaction, err := abi.Pack( + methodName, to0, tokenId, ) @@ -2302,7 +2369,8 @@ func CreateApproveCommand() *cobra.Command { if value == nil { value = big.NewInt(0) } - err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, transaction.Data(), value, safeApi, SafeOperationType(safeOperationType)) + + err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, transaction, value, safeApi, SafeOperationType(safeOperationType), safeNonce) if err != nil { return fmt.Errorf("failed to create Safe proposal: %v", err) } @@ -2365,6 +2433,8 @@ func CreateApproveCommand() *cobra.Command { 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(&safeFunction, "safe-function", "", "Safe function overrider to use for the transaction (optional)") + cmd.Flags().StringVar(&safeNonceRaw, "safe-nonce", "", "Safe nonce overrider for the transaction (optional)") cmd.Flags().StringVar(&to0Raw, "to-0", "", "to-0 argument (common.Address)") cmd.Flags().StringVar(&tokenIdRaw, "token-id", "", "token-id argument") @@ -2372,13 +2442,14 @@ func CreateApproveCommand() *cobra.Command { return cmd } func CreateMintCommand() *cobra.Command { - var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw string + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw, safeFunction, safeNonceRaw string var gasLimit uint64 var simulate bool var timeout uint var contractAddress common.Address var safeAddress, safeApi string var safeOperationType uint8 + var safeNonce *big.Int var to0 common.Address var to0Raw string @@ -2426,6 +2497,17 @@ func CreateMintCommand() *cobra.Command { if SafeOperationType(safeOperationType).String() == "Unknown" { return fmt.Errorf("--safe-operation must be 0 (Call) or 1 (DelegateCall)") } + + if safeNonceRaw == "" { + fmt.Println("--safe-nonce not specified, fetching nonce from Safe contract") + safeNonce = big.NewInt(0) + } else { + safeNonce = new(big.Int) + _, ok := safeNonce.SetString(safeNonceRaw, 0) + if !ok { + return fmt.Errorf("--safe-nonce is not a valid big integer") + } + } } if to0Raw == "" { @@ -2479,9 +2561,19 @@ func CreateMintCommand() *cobra.Command { } if safeAddress != "" { - // Generate transaction data - transaction, err := session.Mint( + abi, err := OwnableERC721MetaData.GetAbi() + if err != nil { + return fmt.Errorf("failed to get ABI: %v", err) + } + + // Generate transaction data (override method name if safe function is specified) + methodName := "mint" + if safeFunction != "" { + methodName = safeFunction + } + transaction, err := abi.Pack( + methodName, to0, tokenId, ) @@ -2495,7 +2587,8 @@ func CreateMintCommand() *cobra.Command { if value == nil { value = big.NewInt(0) } - err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, transaction.Data(), value, safeApi, SafeOperationType(safeOperationType)) + + err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, transaction, value, safeApi, SafeOperationType(safeOperationType), safeNonce) if err != nil { return fmt.Errorf("failed to create Safe proposal: %v", err) } @@ -2558,6 +2651,8 @@ func CreateMintCommand() *cobra.Command { 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(&safeFunction, "safe-function", "", "Safe function overrider to use for the transaction (optional)") + cmd.Flags().StringVar(&safeNonceRaw, "safe-nonce", "", "Safe nonce overrider for the transaction (optional)") cmd.Flags().StringVar(&to0Raw, "to-0", "", "to-0 argument (common.Address)") cmd.Flags().StringVar(&tokenIdRaw, "token-id", "", "token-id argument") @@ -2565,13 +2660,14 @@ func CreateMintCommand() *cobra.Command { return cmd } func CreateRenounceOwnershipCommand() *cobra.Command { - var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw string + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw, safeFunction, safeNonceRaw string var gasLimit uint64 var simulate bool var timeout uint var contractAddress common.Address var safeAddress, safeApi string var safeOperationType uint8 + var safeNonce *big.Int cmd := &cobra.Command{ Use: "renounce-ownership", @@ -2614,6 +2710,17 @@ func CreateRenounceOwnershipCommand() *cobra.Command { if SafeOperationType(safeOperationType).String() == "Unknown" { return fmt.Errorf("--safe-operation must be 0 (Call) or 1 (DelegateCall)") } + + if safeNonceRaw == "" { + fmt.Println("--safe-nonce not specified, fetching nonce from Safe contract") + safeNonce = big.NewInt(0) + } else { + safeNonce = new(big.Int) + _, ok := safeNonce.SetString(safeNonceRaw, 0) + if !ok { + return fmt.Errorf("--safe-nonce is not a valid big integer") + } + } } return nil @@ -2654,8 +2761,20 @@ func CreateRenounceOwnershipCommand() *cobra.Command { } if safeAddress != "" { - // Generate transaction data - transaction, err := session.RenounceOwnership() + abi, err := OwnableERC721MetaData.GetAbi() + if err != nil { + return fmt.Errorf("failed to get ABI: %v", err) + } + + // Generate transaction data (override method name if safe function is specified) + methodName := "renounceOwnership" + if safeFunction != "" { + methodName = safeFunction + } + + transaction, err := abi.Pack( + methodName, + ) if err != nil { return err @@ -2666,7 +2785,8 @@ func CreateRenounceOwnershipCommand() *cobra.Command { if value == nil { value = big.NewInt(0) } - err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, transaction.Data(), value, safeApi, SafeOperationType(safeOperationType)) + + err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, transaction, value, safeApi, SafeOperationType(safeOperationType), safeNonce) if err != nil { return fmt.Errorf("failed to create Safe proposal: %v", err) } @@ -2725,17 +2845,20 @@ func CreateRenounceOwnershipCommand() *cobra.Command { 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(&safeFunction, "safe-function", "", "Safe function overrider to use for the transaction (optional)") + cmd.Flags().StringVar(&safeNonceRaw, "safe-nonce", "", "Safe nonce overrider for the transaction (optional)") return cmd } func CreateSafeTransferFromCommand() *cobra.Command { - var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw string + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw, safeFunction, safeNonceRaw string var gasLimit uint64 var simulate bool var timeout uint var contractAddress common.Address var safeAddress, safeApi string var safeOperationType uint8 + var safeNonce *big.Int var from0 common.Address var from0Raw string @@ -2785,6 +2908,17 @@ func CreateSafeTransferFromCommand() *cobra.Command { if SafeOperationType(safeOperationType).String() == "Unknown" { return fmt.Errorf("--safe-operation must be 0 (Call) or 1 (DelegateCall)") } + + if safeNonceRaw == "" { + fmt.Println("--safe-nonce not specified, fetching nonce from Safe contract") + safeNonce = big.NewInt(0) + } else { + safeNonce = new(big.Int) + _, ok := safeNonce.SetString(safeNonceRaw, 0) + if !ok { + return fmt.Errorf("--safe-nonce is not a valid big integer") + } + } } if from0Raw == "" { @@ -2845,9 +2979,19 @@ func CreateSafeTransferFromCommand() *cobra.Command { } if safeAddress != "" { - // Generate transaction data - transaction, err := session.SafeTransferFrom( + abi, err := OwnableERC721MetaData.GetAbi() + if err != nil { + return fmt.Errorf("failed to get ABI: %v", err) + } + + // Generate transaction data (override method name if safe function is specified) + methodName := "safeTransferFrom" + if safeFunction != "" { + methodName = safeFunction + } + transaction, err := abi.Pack( + methodName, from0, to0, tokenId, @@ -2862,7 +3006,8 @@ func CreateSafeTransferFromCommand() *cobra.Command { if value == nil { value = big.NewInt(0) } - err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, transaction.Data(), value, safeApi, SafeOperationType(safeOperationType)) + + err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, transaction, value, safeApi, SafeOperationType(safeOperationType), safeNonce) if err != nil { return fmt.Errorf("failed to create Safe proposal: %v", err) } @@ -2926,6 +3071,8 @@ func CreateSafeTransferFromCommand() *cobra.Command { 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(&safeFunction, "safe-function", "", "Safe function overrider to use for the transaction (optional)") + cmd.Flags().StringVar(&safeNonceRaw, "safe-nonce", "", "Safe nonce overrider for the transaction (optional)") cmd.Flags().StringVar(&from0Raw, "from-0", "", "from-0 argument (common.Address)") cmd.Flags().StringVar(&to0Raw, "to-0", "", "to-0 argument (common.Address)") @@ -2934,13 +3081,14 @@ func CreateSafeTransferFromCommand() *cobra.Command { return cmd } func CreateSafeTransferFrom0Command() *cobra.Command { - var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw string + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw, safeFunction, safeNonceRaw string var gasLimit uint64 var simulate bool var timeout uint var contractAddress common.Address var safeAddress, safeApi string var safeOperationType uint8 + var safeNonce *big.Int var from0 common.Address var from0Raw string @@ -2992,6 +3140,17 @@ func CreateSafeTransferFrom0Command() *cobra.Command { if SafeOperationType(safeOperationType).String() == "Unknown" { return fmt.Errorf("--safe-operation must be 0 (Call) or 1 (DelegateCall)") } + + if safeNonceRaw == "" { + fmt.Println("--safe-nonce not specified, fetching nonce from Safe contract") + safeNonce = big.NewInt(0) + } else { + safeNonce = new(big.Int) + _, ok := safeNonce.SetString(safeNonceRaw, 0) + if !ok { + return fmt.Errorf("--safe-nonce is not a valid big integer") + } + } } if from0Raw == "" { @@ -3062,9 +3221,19 @@ func CreateSafeTransferFrom0Command() *cobra.Command { } if safeAddress != "" { - // Generate transaction data - transaction, err := session.SafeTransferFrom0( + abi, err := OwnableERC721MetaData.GetAbi() + if err != nil { + return fmt.Errorf("failed to get ABI: %v", err) + } + + // Generate transaction data (override method name if safe function is specified) + methodName := "safeTransferFrom0" + if safeFunction != "" { + methodName = safeFunction + } + transaction, err := abi.Pack( + methodName, from0, to0, tokenId, @@ -3080,7 +3249,8 @@ func CreateSafeTransferFrom0Command() *cobra.Command { if value == nil { value = big.NewInt(0) } - err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, transaction.Data(), value, safeApi, SafeOperationType(safeOperationType)) + + err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, transaction, value, safeApi, SafeOperationType(safeOperationType), safeNonce) if err != nil { return fmt.Errorf("failed to create Safe proposal: %v", err) } @@ -3145,6 +3315,8 @@ func CreateSafeTransferFrom0Command() *cobra.Command { 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(&safeFunction, "safe-function", "", "Safe function overrider to use for the transaction (optional)") + cmd.Flags().StringVar(&safeNonceRaw, "safe-nonce", "", "Safe nonce overrider for the transaction (optional)") cmd.Flags().StringVar(&from0Raw, "from-0", "", "from-0 argument (common.Address)") cmd.Flags().StringVar(&to0Raw, "to-0", "", "to-0 argument (common.Address)") @@ -3154,13 +3326,14 @@ func CreateSafeTransferFrom0Command() *cobra.Command { return cmd } func CreateSetApprovalForAllCommand() *cobra.Command { - var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw string + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw, safeFunction, safeNonceRaw string var gasLimit uint64 var simulate bool var timeout uint var contractAddress common.Address var safeAddress, safeApi string var safeOperationType uint8 + var safeNonce *big.Int var operator common.Address var operatorRaw string @@ -3208,6 +3381,17 @@ func CreateSetApprovalForAllCommand() *cobra.Command { if SafeOperationType(safeOperationType).String() == "Unknown" { return fmt.Errorf("--safe-operation must be 0 (Call) or 1 (DelegateCall)") } + + if safeNonceRaw == "" { + fmt.Println("--safe-nonce not specified, fetching nonce from Safe contract") + safeNonce = big.NewInt(0) + } else { + safeNonce = new(big.Int) + _, ok := safeNonce.SetString(safeNonceRaw, 0) + if !ok { + return fmt.Errorf("--safe-nonce is not a valid big integer") + } + } } if operatorRaw == "" { @@ -3265,9 +3449,19 @@ func CreateSetApprovalForAllCommand() *cobra.Command { } if safeAddress != "" { - // Generate transaction data - transaction, err := session.SetApprovalForAll( + abi, err := OwnableERC721MetaData.GetAbi() + if err != nil { + return fmt.Errorf("failed to get ABI: %v", err) + } + + // Generate transaction data (override method name if safe function is specified) + methodName := "setApprovalForAll" + if safeFunction != "" { + methodName = safeFunction + } + transaction, err := abi.Pack( + methodName, operator, approved, ) @@ -3281,7 +3475,8 @@ func CreateSetApprovalForAllCommand() *cobra.Command { if value == nil { value = big.NewInt(0) } - err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, transaction.Data(), value, safeApi, SafeOperationType(safeOperationType)) + + err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, transaction, value, safeApi, SafeOperationType(safeOperationType), safeNonce) if err != nil { return fmt.Errorf("failed to create Safe proposal: %v", err) } @@ -3344,6 +3539,8 @@ func CreateSetApprovalForAllCommand() *cobra.Command { 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(&safeFunction, "safe-function", "", "Safe function overrider to use for the transaction (optional)") + cmd.Flags().StringVar(&safeNonceRaw, "safe-nonce", "", "Safe nonce overrider for the transaction (optional)") 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)") @@ -3351,13 +3548,14 @@ func CreateSetApprovalForAllCommand() *cobra.Command { return cmd } func CreateTransferFromCommand() *cobra.Command { - var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw string + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw, safeFunction, safeNonceRaw string var gasLimit uint64 var simulate bool var timeout uint var contractAddress common.Address var safeAddress, safeApi string var safeOperationType uint8 + var safeNonce *big.Int var from0 common.Address var from0Raw string @@ -3407,6 +3605,17 @@ func CreateTransferFromCommand() *cobra.Command { if SafeOperationType(safeOperationType).String() == "Unknown" { return fmt.Errorf("--safe-operation must be 0 (Call) or 1 (DelegateCall)") } + + if safeNonceRaw == "" { + fmt.Println("--safe-nonce not specified, fetching nonce from Safe contract") + safeNonce = big.NewInt(0) + } else { + safeNonce = new(big.Int) + _, ok := safeNonce.SetString(safeNonceRaw, 0) + if !ok { + return fmt.Errorf("--safe-nonce is not a valid big integer") + } + } } if from0Raw == "" { @@ -3467,9 +3676,19 @@ func CreateTransferFromCommand() *cobra.Command { } if safeAddress != "" { - // Generate transaction data - transaction, err := session.TransferFrom( + abi, err := OwnableERC721MetaData.GetAbi() + if err != nil { + return fmt.Errorf("failed to get ABI: %v", err) + } + + // Generate transaction data (override method name if safe function is specified) + methodName := "transferFrom" + if safeFunction != "" { + methodName = safeFunction + } + transaction, err := abi.Pack( + methodName, from0, to0, tokenId, @@ -3484,7 +3703,8 @@ func CreateTransferFromCommand() *cobra.Command { if value == nil { value = big.NewInt(0) } - err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, transaction.Data(), value, safeApi, SafeOperationType(safeOperationType)) + + err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, transaction, value, safeApi, SafeOperationType(safeOperationType), safeNonce) if err != nil { return fmt.Errorf("failed to create Safe proposal: %v", err) } @@ -3548,6 +3768,8 @@ func CreateTransferFromCommand() *cobra.Command { 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(&safeFunction, "safe-function", "", "Safe function overrider to use for the transaction (optional)") + cmd.Flags().StringVar(&safeNonceRaw, "safe-nonce", "", "Safe nonce overrider for the transaction (optional)") cmd.Flags().StringVar(&from0Raw, "from-0", "", "from-0 argument (common.Address)") cmd.Flags().StringVar(&to0Raw, "to-0", "", "to-0 argument (common.Address)") @@ -3556,13 +3778,14 @@ func CreateTransferFromCommand() *cobra.Command { return cmd } func CreateTransferOwnershipCommand() *cobra.Command { - var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw string + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw, safeFunction, safeNonceRaw string var gasLimit uint64 var simulate bool var timeout uint var contractAddress common.Address var safeAddress, safeApi string var safeOperationType uint8 + var safeNonce *big.Int var newOwner common.Address var newOwnerRaw string @@ -3608,6 +3831,17 @@ func CreateTransferOwnershipCommand() *cobra.Command { if SafeOperationType(safeOperationType).String() == "Unknown" { return fmt.Errorf("--safe-operation must be 0 (Call) or 1 (DelegateCall)") } + + if safeNonceRaw == "" { + fmt.Println("--safe-nonce not specified, fetching nonce from Safe contract") + safeNonce = big.NewInt(0) + } else { + safeNonce = new(big.Int) + _, ok := safeNonce.SetString(safeNonceRaw, 0) + if !ok { + return fmt.Errorf("--safe-nonce is not a valid big integer") + } + } } if newOwnerRaw == "" { @@ -3655,9 +3889,19 @@ func CreateTransferOwnershipCommand() *cobra.Command { } if safeAddress != "" { - // Generate transaction data - transaction, err := session.TransferOwnership( + abi, err := OwnableERC721MetaData.GetAbi() + if err != nil { + return fmt.Errorf("failed to get ABI: %v", err) + } + + // Generate transaction data (override method name if safe function is specified) + methodName := "transferOwnership" + if safeFunction != "" { + methodName = safeFunction + } + transaction, err := abi.Pack( + methodName, newOwner, ) @@ -3670,7 +3914,8 @@ func CreateTransferOwnershipCommand() *cobra.Command { if value == nil { value = big.NewInt(0) } - err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, transaction.Data(), value, safeApi, SafeOperationType(safeOperationType)) + + err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, transaction, value, safeApi, SafeOperationType(safeOperationType), safeNonce) if err != nil { return fmt.Errorf("failed to create Safe proposal: %v", err) } @@ -3732,6 +3977,8 @@ func CreateTransferOwnershipCommand() *cobra.Command { 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(&safeFunction, "safe-function", "", "Safe function overrider to use for the transaction (optional)") + cmd.Flags().StringVar(&safeNonceRaw, "safe-nonce", "", "Safe nonce overrider for the transaction (optional)") cmd.Flags().StringVar(&newOwnerRaw, "new-owner", "", "new-owner argument (common.Address)") @@ -3959,7 +4206,7 @@ type SafeTransactionData struct { GasPrice string `json:"gasPrice"` GasToken string `json:"gasToken"` RefundReceiver string `json:"refundReceiver"` - Nonce uint64 `json:"nonce"` + Nonce *big.Int `json:"nonce"` SafeTxHash string `json:"safeTxHash"` Sender string `json:"sender"` Signature string `json:"signature"` @@ -3970,7 +4217,7 @@ 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 { +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, safeNonce *big.Int) error { abi, err := CreateCall.CreateCallMetaData.GetAbi() if err != nil { return fmt.Errorf("failed to get ABI: %v", err) @@ -3981,10 +4228,20 @@ func DeployWithSafe(client *ethclient.Client, key *keystore.Key, safeAddress com return fmt.Errorf("failed to pack performCreate2 transaction: %v", err) } - return CreateSafeProposal(client, key, safeAddress, factoryAddress, safeCreateCallTxData, value, safeApi, SafeOperationType(safeOperationType)) + return CreateSafeProposal(client, key, safeAddress, factoryAddress, safeCreateCallTxData, value, safeApi, SafeOperationType(safeOperationType), safeNonce) +} + +func PredictDeploymentAddressSafe(from common.Address, salt [32]byte, deployBytecode []byte) (common.Address, error) { + // Calculate the hash of the init code (deployment bytecode) + initCodeHash := crypto.Keccak256(deployBytecode) + + // Calculate the CREATE2 address + deployedAddress := crypto.CreateAddress2(from, salt, initCodeHash) + + return deployedAddress, nil } -func CreateSafeProposal(client *ethclient.Client, key *keystore.Key, safeAddress common.Address, to common.Address, data []byte, value *big.Int, safeApi string, safeOperationType SafeOperationType) error { +func CreateSafeProposal(client *ethclient.Client, key *keystore.Key, safeAddress common.Address, to common.Address, data []byte, value *big.Int, safeApi string, safeOperationType SafeOperationType, safeNonce *big.Int) error { chainID, err := client.ChainID(context.Background()) if err != nil { return fmt.Errorf("failed to get chain ID: %v", err) @@ -3996,10 +4253,16 @@ func CreateSafeProposal(client *ethclient.Client, key *keystore.Key, safeAddress 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) + nonce := safeNonce + if safeNonce == big.NewInt(0) { + // Fetch the current nonce from the Safe contract + fetchedNonce, err := safeInstance.Nonce(&bind.CallOpts{}) + if err != nil { + return fmt.Errorf("failed to fetch nonce from Safe contract: %v", err) + } + nonce = fetchedNonce + } else { + nonce = safeNonce } safeTransactionData := SafeTransactionData{ @@ -4012,7 +4275,7 @@ func CreateSafeProposal(client *ethclient.Client, key *keystore.Key, safeAddress GasPrice: "0", GasToken: NativeTokenAddress, RefundReceiver: NativeTokenAddress, - Nonce: nonce.Uint64(), + Nonce: nonce, } // Calculate SafeTxHash diff --git a/go.mod b/go.mod index 5adb2c5..3ade577 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/moonstream-to/seer +module github.com/G7DAO/seer go 1.22.0 diff --git a/indexer/db.go b/indexer/db.go index 7c87100..3d9f950 100644 --- a/indexer/db.go +++ b/indexer/db.go @@ -1137,12 +1137,12 @@ func (p *PostgreSQLpgx) UpdateAbiJobsStatus(blockchain string) error { return nil } -func (p *PostgreSQLpgx) SelectAbiJobs(blockchain string, addresses []string, customersIds []string, autoJobs bool) ([]CustomerUpdates, map[string]AbiJobsDeployInfo, error) { +func (p *PostgreSQLpgx) SelectAbiJobs(blockchain string, addresses []string, customersIds []string, autoJobs, isDeployBlockNotNull bool, abiTypes []string) ([]AbiJob, error) { pool := p.GetPool() conn, err := pool.Acquire(context.Background()) if err != nil { - return nil, nil, err + return nil, err } defer conn.Release() @@ -1150,16 +1150,32 @@ func (p *PostgreSQLpgx) SelectAbiJobs(blockchain string, addresses []string, cus queryArgs := make(pgx.NamedArgs) - queryArgs["chain"] = blockchain - queryBuilder.WriteString(` SELECT id, address, user_id, customer_id, abi_selector, chain, abi_name, status, historical_crawl_status, progress, moonworm_task_pickedup, '[' || abi || ']' as abi, (abi::jsonb)->>'type' AS abiType, created_at, updated_at, deployment_block_number FROM abi_jobs - WHERE chain = @chain AND ((abi::jsonb)->>'type' = 'function' or (abi::jsonb)->>'type' = 'event') and deployment_block_number is not null + WHERE true `) + if len(abiTypes) != 0 { + var abiConditions []string + for _, abiType := range abiTypes { + abiConditions = append(abiConditions, fmt.Sprintf("(abi::jsonb)->>'type' = '%s'", abiType)) + } + + queryBuilder.WriteString(fmt.Sprintf("AND (%s) ", strings.Join(abiConditions, " or "))) + } + + if isDeployBlockNotNull { + queryBuilder.WriteString(" AND deployment_block_number IS NOT null") + } + + if blockchain != "" { + queryBuilder.WriteString(" AND chain = @chain ") + queryArgs["chain"] = blockchain + } + if autoJobs { queryBuilder.WriteString(" AND historical_crawl_status != 'done' ") } @@ -1172,7 +1188,7 @@ func (p *PostgreSQLpgx) SelectAbiJobs(blockchain string, addresses []string, cus for i, address := range addresses { addressBytes, err := decodeAddress(address) if err != nil { - return nil, nil, err + return nil, err } addressesBytes[i] = addressBytes // Assign directly to the index } @@ -1188,15 +1204,91 @@ func (p *PostgreSQLpgx) SelectAbiJobs(blockchain string, addresses []string, cus rows, err := conn.Query(context.Background(), queryBuilder.String(), queryArgs) if err != nil { log.Println("Error querying ABI jobs from database", err) - return nil, nil, err + return nil, err } abiJobs, err := pgx.CollectRows(rows, pgx.RowToStructByName[AbiJob]) if err != nil { log.Println("Error collecting ABI jobs rows", err) - return nil, nil, err + return nil, err + } + + return abiJobs, nil +} + +func GetJobIds(abiJobs []AbiJob, isSilent bool) []string { + var jobIds []string + abiJobChains := make(map[string]int) + for _, abiJob := range abiJobs { + jobIds = append(jobIds, abiJob.ID) + if _, ok := abiJobChains[abiJob.Chain]; !ok { + abiJobChains[abiJob.Chain] = 0 + } + abiJobChains[abiJob.Chain]++ + } + + if !isSilent { + fmt.Printf("Found %d total:\n", len(jobIds)) + for k, v := range abiJobChains { + fmt.Printf("- %s - %d jobs\n", k, v) + } + } + + return jobIds +} + +func (p *PostgreSQLpgx) CopyAbiJobs(sourceCustomerId, destCustomerId string, abiJobs []AbiJob) error { + pool := p.GetPool() + + ctx := context.Background() + + conn, err := pool.Acquire(ctx) + if err != nil { + return err + } + defer conn.Release() + + tx, err := conn.Begin(ctx) + if err != nil { + return err + } + defer tx.Rollback(ctx) + + _, prepErr := tx.Prepare(ctx, "insertAbiJob", ` + INSERT INTO abi_jobs (id, address, user_id, customer_id, abi_selector, chain, abi_name, status, historical_crawl_status, progress, moonworm_task_pickedup, abi, created_at, updated_at) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, now(), now()) + `) + if prepErr != nil { + return err + } + + for _, abiJob := range abiJobs { + jobID := uuid.New() + + if len(abiJob.Abi) <= 2 || abiJob.Abi[0] != '[' || abiJob.Abi[len(abiJob.Abi)-1] != ']' { + log.Printf("Passed ABI job, incorrect format: %s", abiJob.Abi) + continue + } + abi := abiJob.Abi[1 : len(abiJob.Abi)-1] + abiBytes := []byte(abi) + + _, execErr := tx.Exec(ctx, "insertAbiJob", jobID, abiJob.Address, abiJob.UserID, destCustomerId, abiJob.AbiSelector, abiJob.Chain, abiJob.AbiName, "true", "pending", 0, false, abiBytes) + if execErr != nil { + return execErr + } + } + + commitErr := tx.Commit(ctx) + if commitErr != nil { + return commitErr } + log.Printf("Copied %d ABI jobs from customer %s to %s.", len(abiJobs), sourceCustomerId, destCustomerId) + + return nil +} + +func ConvertToCustomerUpdatedAndDeployBlockDicts(abiJobs []AbiJob) ([]CustomerUpdates, map[string]AbiJobsDeployInfo, error) { if len(abiJobs) == 0 { return []CustomerUpdates{}, map[string]AbiJobsDeployInfo{}, nil } @@ -1528,3 +1620,34 @@ func (p *PostgreSQLpgx) CreateJobsFromAbi(chain string, address string, abiFile return nil } + +func (p *PostgreSQLpgx) DeleteJobs(jobIds []string) error { + if len(jobIds) == 0 { + log.Println("Nothing to delete") + return nil + } + + pool := p.GetPool() + + conn, err := pool.Acquire(context.Background()) + if err != nil { + return err + } + defer conn.Release() + + var queryBuilder strings.Builder + queryBuilder.WriteString("DELETE FROM abi_jobs WHERE id = ANY(@jobIds)") + + queryArgs := make(pgx.NamedArgs) + queryArgs["jobIds"] = jobIds + + _, delErr := conn.Query(context.Background(), queryBuilder.String(), queryArgs) + if delErr != nil { + log.Printf("Error querying ABI jobs from database, err %v", delErr) + return delErr + } + + log.Printf("Deleted %d jobs", len(jobIds)) + + return nil +} diff --git a/starknet/generators.go b/starknet/generators.go index 6aaa310..c7ab786 100644 --- a/starknet/generators.go +++ b/starknet/generators.go @@ -7,8 +7,8 @@ import ( "strings" "text/template" + "github.com/G7DAO/seer/version" "github.com/iancoleman/strcase" - "github.com/moonstream-to/seer/version" ) // Common parameters required for the generation of all types of artifacts. @@ -672,7 +672,7 @@ func (p *EventParser) Parse(event RawEvent) (ParsedEvent, error) { // This is the Go template used to create header information at the top of the generated code. // At a bare minimum, the header specifies the version of seer that was used to generate the code. // This template should be applied to a HeaderParameters struct. -var HeaderTemplate string = `// This file was generated by seer: https://github.com/moonstream-to/seer. +var HeaderTemplate string = `// This file was generated by seer: https://github.com/G7DAO/seer. // seer version: {{.Version}} // seer command: seer starknet generate {{if .PackageName}}--package {{.PackageName}}{{end}} // Warning: Edit at your own risk. Any edits you make will NOT survive the next code generation. diff --git a/synchronizer/synchronizer.go b/synchronizer/synchronizer.go index 700f585..5dfa7e2 100644 --- a/synchronizer/synchronizer.go +++ b/synchronizer/synchronizer.go @@ -13,10 +13,10 @@ import ( "sync" "time" - seer_blockchain "github.com/moonstream-to/seer/blockchain" - "github.com/moonstream-to/seer/crawler" - "github.com/moonstream-to/seer/indexer" - "github.com/moonstream-to/seer/storage" + seer_blockchain "github.com/G7DAO/seer/blockchain" + "github.com/G7DAO/seer/crawler" + "github.com/G7DAO/seer/indexer" + "github.com/G7DAO/seer/storage" ) type Synchronizer struct { @@ -434,9 +434,13 @@ func (d *Synchronizer) HistoricalSyncRef(customerDbUriFlag string, addresses []s } // Retrieve customer updates and deployment blocks - customerUpdates, addressesAbisInfo, err := indexer.DBConnection.SelectAbiJobs(d.blockchain, addresses, customerIds, autoJobs) + abiJobs, selectJobsErr := indexer.DBConnection.SelectAbiJobs(d.blockchain, addresses, customerIds, autoJobs, true, []string{"function", "event"}) + if selectJobsErr != nil { + return fmt.Errorf("error selecting ABI jobs: %w", selectJobsErr) + } + customerUpdates, addressesAbisInfo, err := indexer.ConvertToCustomerUpdatedAndDeployBlockDicts(abiJobs) if err != nil { - return fmt.Errorf("error selecting ABI jobs: %w", err) + return fmt.Errorf("error parsing ABI jobs: %w", err) } fmt.Printf("Found %d customer updates\n", len(customerUpdates)) diff --git a/version/version.go b/version/version.go index 0589ddd..ea1a905 100644 --- a/version/version.go +++ b/version/version.go @@ -1,3 +1,3 @@ package version -var SeerVersion string = "0.2.0" +var SeerVersion string = "0.3.3"