From 83998272dda9b1401154df55c36dea40fc71bbc8 Mon Sep 17 00:00:00 2001 From: osmaczko <33099791+osmaczko@users.noreply.github.com> Date: Fri, 5 May 2023 17:55:32 +0200 Subject: [PATCH] feat: add featured communities (#3459) --- contracts/directory/address.go | 3 +- contracts/directory/directory.abi | 110 +++++++++++++++++++++ contracts/directory/directory.go | 155 ++++++++++++++++++------------ contracts/directory/directory.sol | 14 --- contracts/directory/doc.go | 2 +- protocol/communities/manager.go | 7 +- protocol/messenger_communities.go | 8 ++ 7 files changed, 219 insertions(+), 80 deletions(-) create mode 100644 contracts/directory/directory.abi delete mode 100644 contracts/directory/directory.sol diff --git a/contracts/directory/address.go b/contracts/directory/address.go index 938995a14..de960081b 100644 --- a/contracts/directory/address.go +++ b/contracts/directory/address.go @@ -9,8 +9,7 @@ import ( var errorNotAvailableOnChainID = errors.New("not available for chainID") var contractAddressByChainID = map[uint64]common.Address{ - 69: common.HexToAddress("0x4BbCCa869E9931280Cb46AE0DfF18881Be581a4d"), // optimism kovan testnet - 420: common.HexToAddress("0xecc8e76abc781c411f7bf79f3b1254b66afe3b75"), // optimism goerli testnet + 420: common.HexToAddress("0x22EE86A14b49890957fE71990073C6C68E05F9C5"), // optimism goerli testnet } func ContractAddress(chainID uint64) (common.Address, error) { diff --git a/contracts/directory/directory.abi b/contracts/directory/directory.abi new file mode 100644 index 000000000..06378aa8d --- /dev/null +++ b/contracts/directory/directory.abi @@ -0,0 +1,110 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "community", + "type": "bytes" + } + ], + "name": "addCommunity", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getCommunities", + "outputs": [ + { + "internalType": "bytes[]", + "name": "", + "type": "bytes[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getFeaturedCommunities", + "outputs": [ + { + "internalType": "bytes[]", + "name": "", + "type": "bytes[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "community", + "type": "bytes" + } + ], + "name": "isCommunityFeatured", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "community", + "type": "bytes" + } + ], + "name": "isCommunityInDirectory", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "community", + "type": "bytes" + } + ], + "name": "removeCommunity", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes[]", + "name": "_featuredCommunities", + "type": "bytes[]" + } + ], + "name": "setFeaturedCommunities", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/contracts/directory/directory.go b/contracts/directory/directory.go index 5fe7967fd..902673f0c 100644 --- a/contracts/directory/directory.go +++ b/contracts/directory/directory.go @@ -4,6 +4,7 @@ package directory import ( + "errors" "math/big" "strings" @@ -17,6 +18,7 @@ import ( // Reference imports to suppress errors if they are not otherwise used. var ( + _ = errors.New _ = big.NewInt _ = strings.NewReader _ = ethereum.NotFound @@ -24,36 +26,17 @@ var ( _ = common.Big1 _ = types.BloomLookup _ = event.NewSubscription + _ = abi.ConvertType ) +// DirectoryMetaData contains all meta data concerning the Directory contract. +var DirectoryMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"community\",\"type\":\"bytes\"}],\"name\":\"addCommunity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCommunities\",\"outputs\":[{\"internalType\":\"bytes[]\",\"name\":\"\",\"type\":\"bytes[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFeaturedCommunities\",\"outputs\":[{\"internalType\":\"bytes[]\",\"name\":\"\",\"type\":\"bytes[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"community\",\"type\":\"bytes\"}],\"name\":\"isCommunityFeatured\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"community\",\"type\":\"bytes\"}],\"name\":\"isCommunityInDirectory\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"community\",\"type\":\"bytes\"}],\"name\":\"removeCommunity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes[]\",\"name\":\"_featuredCommunities\",\"type\":\"bytes[]\"}],\"name\":\"setFeaturedCommunities\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", +} + // DirectoryABI is the input ABI used to generate the binding from. -const DirectoryABI = "[{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"community\",\"type\":\"bytes\"}],\"name\":\"addCommunity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"communities\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCommunities\",\"outputs\":[{\"internalType\":\"bytes[]\",\"name\":\"\",\"type\":\"bytes[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"community\",\"type\":\"bytes\"}],\"name\":\"isCommunityInDirectory\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"community\",\"type\":\"bytes\"}],\"name\":\"removeCommunity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]" - -// DirectoryFuncSigs maps the 4-byte function signature to its string representation. -var DirectoryFuncSigs = map[string]string{ - "74837935": "addCommunity(bytes)", - "e590b56a": "communities(uint256)", - "c251b565": "getCommunities()", - "b3dbb52a": "isCommunityInDirectory(bytes)", - "3c01b93c": "removeCommunity(bytes)", -} - -// DirectoryBin is the compiled bytecode used for deploying new contracts. -var DirectoryBin = "0x608060405234801561001057600080fd5b5061033b806100206000396000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c80633c01b93c1461005c578063748379351461005c578063b3dbb52a14610070578063c251b5651461009b578063e590b56a146100aa575b600080fd5b61006e61006a366004610176565b5050565b005b61008661007e366004610176565b600092915050565b60405190151581526020015b60405180910390f35b60606040516100929190610235565b6100bd6100b8366004610297565b6100ca565b60405161009291906102b0565b600081815481106100da57600080fd5b9060005260206000200160009150905080546100f5906102ca565b80601f0160208091040260200160405190810160405280929190818152602001828054610121906102ca565b801561016e5780601f106101435761010080835404028352916020019161016e565b820191906000526020600020905b81548152906001019060200180831161015157829003601f168201915b505050505081565b6000806020838503121561018957600080fd5b823567ffffffffffffffff808211156101a157600080fd5b818501915085601f8301126101b557600080fd5b8135818111156101c457600080fd5b8660208285010111156101d657600080fd5b60209290920196919550909350505050565b6000815180845260005b8181101561020e576020818501810151868301820152016101f2565b81811115610220576000602083870101525b50601f01601f19169290920160200192915050565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b8281101561028a57603f198886030184526102788583516101e8565b9450928501929085019060010161025c565b5092979650505050505050565b6000602082840312156102a957600080fd5b5035919050565b6020815260006102c360208301846101e8565b9392505050565b600181811c908216806102de57607f821691505b602082108114156102ff57634e487b7160e01b600052602260045260246000fd5b5091905056fea2646970667358221220f39ece68bf28d27ae1776133faa6ead8c1a3f73d975864e0cf6295808b53284664736f6c634300080b0033" - -// DeployDirectory deploys a new Ethereum contract, binding an instance of Directory to it. -func DeployDirectory(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *Directory, error) { - parsed, err := abi.JSON(strings.NewReader(DirectoryABI)) - if err != nil { - return common.Address{}, nil, nil, err - } - - address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(DirectoryBin), backend) - if err != nil { - return common.Address{}, nil, nil, err - } - return address, tx, &Directory{DirectoryCaller: DirectoryCaller{contract: contract}, DirectoryTransactor: DirectoryTransactor{contract: contract}, DirectoryFilterer: DirectoryFilterer{contract: contract}}, nil -} +// Deprecated: Use DirectoryMetaData.ABI instead. +var DirectoryABI = DirectoryMetaData.ABI // Directory is an auto generated Go binding around an Ethereum contract. type Directory struct { @@ -152,11 +135,11 @@ func NewDirectoryFilterer(address common.Address, filterer bind.ContractFilterer // bindDirectory binds a generic wrapper to an already deployed contract. func bindDirectory(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(DirectoryABI)) + parsed, err := DirectoryMetaData.GetAbi() if err != nil { return nil, err } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil } // Call invokes the (constant) contract method with params as input values and @@ -197,37 +180,6 @@ func (_Directory *DirectoryTransactorRaw) Transact(opts *bind.TransactOpts, meth return _Directory.Contract.contract.Transact(opts, method, params...) } -// Communities is a free data retrieval call binding the contract method 0xe590b56a. -// -// Solidity: function communities(uint256 ) view returns(bytes) -func (_Directory *DirectoryCaller) Communities(opts *bind.CallOpts, arg0 *big.Int) ([]byte, error) { - var out []interface{} - err := _Directory.contract.Call(opts, &out, "communities", arg0) - - if err != nil { - return *new([]byte), err - } - - out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) - - return out0, err - -} - -// Communities is a free data retrieval call binding the contract method 0xe590b56a. -// -// Solidity: function communities(uint256 ) view returns(bytes) -func (_Directory *DirectorySession) Communities(arg0 *big.Int) ([]byte, error) { - return _Directory.Contract.Communities(&_Directory.CallOpts, arg0) -} - -// Communities is a free data retrieval call binding the contract method 0xe590b56a. -// -// Solidity: function communities(uint256 ) view returns(bytes) -func (_Directory *DirectoryCallerSession) Communities(arg0 *big.Int) ([]byte, error) { - return _Directory.Contract.Communities(&_Directory.CallOpts, arg0) -} - // GetCommunities is a free data retrieval call binding the contract method 0xc251b565. // // Solidity: function getCommunities() view returns(bytes[]) @@ -259,6 +211,68 @@ func (_Directory *DirectoryCallerSession) GetCommunities() ([][]byte, error) { return _Directory.Contract.GetCommunities(&_Directory.CallOpts) } +// GetFeaturedCommunities is a free data retrieval call binding the contract method 0x967961c6. +// +// Solidity: function getFeaturedCommunities() view returns(bytes[]) +func (_Directory *DirectoryCaller) GetFeaturedCommunities(opts *bind.CallOpts) ([][]byte, error) { + var out []interface{} + err := _Directory.contract.Call(opts, &out, "getFeaturedCommunities") + + if err != nil { + return *new([][]byte), err + } + + out0 := *abi.ConvertType(out[0], new([][]byte)).(*[][]byte) + + return out0, err + +} + +// GetFeaturedCommunities is a free data retrieval call binding the contract method 0x967961c6. +// +// Solidity: function getFeaturedCommunities() view returns(bytes[]) +func (_Directory *DirectorySession) GetFeaturedCommunities() ([][]byte, error) { + return _Directory.Contract.GetFeaturedCommunities(&_Directory.CallOpts) +} + +// GetFeaturedCommunities is a free data retrieval call binding the contract method 0x967961c6. +// +// Solidity: function getFeaturedCommunities() view returns(bytes[]) +func (_Directory *DirectoryCallerSession) GetFeaturedCommunities() ([][]byte, error) { + return _Directory.Contract.GetFeaturedCommunities(&_Directory.CallOpts) +} + +// IsCommunityFeatured is a free data retrieval call binding the contract method 0xf6a18e62. +// +// Solidity: function isCommunityFeatured(bytes community) view returns(bool) +func (_Directory *DirectoryCaller) IsCommunityFeatured(opts *bind.CallOpts, community []byte) (bool, error) { + var out []interface{} + err := _Directory.contract.Call(opts, &out, "isCommunityFeatured", community) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// IsCommunityFeatured is a free data retrieval call binding the contract method 0xf6a18e62. +// +// Solidity: function isCommunityFeatured(bytes community) view returns(bool) +func (_Directory *DirectorySession) IsCommunityFeatured(community []byte) (bool, error) { + return _Directory.Contract.IsCommunityFeatured(&_Directory.CallOpts, community) +} + +// IsCommunityFeatured is a free data retrieval call binding the contract method 0xf6a18e62. +// +// Solidity: function isCommunityFeatured(bytes community) view returns(bool) +func (_Directory *DirectoryCallerSession) IsCommunityFeatured(community []byte) (bool, error) { + return _Directory.Contract.IsCommunityFeatured(&_Directory.CallOpts, community) +} + // IsCommunityInDirectory is a free data retrieval call binding the contract method 0xb3dbb52a. // // Solidity: function isCommunityInDirectory(bytes community) view returns(bool) @@ -331,3 +345,24 @@ func (_Directory *DirectorySession) RemoveCommunity(community []byte) (*types.Tr func (_Directory *DirectoryTransactorSession) RemoveCommunity(community []byte) (*types.Transaction, error) { return _Directory.Contract.RemoveCommunity(&_Directory.TransactOpts, community) } + +// SetFeaturedCommunities is a paid mutator transaction binding the contract method 0xd62879f1. +// +// Solidity: function setFeaturedCommunities(bytes[] _featuredCommunities) returns() +func (_Directory *DirectoryTransactor) SetFeaturedCommunities(opts *bind.TransactOpts, _featuredCommunities [][]byte) (*types.Transaction, error) { + return _Directory.contract.Transact(opts, "setFeaturedCommunities", _featuredCommunities) +} + +// SetFeaturedCommunities is a paid mutator transaction binding the contract method 0xd62879f1. +// +// Solidity: function setFeaturedCommunities(bytes[] _featuredCommunities) returns() +func (_Directory *DirectorySession) SetFeaturedCommunities(_featuredCommunities [][]byte) (*types.Transaction, error) { + return _Directory.Contract.SetFeaturedCommunities(&_Directory.TransactOpts, _featuredCommunities) +} + +// SetFeaturedCommunities is a paid mutator transaction binding the contract method 0xd62879f1. +// +// Solidity: function setFeaturedCommunities(bytes[] _featuredCommunities) returns() +func (_Directory *DirectoryTransactorSession) SetFeaturedCommunities(_featuredCommunities [][]byte) (*types.Transaction, error) { + return _Directory.Contract.SetFeaturedCommunities(&_Directory.TransactOpts, _featuredCommunities) +} diff --git a/contracts/directory/directory.sol b/contracts/directory/directory.sol deleted file mode 100644 index 77be0ad61..000000000 --- a/contracts/directory/directory.sol +++ /dev/null @@ -1,14 +0,0 @@ -pragma solidity ^0.8.5; - -contract Directory { - - bytes[] public communities; - - function isCommunityInDirectory(bytes calldata community) public view returns (bool) { } - - function getCommunities() public view returns (bytes[] memory) { } - - function addCommunity(bytes calldata community) public { } - - function removeCommunity(bytes calldata community) public { } -} diff --git a/contracts/directory/doc.go b/contracts/directory/doc.go index c3fd39e89..a38f14560 100644 --- a/contracts/directory/doc.go +++ b/contracts/directory/doc.go @@ -1,3 +1,3 @@ package directory -//go:generate abigen -sol directory.sol -pkg directory -out directory.go +//go:generate abigen -abi directory.abi -pkg directory -out directory.go diff --git a/protocol/communities/manager.go b/protocol/communities/manager.go index 058ea7c85..fd32500f2 100644 --- a/protocol/communities/manager.go +++ b/protocol/communities/manager.go @@ -402,9 +402,10 @@ func (m *Manager) All() ([]*Community, error) { } type KnownCommunitiesResponse struct { - ContractCommunities []string `json:"contractCommunities"` - Descriptions map[string]*Community `json:"communities"` - UnknownCommunities []string `json:"unknownCommunities"` + ContractCommunities []string `json:"contractCommunities"` + ContractFeaturedCommunities []string `json:"contractFeaturedCommunities"` + Descriptions map[string]*Community `json:"communities"` + UnknownCommunities []string `json:"unknownCommunities"` } func (m *Manager) GetStoredDescriptionForCommunities(communityIDs []types.HexBytes) (response *KnownCommunitiesResponse, err error) { diff --git a/protocol/messenger_communities.go b/protocol/messenger_communities.go index bc409ff42..934c7c965 100644 --- a/protocol/messenger_communities.go +++ b/protocol/messenger_communities.go @@ -346,6 +346,14 @@ func (m *Messenger) CuratedCommunities() (*communities.KnownCommunitiesResponse, return nil, err } + featuredCommunities, err := directory.GetFeaturedCommunities(callOpts) + if err != nil { + return nil, err + } + for _, c := range featuredCommunities { + response.ContractFeaturedCommunities = append(response.ContractFeaturedCommunities, string(c)) + } + go m.requestCommunitiesFromMailserver(response.UnknownCommunities) return response, nil