diff --git a/app/clients/evm/client_pool_test.go b/app/clients/evm/client_pool_test.go index 49b943314..b760704fc 100644 --- a/app/clients/evm/client_pool_test.go +++ b/app/clients/evm/client_pool_test.go @@ -59,7 +59,7 @@ func setupCP() { } func TestNewClientPool(t *testing.T) { - nodeUrls := []string{"https://ethereum-holesky-rpc.publicnode.com", "https://www.wikipedia.org"} + nodeUrls := []string{"https://eth.drpc.org", "https://eth-mainnet.public.blastapi.io"} configEvmPool := config.EvmPool{ BlockConfirmations: 3, NodeUrls: nodeUrls, @@ -88,7 +88,7 @@ func TestNewClientPool(t *testing.T) { } func TestNewClientPool_ContainsNonWorkingURL(t *testing.T) { - nodeUrls := []string{"http://localhost:8546", "https://ethereum-holesky-rpc.publicnode.com"} + nodeUrls := []string{"https://eth-mainnet.public.blastapi.io", "https://eth-mainnet.public.blastapi.io"} configEvmPool := config.EvmPool{ BlockConfirmations: 3, NodeUrls: nodeUrls, @@ -186,7 +186,7 @@ func TestClientPool_ValidateWebsocketUrl_Invalid(t *testing.T) { } func TestClientPool_CheckIfNodeURLIsValid_Valid(t *testing.T) { - result := checkIfNodeURLIsValid("https://ethereum-holesky-rpc.publicnode.com") + result := checkIfNodeURLIsValid("https://eth-mainnet.public.blastapi.io") assert.NoError(t, result) } diff --git a/app/clients/evm/contracts/router/diamond-router.go b/app/clients/evm/contracts/router/diamond-router.go index 6a91c37d0..e7bdfbcab 100644 --- a/app/clients/evm/contracts/router/diamond-router.go +++ b/app/clients/evm/contracts/router/diamond-router.go @@ -4,6 +4,7 @@ package router 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,6 +26,7 @@ var ( _ = common.Big1 _ = types.BloomLookup _ = event.NewSubscription + _ = abi.ConvertType ) // IDiamondCutFacetCut is an auto generated low-level Go binding around an user-defined struct. @@ -46,8 +49,14 @@ type WrappedTokenParams struct { Decimals uint8 } +// RouterMetaData contains all meta data concerning the Router contract. +var RouterMetaData = &bind.MetaData{ + ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"targetChain\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"}],\"name\":\"Burn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"member\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"memberAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Claim\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enumIDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"structIDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"DiamondCut\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"targetChain\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"serviceFee\",\"type\":\"uint256\"}],\"name\":\"Lock\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"member\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"}],\"name\":\"MemberAdminUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"member\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"status\",\"type\":\"bool\"}],\"name\":\"MemberUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"percentage\",\"type\":\"uint256\"}],\"name\":\"MembersPercentageUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"sourceChain\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"transactionId\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"}],\"name\":\"Mint\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"serviceFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"status\",\"type\":\"bool\"}],\"name\":\"NativeTokenUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newServiceFee\",\"type\":\"uint256\"}],\"name\":\"ServiceFeeSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"sourceChain\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"transactionId\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"serviceFee\",\"type\":\"uint256\"}],\"name\":\"Unlock\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"sourceChain\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"nativeToken\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"wrappedToken\",\"type\":\"address\"}],\"name\":\"WrappedTokenDeployed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_targetChain\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_wrappedToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_receiver\",\"type\":\"bytes\"}],\"name\":\"burn\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_targetChain\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_wrappedToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"_deadline\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"_v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"_r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"_s\",\"type\":\"bytes32\"}],\"name\":\"burnWithPermit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_member\",\"type\":\"address\"}],\"name\":\"claim\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_account\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"}],\"name\":\"claimedRewardsPerAccount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_sourceChain\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_nativeToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol\",\"type\":\"string\"},{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"}],\"internalType\":\"structWrappedTokenParams\",\"name\":\"_tokenParams\",\"type\":\"tuple\"}],\"name\":\"deployWrappedToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enumIDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"structIDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"diamondCut\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_functionSelector\",\"type\":\"bytes4\"}],\"name\":\"facetAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"facetAddress_\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facetAddresses\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"facetAddresses_\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_facet\",\"type\":\"address\"}],\"name\":\"facetFunctionSelectors\",\"outputs\":[{\"internalType\":\"bytes4[]\",\"name\":\"facetFunctionSelectors_\",\"type\":\"bytes4[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facets\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"structIDiamondLoupe.Facet[]\",\"name\":\"facets_\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_n\",\"type\":\"uint256\"}],\"name\":\"hasValidSignaturesLength\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_ethHash\",\"type\":\"bytes32\"}],\"name\":\"hashesUsed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_precision\",\"type\":\"uint256\"}],\"name\":\"initFeeCalculator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_members\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"_membersAdmins\",\"type\":\"address[]\"},{\"internalType\":\"uint256\",\"name\":\"_percentage\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_precision\",\"type\":\"uint256\"}],\"name\":\"initGovernance\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_member\",\"type\":\"address\"}],\"name\":\"isMember\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_targetChain\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_nativeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_receiver\",\"type\":\"bytes\"}],\"name\":\"lock\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_targetChain\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_nativeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"_deadline\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"_v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"_r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"_s\",\"type\":\"bytes32\"}],\"name\":\"lockWithPermit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_member\",\"type\":\"address\"}],\"name\":\"memberAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"memberAt\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"membersCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"membersPercentage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"membersPrecision\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_sourceChain\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_transactionId\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"_wrappedToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes[]\",\"name\":\"_signatures\",\"type\":\"bytes[]\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"nativeTokenAt\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"nativeTokensCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"owner_\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"paused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"serviceFeePrecision\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_serviceFeePercentage\",\"type\":\"uint256\"}],\"name\":\"setServiceFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"}],\"name\":\"tokenFeeData\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"serviceFeePercentage\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"feesAccrued\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"previousAccrued\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"accumulator\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_sourceChain\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_transactionId\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"_nativeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"},{\"internalType\":\"bytes[]\",\"name\":\"_signatures\",\"type\":\"bytes[]\"}],\"name\":\"unlock\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_newAdmin\",\"type\":\"address\"}],\"name\":\"updateAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_account\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_accountAdmin\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_status\",\"type\":\"bool\"}],\"name\":\"updateMember\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_member\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_newMemberAdmin\",\"type\":\"address\"}],\"name\":\"updateMemberAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_percentage\",\"type\":\"uint256\"}],\"name\":\"updateMembersPercentage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_nativeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_serviceFee\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"_status\",\"type\":\"bool\"}],\"name\":\"updateNativeToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", +} + // RouterABI is the input ABI used to generate the binding from. -const RouterABI = "[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"targetChain\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"}],\"name\":\"Burn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"targetChain\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"wrappedToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"paymentToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"name\":\"BurnERC721\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"member\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"memberAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Claim\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enumIDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"structIDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"DiamondCut\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"targetChain\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"serviceFee\",\"type\":\"uint256\"}],\"name\":\"Lock\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"member\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"}],\"name\":\"MemberAdminUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"member\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"status\",\"type\":\"bool\"}],\"name\":\"MemberUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"percentage\",\"type\":\"uint256\"}],\"name\":\"MembersPercentageUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"sourceChain\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"transactionId\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"}],\"name\":\"Mint\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"sourceChain\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"transactionId\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"metadata\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"}],\"name\":\"MintERC721\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"serviceFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"status\",\"type\":\"bool\"}],\"name\":\"NativeTokenUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newServiceFee\",\"type\":\"uint256\"}],\"name\":\"ServiceFeeSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"erc721\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"payment\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"name\":\"SetERC721Payment\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"_status\",\"type\":\"bool\"}],\"name\":\"SetPaymentToken\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"sourceChain\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"transactionId\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"serviceFee\",\"type\":\"uint256\"}],\"name\":\"Unlock\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"sourceChain\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"nativeToken\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"wrappedToken\",\"type\":\"address\"}],\"name\":\"WrappedTokenDeployed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_targetChain\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_wrappedToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_receiver\",\"type\":\"bytes\"}],\"name\":\"burn\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_targetChain\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_wrappedToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_tokenId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_paymentToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_fee\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_receiver\",\"type\":\"bytes\"}],\"name\":\"burnERC721\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_targetChain\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_wrappedToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"_deadline\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"_v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"_r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"_s\",\"type\":\"bytes32\"}],\"name\":\"burnWithPermit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_member\",\"type\":\"address\"}],\"name\":\"claim\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_account\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"}],\"name\":\"claimedRewardsPerAccount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_sourceChain\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_nativeToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol\",\"type\":\"string\"},{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"}],\"internalType\":\"structWrappedTokenParams\",\"name\":\"_tokenParams\",\"type\":\"tuple\"}],\"name\":\"deployWrappedToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enumIDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"structIDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"diamondCut\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_erc721\",\"type\":\"address\"}],\"name\":\"erc721Fee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_erc721\",\"type\":\"address\"}],\"name\":\"erc721Payment\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_functionSelector\",\"type\":\"bytes4\"}],\"name\":\"facetAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"facetAddress_\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facetAddresses\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"facetAddresses_\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_facet\",\"type\":\"address\"}],\"name\":\"facetFunctionSelectors\",\"outputs\":[{\"internalType\":\"bytes4[]\",\"name\":\"facetFunctionSelectors_\",\"type\":\"bytes4[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facets\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"structIDiamondLoupe.Facet[]\",\"name\":\"facets_\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_n\",\"type\":\"uint256\"}],\"name\":\"hasValidSignaturesLength\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_ethHash\",\"type\":\"bytes32\"}],\"name\":\"hashesUsed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_precision\",\"type\":\"uint256\"}],\"name\":\"initFeeCalculator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_members\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"_membersAdmins\",\"type\":\"address[]\"},{\"internalType\":\"uint256\",\"name\":\"_percentage\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_precision\",\"type\":\"uint256\"}],\"name\":\"initGovernance\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_member\",\"type\":\"address\"}],\"name\":\"isMember\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_targetChain\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_nativeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_receiver\",\"type\":\"bytes\"}],\"name\":\"lock\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_targetChain\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_nativeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"_deadline\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"_v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"_r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"_s\",\"type\":\"bytes32\"}],\"name\":\"lockWithPermit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_member\",\"type\":\"address\"}],\"name\":\"memberAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"memberAt\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"membersCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"membersPercentage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"membersPrecision\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_sourceChain\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_transactionId\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"_wrappedToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes[]\",\"name\":\"_signatures\",\"type\":\"bytes[]\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_sourceChain\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_transactionId\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"_wrappedToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_metadata\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"},{\"internalType\":\"bytes[]\",\"name\":\"_signatures\",\"type\":\"bytes[]\"}],\"name\":\"mintERC721\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"nativeTokenAt\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"nativeTokensCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"owner_\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"paused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"paymentTokenAt\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"serviceFeePrecision\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_erc721\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_payment\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_fee\",\"type\":\"uint256\"}],\"name\":\"setERC721Payment\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_status\",\"type\":\"bool\"}],\"name\":\"setPaymentToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_serviceFeePercentage\",\"type\":\"uint256\"}],\"name\":\"setServiceFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"}],\"name\":\"supportsPaymentToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"}],\"name\":\"tokenFeeData\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"serviceFeePercentage\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"feesAccrued\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"previousAccrued\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"accumulator\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalPaymentTokens\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_sourceChain\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_transactionId\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"_nativeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"},{\"internalType\":\"bytes[]\",\"name\":\"_signatures\",\"type\":\"bytes[]\"}],\"name\":\"unlock\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_newAdmin\",\"type\":\"address\"}],\"name\":\"updateAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_account\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_accountAdmin\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_status\",\"type\":\"bool\"}],\"name\":\"updateMember\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_member\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_newMemberAdmin\",\"type\":\"address\"}],\"name\":\"updateMemberAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_percentage\",\"type\":\"uint256\"}],\"name\":\"updateMembersPercentage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_nativeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_serviceFee\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"_status\",\"type\":\"bool\"}],\"name\":\"updateNativeToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]" +// Deprecated: Use RouterMetaData.ABI instead. +var RouterABI = RouterMetaData.ABI // Router is an auto generated Go binding around an Ethereum contract. type Router struct { @@ -146,11 +155,11 @@ func NewRouterFilterer(address common.Address, filterer bind.ContractFilterer) ( // bindRouter binds a generic wrapper to an already deployed contract. func bindRouter(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(RouterABI)) + parsed, err := RouterMetaData.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 @@ -253,68 +262,6 @@ func (_Router *RouterCallerSession) ClaimedRewardsPerAccount(_account common.Add return _Router.Contract.ClaimedRewardsPerAccount(&_Router.CallOpts, _account, _token) } -// Erc721Fee is a free data retrieval call binding the contract method 0x4d1a36b8. -// -// Solidity: function erc721Fee(address _erc721) view returns(uint256) -func (_Router *RouterCaller) Erc721Fee(opts *bind.CallOpts, _erc721 common.Address) (*big.Int, error) { - var out []interface{} - err := _Router.contract.Call(opts, &out, "erc721Fee", _erc721) - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// Erc721Fee is a free data retrieval call binding the contract method 0x4d1a36b8. -// -// Solidity: function erc721Fee(address _erc721) view returns(uint256) -func (_Router *RouterSession) Erc721Fee(_erc721 common.Address) (*big.Int, error) { - return _Router.Contract.Erc721Fee(&_Router.CallOpts, _erc721) -} - -// Erc721Fee is a free data retrieval call binding the contract method 0x4d1a36b8. -// -// Solidity: function erc721Fee(address _erc721) view returns(uint256) -func (_Router *RouterCallerSession) Erc721Fee(_erc721 common.Address) (*big.Int, error) { - return _Router.Contract.Erc721Fee(&_Router.CallOpts, _erc721) -} - -// Erc721Payment is a free data retrieval call binding the contract method 0x80b35f85. -// -// Solidity: function erc721Payment(address _erc721) view returns(address) -func (_Router *RouterCaller) Erc721Payment(opts *bind.CallOpts, _erc721 common.Address) (common.Address, error) { - var out []interface{} - err := _Router.contract.Call(opts, &out, "erc721Payment", _erc721) - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -// Erc721Payment is a free data retrieval call binding the contract method 0x80b35f85. -// -// Solidity: function erc721Payment(address _erc721) view returns(address) -func (_Router *RouterSession) Erc721Payment(_erc721 common.Address) (common.Address, error) { - return _Router.Contract.Erc721Payment(&_Router.CallOpts, _erc721) -} - -// Erc721Payment is a free data retrieval call binding the contract method 0x80b35f85. -// -// Solidity: function erc721Payment(address _erc721) view returns(address) -func (_Router *RouterCallerSession) Erc721Payment(_erc721 common.Address) (common.Address, error) { - return _Router.Contract.Erc721Payment(&_Router.CallOpts, _erc721) -} - // FacetAddress is a free data retrieval call binding the contract method 0xcdffacc6. // // Solidity: function facetAddress(bytes4 _functionSelector) view returns(address facetAddress_) @@ -811,37 +758,6 @@ func (_Router *RouterCallerSession) Paused() (bool, error) { return _Router.Contract.Paused(&_Router.CallOpts) } -// PaymentTokenAt is a free data retrieval call binding the contract method 0x3a3934c4. -// -// Solidity: function paymentTokenAt(uint256 _index) view returns(address) -func (_Router *RouterCaller) PaymentTokenAt(opts *bind.CallOpts, _index *big.Int) (common.Address, error) { - var out []interface{} - err := _Router.contract.Call(opts, &out, "paymentTokenAt", _index) - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -// PaymentTokenAt is a free data retrieval call binding the contract method 0x3a3934c4. -// -// Solidity: function paymentTokenAt(uint256 _index) view returns(address) -func (_Router *RouterSession) PaymentTokenAt(_index *big.Int) (common.Address, error) { - return _Router.Contract.PaymentTokenAt(&_Router.CallOpts, _index) -} - -// PaymentTokenAt is a free data retrieval call binding the contract method 0x3a3934c4. -// -// Solidity: function paymentTokenAt(uint256 _index) view returns(address) -func (_Router *RouterCallerSession) PaymentTokenAt(_index *big.Int) (common.Address, error) { - return _Router.Contract.PaymentTokenAt(&_Router.CallOpts, _index) -} - // ServiceFeePrecision is a free data retrieval call binding the contract method 0x6d4b6bf5. // // Solidity: function serviceFeePrecision() view returns(uint256) @@ -904,37 +820,6 @@ func (_Router *RouterCallerSession) SupportsInterface(interfaceId [4]byte) (bool return _Router.Contract.SupportsInterface(&_Router.CallOpts, interfaceId) } -// SupportsPaymentToken is a free data retrieval call binding the contract method 0x530c0668. -// -// Solidity: function supportsPaymentToken(address _token) view returns(bool) -func (_Router *RouterCaller) SupportsPaymentToken(opts *bind.CallOpts, _token common.Address) (bool, error) { - var out []interface{} - err := _Router.contract.Call(opts, &out, "supportsPaymentToken", _token) - - if err != nil { - return *new(bool), err - } - - out0 := *abi.ConvertType(out[0], new(bool)).(*bool) - - return out0, err - -} - -// SupportsPaymentToken is a free data retrieval call binding the contract method 0x530c0668. -// -// Solidity: function supportsPaymentToken(address _token) view returns(bool) -func (_Router *RouterSession) SupportsPaymentToken(_token common.Address) (bool, error) { - return _Router.Contract.SupportsPaymentToken(&_Router.CallOpts, _token) -} - -// SupportsPaymentToken is a free data retrieval call binding the contract method 0x530c0668. -// -// Solidity: function supportsPaymentToken(address _token) view returns(bool) -func (_Router *RouterCallerSession) SupportsPaymentToken(_token common.Address) (bool, error) { - return _Router.Contract.SupportsPaymentToken(&_Router.CallOpts, _token) -} - // TokenFeeData is a free data retrieval call binding the contract method 0xeb6fc3b1. // // Solidity: function tokenFeeData(address _token) view returns(uint256 serviceFeePercentage, uint256 feesAccrued, uint256 previousAccrued, uint256 accumulator) @@ -953,11 +838,14 @@ func (_Router *RouterCaller) TokenFeeData(opts *bind.CallOpts, _token common.Add PreviousAccrued *big.Int Accumulator *big.Int }) + if err != nil { + return *outstruct, err + } - outstruct.ServiceFeePercentage = out[0].(*big.Int) - outstruct.FeesAccrued = out[1].(*big.Int) - outstruct.PreviousAccrued = out[2].(*big.Int) - outstruct.Accumulator = out[3].(*big.Int) + outstruct.ServiceFeePercentage = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + outstruct.FeesAccrued = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) + outstruct.PreviousAccrued = *abi.ConvertType(out[2], new(*big.Int)).(**big.Int) + outstruct.Accumulator = *abi.ConvertType(out[3], new(*big.Int)).(**big.Int) return *outstruct, err @@ -987,37 +875,6 @@ func (_Router *RouterCallerSession) TokenFeeData(_token common.Address) (struct return _Router.Contract.TokenFeeData(&_Router.CallOpts, _token) } -// TotalPaymentTokens is a free data retrieval call binding the contract method 0xb6707500. -// -// Solidity: function totalPaymentTokens() view returns(uint256) -func (_Router *RouterCaller) TotalPaymentTokens(opts *bind.CallOpts) (*big.Int, error) { - var out []interface{} - err := _Router.contract.Call(opts, &out, "totalPaymentTokens") - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// TotalPaymentTokens is a free data retrieval call binding the contract method 0xb6707500. -// -// Solidity: function totalPaymentTokens() view returns(uint256) -func (_Router *RouterSession) TotalPaymentTokens() (*big.Int, error) { - return _Router.Contract.TotalPaymentTokens(&_Router.CallOpts) -} - -// TotalPaymentTokens is a free data retrieval call binding the contract method 0xb6707500. -// -// Solidity: function totalPaymentTokens() view returns(uint256) -func (_Router *RouterCallerSession) TotalPaymentTokens() (*big.Int, error) { - return _Router.Contract.TotalPaymentTokens(&_Router.CallOpts) -} - // Burn is a paid mutator transaction binding the contract method 0xd1979252. // // Solidity: function burn(uint256 _targetChain, address _wrappedToken, uint256 _amount, bytes _receiver) returns() @@ -1039,27 +896,6 @@ func (_Router *RouterTransactorSession) Burn(_targetChain *big.Int, _wrappedToke return _Router.Contract.Burn(&_Router.TransactOpts, _targetChain, _wrappedToken, _amount, _receiver) } -// BurnERC721 is a paid mutator transaction binding the contract method 0xd859fd9b. -// -// Solidity: function burnERC721(uint256 _targetChain, address _wrappedToken, uint256 _tokenId, address _paymentToken, uint256 _fee, bytes _receiver) returns() -func (_Router *RouterTransactor) BurnERC721(opts *bind.TransactOpts, _targetChain *big.Int, _wrappedToken common.Address, _tokenId *big.Int, _paymentToken common.Address, _fee *big.Int, _receiver []byte) (*types.Transaction, error) { - return _Router.contract.Transact(opts, "burnERC721", _targetChain, _wrappedToken, _tokenId, _paymentToken, _fee, _receiver) -} - -// BurnERC721 is a paid mutator transaction binding the contract method 0xd859fd9b. -// -// Solidity: function burnERC721(uint256 _targetChain, address _wrappedToken, uint256 _tokenId, address _paymentToken, uint256 _fee, bytes _receiver) returns() -func (_Router *RouterSession) BurnERC721(_targetChain *big.Int, _wrappedToken common.Address, _tokenId *big.Int, _paymentToken common.Address, _fee *big.Int, _receiver []byte) (*types.Transaction, error) { - return _Router.Contract.BurnERC721(&_Router.TransactOpts, _targetChain, _wrappedToken, _tokenId, _paymentToken, _fee, _receiver) -} - -// BurnERC721 is a paid mutator transaction binding the contract method 0xd859fd9b. -// -// Solidity: function burnERC721(uint256 _targetChain, address _wrappedToken, uint256 _tokenId, address _paymentToken, uint256 _fee, bytes _receiver) returns() -func (_Router *RouterTransactorSession) BurnERC721(_targetChain *big.Int, _wrappedToken common.Address, _tokenId *big.Int, _paymentToken common.Address, _fee *big.Int, _receiver []byte) (*types.Transaction, error) { - return _Router.Contract.BurnERC721(&_Router.TransactOpts, _targetChain, _wrappedToken, _tokenId, _paymentToken, _fee, _receiver) -} - // BurnWithPermit is a paid mutator transaction binding the contract method 0xd7c28714. // // Solidity: function burnWithPermit(uint256 _targetChain, address _wrappedToken, uint256 _amount, bytes _receiver, uint256 _deadline, uint8 _v, bytes32 _r, bytes32 _s) returns() @@ -1270,27 +1106,6 @@ func (_Router *RouterTransactorSession) Mint(_sourceChain *big.Int, _transaction return _Router.Contract.Mint(&_Router.TransactOpts, _sourceChain, _transactionId, _wrappedToken, _receiver, _amount, _signatures) } -// MintERC721 is a paid mutator transaction binding the contract method 0x35b5c501. -// -// Solidity: function mintERC721(uint256 _sourceChain, bytes _transactionId, address _wrappedToken, uint256 _tokenId, string _metadata, address _receiver, bytes[] _signatures) returns() -func (_Router *RouterTransactor) MintERC721(opts *bind.TransactOpts, _sourceChain *big.Int, _transactionId []byte, _wrappedToken common.Address, _tokenId *big.Int, _metadata string, _receiver common.Address, _signatures [][]byte) (*types.Transaction, error) { - return _Router.contract.Transact(opts, "mintERC721", _sourceChain, _transactionId, _wrappedToken, _tokenId, _metadata, _receiver, _signatures) -} - -// MintERC721 is a paid mutator transaction binding the contract method 0x35b5c501. -// -// Solidity: function mintERC721(uint256 _sourceChain, bytes _transactionId, address _wrappedToken, uint256 _tokenId, string _metadata, address _receiver, bytes[] _signatures) returns() -func (_Router *RouterSession) MintERC721(_sourceChain *big.Int, _transactionId []byte, _wrappedToken common.Address, _tokenId *big.Int, _metadata string, _receiver common.Address, _signatures [][]byte) (*types.Transaction, error) { - return _Router.Contract.MintERC721(&_Router.TransactOpts, _sourceChain, _transactionId, _wrappedToken, _tokenId, _metadata, _receiver, _signatures) -} - -// MintERC721 is a paid mutator transaction binding the contract method 0x35b5c501. -// -// Solidity: function mintERC721(uint256 _sourceChain, bytes _transactionId, address _wrappedToken, uint256 _tokenId, string _metadata, address _receiver, bytes[] _signatures) returns() -func (_Router *RouterTransactorSession) MintERC721(_sourceChain *big.Int, _transactionId []byte, _wrappedToken common.Address, _tokenId *big.Int, _metadata string, _receiver common.Address, _signatures [][]byte) (*types.Transaction, error) { - return _Router.Contract.MintERC721(&_Router.TransactOpts, _sourceChain, _transactionId, _wrappedToken, _tokenId, _metadata, _receiver, _signatures) -} - // Pause is a paid mutator transaction binding the contract method 0x8456cb59. // // Solidity: function pause() returns() @@ -1312,48 +1127,6 @@ func (_Router *RouterTransactorSession) Pause() (*types.Transaction, error) { return _Router.Contract.Pause(&_Router.TransactOpts) } -// SetERC721Payment is a paid mutator transaction binding the contract method 0x265155dc. -// -// Solidity: function setERC721Payment(address _erc721, address _payment, uint256 _fee) returns() -func (_Router *RouterTransactor) SetERC721Payment(opts *bind.TransactOpts, _erc721 common.Address, _payment common.Address, _fee *big.Int) (*types.Transaction, error) { - return _Router.contract.Transact(opts, "setERC721Payment", _erc721, _payment, _fee) -} - -// SetERC721Payment is a paid mutator transaction binding the contract method 0x265155dc. -// -// Solidity: function setERC721Payment(address _erc721, address _payment, uint256 _fee) returns() -func (_Router *RouterSession) SetERC721Payment(_erc721 common.Address, _payment common.Address, _fee *big.Int) (*types.Transaction, error) { - return _Router.Contract.SetERC721Payment(&_Router.TransactOpts, _erc721, _payment, _fee) -} - -// SetERC721Payment is a paid mutator transaction binding the contract method 0x265155dc. -// -// Solidity: function setERC721Payment(address _erc721, address _payment, uint256 _fee) returns() -func (_Router *RouterTransactorSession) SetERC721Payment(_erc721 common.Address, _payment common.Address, _fee *big.Int) (*types.Transaction, error) { - return _Router.Contract.SetERC721Payment(&_Router.TransactOpts, _erc721, _payment, _fee) -} - -// SetPaymentToken is a paid mutator transaction binding the contract method 0x430884cf. -// -// Solidity: function setPaymentToken(address _token, bool _status) returns() -func (_Router *RouterTransactor) SetPaymentToken(opts *bind.TransactOpts, _token common.Address, _status bool) (*types.Transaction, error) { - return _Router.contract.Transact(opts, "setPaymentToken", _token, _status) -} - -// SetPaymentToken is a paid mutator transaction binding the contract method 0x430884cf. -// -// Solidity: function setPaymentToken(address _token, bool _status) returns() -func (_Router *RouterSession) SetPaymentToken(_token common.Address, _status bool) (*types.Transaction, error) { - return _Router.Contract.SetPaymentToken(&_Router.TransactOpts, _token, _status) -} - -// SetPaymentToken is a paid mutator transaction binding the contract method 0x430884cf. -// -// Solidity: function setPaymentToken(address _token, bool _status) returns() -func (_Router *RouterTransactorSession) SetPaymentToken(_token common.Address, _status bool) (*types.Transaction, error) { - return _Router.Contract.SetPaymentToken(&_Router.TransactOpts, _token, _status) -} - // SetServiceFee is a paid mutator transaction binding the contract method 0xef2fa169. // // Solidity: function setServiceFee(address _token, uint256 _serviceFeePercentage) returns() @@ -1833,145 +1606,6 @@ func (_Router *RouterFilterer) ParseBurn(log types.Log) (*RouterBurn, error) { return event, nil } -// RouterBurnERC721Iterator is returned from FilterBurnERC721 and is used to iterate over the raw logs and unpacked data for BurnERC721 events raised by the Router contract. -type RouterBurnERC721Iterator struct { - Event *RouterBurnERC721 // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *RouterBurnERC721Iterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(RouterBurnERC721) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(RouterBurnERC721) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *RouterBurnERC721Iterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *RouterBurnERC721Iterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// RouterBurnERC721 represents a BurnERC721 event raised by the Router contract. -type RouterBurnERC721 struct { - TargetChain *big.Int - WrappedToken common.Address - TokenId *big.Int - Receiver []byte - PaymentToken common.Address - Fee *big.Int - Raw types.Log // Blockchain specific contextual infos -} - -// FilterBurnERC721 is a free log retrieval operation binding the contract event 0xeb703661daf51ce0c247ebbf71a8747e6a79f36b2e93a4e5a22f191321e5750e. -// -// Solidity: event BurnERC721(uint256 targetChain, address wrappedToken, uint256 tokenId, bytes receiver, address paymentToken, uint256 fee) -func (_Router *RouterFilterer) FilterBurnERC721(opts *bind.FilterOpts) (*RouterBurnERC721Iterator, error) { - - logs, sub, err := _Router.contract.FilterLogs(opts, "BurnERC721") - if err != nil { - return nil, err - } - return &RouterBurnERC721Iterator{contract: _Router.contract, event: "BurnERC721", logs: logs, sub: sub}, nil -} - -// WatchBurnERC721 is a free log subscription operation binding the contract event 0xeb703661daf51ce0c247ebbf71a8747e6a79f36b2e93a4e5a22f191321e5750e. -// -// Solidity: event BurnERC721(uint256 targetChain, address wrappedToken, uint256 tokenId, bytes receiver, address paymentToken, uint256 fee) -func (_Router *RouterFilterer) WatchBurnERC721(opts *bind.WatchOpts, sink chan<- *RouterBurnERC721) (event.Subscription, error) { - - logs, sub, err := _Router.contract.WatchLogs(opts, "BurnERC721") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(RouterBurnERC721) - if err := _Router.contract.UnpackLog(event, "BurnERC721", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseBurnERC721 is a log parse operation binding the contract event 0xeb703661daf51ce0c247ebbf71a8747e6a79f36b2e93a4e5a22f191321e5750e. -// -// Solidity: event BurnERC721(uint256 targetChain, address wrappedToken, uint256 tokenId, bytes receiver, address paymentToken, uint256 fee) -func (_Router *RouterFilterer) ParseBurnERC721(log types.Log) (*RouterBurnERC721, error) { - event := new(RouterBurnERC721) - if err := _Router.contract.UnpackLog(event, "BurnERC721", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - // RouterClaimIterator is returned from FilterClaim and is used to iterate over the raw logs and unpacked data for Claim events raised by the Router contract. type RouterClaimIterator struct { Event *RouterClaim // Event containing the contract specifics and raw log @@ -2943,9 +2577,9 @@ func (_Router *RouterFilterer) ParseMint(log types.Log) (*RouterMint, error) { return event, nil } -// RouterMintERC721Iterator is returned from FilterMintERC721 and is used to iterate over the raw logs and unpacked data for MintERC721 events raised by the Router contract. -type RouterMintERC721Iterator struct { - Event *RouterMintERC721 // Event containing the contract specifics and raw log +// RouterNativeTokenUpdatedIterator is returned from FilterNativeTokenUpdated and is used to iterate over the raw logs and unpacked data for NativeTokenUpdated events raised by the Router contract. +type RouterNativeTokenUpdatedIterator struct { + Event *RouterNativeTokenUpdated // Event containing the contract specifics and raw log contract *bind.BoundContract // Generic contract to use for unpacking event data event string // Event name to use for unpacking event data @@ -2959,7 +2593,7 @@ type RouterMintERC721Iterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *RouterMintERC721Iterator) Next() bool { +func (it *RouterNativeTokenUpdatedIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -2968,7 +2602,7 @@ func (it *RouterMintERC721Iterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(RouterMintERC721) + it.Event = new(RouterNativeTokenUpdated) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2983,7 +2617,7 @@ func (it *RouterMintERC721Iterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(RouterMintERC721) + it.Event = new(RouterNativeTokenUpdated) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2999,152 +2633,13 @@ func (it *RouterMintERC721Iterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *RouterMintERC721Iterator) Error() error { +func (it *RouterNativeTokenUpdatedIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *RouterMintERC721Iterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// RouterMintERC721 represents a MintERC721 event raised by the Router contract. -type RouterMintERC721 struct { - SourceChain *big.Int - TransactionId []byte - Token common.Address - TokenId *big.Int - Metadata string - Receiver common.Address - Raw types.Log // Blockchain specific contextual infos -} - -// FilterMintERC721 is a free log retrieval operation binding the contract event 0x554e454827c1d5586725e215a4b857d15071ba1d639f920082c5bf63b68de8b8. -// -// Solidity: event MintERC721(uint256 sourceChain, bytes transactionId, address token, uint256 tokenId, string metadata, address receiver) -func (_Router *RouterFilterer) FilterMintERC721(opts *bind.FilterOpts) (*RouterMintERC721Iterator, error) { - - logs, sub, err := _Router.contract.FilterLogs(opts, "MintERC721") - if err != nil { - return nil, err - } - return &RouterMintERC721Iterator{contract: _Router.contract, event: "MintERC721", logs: logs, sub: sub}, nil -} - -// WatchMintERC721 is a free log subscription operation binding the contract event 0x554e454827c1d5586725e215a4b857d15071ba1d639f920082c5bf63b68de8b8. -// -// Solidity: event MintERC721(uint256 sourceChain, bytes transactionId, address token, uint256 tokenId, string metadata, address receiver) -func (_Router *RouterFilterer) WatchMintERC721(opts *bind.WatchOpts, sink chan<- *RouterMintERC721) (event.Subscription, error) { - - logs, sub, err := _Router.contract.WatchLogs(opts, "MintERC721") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(RouterMintERC721) - if err := _Router.contract.UnpackLog(event, "MintERC721", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseMintERC721 is a log parse operation binding the contract event 0x554e454827c1d5586725e215a4b857d15071ba1d639f920082c5bf63b68de8b8. -// -// Solidity: event MintERC721(uint256 sourceChain, bytes transactionId, address token, uint256 tokenId, string metadata, address receiver) -func (_Router *RouterFilterer) ParseMintERC721(log types.Log) (*RouterMintERC721, error) { - event := new(RouterMintERC721) - if err := _Router.contract.UnpackLog(event, "MintERC721", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// RouterNativeTokenUpdatedIterator is returned from FilterNativeTokenUpdated and is used to iterate over the raw logs and unpacked data for NativeTokenUpdated events raised by the Router contract. -type RouterNativeTokenUpdatedIterator struct { - Event *RouterNativeTokenUpdated // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *RouterNativeTokenUpdatedIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(RouterNativeTokenUpdated) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(RouterNativeTokenUpdated) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *RouterNativeTokenUpdatedIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *RouterNativeTokenUpdatedIterator) Close() error { +func (it *RouterNativeTokenUpdatedIterator) Close() error { it.sub.Unsubscribe() return nil } @@ -3651,277 +3146,6 @@ func (_Router *RouterFilterer) ParseServiceFeeSet(log types.Log) (*RouterService return event, nil } -// RouterSetERC721PaymentIterator is returned from FilterSetERC721Payment and is used to iterate over the raw logs and unpacked data for SetERC721Payment events raised by the Router contract. -type RouterSetERC721PaymentIterator struct { - Event *RouterSetERC721Payment // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *RouterSetERC721PaymentIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(RouterSetERC721Payment) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(RouterSetERC721Payment) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *RouterSetERC721PaymentIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *RouterSetERC721PaymentIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// RouterSetERC721Payment represents a SetERC721Payment event raised by the Router contract. -type RouterSetERC721Payment struct { - Erc721 common.Address - Payment common.Address - Fee *big.Int - Raw types.Log // Blockchain specific contextual infos -} - -// FilterSetERC721Payment is a free log retrieval operation binding the contract event 0xf3a7d06752da6baf7839ac92daef9d3094b85f7208c209846eb19511a2828201. -// -// Solidity: event SetERC721Payment(address erc721, address payment, uint256 fee) -func (_Router *RouterFilterer) FilterSetERC721Payment(opts *bind.FilterOpts) (*RouterSetERC721PaymentIterator, error) { - - logs, sub, err := _Router.contract.FilterLogs(opts, "SetERC721Payment") - if err != nil { - return nil, err - } - return &RouterSetERC721PaymentIterator{contract: _Router.contract, event: "SetERC721Payment", logs: logs, sub: sub}, nil -} - -// WatchSetERC721Payment is a free log subscription operation binding the contract event 0xf3a7d06752da6baf7839ac92daef9d3094b85f7208c209846eb19511a2828201. -// -// Solidity: event SetERC721Payment(address erc721, address payment, uint256 fee) -func (_Router *RouterFilterer) WatchSetERC721Payment(opts *bind.WatchOpts, sink chan<- *RouterSetERC721Payment) (event.Subscription, error) { - - logs, sub, err := _Router.contract.WatchLogs(opts, "SetERC721Payment") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(RouterSetERC721Payment) - if err := _Router.contract.UnpackLog(event, "SetERC721Payment", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseSetERC721Payment is a log parse operation binding the contract event 0xf3a7d06752da6baf7839ac92daef9d3094b85f7208c209846eb19511a2828201. -// -// Solidity: event SetERC721Payment(address erc721, address payment, uint256 fee) -func (_Router *RouterFilterer) ParseSetERC721Payment(log types.Log) (*RouterSetERC721Payment, error) { - event := new(RouterSetERC721Payment) - if err := _Router.contract.UnpackLog(event, "SetERC721Payment", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// RouterSetPaymentTokenIterator is returned from FilterSetPaymentToken and is used to iterate over the raw logs and unpacked data for SetPaymentToken events raised by the Router contract. -type RouterSetPaymentTokenIterator struct { - Event *RouterSetPaymentToken // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *RouterSetPaymentTokenIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(RouterSetPaymentToken) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(RouterSetPaymentToken) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *RouterSetPaymentTokenIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *RouterSetPaymentTokenIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// RouterSetPaymentToken represents a SetPaymentToken event raised by the Router contract. -type RouterSetPaymentToken struct { - Token common.Address - Status bool - Raw types.Log // Blockchain specific contextual infos -} - -// FilterSetPaymentToken is a free log retrieval operation binding the contract event 0xfb2da8463afca3d57657a0d7cbeee4ade8c3596d1b1bca20e4795db47975910f. -// -// Solidity: event SetPaymentToken(address _token, bool _status) -func (_Router *RouterFilterer) FilterSetPaymentToken(opts *bind.FilterOpts) (*RouterSetPaymentTokenIterator, error) { - - logs, sub, err := _Router.contract.FilterLogs(opts, "SetPaymentToken") - if err != nil { - return nil, err - } - return &RouterSetPaymentTokenIterator{contract: _Router.contract, event: "SetPaymentToken", logs: logs, sub: sub}, nil -} - -// WatchSetPaymentToken is a free log subscription operation binding the contract event 0xfb2da8463afca3d57657a0d7cbeee4ade8c3596d1b1bca20e4795db47975910f. -// -// Solidity: event SetPaymentToken(address _token, bool _status) -func (_Router *RouterFilterer) WatchSetPaymentToken(opts *bind.WatchOpts, sink chan<- *RouterSetPaymentToken) (event.Subscription, error) { - - logs, sub, err := _Router.contract.WatchLogs(opts, "SetPaymentToken") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(RouterSetPaymentToken) - if err := _Router.contract.UnpackLog(event, "SetPaymentToken", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseSetPaymentToken is a log parse operation binding the contract event 0xfb2da8463afca3d57657a0d7cbeee4ade8c3596d1b1bca20e4795db47975910f. -// -// Solidity: event SetPaymentToken(address _token, bool _status) -func (_Router *RouterFilterer) ParseSetPaymentToken(log types.Log) (*RouterSetPaymentToken, error) { - event := new(RouterSetPaymentToken) - if err := _Router.contract.UnpackLog(event, "SetPaymentToken", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - // RouterUnlockIterator is returned from FilterUnlock and is used to iterate over the raw logs and unpacked data for Unlock events raised by the Router contract. type RouterUnlockIterator struct { Event *RouterUnlock // Event containing the contract specifics and raw log diff --git a/app/clients/evm/contracts/werc721/werc721.go b/app/clients/evm/contracts/werc721/werc721.go deleted file mode 100644 index b088bad7d..000000000 --- a/app/clients/evm/contracts/werc721/werc721.go +++ /dev/null @@ -1,1271 +0,0 @@ -// Code generated - DO NOT EDIT. -// This file is a generated binding and any manual changes will be lost. - -package werc721 - -import ( - "math/big" - "strings" - - ethereum "github.com/ethereum/go-ethereum" - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/event" -) - -// Reference imports to suppress errors if they are not otherwise used. -var ( - _ = big.NewInt - _ = strings.NewReader - _ = ethereum.NotFound - _ = bind.Bind - _ = common.Big1 - _ = types.BloomLookup - _ = event.NewSubscription -) - -// Werc721ABI is the input ABI used to generate the binding from. -const Werc721ABI = "[{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol\",\"type\":\"string\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"approved\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"}],\"name\":\"ApprovalForAll\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"burn\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"getApproved\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"isApprovedForAll\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"ownerOf\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"metadata\",\"type\":\"string\"}],\"name\":\"safeMint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"safeTransferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"safeTransferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"}],\"name\":\"setApprovalForAll\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"tokenURI\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]" - -// Werc721 is an auto generated Go binding around an Ethereum contract. -type Werc721 struct { - Werc721Caller // Read-only binding to the contract - Werc721Transactor // Write-only binding to the contract - Werc721Filterer // Log filterer for contract events -} - -// Werc721Caller is an auto generated read-only Go binding around an Ethereum contract. -type Werc721Caller struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// Werc721Transactor is an auto generated write-only Go binding around an Ethereum contract. -type Werc721Transactor struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// Werc721Filterer is an auto generated log filtering Go binding around an Ethereum contract events. -type Werc721Filterer struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// Werc721Session is an auto generated Go binding around an Ethereum contract, -// with pre-set call and transact options. -type Werc721Session struct { - Contract *Werc721 // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// Werc721CallerSession is an auto generated read-only Go binding around an Ethereum contract, -// with pre-set call options. -type Werc721CallerSession struct { - Contract *Werc721Caller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session -} - -// Werc721TransactorSession is an auto generated write-only Go binding around an Ethereum contract, -// with pre-set transact options. -type Werc721TransactorSession struct { - Contract *Werc721Transactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// Werc721Raw is an auto generated low-level Go binding around an Ethereum contract. -type Werc721Raw struct { - Contract *Werc721 // Generic contract binding to access the raw methods on -} - -// Werc721CallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type Werc721CallerRaw struct { - Contract *Werc721Caller // Generic read-only contract binding to access the raw methods on -} - -// Werc721TransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type Werc721TransactorRaw struct { - Contract *Werc721Transactor // Generic write-only contract binding to access the raw methods on -} - -// NewWerc721 creates a new instance of Werc721, bound to a specific deployed contract. -func NewWerc721(address common.Address, backend bind.ContractBackend) (*Werc721, error) { - contract, err := bindWerc721(address, backend, backend, backend) - if err != nil { - return nil, err - } - return &Werc721{Werc721Caller: Werc721Caller{contract: contract}, Werc721Transactor: Werc721Transactor{contract: contract}, Werc721Filterer: Werc721Filterer{contract: contract}}, nil -} - -// NewWerc721Caller creates a new read-only instance of Werc721, bound to a specific deployed contract. -func NewWerc721Caller(address common.Address, caller bind.ContractCaller) (*Werc721Caller, error) { - contract, err := bindWerc721(address, caller, nil, nil) - if err != nil { - return nil, err - } - return &Werc721Caller{contract: contract}, nil -} - -// NewWerc721Transactor creates a new write-only instance of Werc721, bound to a specific deployed contract. -func NewWerc721Transactor(address common.Address, transactor bind.ContractTransactor) (*Werc721Transactor, error) { - contract, err := bindWerc721(address, nil, transactor, nil) - if err != nil { - return nil, err - } - return &Werc721Transactor{contract: contract}, nil -} - -// NewWerc721Filterer creates a new log filterer instance of Werc721, bound to a specific deployed contract. -func NewWerc721Filterer(address common.Address, filterer bind.ContractFilterer) (*Werc721Filterer, error) { - contract, err := bindWerc721(address, nil, nil, filterer) - if err != nil { - return nil, err - } - return &Werc721Filterer{contract: contract}, nil -} - -// bindWerc721 binds a generic wrapper to an already deployed contract. -func bindWerc721(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(Werc721ABI)) - if err != nil { - return nil, err - } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_Werc721 *Werc721Raw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Werc721.Contract.Werc721Caller.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_Werc721 *Werc721Raw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Werc721.Contract.Werc721Transactor.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_Werc721 *Werc721Raw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Werc721.Contract.Werc721Transactor.contract.Transact(opts, method, params...) -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_Werc721 *Werc721CallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Werc721.Contract.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_Werc721 *Werc721TransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Werc721.Contract.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_Werc721 *Werc721TransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Werc721.Contract.contract.Transact(opts, method, params...) -} - -// BalanceOf is a free data retrieval call binding the contract method 0x70a08231. -// -// Solidity: function balanceOf(address owner) view returns(uint256) -func (_Werc721 *Werc721Caller) BalanceOf(opts *bind.CallOpts, owner common.Address) (*big.Int, error) { - var out []interface{} - err := _Werc721.contract.Call(opts, &out, "balanceOf", owner) - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// BalanceOf is a free data retrieval call binding the contract method 0x70a08231. -// -// Solidity: function balanceOf(address owner) view returns(uint256) -func (_Werc721 *Werc721Session) BalanceOf(owner common.Address) (*big.Int, error) { - return _Werc721.Contract.BalanceOf(&_Werc721.CallOpts, owner) -} - -// BalanceOf is a free data retrieval call binding the contract method 0x70a08231. -// -// Solidity: function balanceOf(address owner) view returns(uint256) -func (_Werc721 *Werc721CallerSession) BalanceOf(owner common.Address) (*big.Int, error) { - return _Werc721.Contract.BalanceOf(&_Werc721.CallOpts, owner) -} - -// GetApproved is a free data retrieval call binding the contract method 0x081812fc. -// -// Solidity: function getApproved(uint256 tokenId) view returns(address) -func (_Werc721 *Werc721Caller) GetApproved(opts *bind.CallOpts, tokenId *big.Int) (common.Address, error) { - var out []interface{} - err := _Werc721.contract.Call(opts, &out, "getApproved", tokenId) - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -// GetApproved is a free data retrieval call binding the contract method 0x081812fc. -// -// Solidity: function getApproved(uint256 tokenId) view returns(address) -func (_Werc721 *Werc721Session) GetApproved(tokenId *big.Int) (common.Address, error) { - return _Werc721.Contract.GetApproved(&_Werc721.CallOpts, tokenId) -} - -// GetApproved is a free data retrieval call binding the contract method 0x081812fc. -// -// Solidity: function getApproved(uint256 tokenId) view returns(address) -func (_Werc721 *Werc721CallerSession) GetApproved(tokenId *big.Int) (common.Address, error) { - return _Werc721.Contract.GetApproved(&_Werc721.CallOpts, tokenId) -} - -// IsApprovedForAll is a free data retrieval call binding the contract method 0xe985e9c5. -// -// Solidity: function isApprovedForAll(address owner, address operator) view returns(bool) -func (_Werc721 *Werc721Caller) IsApprovedForAll(opts *bind.CallOpts, owner common.Address, operator common.Address) (bool, error) { - var out []interface{} - err := _Werc721.contract.Call(opts, &out, "isApprovedForAll", owner, operator) - - if err != nil { - return *new(bool), err - } - - out0 := *abi.ConvertType(out[0], new(bool)).(*bool) - - return out0, err - -} - -// IsApprovedForAll is a free data retrieval call binding the contract method 0xe985e9c5. -// -// Solidity: function isApprovedForAll(address owner, address operator) view returns(bool) -func (_Werc721 *Werc721Session) IsApprovedForAll(owner common.Address, operator common.Address) (bool, error) { - return _Werc721.Contract.IsApprovedForAll(&_Werc721.CallOpts, owner, operator) -} - -// IsApprovedForAll is a free data retrieval call binding the contract method 0xe985e9c5. -// -// Solidity: function isApprovedForAll(address owner, address operator) view returns(bool) -func (_Werc721 *Werc721CallerSession) IsApprovedForAll(owner common.Address, operator common.Address) (bool, error) { - return _Werc721.Contract.IsApprovedForAll(&_Werc721.CallOpts, owner, operator) -} - -// Name is a free data retrieval call binding the contract method 0x06fdde03. -// -// Solidity: function name() view returns(string) -func (_Werc721 *Werc721Caller) Name(opts *bind.CallOpts) (string, error) { - var out []interface{} - err := _Werc721.contract.Call(opts, &out, "name") - - if err != nil { - return *new(string), err - } - - out0 := *abi.ConvertType(out[0], new(string)).(*string) - - return out0, err - -} - -// Name is a free data retrieval call binding the contract method 0x06fdde03. -// -// Solidity: function name() view returns(string) -func (_Werc721 *Werc721Session) Name() (string, error) { - return _Werc721.Contract.Name(&_Werc721.CallOpts) -} - -// Name is a free data retrieval call binding the contract method 0x06fdde03. -// -// Solidity: function name() view returns(string) -func (_Werc721 *Werc721CallerSession) Name() (string, error) { - return _Werc721.Contract.Name(&_Werc721.CallOpts) -} - -// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. -// -// Solidity: function owner() view returns(address) -func (_Werc721 *Werc721Caller) Owner(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _Werc721.contract.Call(opts, &out, "owner") - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. -// -// Solidity: function owner() view returns(address) -func (_Werc721 *Werc721Session) Owner() (common.Address, error) { - return _Werc721.Contract.Owner(&_Werc721.CallOpts) -} - -// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. -// -// Solidity: function owner() view returns(address) -func (_Werc721 *Werc721CallerSession) Owner() (common.Address, error) { - return _Werc721.Contract.Owner(&_Werc721.CallOpts) -} - -// OwnerOf is a free data retrieval call binding the contract method 0x6352211e. -// -// Solidity: function ownerOf(uint256 tokenId) view returns(address) -func (_Werc721 *Werc721Caller) OwnerOf(opts *bind.CallOpts, tokenId *big.Int) (common.Address, error) { - var out []interface{} - err := _Werc721.contract.Call(opts, &out, "ownerOf", tokenId) - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -// OwnerOf is a free data retrieval call binding the contract method 0x6352211e. -// -// Solidity: function ownerOf(uint256 tokenId) view returns(address) -func (_Werc721 *Werc721Session) OwnerOf(tokenId *big.Int) (common.Address, error) { - return _Werc721.Contract.OwnerOf(&_Werc721.CallOpts, tokenId) -} - -// OwnerOf is a free data retrieval call binding the contract method 0x6352211e. -// -// Solidity: function ownerOf(uint256 tokenId) view returns(address) -func (_Werc721 *Werc721CallerSession) OwnerOf(tokenId *big.Int) (common.Address, error) { - return _Werc721.Contract.OwnerOf(&_Werc721.CallOpts, tokenId) -} - -// SupportsInterface is a free data retrieval call binding the contract method 0x01ffc9a7. -// -// Solidity: function supportsInterface(bytes4 interfaceId) view returns(bool) -func (_Werc721 *Werc721Caller) SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) { - var out []interface{} - err := _Werc721.contract.Call(opts, &out, "supportsInterface", interfaceId) - - if err != nil { - return *new(bool), err - } - - out0 := *abi.ConvertType(out[0], new(bool)).(*bool) - - return out0, err - -} - -// SupportsInterface is a free data retrieval call binding the contract method 0x01ffc9a7. -// -// Solidity: function supportsInterface(bytes4 interfaceId) view returns(bool) -func (_Werc721 *Werc721Session) SupportsInterface(interfaceId [4]byte) (bool, error) { - return _Werc721.Contract.SupportsInterface(&_Werc721.CallOpts, interfaceId) -} - -// SupportsInterface is a free data retrieval call binding the contract method 0x01ffc9a7. -// -// Solidity: function supportsInterface(bytes4 interfaceId) view returns(bool) -func (_Werc721 *Werc721CallerSession) SupportsInterface(interfaceId [4]byte) (bool, error) { - return _Werc721.Contract.SupportsInterface(&_Werc721.CallOpts, interfaceId) -} - -// Symbol is a free data retrieval call binding the contract method 0x95d89b41. -// -// Solidity: function symbol() view returns(string) -func (_Werc721 *Werc721Caller) Symbol(opts *bind.CallOpts) (string, error) { - var out []interface{} - err := _Werc721.contract.Call(opts, &out, "symbol") - - if err != nil { - return *new(string), err - } - - out0 := *abi.ConvertType(out[0], new(string)).(*string) - - return out0, err - -} - -// Symbol is a free data retrieval call binding the contract method 0x95d89b41. -// -// Solidity: function symbol() view returns(string) -func (_Werc721 *Werc721Session) Symbol() (string, error) { - return _Werc721.Contract.Symbol(&_Werc721.CallOpts) -} - -// Symbol is a free data retrieval call binding the contract method 0x95d89b41. -// -// Solidity: function symbol() view returns(string) -func (_Werc721 *Werc721CallerSession) Symbol() (string, error) { - return _Werc721.Contract.Symbol(&_Werc721.CallOpts) -} - -// TokenURI is a free data retrieval call binding the contract method 0xc87b56dd. -// -// Solidity: function tokenURI(uint256 tokenId) view returns(string) -func (_Werc721 *Werc721Caller) TokenURI(opts *bind.CallOpts, tokenId *big.Int) (string, error) { - var out []interface{} - err := _Werc721.contract.Call(opts, &out, "tokenURI", tokenId) - - if err != nil { - return *new(string), err - } - - out0 := *abi.ConvertType(out[0], new(string)).(*string) - - return out0, err - -} - -// TokenURI is a free data retrieval call binding the contract method 0xc87b56dd. -// -// Solidity: function tokenURI(uint256 tokenId) view returns(string) -func (_Werc721 *Werc721Session) TokenURI(tokenId *big.Int) (string, error) { - return _Werc721.Contract.TokenURI(&_Werc721.CallOpts, tokenId) -} - -// TokenURI is a free data retrieval call binding the contract method 0xc87b56dd. -// -// Solidity: function tokenURI(uint256 tokenId) view returns(string) -func (_Werc721 *Werc721CallerSession) TokenURI(tokenId *big.Int) (string, error) { - return _Werc721.Contract.TokenURI(&_Werc721.CallOpts, tokenId) -} - -// Approve is a paid mutator transaction binding the contract method 0x095ea7b3. -// -// Solidity: function approve(address to, uint256 tokenId) returns() -func (_Werc721 *Werc721Transactor) Approve(opts *bind.TransactOpts, to common.Address, tokenId *big.Int) (*types.Transaction, error) { - return _Werc721.contract.Transact(opts, "approve", to, tokenId) -} - -// Approve is a paid mutator transaction binding the contract method 0x095ea7b3. -// -// Solidity: function approve(address to, uint256 tokenId) returns() -func (_Werc721 *Werc721Session) Approve(to common.Address, tokenId *big.Int) (*types.Transaction, error) { - return _Werc721.Contract.Approve(&_Werc721.TransactOpts, to, tokenId) -} - -// Approve is a paid mutator transaction binding the contract method 0x095ea7b3. -// -// Solidity: function approve(address to, uint256 tokenId) returns() -func (_Werc721 *Werc721TransactorSession) Approve(to common.Address, tokenId *big.Int) (*types.Transaction, error) { - return _Werc721.Contract.Approve(&_Werc721.TransactOpts, to, tokenId) -} - -// Burn is a paid mutator transaction binding the contract method 0x42966c68. -// -// Solidity: function burn(uint256 tokenId) returns() -func (_Werc721 *Werc721Transactor) Burn(opts *bind.TransactOpts, tokenId *big.Int) (*types.Transaction, error) { - return _Werc721.contract.Transact(opts, "burn", tokenId) -} - -// Burn is a paid mutator transaction binding the contract method 0x42966c68. -// -// Solidity: function burn(uint256 tokenId) returns() -func (_Werc721 *Werc721Session) Burn(tokenId *big.Int) (*types.Transaction, error) { - return _Werc721.Contract.Burn(&_Werc721.TransactOpts, tokenId) -} - -// Burn is a paid mutator transaction binding the contract method 0x42966c68. -// -// Solidity: function burn(uint256 tokenId) returns() -func (_Werc721 *Werc721TransactorSession) Burn(tokenId *big.Int) (*types.Transaction, error) { - return _Werc721.Contract.Burn(&_Werc721.TransactOpts, tokenId) -} - -// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. -// -// Solidity: function renounceOwnership() returns() -func (_Werc721 *Werc721Transactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Werc721.contract.Transact(opts, "renounceOwnership") -} - -// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. -// -// Solidity: function renounceOwnership() returns() -func (_Werc721 *Werc721Session) RenounceOwnership() (*types.Transaction, error) { - return _Werc721.Contract.RenounceOwnership(&_Werc721.TransactOpts) -} - -// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. -// -// Solidity: function renounceOwnership() returns() -func (_Werc721 *Werc721TransactorSession) RenounceOwnership() (*types.Transaction, error) { - return _Werc721.Contract.RenounceOwnership(&_Werc721.TransactOpts) -} - -// SafeMint is a paid mutator transaction binding the contract method 0xcd279c7c. -// -// Solidity: function safeMint(address to, uint256 tokenId, string metadata) returns() -func (_Werc721 *Werc721Transactor) SafeMint(opts *bind.TransactOpts, to common.Address, tokenId *big.Int, metadata string) (*types.Transaction, error) { - return _Werc721.contract.Transact(opts, "safeMint", to, tokenId, metadata) -} - -// SafeMint is a paid mutator transaction binding the contract method 0xcd279c7c. -// -// Solidity: function safeMint(address to, uint256 tokenId, string metadata) returns() -func (_Werc721 *Werc721Session) SafeMint(to common.Address, tokenId *big.Int, metadata string) (*types.Transaction, error) { - return _Werc721.Contract.SafeMint(&_Werc721.TransactOpts, to, tokenId, metadata) -} - -// SafeMint is a paid mutator transaction binding the contract method 0xcd279c7c. -// -// Solidity: function safeMint(address to, uint256 tokenId, string metadata) returns() -func (_Werc721 *Werc721TransactorSession) SafeMint(to common.Address, tokenId *big.Int, metadata string) (*types.Transaction, error) { - return _Werc721.Contract.SafeMint(&_Werc721.TransactOpts, to, tokenId, metadata) -} - -// SafeTransferFrom is a paid mutator transaction binding the contract method 0x42842e0e. -// -// Solidity: function safeTransferFrom(address from, address to, uint256 tokenId) returns() -func (_Werc721 *Werc721Transactor) SafeTransferFrom(opts *bind.TransactOpts, from common.Address, to common.Address, tokenId *big.Int) (*types.Transaction, error) { - return _Werc721.contract.Transact(opts, "safeTransferFrom", from, to, tokenId) -} - -// SafeTransferFrom is a paid mutator transaction binding the contract method 0x42842e0e. -// -// Solidity: function safeTransferFrom(address from, address to, uint256 tokenId) returns() -func (_Werc721 *Werc721Session) SafeTransferFrom(from common.Address, to common.Address, tokenId *big.Int) (*types.Transaction, error) { - return _Werc721.Contract.SafeTransferFrom(&_Werc721.TransactOpts, from, to, tokenId) -} - -// SafeTransferFrom is a paid mutator transaction binding the contract method 0x42842e0e. -// -// Solidity: function safeTransferFrom(address from, address to, uint256 tokenId) returns() -func (_Werc721 *Werc721TransactorSession) SafeTransferFrom(from common.Address, to common.Address, tokenId *big.Int) (*types.Transaction, error) { - return _Werc721.Contract.SafeTransferFrom(&_Werc721.TransactOpts, from, to, tokenId) -} - -// SafeTransferFrom0 is a paid mutator transaction binding the contract method 0xb88d4fde. -// -// Solidity: function safeTransferFrom(address from, address to, uint256 tokenId, bytes _data) returns() -func (_Werc721 *Werc721Transactor) SafeTransferFrom0(opts *bind.TransactOpts, from common.Address, to common.Address, tokenId *big.Int, _data []byte) (*types.Transaction, error) { - return _Werc721.contract.Transact(opts, "safeTransferFrom0", from, to, tokenId, _data) -} - -// SafeTransferFrom0 is a paid mutator transaction binding the contract method 0xb88d4fde. -// -// Solidity: function safeTransferFrom(address from, address to, uint256 tokenId, bytes _data) returns() -func (_Werc721 *Werc721Session) SafeTransferFrom0(from common.Address, to common.Address, tokenId *big.Int, _data []byte) (*types.Transaction, error) { - return _Werc721.Contract.SafeTransferFrom0(&_Werc721.TransactOpts, from, to, tokenId, _data) -} - -// SafeTransferFrom0 is a paid mutator transaction binding the contract method 0xb88d4fde. -// -// Solidity: function safeTransferFrom(address from, address to, uint256 tokenId, bytes _data) returns() -func (_Werc721 *Werc721TransactorSession) SafeTransferFrom0(from common.Address, to common.Address, tokenId *big.Int, _data []byte) (*types.Transaction, error) { - return _Werc721.Contract.SafeTransferFrom0(&_Werc721.TransactOpts, from, to, tokenId, _data) -} - -// SetApprovalForAll is a paid mutator transaction binding the contract method 0xa22cb465. -// -// Solidity: function setApprovalForAll(address operator, bool approved) returns() -func (_Werc721 *Werc721Transactor) SetApprovalForAll(opts *bind.TransactOpts, operator common.Address, approved bool) (*types.Transaction, error) { - return _Werc721.contract.Transact(opts, "setApprovalForAll", operator, approved) -} - -// SetApprovalForAll is a paid mutator transaction binding the contract method 0xa22cb465. -// -// Solidity: function setApprovalForAll(address operator, bool approved) returns() -func (_Werc721 *Werc721Session) SetApprovalForAll(operator common.Address, approved bool) (*types.Transaction, error) { - return _Werc721.Contract.SetApprovalForAll(&_Werc721.TransactOpts, operator, approved) -} - -// SetApprovalForAll is a paid mutator transaction binding the contract method 0xa22cb465. -// -// Solidity: function setApprovalForAll(address operator, bool approved) returns() -func (_Werc721 *Werc721TransactorSession) SetApprovalForAll(operator common.Address, approved bool) (*types.Transaction, error) { - return _Werc721.Contract.SetApprovalForAll(&_Werc721.TransactOpts, operator, approved) -} - -// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd. -// -// Solidity: function transferFrom(address from, address to, uint256 tokenId) returns() -func (_Werc721 *Werc721Transactor) TransferFrom(opts *bind.TransactOpts, from common.Address, to common.Address, tokenId *big.Int) (*types.Transaction, error) { - return _Werc721.contract.Transact(opts, "transferFrom", from, to, tokenId) -} - -// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd. -// -// Solidity: function transferFrom(address from, address to, uint256 tokenId) returns() -func (_Werc721 *Werc721Session) TransferFrom(from common.Address, to common.Address, tokenId *big.Int) (*types.Transaction, error) { - return _Werc721.Contract.TransferFrom(&_Werc721.TransactOpts, from, to, tokenId) -} - -// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd. -// -// Solidity: function transferFrom(address from, address to, uint256 tokenId) returns() -func (_Werc721 *Werc721TransactorSession) TransferFrom(from common.Address, to common.Address, tokenId *big.Int) (*types.Transaction, error) { - return _Werc721.Contract.TransferFrom(&_Werc721.TransactOpts, from, to, tokenId) -} - -// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. -// -// Solidity: function transferOwnership(address newOwner) returns() -func (_Werc721 *Werc721Transactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { - return _Werc721.contract.Transact(opts, "transferOwnership", newOwner) -} - -// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. -// -// Solidity: function transferOwnership(address newOwner) returns() -func (_Werc721 *Werc721Session) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { - return _Werc721.Contract.TransferOwnership(&_Werc721.TransactOpts, newOwner) -} - -// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. -// -// Solidity: function transferOwnership(address newOwner) returns() -func (_Werc721 *Werc721TransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { - return _Werc721.Contract.TransferOwnership(&_Werc721.TransactOpts, newOwner) -} - -// Werc721ApprovalIterator is returned from FilterApproval and is used to iterate over the raw logs and unpacked data for Approval events raised by the Werc721 contract. -type Werc721ApprovalIterator struct { - Event *Werc721Approval // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *Werc721ApprovalIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(Werc721Approval) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(Werc721Approval) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *Werc721ApprovalIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *Werc721ApprovalIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// Werc721Approval represents a Approval event raised by the Werc721 contract. -type Werc721Approval struct { - Owner common.Address - Approved common.Address - TokenId *big.Int - Raw types.Log // Blockchain specific contextual infos -} - -// FilterApproval is a free log retrieval operation binding the contract event 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925. -// -// Solidity: event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId) -func (_Werc721 *Werc721Filterer) FilterApproval(opts *bind.FilterOpts, owner []common.Address, approved []common.Address, tokenId []*big.Int) (*Werc721ApprovalIterator, error) { - - var ownerRule []interface{} - for _, ownerItem := range owner { - ownerRule = append(ownerRule, ownerItem) - } - var approvedRule []interface{} - for _, approvedItem := range approved { - approvedRule = append(approvedRule, approvedItem) - } - var tokenIdRule []interface{} - for _, tokenIdItem := range tokenId { - tokenIdRule = append(tokenIdRule, tokenIdItem) - } - - logs, sub, err := _Werc721.contract.FilterLogs(opts, "Approval", ownerRule, approvedRule, tokenIdRule) - if err != nil { - return nil, err - } - return &Werc721ApprovalIterator{contract: _Werc721.contract, event: "Approval", logs: logs, sub: sub}, nil -} - -// WatchApproval is a free log subscription operation binding the contract event 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925. -// -// Solidity: event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId) -func (_Werc721 *Werc721Filterer) WatchApproval(opts *bind.WatchOpts, sink chan<- *Werc721Approval, owner []common.Address, approved []common.Address, tokenId []*big.Int) (event.Subscription, error) { - - var ownerRule []interface{} - for _, ownerItem := range owner { - ownerRule = append(ownerRule, ownerItem) - } - var approvedRule []interface{} - for _, approvedItem := range approved { - approvedRule = append(approvedRule, approvedItem) - } - var tokenIdRule []interface{} - for _, tokenIdItem := range tokenId { - tokenIdRule = append(tokenIdRule, tokenIdItem) - } - - logs, sub, err := _Werc721.contract.WatchLogs(opts, "Approval", ownerRule, approvedRule, tokenIdRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(Werc721Approval) - if err := _Werc721.contract.UnpackLog(event, "Approval", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseApproval is a log parse operation binding the contract event 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925. -// -// Solidity: event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId) -func (_Werc721 *Werc721Filterer) ParseApproval(log types.Log) (*Werc721Approval, error) { - event := new(Werc721Approval) - if err := _Werc721.contract.UnpackLog(event, "Approval", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// Werc721ApprovalForAllIterator is returned from FilterApprovalForAll and is used to iterate over the raw logs and unpacked data for ApprovalForAll events raised by the Werc721 contract. -type Werc721ApprovalForAllIterator struct { - Event *Werc721ApprovalForAll // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *Werc721ApprovalForAllIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(Werc721ApprovalForAll) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(Werc721ApprovalForAll) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *Werc721ApprovalForAllIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *Werc721ApprovalForAllIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// Werc721ApprovalForAll represents a ApprovalForAll event raised by the Werc721 contract. -type Werc721ApprovalForAll struct { - Owner common.Address - Operator common.Address - Approved bool - Raw types.Log // Blockchain specific contextual infos -} - -// FilterApprovalForAll is a free log retrieval operation binding the contract event 0x17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31. -// -// Solidity: event ApprovalForAll(address indexed owner, address indexed operator, bool approved) -func (_Werc721 *Werc721Filterer) FilterApprovalForAll(opts *bind.FilterOpts, owner []common.Address, operator []common.Address) (*Werc721ApprovalForAllIterator, error) { - - var ownerRule []interface{} - for _, ownerItem := range owner { - ownerRule = append(ownerRule, ownerItem) - } - var operatorRule []interface{} - for _, operatorItem := range operator { - operatorRule = append(operatorRule, operatorItem) - } - - logs, sub, err := _Werc721.contract.FilterLogs(opts, "ApprovalForAll", ownerRule, operatorRule) - if err != nil { - return nil, err - } - return &Werc721ApprovalForAllIterator{contract: _Werc721.contract, event: "ApprovalForAll", logs: logs, sub: sub}, nil -} - -// WatchApprovalForAll is a free log subscription operation binding the contract event 0x17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31. -// -// Solidity: event ApprovalForAll(address indexed owner, address indexed operator, bool approved) -func (_Werc721 *Werc721Filterer) WatchApprovalForAll(opts *bind.WatchOpts, sink chan<- *Werc721ApprovalForAll, owner []common.Address, operator []common.Address) (event.Subscription, error) { - - var ownerRule []interface{} - for _, ownerItem := range owner { - ownerRule = append(ownerRule, ownerItem) - } - var operatorRule []interface{} - for _, operatorItem := range operator { - operatorRule = append(operatorRule, operatorItem) - } - - logs, sub, err := _Werc721.contract.WatchLogs(opts, "ApprovalForAll", ownerRule, operatorRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(Werc721ApprovalForAll) - if err := _Werc721.contract.UnpackLog(event, "ApprovalForAll", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseApprovalForAll is a log parse operation binding the contract event 0x17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31. -// -// Solidity: event ApprovalForAll(address indexed owner, address indexed operator, bool approved) -func (_Werc721 *Werc721Filterer) ParseApprovalForAll(log types.Log) (*Werc721ApprovalForAll, error) { - event := new(Werc721ApprovalForAll) - if err := _Werc721.contract.UnpackLog(event, "ApprovalForAll", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// Werc721OwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the Werc721 contract. -type Werc721OwnershipTransferredIterator struct { - Event *Werc721OwnershipTransferred // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *Werc721OwnershipTransferredIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(Werc721OwnershipTransferred) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(Werc721OwnershipTransferred) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *Werc721OwnershipTransferredIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *Werc721OwnershipTransferredIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// Werc721OwnershipTransferred represents a OwnershipTransferred event raised by the Werc721 contract. -type Werc721OwnershipTransferred struct { - PreviousOwner common.Address - NewOwner common.Address - Raw types.Log // Blockchain specific contextual infos -} - -// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. -// -// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -func (_Werc721 *Werc721Filterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*Werc721OwnershipTransferredIterator, error) { - - var previousOwnerRule []interface{} - for _, previousOwnerItem := range previousOwner { - previousOwnerRule = append(previousOwnerRule, previousOwnerItem) - } - var newOwnerRule []interface{} - for _, newOwnerItem := range newOwner { - newOwnerRule = append(newOwnerRule, newOwnerItem) - } - - logs, sub, err := _Werc721.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) - if err != nil { - return nil, err - } - return &Werc721OwnershipTransferredIterator{contract: _Werc721.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil -} - -// WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. -// -// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -func (_Werc721 *Werc721Filterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *Werc721OwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { - - var previousOwnerRule []interface{} - for _, previousOwnerItem := range previousOwner { - previousOwnerRule = append(previousOwnerRule, previousOwnerItem) - } - var newOwnerRule []interface{} - for _, newOwnerItem := range newOwner { - newOwnerRule = append(newOwnerRule, newOwnerItem) - } - - logs, sub, err := _Werc721.contract.WatchLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(Werc721OwnershipTransferred) - if err := _Werc721.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseOwnershipTransferred is a log parse operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. -// -// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -func (_Werc721 *Werc721Filterer) ParseOwnershipTransferred(log types.Log) (*Werc721OwnershipTransferred, error) { - event := new(Werc721OwnershipTransferred) - if err := _Werc721.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// Werc721TransferIterator is returned from FilterTransfer and is used to iterate over the raw logs and unpacked data for Transfer events raised by the Werc721 contract. -type Werc721TransferIterator struct { - Event *Werc721Transfer // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *Werc721TransferIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(Werc721Transfer) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(Werc721Transfer) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *Werc721TransferIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *Werc721TransferIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// Werc721Transfer represents a Transfer event raised by the Werc721 contract. -type Werc721Transfer struct { - From common.Address - To common.Address - TokenId *big.Int - Raw types.Log // Blockchain specific contextual infos -} - -// FilterTransfer is a free log retrieval operation binding the contract event 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef. -// -// Solidity: event Transfer(address indexed from, address indexed to, uint256 indexed tokenId) -func (_Werc721 *Werc721Filterer) FilterTransfer(opts *bind.FilterOpts, from []common.Address, to []common.Address, tokenId []*big.Int) (*Werc721TransferIterator, error) { - - var fromRule []interface{} - for _, fromItem := range from { - fromRule = append(fromRule, fromItem) - } - var toRule []interface{} - for _, toItem := range to { - toRule = append(toRule, toItem) - } - var tokenIdRule []interface{} - for _, tokenIdItem := range tokenId { - tokenIdRule = append(tokenIdRule, tokenIdItem) - } - - logs, sub, err := _Werc721.contract.FilterLogs(opts, "Transfer", fromRule, toRule, tokenIdRule) - if err != nil { - return nil, err - } - return &Werc721TransferIterator{contract: _Werc721.contract, event: "Transfer", logs: logs, sub: sub}, nil -} - -// WatchTransfer is a free log subscription operation binding the contract event 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef. -// -// Solidity: event Transfer(address indexed from, address indexed to, uint256 indexed tokenId) -func (_Werc721 *Werc721Filterer) WatchTransfer(opts *bind.WatchOpts, sink chan<- *Werc721Transfer, from []common.Address, to []common.Address, tokenId []*big.Int) (event.Subscription, error) { - - var fromRule []interface{} - for _, fromItem := range from { - fromRule = append(fromRule, fromItem) - } - var toRule []interface{} - for _, toItem := range to { - toRule = append(toRule, toItem) - } - var tokenIdRule []interface{} - for _, tokenIdItem := range tokenId { - tokenIdRule = append(tokenIdRule, tokenIdItem) - } - - logs, sub, err := _Werc721.contract.WatchLogs(opts, "Transfer", fromRule, toRule, tokenIdRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(Werc721Transfer) - if err := _Werc721.contract.UnpackLog(event, "Transfer", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseTransfer is a log parse operation binding the contract event 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef. -// -// Solidity: event Transfer(address indexed from, address indexed to, uint256 indexed tokenId) -func (_Werc721 *Werc721Filterer) ParseTransfer(log types.Log) (*Werc721Transfer, error) { - event := new(Werc721Transfer) - if err := _Werc721.contract.UnpackLog(event, "Transfer", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} diff --git a/app/clients/hedera/client.go b/app/clients/hedera/client.go index 99d3e3212..65627852b 100644 --- a/app/clients/hedera/client.go +++ b/app/clients/hedera/client.go @@ -203,20 +203,6 @@ func (hc Node) SubmitScheduledHbarTransferTransaction( return hc.submitScheduledTransferTransaction(payerAccountID, memo, transferTransaction) } -func (hc Node) SubmitScheduledNftTransferTransaction( - nftID hedera.NftID, - payerAccount hedera.AccountID, - sender hedera.AccountID, - receiving hedera.AccountID, - memo string, approved bool) (*hedera.TransactionResponse, error) { - - transferTransaction := hedera. - NewTransferTransaction(). - AddApprovedNftTransfer(nftID, sender, receiving, approved) - - return hc.submitScheduledTransferTransaction(payerAccount, memo, transferTransaction) -} - func (hc Node) TransactionReceiptQuery(transactionID hedera.TransactionID, nodeAccIds []hedera.AccountID) (hedera.TransactionReceipt, error) { return hedera.NewTransactionReceiptQuery(). SetTransactionID(transactionID). @@ -225,18 +211,6 @@ func (hc Node) TransactionReceiptQuery(transactionID hedera.TransactionID, nodeA Execute(hc.GetClient()) } -func (hc Node) SubmitScheduledNftApproveTransaction( - payer hedera.AccountID, - memo string, - nftId hedera.NftID, - owner hedera.AccountID, - spender hedera.AccountID) (*hedera.TransactionResponse, error) { - tx := hedera.NewAccountAllowanceApproveTransaction(). - ApproveTokenNftAllowance(nftId, owner, spender) - - return hc.submitScheduledAllowTransaction(payer, memo, tx) -} - func (hc Node) submitScheduledAllowTransaction(payer hedera.AccountID, memo string, tx *hedera.AccountAllowanceApproveTransaction) (*hedera.TransactionResponse, error) { tx, err := tx.FreezeWith(hc.GetClient()) if err != nil { diff --git a/app/clients/hedera/mirror-node/client.go b/app/clients/hedera/mirror-node/client.go index b9281ecc1..a8786692c 100644 --- a/app/clients/hedera/mirror-node/client.go +++ b/app/clients/hedera/mirror-node/client.go @@ -227,33 +227,6 @@ func (c Client) GetMessagesForTopicBetween(topicId hedera.TopicID, from, to int6 return res, nil } -// GetNftTransactions returns the nft transactions for tokenID and serialNum -func (c Client) GetNftTransactions(tokenID string, serialNum int64) (transaction.NftTransactionsResponse, error) { - query := fmt.Sprintf("%stokens/%s/nfts/%d/transactions", c.mirrorAPIAddress, tokenID, serialNum) - - httpResponse, err := c.get(query) - if err != nil { - return transaction.NftTransactionsResponse{}, err - } - - bodyBytes, err := readResponseBody(httpResponse) - if err != nil { - return transaction.NftTransactionsResponse{}, err - } - - if httpResponse.StatusCode != http.StatusOK { - return transaction.NftTransactionsResponse{}, fmt.Errorf("mirror Node API [%s] ended with Status Code [%d]. Body bytes: [%s]", query, httpResponse.StatusCode, bodyBytes) - } - - var response *transaction.NftTransactionsResponse - err = json.Unmarshal(bodyBytes, &response) - if err != nil { - return transaction.NftTransactionsResponse{}, err - } - - return *response, nil -} - func (c Client) GetTransaction(transactionID string) (*transaction.Response, error) { transactionsDownloadQuery := fmt.Sprintf("/%s", transactionID) @@ -324,32 +297,6 @@ func (c Client) GetStateProof(transactionID string) ([]byte, error) { return readResponseBody(response) } -func (c Client) GetNft(tokenID string, serialNum int64) (*transaction.Nft, error) { - nftQuery := fmt.Sprintf("%s%d", "/nfts/", serialNum) - query := fmt.Sprintf("%s%s%s%s", c.mirrorAPIAddress, "tokens/", tokenID, nftQuery) - - httpResponse, e := c.get(query) - if e != nil { - return nil, e - } - if httpResponse.StatusCode >= 400 { - return nil, fmt.Errorf(`failed to execute query: [%s]. Error: [%s]`, query, query) - } - - bodyBytes, e := readResponseBody(httpResponse) - if e != nil { - return nil, e - } - - var response *transaction.Nft - e = json.Unmarshal(bodyBytes, &response) - if e != nil { - return nil, e - } - - return response, nil -} - func (c Client) AccountExists(accountID hedera.AccountID) bool { mirrorNodeApiTransactionAddress := fmt.Sprintf("%s%s", c.mirrorAPIAddress, "accounts") accountQuery := fmt.Sprintf("%s/%s", diff --git a/app/clients/hedera/mirror-node/client_test.go b/app/clients/hedera/mirror-node/client_test.go index 7df3a477c..c5792f5d2 100644 --- a/app/clients/hedera/mirror-node/client_test.go +++ b/app/clients/hedera/mirror-node/client_test.go @@ -466,39 +466,6 @@ func Test_GetMessagesForTopicBetween(t *testing.T) { assert.Nil(t, err) } -func Test_GetNftTransactions_HttpErr(t *testing.T) { - setup() - mocks.MHTTPClient.On("Get", mock.Anything).Return(nil, errors.New("some-error")) - response, err := c.GetNftTransactions("0.0.42", sequenceNumber) - assert.Error(t, errors.New("some-error"), err) - assert.Equal(t, transaction.NftTransactionsResponse{}, response) -} - -func Test_GetNftTransactions(t *testing.T) { - setup() - - expected := transaction.NftTransactionsResponse{ - Transactions: []transaction.NftTransaction{ - { - TransactionID: "TransactionID", - Type: "Type", - SenderAccountID: "SenderAccountID", - ReceiverAccountID: "ReceiverAccountID", - }, - }, - } - - encodedContent, err := httpHelper.EncodeBodyContent(expected) - if err != nil { - t.Fatal(err) - } - - mocks.MHTTPClient.On("Get", mock.Anything).Return(&http.Response{StatusCode: 200, Body: encodedContent}, nil) - response, err := c.GetNftTransactions("0.0.42", sequenceNumber) - assert.Nil(t, err) - assert.Equal(t, expected, response) -} - func Test_GetSuccessfulTransaction_HttpErr(t *testing.T) { setup() @@ -559,34 +526,6 @@ func Test_GetSchedule(t *testing.T) { assert.Equal(t, expected.ConsensusTimestamp, response.ConsensusTimestamp) } -func Test_GetNft_HttpErr(t *testing.T) { - setup() - - mocks.MHTTPClient.On("Get", mock.Anything).Return(nil, errors.New("some-error")) - response, err := c.GetNft("0.0.42", 42) - assert.Error(t, errors.New("some-error"), err) - assert.Nil(t, response) -} - -func Test_GetNft(t *testing.T) { - setup() - - expected := transaction.Nft{ - CreatedTimestamp: "1", - SerialNumber: 42, - } - - encodedContent, err := httpHelper.EncodeBodyContent(expected) - if err != nil { - t.Fatal(err) - } - - mocks.MHTTPClient.On("Get", mock.Anything).Return(&http.Response{StatusCode: 200, Body: encodedContent}, nil) - response, err := c.GetNft("0.0.42", 42) - assert.Nil(t, err) - assert.Equal(t, expected.SerialNumber, response.SerialNumber) -} - func Test_AccountExists_ShouldNotExists(t *testing.T) { setup() diff --git a/app/clients/hedera/mirror-node/model/transaction/transaction.go b/app/clients/hedera/mirror-node/model/transaction/transaction.go index ac616e4ad..20cb4b0ee 100644 --- a/app/clients/hedera/mirror-node/model/transaction/transaction.go +++ b/app/clients/hedera/mirror-node/model/transaction/transaction.go @@ -42,7 +42,6 @@ type ( TransactionID string `json:"transaction_id"` Transfers []Transfer `json:"transfers"` TokenTransfers []Transfer `json:"token_transfers"` - NftTransfers []NftTransfer `json:"nft_transfers"` } // Transfer struct used by the Hedera Mirror node REST API Transfer struct { @@ -51,13 +50,6 @@ type ( // When retrieving ordinary hbar transfers, this field does not get populated Token string `json:"token_id"` } - // NftTransfer struct used by the Hedera mirror node REST API - NftTransfer struct { - ReceiverAccountID string `json:"receiver_account_id"` - SenderAccountID string `json:"sender_account_id"` - SerialNumber int64 `json:"serial_number"` - Token string `json:"token_id"` - } // Response struct used by the Hedera Mirror node REST API and returned once // account transactions are queried Response struct { @@ -74,37 +66,12 @@ type ( PayerAccountId string `json:"payer_account_id"` ScheduleId string `json:"schedule_id"` } - - // Nft struct used by Hedera Mirror node REST API to return information - // for a given Nft entity - Nft struct { - AccountID string `json:"account_id"` // The account ID of the account associated with the NFT - CreatedTimestamp string `json:"created_timestamp"` // The timestamp of when the NFT was created - Deleted bool `json:"deleted"` // Whether the token was deleted or not - Metadata string `json:"metadata"` // The metadata of the NFT, in base64 - ModifiedTimestamp string `json:"modified_timestamp"` // The last time the token properties were modified - SerialNumber int64 `json:"serial_number"` // The serial number of the NFT - TokenID string `json:"token_id"` // The token ID of the NFT - } - // NftTransactionsResponse struct used by Hedera Mirror node REST API to return information - // about an NFT's transaction - NftTransactionsResponse struct { - Transactions []NftTransaction `json:"transactions"` - Links Pagination `json:"links"` - } - NftTransaction struct { - TransactionID string `json:"transaction_id"` // The transaction ID of the transaction - Type string `json:"type"` // The type of transaction TOKENBURN, TOKEMINT, CRYPTOTRANSFER - SenderAccountID string `json:"sender_account_id"` // The account that sent the NFT - ReceiverAccountID string `json:"receiver_account_id"` // The account that received the NFT - } Pagination struct { Next string `json:"next"` // Hyperlink to the next page of results } // ParsedTransfer Used in GetIncomingTransfer to return the information about an Incoming Transfer ParsedTransfer struct { - IsNft bool - AmountOrSerialNum int64 + Amount int64 Asset string } ) @@ -131,16 +98,6 @@ func (t Transaction) getIncomingTokenAmountFor(account string) (int64, string, e return 0, "", errors.New("no incoming token transfer found") } -func (t Transaction) getIncomingNftTransferFor(account string) (serialNum int64, token string, err error) { - for _, ntr := range t.NftTransfers { - if ntr.ReceiverAccountID == account { - return ntr.SerialNumber, ntr.Token, nil - } - } - - return 0, "", errors.New("no incoming nft transfer found") -} - // GetHBARTransfer gets the HBAR transfer for an Account func (t Transaction) GetHBARTransfer(account string) (amount int64, isFound bool) { for _, tr := range t.Transfers { @@ -165,24 +122,13 @@ func (t Transaction) GetTokenTransfer(account string) (amount int64, isFound boo // Process Hedera -> EVM TX // GetIncomingTransfer returns the transfer to an account in the following order: -// 1. Checks if there is an NFT transfer -// 2. Checks if there is a Fungible Token transfer -// 3. Checks if there is an HBAR transfer +// 1. Checks if there is a Fungible Token transfer +// 2. Checks if there is an HBAR transfer func (t Transaction) GetIncomingTransfer(account string) (parsed ParsedTransfer, err error) { - serialNum, asset, err := t.getIncomingNftTransferFor(account) - if err == nil { - return ParsedTransfer{ - IsNft: true, - AmountOrSerialNum: serialNum, - Asset: asset, - }, nil - } - amount, asset, err := t.getIncomingTokenAmountFor(account) if err == nil { return ParsedTransfer{ - IsNft: false, - AmountOrSerialNum: amount, + Amount: amount, Asset: asset, }, nil } @@ -190,8 +136,7 @@ func (t Transaction) GetIncomingTransfer(account string) (parsed ParsedTransfer, amount, asset, err = t.getIncomingAmountFor(account) if err == nil { return ParsedTransfer{ - IsNft: false, - AmountOrSerialNum: amount, + Amount: amount, Asset: asset, }, nil } diff --git a/app/clients/hedera/mirror-node/model/transaction/transaction_test.go b/app/clients/hedera/mirror-node/model/transaction/transaction_test.go index 2a25a0baf..57e6849e0 100644 --- a/app/clients/hedera/mirror-node/model/transaction/transaction_test.go +++ b/app/clients/hedera/mirror-node/model/transaction/transaction_test.go @@ -31,9 +31,6 @@ var ( tokenAccountId = "0.0.555555" amount = int64(10) token = "0.0.111111" - nftSenderAccountId = "0.0.666666" - nftReceiverAccountId = "0.0.777777" - serialNumber = int64(1234) olderConsensusTimestamp = "1631092490.303966000" moreRecentConsensusTimestamp = "1631092491.483966000" nonExistingAccount = "0.0.non-existing" @@ -64,9 +61,8 @@ func Test_GetIncomingTransfer_Transfer(t *testing.T) { parsedTransfer, err := transaction.GetIncomingTransfer(transferAccountId) assert.Nil(t, err) - assert.False(t, parsedTransfer.IsNft) assert.Equal(t, constants.Hbar, parsedTransfer.Asset) - assert.Equal(t, amount, parsedTransfer.AmountOrSerialNum) + assert.Equal(t, amount, parsedTransfer.Amount) } func Test_GetIncomingTransfer_TokenTransfer(t *testing.T) { @@ -75,20 +71,8 @@ func Test_GetIncomingTransfer_TokenTransfer(t *testing.T) { parsedTransfer, err := transaction.GetIncomingTransfer(tokenAccountId) assert.Nil(t, err) - assert.False(t, parsedTransfer.IsNft) assert.Equal(t, token, parsedTransfer.Asset) - assert.Equal(t, amount, parsedTransfer.AmountOrSerialNum) -} - -func Test_GetIncomingTransfer_NftTransfer(t *testing.T) { - setup() - - parsedTransfer, err := transaction.GetIncomingTransfer(nftReceiverAccountId) - - assert.Nil(t, err) - assert.True(t, parsedTransfer.IsNft) - assert.Equal(t, token, parsedTransfer.Asset) - assert.Equal(t, serialNumber, parsedTransfer.AmountOrSerialNum) + assert.Equal(t, amount, parsedTransfer.Amount) } func Test_GetIncomingTransfer_NonExisting(t *testing.T) { @@ -158,14 +142,6 @@ func setup() { Token: constants.Hbar, }, }, - NftTransfers: []NftTransfer{ - { - SenderAccountID: nftSenderAccountId, - ReceiverAccountID: nftReceiverAccountId, - SerialNumber: serialNumber, - Token: token, - }, - }, ConsensusTimestamp: olderConsensusTimestamp, } diff --git a/app/domain/client/diamond-router.go b/app/domain/client/diamond-router.go index 6de2b9ad9..eac095170 100644 --- a/app/domain/client/diamond-router.go +++ b/app/domain/client/diamond-router.go @@ -33,7 +33,6 @@ type DiamondRouter interface { ParseBurn(log types.Log) (*router.RouterBurn, error) ParseLock(log types.Log) (*router.RouterLock, error) ParseUnlock(log types.Log) (*router.RouterUnlock, error) - ParseBurnERC721(log types.Log) (*router.RouterBurnERC721, error) WatchBurn(opts *bind.WatchOpts, sink chan<- *router.RouterBurn) (event.Subscription, error) MembersCount(opts *bind.CallOpts) (*big.Int, error) MemberAt(opts *bind.CallOpts, _index *big.Int) (common.Address, error) @@ -43,6 +42,4 @@ type DiamondRouter interface { PreviousAccrued *big.Int Accumulator *big.Int }, error) - Erc721Fee(opts *bind.CallOpts, _erc721 common.Address) (*big.Int, error) - Erc721Payment(opts *bind.CallOpts, _erc721 common.Address) (common.Address, error) } diff --git a/app/domain/client/evm_nft.go b/app/domain/client/evm_nft.go deleted file mode 100644 index d5d1f3867..000000000 --- a/app/domain/client/evm_nft.go +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2022 LimeChain Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package client - -import ( - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/common" - "math/big" -) - -type EvmNft interface { - Name(opts *bind.CallOpts) (string, error) - Symbol(opts *bind.CallOpts) (string, error) - BalanceOf(opts *bind.CallOpts, owner common.Address) (*big.Int, error) - // TODO: Uncomment when we update the NFTs to extend ERC721Enumerable - //TotalSupply(opts *bind.CallOpts) (*big.Int, error) -} diff --git a/app/domain/client/mirror-node.go b/app/domain/client/mirror-node.go index 183f2a86d..188143cf9 100644 --- a/app/domain/client/mirror-node.go +++ b/app/domain/client/mirror-node.go @@ -52,8 +52,6 @@ type MirrorNode interface { GetLatestMessages(topicId hedera.TopicID, limit int64) ([]message.Message, error) // GetMessagesForTopicBetween returns all topic messages for a given topic between timestamp `from` included and `to` excluded GetMessagesForTopicBetween(topicId hedera.TopicID, from, to int64) ([]message.Message, error) - // GetNftTransactions returns the nft transactions for tokenID and serialNum - GetNftTransactions(tokenID string, serialNum int64) (transaction.NftTransactionsResponse, error) // GetScheduledTransaction gets the Scheduled transaction of an executed transaction GetScheduledTransaction(transactionID string) (*transaction.Response, error) // GetTransaction gets all data related to a specific transaction id or returns an error @@ -65,8 +63,6 @@ type MirrorNode interface { // GetStateProof sends a query to get the state proof. If the query is successful, the function returns the state. // If the query returns a status != 200, the function returns an error. GetStateProof(transactionID string) ([]byte, error) - // GetNft retrieves an nft token entity by its id and serial number - GetNft(tokenID string, serialNum int64) (*transaction.Nft, error) // AccountExists sends a query to check whether a specific account exists. If the query returns a status != 200, the function returns a false value AccountExists(accountID hedera.AccountID) bool // GetAccount gets the account data by ID. diff --git a/app/domain/client/node.go b/app/domain/client/node.go index 07e24eb25..34b9deffe 100644 --- a/app/domain/client/node.go +++ b/app/domain/client/node.go @@ -31,10 +31,6 @@ type HederaNode interface { SubmitScheduledTokenTransferTransaction(tokenID hedera.TokenID, transfers []transfer.Hedera, payerAccountID hedera.AccountID, memo string) (*hedera.TransactionResponse, error) // SubmitScheduledHbarTransferTransaction creates an hbar transfer transaction and submits it as a scheduled transfer transaction SubmitScheduledHbarTransferTransaction(transfers []transfer.Hedera, payerAccountID hedera.AccountID, memo string) (*hedera.TransactionResponse, error) - // SubmitScheduledNftTransferTransaction creates an Nft transfer transaction and submits it as a scheduled transfer transactions - SubmitScheduledNftTransferTransaction(nftID hedera.NftID, payerAccount hedera.AccountID, sender hedera.AccountID, receiving hedera.AccountID, memo string, approved bool) (*hedera.TransactionResponse, error) - // SubmitScheduledNftApproveTransaction creates an allowance of for the nft for the spender and submits it as a scheduled transaction - SubmitScheduledNftApproveTransaction(payer hedera.AccountID, memo string, nftId hedera.NftID, owner, spender hedera.AccountID) (*hedera.TransactionResponse, error) // SubmitScheduleSign submits a ScheduleSign transaction for a given ScheduleID SubmitScheduleSign(scheduleID hedera.ScheduleID) (*hedera.TransactionResponse, error) // SubmitScheduledTokenMintTransaction creates a token mint transaction and submits it as a scheduled mint transaction diff --git a/app/domain/service/assets.go b/app/domain/service/assets.go index 5cf5e1157..6f5711cab 100644 --- a/app/domain/service/assets.go +++ b/app/domain/service/assets.go @@ -25,8 +25,6 @@ import ( type Assets interface { // FungibleNetworkAssets Gets all Fungible Assets by Network ID FungibleNetworkAssets() map[uint64][]string - // NonFungibleNetworkAssets Gets all Non-Fungible Assets by Network ID - NonFungibleNetworkAssets() map[uint64][]string // NativeToWrappedAssets Gets all Native assets with their Wrapped assets by Network ID NativeToWrappedAssets() map[uint64]map[string]map[uint64]string // WrappedFromNative Gets All Wrapped Assets for passed Native Asset's address @@ -45,12 +43,8 @@ type Assets interface { OppositeAsset(sourceChainId uint64, targetChainId uint64, assetAddress string) string // FungibleAssetInfo Gets FungibleAssetInfo FungibleAssetInfo(networkId uint64, assetAddress string) (assetInfo *assetModel.FungibleAssetInfo, exist bool) - // NonFungibleAssetInfo Gets NonFungibleAssetInfo - NonFungibleAssetInfo(networkId uint64, assetAddressOrId string) (assetInfo *assetModel.NonFungibleAssetInfo, exist bool) // FetchHederaTokenReserveAmount Gets Hedera's Token Reserve Amount FetchHederaTokenReserveAmount(assetId string, mirrorNode client.MirrorNode, isNative bool, hederaTokenBalances map[string]int) (reserveAmount *big.Int, err error) // FetchEvmFungibleReserveAmount Gets EVM's Fungible Token Reserve Amount FetchEvmFungibleReserveAmount(networkId uint64, assetAddress string, isNative bool, evmTokenClient client.EvmFungibleToken, routerContractAddress string) (inLowestDenomination *big.Int, err error) - // FetchEvmNonFungibleReserveAmount Gets EVM's Non-Fungible Token Reserve Amount - FetchEvmNonFungibleReserveAmount(networkId uint64, assetAddress string, isNative bool, evmTokenClient client.EvmNft, routerContractAddress string) (inLowestDenomination *big.Int, err error) } diff --git a/app/domain/service/contracts.go b/app/domain/service/contracts.go index fcbe1c05a..8d49e4744 100644 --- a/app/domain/service/contracts.go +++ b/app/domain/service/contracts.go @@ -48,8 +48,6 @@ type Contracts interface { ParseLockLog(log types.Log) (*abi.RouterLock, error) // ParseUnlockLog parses a general typed log to a RouterUnlock event ParseUnlockLog(log types.Log) (*abi.RouterUnlock, error) - // ParseBurnERC721Log parses a general typed log to a BurnERC721event - ParseBurnERC721Log(log types.Log) (*abi.RouterBurnERC721, error) // WatchBurnEventLogs creates a subscription for Burn Events emitted in the Bridge contract WatchBurnEventLogs(opts *bind.WatchOpts, sink chan<- *abi.RouterBurn) (event.Subscription, error) // WatchLockEventLogs creates a subscription for Lock Events emitted in the Bridge contract diff --git a/app/domain/service/messages.go b/app/domain/service/messages.go index d7c027e14..bf067b08c 100644 --- a/app/domain/service/messages.go +++ b/app/domain/service/messages.go @@ -25,13 +25,8 @@ type Messages interface { // SanityCheckFungibleSignature performs any validation required prior handling the topic message // (verifies input data against the corresponding Transaction record) SanityCheckFungibleSignature(tm *proto.TopicEthSignatureMessage) (bool, error) - // SanityCheckNftSignature performs any validation required prior handling the topic message - // (verifies input data against the corresponding Transaction record) - SanityCheckNftSignature(tm *proto.TopicEthNftSignatureMessage) (bool, error) // ProcessSignature processes the signature message, verifying and updating all necessary fields in the DB ProcessSignature(transferID, signature string, targetChainId uint64, timestamp int64, authMsg []byte) error // SignFungibleMessage signs a Fungible message based on Transfer SignFungibleMessage(transfer payload.Transfer) ([]byte, error) - // SignNftMessage signs an NFT messaged based on Transfer - SignNftMessage(transfer payload.Transfer) ([]byte, error) } diff --git a/app/domain/service/pricing.go b/app/domain/service/pricing.go index 2055e8cd4..f76b40f37 100644 --- a/app/domain/service/pricing.go +++ b/app/domain/service/pricing.go @@ -27,10 +27,4 @@ type Pricing interface { FetchAndUpdateUsdPrices() error // GetMinAmountsForAPI getting all prices by networkId GetMinAmountsForAPI() map[uint64]map[string]string - // GetHederaNftFee returns the nft fee for Hedera NFTs based on token id - GetHederaNftFee(token string) (int64, bool) - // GetHederaNftPrevFee returns the previous nft fee for Hedera NFTs based on token id - GetHederaNftPrevFee(token string) (int64, bool) - - NftFees() map[uint64]map[string]pricing.NonFungibleFee } diff --git a/app/domain/service/read-only.go b/app/domain/service/read-only.go index 288791438..665a5a687 100644 --- a/app/domain/service/read-only.go +++ b/app/domain/service/read-only.go @@ -17,19 +17,11 @@ package service import ( - "github.com/hashgraph/hedera-sdk-go/v2" mirror_node "github.com/limechain/hedera-eth-bridge-validator/app/clients/hedera/mirror-node/model/transaction" model "github.com/limechain/hedera-eth-bridge-validator/app/model/transfer" - "github.com/limechain/hedera-eth-bridge-validator/app/process/payload" ) type ReadOnly interface { FindTransfer(transferID string, fetch func() (*mirror_node.Response, error), save func(transactionID, scheduleID, status string) error) FindAssetTransfer(transferID string, asset string, transfers []model.Hedera, fetch func() (*mirror_node.Response, error), save func(transactionID, scheduleID, status string) error) - FindNftTransfer(transferID string, tokenID string, serialNum int64, sender string, receiver string, - save func(transactionID, scheduleID, status string) error) - FindScheduledNftAllowanceApprove( - t *payload.Transfer, - sender hedera.AccountID, - save func(transactionID, scheduleID, status string) error) } diff --git a/app/domain/service/scheduled.go b/app/domain/service/scheduled.go index 4e0a40f25..51c567ccb 100644 --- a/app/domain/service/scheduled.go +++ b/app/domain/service/scheduled.go @@ -17,7 +17,6 @@ package service import ( - "github.com/hashgraph/hedera-sdk-go/v2" "github.com/limechain/hedera-eth-bridge-validator/app/model/transfer" ) @@ -30,10 +29,4 @@ type Scheduled interface { ExecuteScheduledMintTransaction(id, asset string, amount int64, status *chan string, onExecutionSuccess func(transactionID, scheduleID string), onExecutionFail, onSuccess, onFail func(transactionID string)) // ExecuteScheduledBurnTransaction submits a scheduled burn transaction and executes provided functions when necessary ExecuteScheduledBurnTransaction(id, asset string, amount int64, status *chan string, onExecutionSuccess func(transactionID, scheduleID string), onExecutionFail, onSuccess, onFail func(transactionID string)) - // ExecuteScheduledNftTransferTransaction submits a scheduled nft transfer transaction and executes provided functions when necessary - ExecuteScheduledNftTransferTransaction(id string, nftID hedera.NftID, sender hedera.AccountID, receiving hedera.AccountID, approved bool, onExecutionSuccess func(transactionID, scheduleID string), onExecutionFail, onSuccess, onFail func(transactionID string)) - // ExecuteScheduledNftAllowTransaction submits a scheduled NFT allow transaction and executes provided functions when necessary - ExecuteScheduledNftAllowTransaction( - id string, nftID hedera.NftID, owner hedera.AccountID, spender hedera.AccountID, - onExecutionSuccess func(txId, scheduleId string), onExecutionFail, onSuccess, onFail func(txId string)) } diff --git a/app/domain/service/transfers.go b/app/domain/service/transfers.go index 59c3b4418..2b62122fb 100644 --- a/app/domain/service/transfers.go +++ b/app/domain/service/transfers.go @@ -34,9 +34,6 @@ type Transfers interface { // ProcessNativeTransfer processes the native fungible transfer message by signing the required // authorisation signature submitting it into the required HCS Topic ProcessNativeTransfer(tm payload.Transfer) error - // ProcessNativeNftTransfer processes the native nft transfer message by signing the required - // authorisation signature submitting it into the required HCS Topic - ProcessNativeNftTransfer(tm payload.Transfer) error // ProcessWrappedTransfer processes the wrapped transfer message by signing the required // authorisation signature submitting it into the required HCS Topic ProcessWrappedTransfer(tm payload.Transfer) error @@ -50,7 +47,6 @@ type Transfers interface { } type TransferData struct { - IsNft bool `json:"isNft"` Recipient string `json:"recipient"` RouterAddress string `json:"routerAddress"` SourceChainId uint64 `json:"sourceChainId"` @@ -62,12 +58,6 @@ type TransferData struct { Majority bool `json:"majority"` } -type NonFungibleTransferData struct { - TransferData - TokenId int64 `json:"tokenId"` - Metadata string `json:"metadata"` -} - type FungibleTransferData struct { TransferData Amount string `json:"amount"` diff --git a/app/helper/blacklist/blacklist.go b/app/helper/blacklist/blacklist.go index a4763014a..9b5c1565f 100644 --- a/app/helper/blacklist/blacklist.go +++ b/app/helper/blacklist/blacklist.go @@ -45,11 +45,5 @@ func CheckTxForBlacklistedAccounts(blacklistedAccounts []string, tx transaction. } } - for i := range tx.NftTransfers { - if IsBlacklistedAccount(blacklistedAccounts, tx.NftTransfers[i].SenderAccountID) { - return fmt.Errorf("[%s], Acc: [%v] - Found blacklisted transfer", tx.TransactionID, tx.NftTransfers[i].SenderAccountID) - } - } - return nil } diff --git a/app/helper/blacklist/helper_test.go b/app/helper/blacklist/helper_test.go index 6837eab28..2f6a45281 100644 --- a/app/helper/blacklist/helper_test.go +++ b/app/helper/blacklist/helper_test.go @@ -30,30 +30,6 @@ func Test_IsBlacklistedAccount(t *testing.T) { assert.False(t, IsBlacklistedAccount(blacklist, "0x000002")) } -func Test_CheckNFTTxForBlacklistedAccounts(t *testing.T) { - tx := setupTX() - tx.NftTransfers = []transaction.NftTransfer{ - {ReceiverAccountID: "0.0.111", - SenderAccountID: "0.0.233", - SerialNumber: 1, - Token: "0.0.21241241"}, - } - - assert.NoError(t, CheckTxForBlacklistedAccounts(blacklist, tx)) -} - -func Test_CheckNFTTxForBlacklistedAccounts_Fails(t *testing.T) { - tx := setupTX() - tx.NftTransfers = []transaction.NftTransfer{ - {ReceiverAccountID: "0.0.111", - SenderAccountID: "0.0.333", - SerialNumber: 1, - Token: "0.0.21241241"}, - } - - assert.Error(t, CheckTxForBlacklistedAccounts(blacklist, tx)) -} - func Test_CheckTokenTxForBlacklistedAccounts(t *testing.T) { tx := setupTX() assert.NoError(t, CheckTxForBlacklistedAccounts(blacklist, tx)) diff --git a/app/helper/fee/fee.go b/app/helper/fee/fee.go index ebf841dda..35f6cecd8 100644 --- a/app/helper/fee/fee.go +++ b/app/helper/fee/fee.go @@ -18,7 +18,6 @@ package fee import ( "github.com/hashgraph/hedera-sdk-go/v2" - "github.com/limechain/hedera-eth-bridge-validator/app/model/asset" model "github.com/limechain/hedera-eth-bridge-validator/app/model/transfer" "strconv" ) @@ -40,28 +39,3 @@ func TotalFeeFromTransfers(transfers []model.Hedera, receiver hedera.AccountID) return strconv.FormatInt(result, 10), hasReceiver } - -// SumFallbackFeeAmounts sums fallback fees in HBAR and by token ID -// Returns the sum of the fallback fees in HBAR and by token ID -func SumFallbackFeeAmounts(customFees asset.CustomFees) asset.CustomFeeTotalAmounts { - customFeeAmounts := new(asset.CustomFeeTotalAmounts) - customFeeAmounts.FallbackFeeAmountsByTokenId = make(map[string]int64) - sumFallbackFeeAmounts(customFees.RoyaltyFees, customFeeAmounts) - - return *customFeeAmounts -} - -func sumFallbackFeeAmounts(royaltyFees []asset.RoyaltyFee, customFeeAmounts *asset.CustomFeeTotalAmounts) { - for _, royaltyFee := range royaltyFees { - if royaltyFee.FallbackFee.DenominatingTokenId == nil { - customFeeAmounts.FallbackFeeAmountInHbar += royaltyFee.FallbackFee.Amount - } else { - tokenId := *royaltyFee.FallbackFee.DenominatingTokenId - if _, ok := customFeeAmounts.FallbackFeeAmountsByTokenId[tokenId]; !ok { - customFeeAmounts.FallbackFeeAmountsByTokenId[tokenId] = royaltyFee.FallbackFee.Amount - } else { - customFeeAmounts.FallbackFeeAmountsByTokenId[tokenId] += royaltyFee.FallbackFee.Amount - } - } - } -} diff --git a/app/helper/fee/fee_test.go b/app/helper/fee/fee_test.go index db2ef2af0..c27a2ae96 100644 --- a/app/helper/fee/fee_test.go +++ b/app/helper/fee/fee_test.go @@ -18,7 +18,6 @@ package fee import ( "github.com/hashgraph/hedera-sdk-go/v2" - "github.com/limechain/hedera-eth-bridge-validator/app/model/asset" model "github.com/limechain/hedera-eth-bridge-validator/app/model/transfer" "github.com/stretchr/testify/assert" "testing" @@ -72,48 +71,3 @@ func Test_TotalFeeFromTransfers_ReceiverNotFound(t *testing.T) { assert.Equal(t, expectedFee, actualFee) assert.Equal(t, expectedReceiverFound, actualReceiverFound) } - -func Test_SumFallbackFeeAmounts(t *testing.T) { - hbarFee := asset.FixedFee{ - Amount: 50, - DenominatingTokenId: nil, // HBAR - } - token1Name := "token1" - token1Fee := asset.FixedFee{ - Amount: 150, - DenominatingTokenId: &token1Name, - } - token2Name := "token2" - token2Fee1 := asset.FixedFee{ - Amount: 30, - DenominatingTokenId: &token2Name, - } - token2Fee2 := asset.FixedFee{ - Amount: 60, - DenominatingTokenId: &token2Name, - } - customFees := asset.CustomFees{ - RoyaltyFees: []asset.RoyaltyFee{ - { - FallbackFee: hbarFee, - }, - { - FallbackFee: token1Fee, - }, - { - FallbackFee: token2Fee1, - }, - { - FallbackFee: token2Fee2, - }, - }, - } - - result := SumFallbackFeeAmounts(customFees) - - assert.Equal(t, result.FallbackFeeAmountInHbar, hbarFee.Amount) - assert.Equal(t, result.FallbackFeeAmountsByTokenId[token1Name], token1Fee.Amount) - - token2TotalFee := token2Fee1.Amount + token2Fee2.Amount - assert.Equal(t, result.FallbackFeeAmountsByTokenId[token2Name], token2TotalFee) -} diff --git a/app/helper/hedera/nft.go b/app/helper/hedera/nft.go deleted file mode 100644 index ec8cef111..000000000 --- a/app/helper/hedera/nft.go +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright 2022 LimeChain Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package hedera - -import ( - "database/sql" - "github.com/limechain/hedera-eth-bridge-validator/app/domain/repository" - syncHelper "github.com/limechain/hedera-eth-bridge-validator/app/helper/sync" - "github.com/limechain/hedera-eth-bridge-validator/app/persistence/entity" - "github.com/limechain/hedera-eth-bridge-validator/app/persistence/entity/status" - log "github.com/sirupsen/logrus" - "sync" -) - -func ScheduledNftTxExecutionCallbacks( - transferRepository repository.Transfer, - scheduleRepository repository.Schedule, - logger *log.Entry, - id string, - hasReceiver bool, - statusResult *string, - operation string, - wg *sync.WaitGroup, -) (onExecutionSuccess func(transactionID, scheduleID string), onExecutionFail func(transactionID string)) { - onExecutionSuccess = func(transactionID, scheduleID string) { - logger.Infof("[%s] - Updating db status to Submitted with TransactionID [%s].", - id, - transactionID) - err := scheduleRepository.Create(&entity.Schedule{ - ScheduleID: scheduleID, - Operation: operation, - TransactionID: transactionID, - HasReceiver: hasReceiver, - Status: status.Submitted, - TransferID: sql.NullString{ - String: id, - Valid: true, - }, - }) - if err != nil { - defer wg.Done() - *statusResult = syncHelper.FAIL - logger.Errorf( - "[%s] - Failed to update submitted status with TransactionID [%s], ScheduleID [%s]. Error [%s].", - id, transactionID, scheduleID, err) - - return - } - } - - onExecutionFail = func(transactionID string) { - defer wg.Done() - *statusResult = syncHelper.FAIL - err := scheduleRepository.Create(&entity.Schedule{ - TransactionID: transactionID, - Status: status.Failed, - HasReceiver: hasReceiver, - TransferID: sql.NullString{ - String: id, - Valid: true, - }, - }) - if err != nil { - logger.Errorf("[%s] - Failed to update status failed. Error [%s].", id, err) - return - } - - err = transferRepository.UpdateStatusFailed(id) - if err != nil { - logger.Errorf("[%s] - Failed to update status failed. Error [%s].", id, err) - return - } - } - - return onExecutionSuccess, onExecutionFail -} - -func ScheduledNftTxMinedCallbacks( - transferRepository repository.Transfer, - scheduleRepository repository.Schedule, - logger *log.Entry, - id string, - status *string, - wg *sync.WaitGroup, -) (onSuccess, onFail func(transactionID string)) { - onSuccess = func(transactionID string) { - defer wg.Done() - logger.Debugf("[%s] - Scheduled TX execution successful.", id) - err := transferRepository.UpdateStatusCompleted(id) - if err != nil { - *status = syncHelper.FAIL - logger.Errorf("[%s] - Failed to update status completed. Error [%s].", id, err) - return - } - err = scheduleRepository.UpdateStatusCompleted(transactionID) - if err != nil { - *status = syncHelper.FAIL - logger.Errorf("[%s] - Failed to update status completed. Error [%s].", transactionID, err) - return - } - *status = syncHelper.DONE - } - - onFail = func(transactionID string) { - defer wg.Done() - *status = syncHelper.FAIL - logger.Debugf("[%s] - Scheduled TX execution has failed.", id) - err := scheduleRepository.UpdateStatusFailed(transactionID) - if err != nil { - logger.Errorf("[%s] - Failed to update status signature failed. Error [%s].", id, err) - return - } - - err = transferRepository.UpdateStatusFailed(id) - if err != nil { - logger.Errorf("[%s] - Failed to update status failed. Error [%s].", transactionID, err) - return - } - } - - return onSuccess, onFail -} diff --git a/app/helper/hedera/nft_test.go b/app/helper/hedera/nft_test.go deleted file mode 100644 index d5924eccb..000000000 --- a/app/helper/hedera/nft_test.go +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright 2022 LimeChain Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package hedera - -import ( - "database/sql" - "errors" - "github.com/limechain/hedera-eth-bridge-validator/app/persistence/entity" - "github.com/limechain/hedera-eth-bridge-validator/app/persistence/entity/schedule" - "github.com/limechain/hedera-eth-bridge-validator/app/persistence/entity/status" - "github.com/limechain/hedera-eth-bridge-validator/test/mocks" - log "github.com/sirupsen/logrus" - "sync" - "testing" -) - -var ( - logger *log.Entry - transactionId = "0.0.1234" - scheduleId = "0.0.5678" - statusResult *string - wg *sync.WaitGroup - createdScheduleOnSuccess = &entity.Schedule{ - TransactionID: transactionId, - ScheduleID: scheduleId, - HasReceiver: true, - Operation: schedule.TRANSFER, - Status: status.Submitted, - TransferID: sql.NullString{ - String: transactionId, - Valid: true, - }, - } - createdScheduleOnError = *createdScheduleOnSuccess - error = errors.New("some-error") -) - -func Test_ScheduledNftTxExecutionCallbacks(t *testing.T) { - setupNftTest(true) - - onSuccess, onFail := ScheduledNftTxExecutionCallbacks(mocks.MTransferRepository, mocks.MScheduleRepository, logger, transactionId, true, statusResult, schedule.TRANSFER, wg) - - onSuccess(transactionId, scheduleId) - onFail(transactionId) -} - -func Test_ScheduledNftTxExecutionCallbacks_ErrScheduleCreateOnSuccess(t *testing.T) { - setupNftTest(false) - - mocks.MScheduleRepository.On("Create", createdScheduleOnSuccess).Return(error) - - onSuccess, _ := ScheduledNftTxExecutionCallbacks(mocks.MTransferRepository, mocks.MScheduleRepository, logger, transactionId, true, statusResult, schedule.TRANSFER, wg) - - onSuccess(transactionId, scheduleId) -} - -func Test_ScheduledNftTxExecutionCallbacks_ErrScheduleCreateOnFail(t *testing.T) { - setupNftTest(false) - updateFieldsForCreatedScheduleOnError() - mocks.MScheduleRepository.On("Create", &createdScheduleOnError).Return(error) - - _, onFail := ScheduledNftTxExecutionCallbacks(mocks.MTransferRepository, mocks.MScheduleRepository, logger, transactionId, true, statusResult, schedule.TRANSFER, wg) - - onFail(transactionId) -} - -func Test_ScheduledNftTxExecutionCallbacks_ErrUpdateStatusFailedOnFail(t *testing.T) { - setupNftTest(false) - updateFieldsForCreatedScheduleOnError() - mocks.MScheduleRepository.On("Create", &createdScheduleOnError).Return(nil) - mocks.MTransferRepository.On("UpdateStatusFailed", transactionId).Return(error) - - _, onFail := ScheduledNftTxExecutionCallbacks(mocks.MTransferRepository, mocks.MScheduleRepository, logger, transactionId, true, statusResult, schedule.TRANSFER, wg) - - onFail(transactionId) -} - -func Test_ScheduledNftTxMinedCallbacks(t *testing.T) { - setupNftTest(true) - mocks.MTransferRepository.On("UpdateStatusCompleted", transactionId).Return(nil) - mocks.MScheduleRepository.On("UpdateStatusCompleted", transactionId).Return(nil) - mocks.MScheduleRepository.On("UpdateStatusFailed", transactionId).Return(nil) - wg.Add(1) - - onSuccess, onFail := ScheduledNftTxMinedCallbacks(mocks.MTransferRepository, mocks.MScheduleRepository, logger, transactionId, statusResult, wg) - - onSuccess(transactionId) - onFail(transactionId) -} - -func Test_ScheduledNftTxMinedCallbacks_ErrTransferUpdateStatusCompletedOnSuccess(t *testing.T) { - setupNftTest(true) - mocks.MTransferRepository.On("UpdateStatusCompleted", transactionId).Return(error) - wg.Add(1) - - onSuccess, _ := ScheduledNftTxMinedCallbacks(mocks.MTransferRepository, mocks.MScheduleRepository, logger, transactionId, statusResult, wg) - - onSuccess(transactionId) -} - -func Test_ScheduledNftTxMinedCallbacks_ErrScheduleUpdateStatusCompletedOnSuccess(t *testing.T) { - setupNftTest(true) - mocks.MTransferRepository.On("UpdateStatusCompleted", transactionId).Return(nil) - mocks.MScheduleRepository.On("UpdateStatusCompleted", transactionId).Return(error) - wg.Add(1) - - onSuccess, _ := ScheduledNftTxMinedCallbacks(mocks.MTransferRepository, mocks.MScheduleRepository, logger, transactionId, statusResult, wg) - - onSuccess(transactionId) -} - -func Test_ScheduledNftTxMinedCallbacks_ErrScheduleUpdateStatusCompletedOnFail(t *testing.T) { - setupNftTest(true) - mocks.MScheduleRepository.On("UpdateStatusFailed", transactionId).Return(error) - wg.Add(1) - - _, onFail := ScheduledNftTxMinedCallbacks(mocks.MTransferRepository, mocks.MScheduleRepository, logger, transactionId, statusResult, wg) - - onFail(transactionId) -} - -func Test_ScheduledNftTxMinedCallbacks_ErrTransferUpdateStatusCompletedOnFail(t *testing.T) { - setupNftTest(false) - mocks.MScheduleRepository.On("UpdateStatusFailed", transactionId).Return(nil) - mocks.MTransferRepository.On("UpdateStatusFailed", transactionId).Return(error) - wg.Add(1) - - _, onFail := ScheduledNftTxMinedCallbacks(mocks.MTransferRepository, mocks.MScheduleRepository, logger, transactionId, statusResult, wg) - - onFail(transactionId) -} - -func setupNftTest(withMocks bool) { - mocks.Setup() - wg = new(sync.WaitGroup) - wg.Add(1) - statusResult = new(string) - logger = log.WithField("context", "Test") - - if withMocks { - updateFieldsForCreatedScheduleOnError() - mocks.MScheduleRepository.On("Create", createdScheduleOnSuccess).Return(nil).Once() - mocks.MScheduleRepository.On("Create", &createdScheduleOnError).Return(nil).Once() - mocks.MTransferRepository.On("UpdateStatusFailed", transactionId).Return(nil) - } -} - -func updateFieldsForCreatedScheduleOnError() { - createdScheduleOnError = *createdScheduleOnSuccess - createdScheduleOnError.ScheduleID = "" - createdScheduleOnError.Operation = "" - createdScheduleOnError.Status = status.Failed -} diff --git a/app/helper/memo/helper_test.go b/app/helper/memo/helper_test.go index a866e0fb1..e7d7a86cb 100644 --- a/app/helper/memo/helper_test.go +++ b/app/helper/memo/helper_test.go @@ -24,8 +24,6 @@ import ( const ( validMemoBase64 = "My0weDM4RTg5MzdiNUE3YjlmMzc5YjE3MGI5OUY1YkRlQjJiMzY0ZGZCNjU=" validMemo = "3-0x38E8937b5A7b9f379b170b99F5bDeB2b364dfB65" - validNFTMemo = "3-0x38E8937b5A7b9f379b170b99F5bDeB2b364dfB65-12@0.0.132414142" - validNFTMemoBase64 = "My0weDM4RTg5MzdiNUE3YjlmMzc5YjE3MGI5OUY1YkRlQjJiMzY0ZGZCNjUtMTJAMC4wLjEzMjQxNDE0Mg==" nonValidEthAddress = "0" nonValidEthAddressBase64 = "MHgzOEU4OTM3YjVBN2I5ZjM3OWIxNzBiOTlGNWJEZUIyYjM2NGRmQjYq" ) @@ -36,12 +34,6 @@ func Test_Validate(t *testing.T) { assert.Nil(t, err) } -func Test_ValidateForNFT(t *testing.T) { - decodedAddress, err := Validate(validNFTMemoBase64) - assert.Equal(t, validNFTMemo, decodedAddress) - assert.Nil(t, err) -} - func Test_WrongAddress(t *testing.T) { _, err := Validate(nonValidEthAddressBase64) expectedError := "Memo is invalid or has invalid encoding format: [0x38E8937b5A7b9f379b170b99F5bDeB2b364dfB6*]" diff --git a/app/helper/message/helper.go b/app/helper/message/helper.go index 7931db0bb..61343f5c9 100644 --- a/app/helper/message/helper.go +++ b/app/helper/message/helper.go @@ -29,12 +29,3 @@ func UpdateHederaChainIdOfFungibleMsg(msg *model.TopicEthSignatureMessage) { msg.TargetChainId = constants.HederaNetworkId } } - -func UpdateHederaChainIdOfNftMsg(msg *model.TopicEthNftSignatureMessage) { - if msg.SourceChainId == constants.OldHederaNetworkId { - msg.SourceChainId = constants.HederaNetworkId - } - if msg.TargetChainId == constants.OldHederaNetworkId { - msg.TargetChainId = constants.HederaNetworkId - } -} diff --git a/app/helper/message/helper_test.go b/app/helper/message/helper_test.go index bd3d177eb..a6220197b 100644 --- a/app/helper/message/helper_test.go +++ b/app/helper/message/helper_test.go @@ -28,11 +28,6 @@ var ( SourceChainId: constants.OldHederaNetworkId, TargetChainId: constants.OldHederaNetworkId, } - - nonFungibleSignatureMsg = &model.TopicEthNftSignatureMessage{ - SourceChainId: constants.OldHederaNetworkId, - TargetChainId: constants.OldHederaNetworkId, - } ) func Test_UpdateHederaChainIdOfFungibleMsg(t *testing.T) { @@ -40,9 +35,3 @@ func Test_UpdateHederaChainIdOfFungibleMsg(t *testing.T) { assert.Equal(t, fungibleSignatureMsg.SourceChainId, constants.HederaNetworkId) assert.Equal(t, fungibleSignatureMsg.TargetChainId, constants.HederaNetworkId) } - -func Test_UpdateHederaChainIdOfNftMsg(t *testing.T) { - UpdateHederaChainIdOfNftMsg(nonFungibleSignatureMsg) - assert.Equal(t, nonFungibleSignatureMsg.SourceChainId, constants.HederaNetworkId) - assert.Equal(t, nonFungibleSignatureMsg.TargetChainId, constants.HederaNetworkId) -} diff --git a/app/model/asset/asset.go b/app/model/asset/asset.go index 53dacc1b8..f62250e54 100644 --- a/app/model/asset/asset.go +++ b/app/model/asset/asset.go @@ -17,7 +17,6 @@ package asset import ( - "github.com/limechain/hedera-eth-bridge-validator/app/clients/hedera/mirror-node/model/token" "math/big" "github.com/shopspring/decimal" @@ -36,53 +35,4 @@ type FungibleAssetInfo struct { Decimals uint8 `json:"decimals"` IsNative bool `json:"isNative"` ReserveAmount *big.Int `json:"-"` -} -type CustomFeeTotalAmounts struct { - FallbackFeeAmountInHbar int64 `json:"-"` - FallbackFeeAmountsByTokenId map[string]int64 `json:"-"` -} - -type NonFungibleAssetInfo struct { - Name string `json:"name"` - Symbol string `json:"symbol"` - IsNative bool `json:"isNative"` - ReserveAmount *big.Int `json:"-"` - CustomFees CustomFees `json:"customFees"` - CustomFeeTotalAmounts CustomFeeTotalAmounts `json:"-"` - TreasuryAccountId string `json:"-"` -} - -type CustomFees struct { - CreatedTimestamp string `json:"createdTimestamp"` - RoyaltyFees []RoyaltyFee `json:"royaltyFees"` -} - -func (c *CustomFees) InitFromResponse(customFees token.CustomFees) { - c.CreatedTimestamp = customFees.CreatedTimestamp - c.RoyaltyFees = make([]RoyaltyFee, len(customFees.RoyaltyFees)) - for i, fee := range customFees.RoyaltyFees { - c.RoyaltyFees[i].InitFromResponse(fee) - } -} - -type FixedFee struct { - Amount int64 `json:"amount"` - DenominatingTokenId *string `json:"denominatingTokenId"` -} - -func (f *FixedFee) InitFromResponse(fee token.FixedFee) { - f.Amount = fee.Amount - f.DenominatingTokenId = fee.DenominatingTokenId -} - -type RoyaltyFee struct { - Amount token.Fraction `json:"amount"` - FallbackFee FixedFee `json:"fallbackFee"` - CollectorAccountID string `json:"collectorAccountId"` -} - -func (r *RoyaltyFee) InitFromResponse(fee token.RoyaltyFee) { - r.Amount = fee.Amount - r.FallbackFee.InitFromResponse(fee.FallbackFee) - r.CollectorAccountID = fee.CollectorAccountID -} +} \ No newline at end of file diff --git a/app/model/auth-message/auth-message.go b/app/model/auth-message/auth-message.go index 271183d13..a33c2ac15 100644 --- a/app/model/auth-message/auth-message.go +++ b/app/model/auth-message/auth-message.go @@ -49,74 +49,6 @@ func EncodeFungibleBytesFrom(sourceChainId, targetChainId uint64, txId, asset, r return keccak(bytesToHash), nil } -// EncodeNftBytesFrom returns the array of bytes representing an -// authorisation ERC-721 NFT signature for Mint ready to be signed by EVM Private Key -func EncodeNftBytesFrom(sourceChainId, targetChainId uint64, txId, asset string, serialNum int64, metadata, receiverEthAddress string) ([]byte, error) { - args, err := generateNftArguments() - if err != nil { - return nil, err - } - - bytesToHash, err := args.Pack( - new(big.Int).SetUint64(sourceChainId), - new(big.Int).SetUint64(targetChainId), - []byte(txId), - common.HexToAddress(asset), - big.NewInt(serialNum), - metadata, - common.HexToAddress(receiverEthAddress)) - if err != nil { - return nil, err - } - return keccak(bytesToHash), nil -} - -func generateNftArguments() (abi.Arguments, error) { - bytesType, err := abi.NewType("bytes", "", nil) - if err != nil { - return nil, err - } - - uint256Type, err := abi.NewType("uint256", "", nil) - if err != nil { - return nil, err - } - - addressType, err := abi.NewType("address", "", nil) - if err != nil { - return nil, err - } - - stringType, err := abi.NewType("string", "internalType", nil) - if err != nil { - return nil, err - } - - return abi.Arguments{ - { - Type: uint256Type, - }, - { - Type: uint256Type, - }, - { - Type: bytesType, - }, - { - Type: addressType, - }, - { - Type: uint256Type, - }, - { - Type: stringType, - }, - { - Type: addressType, - }, - }, nil -} - func generateFungibleArguments() (abi.Arguments, error) { bytesType, err := abi.NewType("bytes", "", nil) if err != nil { diff --git a/app/model/bridge-config-event/params.go b/app/model/bridge-config-event/params.go index 4b87e4cca..b315678f3 100644 --- a/app/model/bridge-config-event/params.go +++ b/app/model/bridge-config-event/params.go @@ -26,6 +26,5 @@ type Params struct { Bridge *config.Bridge ParsedBridge *parser.Bridge EvmFungibleTokenClients map[uint64]map[string]client.EvmFungibleToken - EvmNFTClients map[uint64]map[string]client.EvmNft RouterClients map[uint64]client.DiamondRouter } diff --git a/app/model/message/message.go b/app/model/message/message.go index ab2ff6bbe..aafe404ee 100644 --- a/app/model/message/message.go +++ b/app/model/message/message.go @@ -38,10 +38,6 @@ func FromBytes(data []byte) (*Message, error) { return nil, err } switch msg.Message.(type) { - case *model.TopicMessage_NftSignatureMessage: - nftMsg := msg.GetNftSignatureMessage() - msgHelper.UpdateHederaChainIdOfNftMsg(nftMsg) - return &Message{TopicMessage: msg}, nil case *model.TopicMessage_FungibleSignatureMessage: fungibleMsg := msg.GetFungibleSignatureMessage() msgHelper.UpdateHederaChainIdOfFungibleMsg(fungibleMsg) @@ -93,11 +89,6 @@ func NewFungibleSignature(topicMsg *model.TopicEthSignatureMessage) *Message { return &Message{TopicMessage: &model.TopicMessage{Message: &model.TopicMessage_FungibleSignatureMessage{FungibleSignatureMessage: topicMsg}}} } -// NewNftSignature instantiates Signature Message struct ready for submission to the Bridge Topic -func NewNftSignature(topicMsg *model.TopicEthNftSignatureMessage) *Message { - return &Message{TopicMessage: &model.TopicMessage{Message: &model.TopicMessage_NftSignatureMessage{NftSignatureMessage: topicMsg}}} -} - // ToBytes marshals the underlying protobuf Message into bytes func (tm *Message) ToBytes() ([]byte, error) { return proto.Marshal(tm.TopicMessage) diff --git a/app/model/pricing/pricing.go b/app/model/pricing/pricing.go index 32989c925..14efbed5e 100644 --- a/app/model/pricing/pricing.go +++ b/app/model/pricing/pricing.go @@ -27,15 +27,3 @@ type TokenPriceInfo struct { MinAmountWithFee *big.Int DefaultMinAmount *big.Int } - -type NonFungibleFee struct { - IsNative bool `json:"isNative"` - PaymentToken string `json:"paymentToken"` - Fee decimal.Decimal `json:"fee"` - CustomFees []CustomFee `json:"customFees"` -} - -type CustomFee struct { - PaymentToken string `json:"paymentToken"` - Fee decimal.Decimal `json:"fee"` -} diff --git a/app/model/transfer/transfer.go b/app/model/transfer/transfer.go index 141f79c26..f7e8d4c22 100644 --- a/app/model/transfer/transfer.go +++ b/app/model/transfer/transfer.go @@ -18,8 +18,6 @@ package transfer import ( "time" - - "github.com/hashgraph/hedera-sdk-go/v2" ) // Transfer serves as a data transfer object and response model @@ -33,9 +31,6 @@ type Transfer struct { NativeAsset string `json:"nativeAsset"` Receiver string `json:"receiver"` Amount string `json:"amount,omitempty"` - SerialNum int64 `json:"serialNum,omitempty"` - Metadata string `json:"metadata,omitempty"` - IsNft bool `json:"isNft"` Originator string `json:"originator"` Timestamp time.Time `json:"timestamp"` Fee string `json:"fee,omitempty"` @@ -63,7 +58,6 @@ type Filter struct { type SanityCheckResult struct { ChainId uint64 EvmAddress string - NftId *hedera.NftID Err error } diff --git a/app/persistence/entity/transfer.go b/app/persistence/entity/transfer.go index 9333406c0..361d1edcb 100644 --- a/app/persistence/entity/transfer.go +++ b/app/persistence/entity/transfer.go @@ -37,9 +37,6 @@ type Transfer struct { Amount string Fee string Status string - SerialNumber int64 - Metadata string - IsNft bool `gorm:"default:false"` Timestamp NanoTime `sql:"type:bigint" gorm:"index:,sort:desc"` Originator string Messages []Message `gorm:"foreignKey:TransferID"` @@ -58,9 +55,6 @@ func (t *Transfer) ToDto() *transferModel.Transfer { NativeAsset: t.NativeAsset, Receiver: t.Receiver, Amount: t.Amount, - SerialNum: t.SerialNumber, - Metadata: t.Metadata, - IsNft: t.IsNft, Originator: t.Originator, Timestamp: t.Timestamp.Time, Fee: t.Fee, diff --git a/app/persistence/transfer/transfer.go b/app/persistence/transfer/transfer.go index ed0937f3d..4ddaffdef 100644 --- a/app/persistence/transfer/transfer.go +++ b/app/persistence/transfer/transfer.go @@ -253,9 +253,6 @@ func (r *Repository) create(ct *payload.Transfer, status string) (*entity.Transf Receiver: ct.Receiver, Amount: ct.Amount, Status: status, - SerialNumber: ct.SerialNum, - Metadata: ct.Metadata, - IsNft: ct.IsNft, Timestamp: entity.NanoTime{Time: ct.Timestamp}, Originator: ct.Originator, } diff --git a/app/persistence/transfer/transfer_test.go b/app/persistence/transfer/transfer_test.go index 658c499d2..2f75c10a3 100644 --- a/app/persistence/transfer/transfer_test.go +++ b/app/persistence/transfer/transfer_test.go @@ -58,19 +58,16 @@ var ( amount = "amount" fee = "" someStatus = status.Initial - serialNumber = int64(0) - metadata = "metadata" - isNft = false now = time.Now().UTC() nanoTime = entity.NanoTime{Time: now} originator = "originator" originatorEVM = "0x1235" - transferColumns = []string{"transaction_id", "source_chain_id", "target_chain_id", "native_chain_id", "source_asset", "target_asset", "native_asset", "receiver", "amount", "fee", "status", "serial_number", "metadata", "is_nft", "timestamp", "originator"} + transferColumns = []string{"transaction_id", "source_chain_id", "target_chain_id", "native_chain_id", "source_asset", "target_asset", "native_asset", "receiver", "amount", "fee", "status", "timestamp", "originator"} feeColumns = []string{"transaction_id", "schedule_id", "amount", "status", "transfer_id"} messageColumns = []string{"transfer_id", "hash", "signature", "signer", "transaction_timestamp"} - transferRowArgs = []driver.Value{transactionId, sourceChainId, targetChainId, nativeChainId, sourceAsset, targetAsset, nativeAsset, receiver, amount, fee, someStatus, serialNumber, metadata, isNft, nanoTime, originator} + transferRowArgs = []driver.Value{transactionId, sourceChainId, targetChainId, nativeChainId, sourceAsset, targetAsset, nativeAsset, receiver, amount, fee, someStatus, nanoTime, originator} feesRowArgs = []driver.Value{ transactionId, expectedEntityFee.ScheduleID, @@ -92,9 +89,6 @@ var ( Amount: amount, Fee: fee, Status: someStatus, - SerialNumber: serialNumber, - Metadata: metadata, - IsNft: isNft, Timestamp: nanoTime, Originator: originator, } @@ -108,9 +102,6 @@ var ( NativeAsset: nativeAsset, Receiver: receiver, Amount: amount, - SerialNum: serialNumber, - Metadata: metadata, - IsNft: isNft, NetworkTimestamp: time.Now().String(), Timestamp: now, Originator: originator, @@ -146,9 +137,6 @@ var ( Amount: amount, Fee: fee, Status: someStatus, - SerialNumber: serialNumber, - Metadata: metadata, - IsNft: isNft, Timestamp: nanoTime, Originator: originator, Fees: []entity.Fee{ @@ -167,9 +155,6 @@ var ( Amount: amount, Fee: fee, Status: someStatus, - SerialNumber: serialNumber, - Metadata: metadata, - IsNft: isNft, Timestamp: nanoTime, Originator: originator, Fees: []entity.Fee{ @@ -185,8 +170,8 @@ var ( getWithPreloadsFeesQuery = regexp.QuoteMeta(`SELECT * FROM "fees" WHERE "fees"."transfer_id" = $1`) getWithPreloadsMessagesQuery = regexp.QuoteMeta(`SELECT * FROM "messages" WHERE "messages"."transfer_id" = $1`) - createQuery = regexp.QuoteMeta(`INSERT INTO "transfers" ("transaction_id","source_chain_id","target_chain_id","native_chain_id","source_asset","target_asset","native_asset","receiver","amount","fee","status","serial_number","metadata","is_nft","timestamp","originator") VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16)`) - saveQuery = regexp.QuoteMeta(`UPDATE "transfers" SET "source_chain_id"=$1,"target_chain_id"=$2,"native_chain_id"=$3,"source_asset"=$4,"target_asset"=$5,"native_asset"=$6,"receiver"=$7,"amount"=$8,"fee"=$9,"status"=$10,"serial_number"=$11,"metadata"=$12,"is_nft"=$13,"timestamp"=$14,"originator"=$15 WHERE "transaction_id" = $16`) + createQuery = regexp.QuoteMeta(`INSERT INTO "transfers" ("transaction_id","source_chain_id","target_chain_id","native_chain_id","source_asset","target_asset","native_asset","receiver","amount","fee","status","timestamp","originator") VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13)`) + saveQuery = regexp.QuoteMeta(`UPDATE "transfers" SET "source_chain_id"=$1,"target_chain_id"=$2,"native_chain_id"=$3,"source_asset"=$4,"target_asset"=$5,"native_asset"=$6,"receiver"=$7,"amount"=$8,"fee"=$9,"status"=$10,"timestamp"=$11,"originator"=$12 WHERE "transaction_id" = $13`) updateFeeQuery = regexp.QuoteMeta(`UPDATE "transfers" SET "fee"=$1 WHERE transaction_id = $2`) updateStatusQuery = regexp.QuoteMeta(`UPDATE "transfers" SET "status"=$1 WHERE transaction_id = $2`) @@ -326,9 +311,6 @@ func Test_Create(t *testing.T) { amount, "", //fee someStatus, - serialNumber, - metadata, - isNft, nanoTime, originator) @@ -352,9 +334,6 @@ func Test_Create_Err(t *testing.T) { amount, "", //fee someStatus, - serialNumber, - metadata, - isNft, nanoTime, originator) @@ -377,9 +356,6 @@ func Test_Save(t *testing.T) { amount, fee, someStatus, - serialNumber, - metadata, - isNft, nanoTime, originator, transactionId) @@ -402,9 +378,6 @@ func Test_Save_Err(t *testing.T) { amount, fee, someStatus, - serialNumber, - metadata, - isNft, nanoTime, originator, transactionId) @@ -492,9 +465,6 @@ func Test_create(t *testing.T) { amount, "", //fee someStatus, - serialNumber, - metadata, - isNft, nanoTime, originator) @@ -518,9 +488,6 @@ func Test_create_Err(t *testing.T) { amount, "", //fee someStatus, - serialNumber, - metadata, - isNft, nanoTime, originator) diff --git a/app/process/handler/message/handler.go b/app/process/handler/message/handler.go index dc4b1b05d..ac36b30bf 100644 --- a/app/process/handler/message/handler.go +++ b/app/process/handler/message/handler.go @@ -94,14 +94,8 @@ func (cmh Handler) Handle(payload interface{}) { case *proto.TopicMessage_FungibleSignatureMessage: msgHelper.UpdateHederaChainIdOfFungibleMsg(msg.FungibleSignatureMessage) cmh.handleFungibleSignatureMessage(msg.FungibleSignatureMessage, m.TransactionTimestamp) - break - case *proto.TopicMessage_NftSignatureMessage: - msgHelper.UpdateHederaChainIdOfNftMsg(msg.NftSignatureMessage) - cmh.handleNftSignatureMessage(msg.NftSignatureMessage, m.TransactionTimestamp) - break default: cmh.logger.Errorf("Invalid topic message provided: [%v]", msg) - break } } @@ -131,38 +125,10 @@ func (cmh Handler) handleFungibleSignatureMessage(tsm *proto.TopicEthSignatureMe return } - cmh.completeTransfer(tsm.TransferID, tsm.TargetChainId, tsm.SourceChainId, tsm.Asset, false) + cmh.completeTransfer(tsm.TransferID, tsm.TargetChainId, tsm.SourceChainId, tsm.Asset) } -// handleNftSignatureMessage is the main component responsible for the processing of new incoming Signature Messages -func (cmh Handler) handleNftSignatureMessage(tsm *proto.TopicEthNftSignatureMessage, timestamp int64) { - valid, err := cmh.messages.SanityCheckNftSignature(tsm) - if err != nil { - cmh.logger.Errorf("[%s] - Failed to perform sanity check on nft incoming signature [%s].", tsm.TransferID, tsm.GetSignature()) - return - } - if !valid { - cmh.logger.Errorf("[%s] - Incoming nft signature is invalid", tsm.TransferID) - return - } - - // Parse incoming message - authMsgBytes, err := auth_message.EncodeNftBytesFrom(tsm.SourceChainId, tsm.TargetChainId, tsm.TransferID, tsm.Asset, int64(tsm.TokenId), tsm.Metadata, tsm.Recipient) - if err != nil { - cmh.logger.Errorf("[%s] - Failed to encode the authorisation nft signature. Error: [%s]", tsm.TransferID, err) - return - } - - err = cmh.messages.ProcessSignature(tsm.TransferID, tsm.Signature, tsm.TargetChainId, timestamp, authMsgBytes) - if err != nil { - cmh.logger.Errorf("[%s] - Could not process nft signature [%s]", tsm.TransferID, tsm.GetSignature()) - return - } - - cmh.completeTransfer(tsm.TransferID, tsm.TargetChainId, tsm.SourceChainId, tsm.Asset, true) -} - -func (cmh Handler) completeTransfer(transferID string, targetChainId, sourceChainId uint64, asset string, isNFT bool) { +func (cmh Handler) completeTransfer(transferID string, targetChainId, sourceChainId uint64, asset string) { majorityReached, err := cmh.checkMajority(transferID, targetChainId) if err != nil { cmh.logger.Errorf("[%s] - Could not determine whether majority was reached. Error: [%s]", transferID, err) @@ -170,17 +136,16 @@ func (cmh Handler) completeTransfer(transferID string, targetChainId, sourceChai } if majorityReached { - if !isNFT { // metrics for fungible only - oppositeAsset := cmh.assetsService.OppositeAsset(sourceChainId, targetChainId, asset) - metrics.SetMajorityReached( - sourceChainId, - targetChainId, - oppositeAsset, - transferID, - cmh.prometheusService, - cmh.logger, - ) - } + oppositeAsset := cmh.assetsService.OppositeAsset(sourceChainId, targetChainId, asset) + metrics.SetMajorityReached( + sourceChainId, + targetChainId, + oppositeAsset, + transferID, + cmh.prometheusService, + cmh.logger, + ) + err = cmh.transferRepository.UpdateStatusCompleted(transferID) if err != nil { cmh.logger.Errorf("[%s] - Failed to complete. Error: [%s]", transferID, err) diff --git a/app/process/handler/nft/fee-message/handler.go b/app/process/handler/nft/fee-message/handler.go deleted file mode 100644 index 7d63ee320..000000000 --- a/app/process/handler/nft/fee-message/handler.go +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2022 LimeChain Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package fee_message - -import ( - "github.com/limechain/hedera-eth-bridge-validator/app/domain/service" - "github.com/limechain/hedera-eth-bridge-validator/app/persistence/entity/status" - "github.com/limechain/hedera-eth-bridge-validator/app/process/payload" - "github.com/limechain/hedera-eth-bridge-validator/config" - log "github.com/sirupsen/logrus" -) - -// Handler is transfers event handler -type Handler struct { - transfersService service.Transfers - logger *log.Entry -} - -func NewHandler(transfersService service.Transfers) *Handler { - return &Handler{ - logger: config.GetLoggerFor("Hedera Transfer and Topic Submission Handler"), - transfersService: transfersService, - } -} - -func (fmh Handler) Handle(p interface{}) { - transferMsg, ok := p.(*payload.Transfer) - if !ok { - fmh.logger.Errorf("Could not cast payload [%s]", p) - return - } - - transactionRecord, err := fmh.transfersService.InitiateNewTransfer(*transferMsg) - if err != nil { - fmh.logger.Errorf("[%s] - Error occurred while initiating processing. Error: [%s]", transferMsg.TransactionId, err) - return - } - - if transactionRecord.Status != status.Initial { - fmh.logger.Debugf("[%s] - Previously added with status [%s]. Skipping further execution.", transactionRecord.TransactionID, transactionRecord.Status) - return - } - - err = fmh.transfersService.ProcessNativeNftTransfer(*transferMsg) - if err != nil { - fmh.logger.Errorf("[%s] - Processing failed. Error: [%s]", transferMsg.TransactionId, err) - return - } -} diff --git a/app/process/handler/nft/fee-message/handler_test.go b/app/process/handler/nft/fee-message/handler_test.go deleted file mode 100644 index 041aac1f5..000000000 --- a/app/process/handler/nft/fee-message/handler_test.go +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright 2022 LimeChain Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package fee_message - -import ( - "errors" - "testing" - "time" - - "github.com/limechain/hedera-eth-bridge-validator/app/persistence/entity" - "github.com/limechain/hedera-eth-bridge-validator/app/persistence/entity/status" - "github.com/limechain/hedera-eth-bridge-validator/app/process/payload" - "github.com/limechain/hedera-eth-bridge-validator/config" - "github.com/limechain/hedera-eth-bridge-validator/constants" - testConstants "github.com/limechain/hedera-eth-bridge-validator/test/constants" - "github.com/limechain/hedera-eth-bridge-validator/test/mocks" - "github.com/stretchr/testify/assert" -) - -var ( - handler *Handler - transactionId = "1234" - sourceChainId = constants.HederaNetworkId - targetChainId = testConstants.EthereumNetworkId - nativeChainId = constants.HederaNetworkId - sourceAsset = testConstants.NetworkEthereumNFTWrappedTokenForNetworkHedera - targetAsset = testConstants.NetworkHederaNonFungibleNativeToken - nativeAsset = testConstants.NetworkHederaNonFungibleNativeToken - receiver = "0.0.455300" - amount = "1000000000000000000" - serialNum = int64(123) - metadata = "SomeMetadata" - fee = "10000" - isNft = true - timestamp = time.Now().UTC().String() - entityStatus = status.Initial - nilErr error - - p = &payload.Transfer{ - TransactionId: transactionId, - SourceChainId: sourceChainId, - TargetChainId: targetChainId, - NativeChainId: nativeChainId, - SourceAsset: sourceAsset, - TargetAsset: targetAsset, - NativeAsset: nativeAsset, - Receiver: receiver, - Amount: amount, - SerialNum: serialNum, - Metadata: metadata, - IsNft: isNft, - NetworkTimestamp: timestamp, - } - - resultEntityTransfer = &entity.Transfer{ - TransactionID: transactionId, - SourceChainID: sourceChainId, - TargetChainID: targetChainId, - NativeChainID: nativeChainId, - SourceAsset: sourceAsset, - TargetAsset: targetAsset, - NativeAsset: nativeAsset, - Receiver: receiver, - Amount: amount, - Fee: fee, - Status: entityStatus, - SerialNumber: serialNum, - Metadata: metadata, - IsNft: isNft, - Messages: make([]entity.Message, 0), - Fees: make([]entity.Fee, 0), - Schedules: make([]entity.Schedule, 0), - } -) - -func Test_NewHandler(t *testing.T) { - setup() - - actualHandler := NewHandler(mocks.MTransferService) - - assert.Equal(t, handler, actualHandler) -} - -func Test_Handle(t *testing.T) { - setup() - - mocks.MTransferService.On("InitiateNewTransfer", *p).Return(resultEntityTransfer, nilErr) - mocks.MTransferService.On("ProcessNativeNftTransfer", *p).Return(nilErr) - - handler.Handle(p) - - mocks.MTransferService.AssertCalled(t, "InitiateNewTransfer", *p) - mocks.MTransferService.AssertCalled(t, "ProcessNativeNftTransfer", *p) -} - -func Test_Handle_CastError(t *testing.T) { - setup() - brokenPayload := "Not a transfer" - - handler.Handle(brokenPayload) - - mocks.MTransferService.AssertNotCalled(t, "InitiateNewTransfer", *p) - mocks.MTransferService.AssertNotCalled(t, "ProcessNativeNftTransfer", *p) -} - -func Test_Handle_TransactionError(t *testing.T) { - setup() - - mocks.MTransferService.On("InitiateNewTransfer", *p).Return(resultEntityTransfer, errors.New("failed to create record")) - - handler.Handle(p) - - mocks.MTransferService.AssertCalled(t, "InitiateNewTransfer", *p) - mocks.MTransferService.AssertNotCalled(t, "ProcessNativeNftTransfer", *p) -} - -func Test_Handle_ProcessNativeNftTransferError(t *testing.T) { - setup() - - mocks.MTransferService.On("InitiateNewTransfer", *p).Return(resultEntityTransfer, nilErr) - mocks.MTransferService.On("ProcessNativeNftTransfer", *p).Return(errors.New("failed to process native NFT transfer")) - - handler.Handle(p) - - mocks.MTransferService.AssertCalled(t, "InitiateNewTransfer", *p) - mocks.MTransferService.AssertCalled(t, "ProcessNativeNftTransfer", *p) -} - -func Test_Handle_NotInitial(t *testing.T) { - setup() - - resultEntityTransfer.Status = status.Submitted - mocks.MTransferService.On("InitiateNewTransfer", *p).Return(resultEntityTransfer, nilErr) - mocks.MTransferService.On("ProcessNativeNftTransfer", *p).Return(nilErr) - - handler.Handle(p) - - resultEntityTransfer.Status = entityStatus - - mocks.MTransferService.AssertCalled(t, "InitiateNewTransfer", *p) - mocks.MTransferService.AssertNotCalled(t, "ProcessNativeNftTransfer", *p) - -} - -func setup() { - mocks.Setup() - - handler = &Handler{ - transfersService: mocks.MTransferService, - logger: config.GetLoggerFor("Hedera Transfer and Topic Submission Handler"), - } - -} diff --git a/app/process/handler/nft/transfer/handler.go b/app/process/handler/nft/transfer/handler.go deleted file mode 100644 index 387e2b42e..000000000 --- a/app/process/handler/nft/transfer/handler.go +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright 2022 LimeChain Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package transfer - -import ( - hederaHelper "github.com/limechain/hedera-eth-bridge-validator/app/helper/hedera" - "github.com/limechain/hedera-eth-bridge-validator/app/persistence/entity/schedule" - "sync" - - "github.com/hashgraph/hedera-sdk-go/v2" - "github.com/limechain/hedera-eth-bridge-validator/app/domain/repository" - "github.com/limechain/hedera-eth-bridge-validator/app/domain/service" - "github.com/limechain/hedera-eth-bridge-validator/app/persistence/entity/status" - "github.com/limechain/hedera-eth-bridge-validator/app/process/payload" - "github.com/limechain/hedera-eth-bridge-validator/config" - log "github.com/sirupsen/logrus" -) - -// Handler is transfers event handler -type Handler struct { - bridgeAccount hedera.AccountID - repository repository.Transfer - scheduleRepository repository.Schedule - scheduledService service.Scheduled - transfersService service.Transfers - logger *log.Entry -} - -func NewHandler( - bridgeAccount string, - repository repository.Transfer, - scheduleRepository repository.Schedule, - transfersService service.Transfers, - scheduledService service.Scheduled, -) *Handler { - bridgeAcc, err := hedera.AccountIDFromString(bridgeAccount) - if err != nil { - log.Fatalf("Invalid account id [%s]. Error: [%s]", bridgeAccount, err) - } - - return &Handler{ - bridgeAccount: bridgeAcc, - repository: repository, - scheduleRepository: scheduleRepository, - scheduledService: scheduledService, - transfersService: transfersService, - logger: config.GetLoggerFor("Hedera Native Scheduled Nft Transfer Handler"), - } -} - -func (nth Handler) Handle(p interface{}) { - transfer, ok := p.(*payload.Transfer) - if !ok { - nth.logger.Errorf("Could not cast payload [%s]", p) - return - } - - receiver, err := hedera.AccountIDFromString(transfer.Receiver) - if err != nil { - nth.logger.Errorf("[%s] - Failed to parse event account [%s]. Error [%s].", transfer.TransactionId, transfer.Receiver, err) - return - } - - token, err := hedera.TokenIDFromString(transfer.TargetAsset) - if err != nil { - nth.logger.Errorf("[%s] - Failed to parse token [%s]. Error [%s].", transfer.TransactionId, transfer.TargetAsset, err) - return - } - nftID := hedera.NftID{ - TokenID: token, - SerialNumber: transfer.SerialNum, - } - - transactionRecord, err := nth.transfersService.InitiateNewTransfer(*transfer) - if err != nil { - nth.logger.Errorf("[%s] - Error occurred while initiating processing. Error: [%s]", transfer.TransactionId, err) - return - } - - if transactionRecord.Status != status.Initial { - nth.logger.Debugf("[%s] - Previously added with status [%s]. Skipping further execution.", transactionRecord.TransactionID, transactionRecord.Status) - return - } - - var statusResult string - wg := new(sync.WaitGroup) - wg.Add(1) - onExecutionSuccess, onExecutionFail := hederaHelper.ScheduledNftTxExecutionCallbacks(nth.repository, nth.scheduleRepository, nth.logger, transfer.TransactionId, true, &statusResult, schedule.APPROVE, wg) - onSuccess, onFail := hederaHelper.ScheduledNftTxMinedCallbacks(nth.repository, nth.scheduleRepository, nth.logger, transfer.TransactionId, &statusResult, wg) - - nth.scheduledService.ExecuteScheduledNftAllowTransaction(transfer.TransactionId, nftID, nth.bridgeAccount, receiver, onExecutionSuccess, onExecutionFail, onSuccess, onFail) -} diff --git a/app/process/handler/nft/transfer/handler_test.go b/app/process/handler/nft/transfer/handler_test.go deleted file mode 100644 index 7dbf989e1..000000000 --- a/app/process/handler/nft/transfer/handler_test.go +++ /dev/null @@ -1,495 +0,0 @@ -/* - * Copyright 2022 LimeChain Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package transfer - -import ( - "database/sql" - "errors" - "sync" - "testing" - "time" - - hederaHelper "github.com/limechain/hedera-eth-bridge-validator/app/helper/hedera" - - "github.com/hashgraph/hedera-sdk-go/v2" - "github.com/limechain/hedera-eth-bridge-validator/app/persistence/entity" - "github.com/limechain/hedera-eth-bridge-validator/app/persistence/entity/schedule" - "github.com/limechain/hedera-eth-bridge-validator/app/persistence/entity/status" - "github.com/limechain/hedera-eth-bridge-validator/app/process/payload" - "github.com/limechain/hedera-eth-bridge-validator/config" - "github.com/limechain/hedera-eth-bridge-validator/constants" - testConstants "github.com/limechain/hedera-eth-bridge-validator/test/constants" - "github.com/limechain/hedera-eth-bridge-validator/test/mocks" - test_config "github.com/limechain/hedera-eth-bridge-validator/test/test-config" - log "github.com/sirupsen/logrus" - "github.com/stretchr/testify/assert" -) - -var ( - handler *Handler - bridgeAccount = test_config.TestConfig.Bridge.Hedera.BridgeAccount - transactionId = "1234" - sourceChainId = constants.HederaNetworkId - targetChainId = testConstants.EthereumNetworkId - nativeChainId = constants.HederaNetworkId - sourceAsset = testConstants.NetworkEthereumNFTWrappedTokenForNetworkHedera - targetAsset = testConstants.NetworkHederaNonFungibleNativeToken - nativeAsset = testConstants.NetworkHederaNonFungibleNativeToken - receiver = "0.0.455300" - amount = "1000000000000000000" - serialNum = int64(123) - metadata = "SomeMetadata" - fee = "10000" - isNft = true - timestamp = time.Now().UTC().String() - entityStatus = status.Initial - nilErr error - - p = &payload.Transfer{ - TransactionId: transactionId, - SourceChainId: sourceChainId, - TargetChainId: targetChainId, - NativeChainId: nativeChainId, - SourceAsset: sourceAsset, - TargetAsset: targetAsset, - NativeAsset: nativeAsset, - Receiver: receiver, - Amount: amount, - SerialNum: serialNum, - Metadata: metadata, - IsNft: isNft, - NetworkTimestamp: timestamp, - } - - resultEntityTransfer = &entity.Transfer{ - TransactionID: transactionId, - SourceChainID: sourceChainId, - TargetChainID: targetChainId, - NativeChainID: nativeChainId, - SourceAsset: sourceAsset, - TargetAsset: targetAsset, - NativeAsset: nativeAsset, - Receiver: receiver, - Amount: amount, - Fee: fee, - Status: entityStatus, - SerialNumber: serialNum, - Metadata: metadata, - IsNft: isNft, - Messages: make([]entity.Message, 0), - Fees: make([]entity.Fee, 0), - Schedules: make([]entity.Schedule, 0), - } - - bridgeAccountId hedera.AccountID - receiverAccountId hedera.AccountID - - scheduleId = "0.0.675300" - onSuccessScheduleEntity = &entity.Schedule{ - TransactionID: transactionId, - ScheduleID: scheduleId, - HasReceiver: true, - Operation: schedule.TRANSFER, - Status: status.Submitted, - TransferID: sql.NullString{String: transactionId, Valid: true}, - } - onFailureScheduleEntity = &entity.Schedule{ - TransactionID: transactionId, - ScheduleID: "", - HasReceiver: true, - Operation: "", - Status: status.Failed, - TransferID: sql.NullString{String: transactionId, Valid: true}, - } -) - -func Test_NewHandler(t *testing.T) { - setup(t) - - actualHandler := NewHandler( - bridgeAccount, - mocks.MTransferRepository, - mocks.MScheduleRepository, - mocks.MTransferService, - mocks.MScheduledService) - - assert.Equal(t, handler, actualHandler) -} - -func Test_NewHandler_BridgeAccountError(t *testing.T) { - setup(t) - - defer func() { log.StandardLogger().ExitFunc = nil }() - fatal := false - log.StandardLogger().ExitFunc = func(int) { fatal = true } - - _ = NewHandler( - "", - mocks.MTransferRepository, - mocks.MScheduleRepository, - mocks.MTransferService, - mocks.MScheduledService) - - assert.Equal(t, true, fatal) -} - -func Test_Handle(t *testing.T) { - setup(t) - - token, err := hedera.TokenIDFromString(targetAsset) - if err != nil { - t.Fatal(err) - } - nftID := hedera.NftID{ - TokenID: token, - SerialNumber: serialNum, - } - - mocks.MTransferService.On("InitiateNewTransfer", *p).Return(resultEntityTransfer, nilErr) - mocks.MScheduledService.On("ExecuteScheduledNftAllowTransaction", - transactionId, - nftID, - bridgeAccountId, - receiverAccountId, - ).Return() - - handler.Handle(p) - - mocks.MTransferService.AssertCalled(t, "InitiateNewTransfer", *p) - mocks.MScheduledService.AssertCalled(t, "ExecuteScheduledNftAllowTransaction", - transactionId, - nftID, - bridgeAccountId, - receiverAccountId) -} - -func Test_Handle_CastError(t *testing.T) { - setup(t) - brokenPayload := "Not a transfer" - - handler.Handle(brokenPayload) - - mocks.MTransferService.AssertNotCalled(t, "InitiateNewTransfer") - mocks.MScheduledService.AssertNotCalled(t, "ExecuteScheduledNftTransferTransaction") -} - -func Test_Handle_ReceiverError(t *testing.T) { - setup(t) - p.Receiver = "" - - handler.Handle(p) - - p.Receiver = receiver - - mocks.MTransferService.AssertNotCalled(t, "InitiateNewTransfer") - mocks.MScheduledService.AssertNotCalled(t, "ExecuteScheduledNftTransferTransaction") -} - -func Test_Handle_TokenError(t *testing.T) { - setup(t) - p.TargetAsset = "" - - handler.Handle(p) - - p.TargetAsset = targetAsset - - mocks.MTransferService.AssertNotCalled(t, "InitiateNewTransfer") - mocks.MScheduledService.AssertNotCalled(t, "ExecuteScheduledNftTransferTransaction") -} - -func Test_Handle_TransactionError(t *testing.T) { - setup(t) - mocks.MTransferService.On("InitiateNewTransfer", *p).Return(resultEntityTransfer, errors.New("failed to create record")) - - handler.Handle(p) - - mocks.MTransferService.AssertCalled(t, "InitiateNewTransfer", *p) - mocks.MScheduledService.AssertNotCalled(t, "ExecuteScheduledNftTransferTransaction") -} - -func Test_Handle_NotInitialStatus(t *testing.T) { - setup(t) - resultEntityTransfer.Status = status.Submitted - mocks.MTransferService.On("InitiateNewTransfer", *p).Return(resultEntityTransfer, nilErr) - - handler.Handle(p) - - resultEntityTransfer.Status = entityStatus - - mocks.MTransferService.AssertCalled(t, "InitiateNewTransfer", *p) - mocks.MScheduledService.AssertNotCalled(t, "ExecuteScheduledNftTransferTransaction") -} - -func Test_scheduledTxMinedCallbacks(t *testing.T) { - setup(t) - - mocks.MTransferRepository.On("UpdateStatusCompleted", transactionId).Return(nilErr) - mocks.MTransferRepository.On("UpdateStatusFailed", transactionId).Return(nilErr) - mocks.MScheduleRepository.On("UpdateStatusCompleted", transactionId).Return(nilErr) - mocks.MScheduleRepository.On("UpdateStatusFailed", transactionId).Return(nilErr) - - statusResult := new(string) - wg := new(sync.WaitGroup) - wg.Add(2) - onSuccess, onFailure := hederaHelper.ScheduledNftTxMinedCallbacks( - handler.repository, - handler.scheduleRepository, - handler.logger, - transactionId, - statusResult, - wg) - onSuccess(transactionId) - onFailure(transactionId) - - mocks.MTransferRepository.AssertCalled(t, "UpdateStatusCompleted", transactionId) - mocks.MTransferRepository.AssertCalled(t, "UpdateStatusFailed", transactionId) - mocks.MScheduleRepository.AssertCalled(t, "UpdateStatusCompleted", transactionId) - mocks.MScheduleRepository.AssertCalled(t, "UpdateStatusFailed", transactionId) -} - -func Test_scheduledTxMinedCallbacks_TransferRepoErrorOnSuccess(t *testing.T) { - setup(t) - - err := errors.New("some error") - mocks.MTransferRepository.On("UpdateStatusCompleted", transactionId).Return(err) - - statusResult := new(string) - wg := new(sync.WaitGroup) - wg.Add(1) - onSuccess, _ := hederaHelper.ScheduledNftTxMinedCallbacks( - handler.repository, - handler.scheduleRepository, - handler.logger, - transactionId, - statusResult, - wg) - onSuccess(transactionId) - - mocks.MTransferRepository.AssertCalled(t, "UpdateStatusCompleted", transactionId) - mocks.MScheduleRepository.AssertNotCalled(t, "UpdateStatusCompleted") -} - -func Test_scheduledTxMinedCallbacks_ScheduleRepoErrorOnSuccess(t *testing.T) { - setup(t) - - err := errors.New("some error") - mocks.MTransferRepository.On("UpdateStatusCompleted", transactionId).Return(nilErr) - mocks.MScheduleRepository.On("UpdateStatusCompleted", transactionId).Return(err) - - statusResult := new(string) - wg := new(sync.WaitGroup) - wg.Add(1) - onSuccess, _ := hederaHelper.ScheduledNftTxMinedCallbacks( - handler.repository, - handler.scheduleRepository, - handler.logger, - transactionId, - statusResult, - wg) - onSuccess(transactionId) - - mocks.MTransferRepository.AssertCalled(t, "UpdateStatusCompleted", transactionId) - mocks.MScheduleRepository.AssertCalled(t, "UpdateStatusCompleted", transactionId) -} - -func Test_scheduledTxMinedCallbacks_TransferRepoErrorOnFailure(t *testing.T) { - setup(t) - - err := errors.New("some error") - mocks.MScheduleRepository.On("UpdateStatusFailed", transactionId).Return(nilErr) - mocks.MTransferRepository.On("UpdateStatusFailed", transactionId).Return(err) - - statusResult := new(string) - wg := new(sync.WaitGroup) - wg.Add(1) - _, onFailure := hederaHelper.ScheduledNftTxMinedCallbacks( - handler.repository, - handler.scheduleRepository, - handler.logger, - transactionId, - statusResult, - wg) - onFailure(transactionId) - - mocks.MScheduleRepository.AssertCalled(t, "UpdateStatusFailed", transactionId) - mocks.MTransferRepository.AssertCalled(t, "UpdateStatusFailed", transactionId) -} - -func Test_scheduledTxMinedCallbacks_ScheduledRepoErrorOnFailure(t *testing.T) { - setup(t) - - err := errors.New("some error") - mocks.MScheduleRepository.On("UpdateStatusFailed", transactionId).Return(err) - - statusResult := new(string) - wg := new(sync.WaitGroup) - wg.Add(1) - _, onFailure := hederaHelper.ScheduledNftTxMinedCallbacks( - handler.repository, - handler.scheduleRepository, - handler.logger, - transactionId, - statusResult, - wg) - onFailure(transactionId) - - mocks.MScheduleRepository.AssertCalled(t, "UpdateStatusFailed", transactionId) - mocks.MTransferRepository.AssertNotCalled(t, "UpdateStatusFailed") -} - -func Test_scheduledTxExecutionCallbacks_OnSuccess(t *testing.T) { - setup(t) - - mocks.MScheduleRepository.On("Create", onSuccessScheduleEntity).Return(nilErr) - - statusResult := new(string) - wg := new(sync.WaitGroup) - wg.Add(1) - onSuccess, _ := hederaHelper.ScheduledNftTxExecutionCallbacks( - handler.repository, - handler.scheduleRepository, - handler.logger, - transactionId, - true, - statusResult, - schedule.TRANSFER, - wg) - - onSuccess(transactionId, scheduleId) - - mocks.MScheduleRepository.AssertCalled(t, "Create", onSuccessScheduleEntity) - -} - -func Test_scheduledTxExecutionCallbacks_OnSuccess_Err(t *testing.T) { - setup(t) - - mocks.MScheduleRepository.On("Create", onSuccessScheduleEntity).Return(errors.New("some error")) - - statusResult := new(string) - wg := new(sync.WaitGroup) - wg.Add(1) - onSuccess, _ := hederaHelper.ScheduledNftTxExecutionCallbacks( - handler.repository, - handler.scheduleRepository, - handler.logger, - transactionId, - true, - statusResult, - schedule.TRANSFER, - wg) - - onSuccess(transactionId, scheduleId) - - mocks.MScheduleRepository.AssertCalled(t, "Create", onSuccessScheduleEntity) - -} - -func Test_scheduledTxExecutionCallbacks_OnFailure(t *testing.T) { - setup(t) - - mocks.MScheduleRepository.On("Create", onFailureScheduleEntity).Return(nilErr) - mocks.MTransferRepository.On("UpdateStatusFailed", transactionId).Return(nilErr) - - statusResult := new(string) - wg := new(sync.WaitGroup) - wg.Add(1) - _, OnFailure := hederaHelper.ScheduledNftTxExecutionCallbacks( - handler.repository, - handler.scheduleRepository, - handler.logger, - transactionId, - true, - statusResult, - schedule.TRANSFER, - wg) - OnFailure(transactionId) - - mocks.MScheduleRepository.AssertCalled(t, "Create", onFailureScheduleEntity) - mocks.MTransferRepository.AssertCalled(t, "UpdateStatusFailed", transactionId) -} - -func Test_scheduledTxExecutionCallbacks_OnFailure_CreateEntityErr(t *testing.T) { - setup(t) - - mocks.MScheduleRepository.On("Create", onFailureScheduleEntity).Return(errors.New("some error")) - - statusResult := new(string) - wg := new(sync.WaitGroup) - wg.Add(1) - _, OnFailure := hederaHelper.ScheduledNftTxExecutionCallbacks( - handler.repository, - handler.scheduleRepository, - handler.logger, - transactionId, - true, - statusResult, - schedule.TRANSFER, - wg) - OnFailure(transactionId) - - mocks.MScheduleRepository.AssertCalled(t, "Create", onFailureScheduleEntity) -} - -func Test_scheduledTxExecutionCallbacks_OnFailure_UpdateStatusErr(t *testing.T) { - setup(t) - - mocks.MScheduleRepository.On("Create", onFailureScheduleEntity).Return(nilErr) - mocks.MTransferRepository.On("UpdateStatusFailed", transactionId).Return(errors.New("some error")) - - statusResult := new(string) - wg := new(sync.WaitGroup) - wg.Add(1) - _, OnFailure := hederaHelper.ScheduledNftTxExecutionCallbacks( - handler.repository, - handler.scheduleRepository, - handler.logger, - transactionId, - true, - statusResult, - schedule.TRANSFER, - wg) - OnFailure(transactionId) - - mocks.MScheduleRepository.AssertCalled(t, "Create", onFailureScheduleEntity) - mocks.MTransferRepository.AssertCalled(t, "UpdateStatusFailed", transactionId) -} - -func setup(t *testing.T) { - mocks.Setup() - var err error - - bridgeAccountId, err = hedera.AccountIDFromString(bridgeAccount) - if err != nil { - t.Fatalf("Invalid bridge account id [%s]. Error: [%s]", bridgeAccount, err) - } - - receiverAccountId, err = hedera.AccountIDFromString(receiver) - if err != nil { - t.Fatalf("Invalid receiver account id [%s]. Error: [%s]", receiver, err) - } - - handler = &Handler{ - bridgeAccountId, - mocks.MTransferRepository, - mocks.MScheduleRepository, - mocks.MScheduledService, - mocks.MTransferService, - config.GetLoggerFor("Hedera Native Scheduled Nft Transfer Handler"), - } - -} diff --git a/app/process/handler/read-only/nft/fee/handler.go b/app/process/handler/read-only/nft/fee/handler.go deleted file mode 100644 index ae7bc40e9..000000000 --- a/app/process/handler/read-only/nft/fee/handler.go +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright 2022 LimeChain Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package fee - -import ( - "database/sql" - "strconv" - - "github.com/hashgraph/hedera-sdk-go/v2" - mirror_node "github.com/limechain/hedera-eth-bridge-validator/app/clients/hedera/mirror-node/model/transaction" - "github.com/limechain/hedera-eth-bridge-validator/app/domain/client" - "github.com/limechain/hedera-eth-bridge-validator/app/domain/repository" - "github.com/limechain/hedera-eth-bridge-validator/app/domain/service" - model "github.com/limechain/hedera-eth-bridge-validator/app/model/transfer" - "github.com/limechain/hedera-eth-bridge-validator/app/persistence/entity" - "github.com/limechain/hedera-eth-bridge-validator/app/persistence/entity/schedule" - "github.com/limechain/hedera-eth-bridge-validator/app/persistence/entity/status" - "github.com/limechain/hedera-eth-bridge-validator/app/process/payload" - "github.com/limechain/hedera-eth-bridge-validator/app/services/fee/distributor" - "github.com/limechain/hedera-eth-bridge-validator/config" - "github.com/limechain/hedera-eth-bridge-validator/constants" - log "github.com/sirupsen/logrus" -) - -// Handler is transfers event handler -type Handler struct { - transferRepository repository.Transfer - feeRepository repository.Fee - scheduleRepository repository.Schedule - mirrorNode client.MirrorNode - bridgeAccount hedera.AccountID - distributor service.Distributor - transfersService service.Transfers - readOnlyService service.ReadOnly - logger *log.Entry -} - -func NewHandler( - transferRepository repository.Transfer, - feeRepository repository.Fee, - scheduleRepository repository.Schedule, - mirrorNode client.MirrorNode, - bridgeAccount string, - distributor service.Distributor, - transfersService service.Transfers, - readOnlyService service.ReadOnly) *Handler { - bridgeAcc, err := hedera.AccountIDFromString(bridgeAccount) - if err != nil { - log.Fatalf("Invalid account id [%s]. Error: [%s]", bridgeAccount, err) - } - - instance := &Handler{ - transferRepository: transferRepository, - feeRepository: feeRepository, - scheduleRepository: scheduleRepository, - mirrorNode: mirrorNode, - bridgeAccount: bridgeAcc, - logger: config.GetLoggerFor("Hedera Transfer and Topic Submission Read-only Handler"), - transfersService: transfersService, - distributor: distributor, - readOnlyService: readOnlyService, - } - - return instance -} - -func (fmh Handler) Handle(p interface{}) { - transferMsg, ok := p.(*payload.Transfer) - if !ok { - fmh.logger.Errorf("Could not cast payload [%s]", p) - return - } - - transactionRecord, err := fmh.transfersService.InitiateNewTransfer(*transferMsg) - if err != nil { - fmh.logger.Errorf("[%s] - Error occurred while initiating processing. Error: [%s]", transferMsg.TransactionId, err) - return - } - - if transactionRecord.Status != status.Initial { - fmh.logger.Debugf("[%s] - Previously added with status [%s]. Skipping further execution.", transactionRecord.TransactionID, transactionRecord.Status) - return - } - - fmh.readOnlyService.FindNftTransfer( - transferMsg.TransactionId, - transferMsg.SourceAsset, - transferMsg.SerialNum, - transferMsg.Originator, - fmh.bridgeAccount.String(), - func(transactionID, scheduleID, status string) error { - err := fmh.scheduleRepository.Create(&entity.Schedule{ - TransactionID: transferMsg.TransactionId, - ScheduleID: scheduleID, - Operation: schedule.TRANSFER, - Status: status, - HasReceiver: true, - TransferID: sql.NullString{ - String: transferMsg.TransactionId, - Valid: true, - }, - }) - if err != nil { - fmh.logger.Errorf("[%s] - Failed to create scheduled entity [%s]. Error: [%s]", transactionID, scheduleID, err) - return err - } - - return fmh.transferRepository.UpdateStatusCompleted(transactionID) - }, - ) - - validFee := fmh.distributor.ValidAmount(transferMsg.Fee) - err = fmh.transferRepository.UpdateFee(transferMsg.TransactionId, strconv.FormatInt(validFee, 10)) - if err != nil { - fmh.logger.Errorf("[%s] - Failed to update fee [%d]. Error: [%s]", transferMsg.TransactionId, validFee, err) - return - } - - transfers, _ := fmh.distributor.CalculateMemberDistribution(validFee) - - splitTransfers := distributor.SplitAccountAmounts(transfers, - model.Hedera{ - AccountID: fmh.bridgeAccount, - Amount: -validFee, - }) - - for _, splitTransfer := range splitTransfers { - feeAmount := -splitTransfer[len(splitTransfer)-1].Amount - fmh.readOnlyService.FindAssetTransfer(transferMsg.TransactionId, constants.Hbar, splitTransfer, - func() (*mirror_node.Response, error) { - return fmh.feeTransfersFetch(transferMsg) - }, - func(transactionID, scheduleID, status string) error { - return fmh.feeTransfersSave(transactionID, scheduleID, status, transferMsg, feeAmount) - }) - } -} - -func (fmh Handler) feeTransfersFetch(transferMsg *payload.Transfer) (*mirror_node.Response, error) { - return fmh.mirrorNode.GetAccountDebitTransactionsAfterTimestampString(fmh.bridgeAccount, transferMsg.NetworkTimestamp) -} - -func (fmh Handler) feeTransfersSave(transactionID string, scheduleID string, status string, transferMsg *payload.Transfer, feeAmount int64) error { - err := fmh.scheduleRepository.Create(&entity.Schedule{ - TransactionID: transactionID, - ScheduleID: scheduleID, - Operation: schedule.TRANSFER, - Status: status, - TransferID: sql.NullString{ - String: transferMsg.TransactionId, - Valid: true, - }, - }) - if err != nil { - fmh.logger.Errorf("[%s] - Failed to create scheduled entity [%s]. Error: [%s]", transferMsg.TransactionId, scheduleID, err) - return err - } - err = fmh.feeRepository.Create(&entity.Fee{ - TransactionID: transactionID, - ScheduleID: scheduleID, - Amount: strconv.FormatInt(feeAmount, 10), - Status: status, - TransferID: sql.NullString{ - String: transferMsg.TransactionId, - Valid: true, - }, - }) - if err != nil { - fmh.logger.Errorf("[%s] - Failed to create fee entity [%s]. Error: [%s]", transferMsg.TransactionId, scheduleID, err) - } - return err -} diff --git a/app/process/handler/read-only/nft/fee/handler_test.go b/app/process/handler/read-only/nft/fee/handler_test.go deleted file mode 100644 index 50c1e7997..000000000 --- a/app/process/handler/read-only/nft/fee/handler_test.go +++ /dev/null @@ -1,337 +0,0 @@ -/* - * Copyright 2022 LimeChain Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package fee - -import ( - "database/sql" - "errors" - "strconv" - "testing" - "time" - - "github.com/hashgraph/hedera-sdk-go/v2" - mirrorNodeErr "github.com/limechain/hedera-eth-bridge-validator/app/clients/hedera/mirror-node/model/error" - "github.com/limechain/hedera-eth-bridge-validator/app/clients/hedera/mirror-node/model/transaction" - model "github.com/limechain/hedera-eth-bridge-validator/app/model/transfer" - "github.com/limechain/hedera-eth-bridge-validator/app/persistence/entity" - "github.com/limechain/hedera-eth-bridge-validator/app/persistence/entity/schedule" - "github.com/limechain/hedera-eth-bridge-validator/app/persistence/entity/status" - "github.com/limechain/hedera-eth-bridge-validator/app/process/payload" - "github.com/limechain/hedera-eth-bridge-validator/config" - "github.com/limechain/hedera-eth-bridge-validator/constants" - testConstants "github.com/limechain/hedera-eth-bridge-validator/test/constants" - "github.com/limechain/hedera-eth-bridge-validator/test/mocks" - log "github.com/sirupsen/logrus" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/mock" -) - -var ( - handler *Handler - bridgeAccountAsStr = "0.0.111111" - bridgeAccount hedera.AccountID - transactionId = "1234" - sourceChainId = constants.HederaNetworkId - targetChainId = testConstants.EthereumNetworkId - nativeChainId = constants.HederaNetworkId - sourceAsset = testConstants.NetworkHederaNonFungibleNativeToken - targetAsset = testConstants.NetworkEthereumNFTWrappedTokenForNetworkHedera - nativeAsset = testConstants.NetworkHederaNonFungibleNativeToken - receiver = "0.0.455300" - amount = "1000000000000000000" - serialNum = int64(123) - metadata = "SomeMetadata" - fee = "10000" - isNft = true - timestamp = time.Now().UTC().String() - entityStatus = status.Initial - nilErr error - - p = &payload.Transfer{ - TransactionId: transactionId, - SourceChainId: sourceChainId, - TargetChainId: targetChainId, - NativeChainId: nativeChainId, - SourceAsset: sourceAsset, - TargetAsset: targetAsset, - NativeAsset: nativeAsset, - Receiver: receiver, - Amount: amount, - SerialNum: serialNum, - Metadata: metadata, - IsNft: isNft, - NetworkTimestamp: timestamp, - Fee: hederaFeeForSourceAsset, - } - - entityTransfer = &entity.Transfer{ - TransactionID: transactionId, - SourceChainID: sourceChainId, - TargetChainID: targetChainId, - NativeChainID: nativeChainId, - SourceAsset: sourceAsset, - TargetAsset: targetAsset, - NativeAsset: nativeAsset, - Receiver: receiver, - Amount: amount, - Fee: fee, - Status: entityStatus, - SerialNumber: serialNum, - Metadata: metadata, - IsNft: isNft, - Messages: make([]entity.Message, 0), - Fees: make([]entity.Fee, 0), - Schedules: make([]entity.Schedule, 0), - } - validatorAccountIdsAsStr = []string{"0.0.26306401", "0.0.26306402", "0.0.26306403"} - countOfValidators = int64(len(validatorAccountIdsAsStr)) - validatorAccountIds = make([]hedera.AccountID, countOfValidators) - hederaFeeForSourceAsset = testConstants.HederaNftFees[sourceAsset] - validFee = (hederaFeeForSourceAsset / countOfValidators) * countOfValidators - formattedValidFee = strconv.FormatInt(validFee, 10) - feePerValidator = validFee / countOfValidators - hederaTransfers = make([]model.Hedera, countOfValidators) - splitTransfers = make([][]model.Hedera, 1) - scheduleId = "33333" - - scheduleEntity = &entity.Schedule{ - TransactionID: transactionId, - ScheduleID: scheduleId, - HasReceiver: false, - Operation: schedule.TRANSFER, - Status: status.Completed, - TransferID: sql.NullString{String: transactionId, Valid: true}, - } - feeEntity = &entity.Fee{ - TransactionID: transactionId, - ScheduleID: scheduleId, - Amount: strconv.FormatInt(-validFee, 10), - Status: status.Completed, - TransferID: sql.NullString{String: transactionId, Valid: true}, - } -) - -func Test_NewHandler(t *testing.T) { - setup(t, false) - - actualHandler := NewHandler( - mocks.MTransferRepository, - mocks.MFeeRepository, - mocks.MScheduleRepository, - mocks.MHederaMirrorClient, - bridgeAccountAsStr, - mocks.MDistributorService, - mocks.MTransferService, - mocks.MReadOnlyService, - ) - - assert.Equal(t, handler, actualHandler) -} - -func Test_NewHandler_ErrOnBridgeAccountParse(t *testing.T) { - setup(t, false) - - defer func() { log.StandardLogger().ExitFunc = nil }() - fatal := false - log.StandardLogger().ExitFunc = func(int) { fatal = true } - - _ = NewHandler( - mocks.MTransferRepository, - mocks.MFeeRepository, - mocks.MScheduleRepository, - mocks.MHederaMirrorClient, - "invalid account", - mocks.MDistributorService, - mocks.MTransferService, - mocks.MReadOnlyService, - ) - - assert.Equal(t, true, fatal) -} - -func Test_Handle(t *testing.T) { - setup(t, true) - - mocks.MTransferService.On("InitiateNewTransfer", *p).Return(entityTransfer, nil) - mocks.MDistributorService.On("ValidAmount", hederaFeeForSourceAsset).Return(validFee) - mocks.MTransferRepository.On("UpdateFee", transactionId, formattedValidFee).Return(nil) - mocks.MDistributorService.On("CalculateMemberDistribution", validFee).Return(hederaTransfers, nilErr) - mocks.MReadOnlyService.On("FindNftTransfer", transactionId, sourceAsset, serialNum, mock.Anything, bridgeAccountAsStr, mock.Anything) - mocks.MReadOnlyService.On("FindAssetTransfer", transactionId, constants.Hbar, splitTransfers[0], mock.Anything, mock.Anything) - - handler.Handle(p) - - mocks.MTransferService.AssertCalled(t, "InitiateNewTransfer", *p) - mocks.MDistributorService.AssertCalled(t, "ValidAmount", hederaFeeForSourceAsset) - mocks.MTransferRepository.AssertCalled(t, "UpdateFee", transactionId, formattedValidFee) - mocks.MDistributorService.AssertCalled(t, "CalculateMemberDistribution", validFee) - mocks.MReadOnlyService.AssertCalled(t, "FindNftTransfer", transactionId, sourceAsset, serialNum, mock.Anything, bridgeAccountAsStr, mock.Anything) - mocks.MReadOnlyService.AssertCalled(t, "FindAssetTransfer", transactionId, constants.Hbar, splitTransfers[0], mock.Anything, mock.Anything) -} - -func Test_Handle_ErrOnCast(t *testing.T) { - setup(t, true) - brokenPayload := "not a transfer" - - handler.Handle(brokenPayload) - - mocks.MTransferService.AssertNotCalled(t, "InitiateNewTransfer", *p) - mocks.MDistributorService.AssertNotCalled(t, "ValidAmount", hederaFeeForSourceAsset) - mocks.MTransferRepository.AssertNotCalled(t, "UpdateFee", transactionId, formattedValidFee) - mocks.MDistributorService.AssertNotCalled(t, "CalculateMemberDistribution", validFee) - mocks.MReadOnlyService.AssertNotCalled(t, "FindAssetTransfer", transactionId, constants.Hbar, splitTransfers[0], mock.Anything, mock.Anything) -} - -func Test_Handle_ErrOnTransactionRecord(t *testing.T) { - setup(t, true) - var nilTransfer *entity.Transfer - mocks.MTransferService.On("InitiateNewTransfer", *p).Return(nilTransfer, errors.New("failed to create transaction record")) - - handler.Handle(p) - - mocks.MTransferService.AssertCalled(t, "InitiateNewTransfer", *p) - mocks.MDistributorService.AssertNotCalled(t, "ValidAmount", hederaFeeForSourceAsset) - mocks.MTransferRepository.AssertNotCalled(t, "UpdateFee", transactionId, formattedValidFee) - mocks.MDistributorService.AssertNotCalled(t, "CalculateMemberDistribution", validFee) - mocks.MReadOnlyService.AssertNotCalled(t, "FindAssetTransfer", transactionId, constants.Hbar, splitTransfers[0], mock.Anything, mock.Anything) -} - -func Test_Handle_TransactionRecordNotInitialStatus(t *testing.T) { - setup(t, true) - entityTransfer.Status = status.Completed - mocks.MTransferService.On("InitiateNewTransfer", *p).Return(entityTransfer, nilErr) - - handler.Handle(p) - - entityTransfer.Status = entityStatus - - mocks.MTransferService.AssertCalled(t, "InitiateNewTransfer", *p) - mocks.MDistributorService.AssertNotCalled(t, "ValidAmount", hederaFeeForSourceAsset) - mocks.MTransferRepository.AssertNotCalled(t, "UpdateFee", transactionId, formattedValidFee) - mocks.MDistributorService.AssertNotCalled(t, "CalculateMemberDistribution", validFee) - mocks.MReadOnlyService.AssertNotCalled(t, "FindAssetTransfer", transactionId, constants.Hbar, splitTransfers[0], mock.Anything, mock.Anything) -} - -func Test_Handle_ErrOnUpdateFee(t *testing.T) { - setup(t, true) - - mocks.MTransferService.On("InitiateNewTransfer", *p).Return(entityTransfer, nil) - mocks.MDistributorService.On("ValidAmount", hederaFeeForSourceAsset).Return(validFee) - mocks.MTransferRepository.On("UpdateFee", transactionId, formattedValidFee).Return(errors.New("failed to create transaction record")) - mocks.MReadOnlyService.On("FindNftTransfer", transactionId, sourceAsset, serialNum, mock.Anything, bridgeAccountAsStr, mock.Anything) - - handler.Handle(p) - - mocks.MTransferService.AssertCalled(t, "InitiateNewTransfer", *p) - mocks.MDistributorService.AssertCalled(t, "ValidAmount", hederaFeeForSourceAsset) - mocks.MTransferRepository.AssertCalled(t, "UpdateFee", transactionId, formattedValidFee) - mocks.MDistributorService.AssertNotCalled(t, "CalculateMemberDistribution", validFee) - mocks.MReadOnlyService.AssertNotCalled(t, "FindAssetTransfer", transactionId, constants.Hbar, splitTransfers[0], mock.Anything, mock.Anything) - mocks.MReadOnlyService.AssertCalled(t, "FindNftTransfer", transactionId, sourceAsset, serialNum, mock.Anything, bridgeAccountAsStr, mock.Anything) -} - -func Test_fetch(t *testing.T) { - setup(t, false) - expectedResponse := &transaction.Response{ - Transactions: []transaction.Transaction{}, - Status: mirrorNodeErr.Status{}, - } - mocks.MHederaMirrorClient.On( - "GetAccountDebitTransactionsAfterTimestampString", - bridgeAccount, - p.NetworkTimestamp, - ).Return(expectedResponse, nilErr) - - actualResponse, err := handler.feeTransfersFetch(p) - - assert.Nil(t, err) - assert.Equal(t, expectedResponse, actualResponse) - mocks.MHederaMirrorClient.AssertCalled(t, "GetAccountDebitTransactionsAfterTimestampString", bridgeAccount, p.NetworkTimestamp) -} - -func Test_save(t *testing.T) { - setup(t, false) - mocks.MScheduleRepository.On("Create", scheduleEntity).Return(nilErr) - mocks.MFeeRepository.On("Create", feeEntity).Return(nilErr) - - err := handler.feeTransfersSave(transactionId, scheduleId, status.Completed, p, -validFee) - - assert.Nil(t, err) - mocks.MScheduleRepository.AssertCalled(t, "Create", scheduleEntity) - mocks.MFeeRepository.AssertCalled(t, "Create", feeEntity) -} - -func Test_save_ErrOnCreateScheduleEntity(t *testing.T) { - setup(t, false) - expectedErr := errors.New("failed to create schedule record") - mocks.MScheduleRepository.On("Create", scheduleEntity).Return(expectedErr) - - err := handler.feeTransfersSave(transactionId, scheduleId, status.Completed, p, -validFee) - - assert.Equal(t, expectedErr, err) - mocks.MScheduleRepository.AssertCalled(t, "Create", scheduleEntity) - mocks.MFeeRepository.AssertNotCalled(t, "Create", feeEntity) -} - -func Test_save_ErrOnCreateFeeEntity(t *testing.T) { - setup(t, false) - expectedErr := errors.New("failed to create fee record") - mocks.MScheduleRepository.On("Create", scheduleEntity).Return(nilErr) - mocks.MFeeRepository.On("Create", feeEntity).Return(expectedErr) - - err := handler.feeTransfersSave(transactionId, scheduleId, status.Completed, p, -validFee) - - assert.Equal(t, expectedErr, err) - mocks.MScheduleRepository.AssertCalled(t, "Create", scheduleEntity) - mocks.MFeeRepository.AssertCalled(t, "Create", feeEntity) -} - -func setup(t *testing.T, setupForHandle bool) { - mocks.Setup() - - var err error - bridgeAccount, err = hedera.AccountIDFromString(bridgeAccountAsStr) - if err != nil { - t.Fatalf("Invalid account id [%s]. Error: [%s]", bridgeAccount, err) - } - splitTransfers[0] = make([]model.Hedera, countOfValidators+1) - if setupForHandle { - for index, accountIdStr := range validatorAccountIdsAsStr { - accountId, err := hedera.AccountIDFromString(accountIdStr) - if err != nil { - t.Fatalf("Invalid account id [%s]. Error: [%s]", accountIdStr, err) - } - validatorAccountIds[index] = accountId - transferPerValidator := model.Hedera{AccountID: accountId, Amount: feePerValidator} - hederaTransfers[index] = transferPerValidator - splitTransfers[0][index] = transferPerValidator - } - splitTransfers[0][len(splitTransfers[0])-1] = model.Hedera{AccountID: bridgeAccount, Amount: -validFee} - } - - handler = &Handler{ - transferRepository: mocks.MTransferRepository, - feeRepository: mocks.MFeeRepository, - scheduleRepository: mocks.MScheduleRepository, - mirrorNode: mocks.MHederaMirrorClient, - bridgeAccount: bridgeAccount, - distributor: mocks.MDistributorService, - transfersService: mocks.MTransferService, - readOnlyService: mocks.MReadOnlyService, - logger: config.GetLoggerFor("Hedera Transfer and Topic Submission Read-only Handler"), - } -} diff --git a/app/process/handler/read-only/nft/transfer/handler.go b/app/process/handler/read-only/nft/transfer/handler.go deleted file mode 100644 index c6cd55964..000000000 --- a/app/process/handler/read-only/nft/transfer/handler.go +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright 2022 LimeChain Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package transfer - -import ( - "database/sql" - - "github.com/hashgraph/hedera-sdk-go/v2" - "github.com/limechain/hedera-eth-bridge-validator/app/domain/repository" - "github.com/limechain/hedera-eth-bridge-validator/app/domain/service" - "github.com/limechain/hedera-eth-bridge-validator/app/persistence/entity" - "github.com/limechain/hedera-eth-bridge-validator/app/persistence/entity/schedule" - "github.com/limechain/hedera-eth-bridge-validator/app/persistence/entity/status" - "github.com/limechain/hedera-eth-bridge-validator/app/process/payload" - "github.com/limechain/hedera-eth-bridge-validator/config" - log "github.com/sirupsen/logrus" -) - -// Handler is transfers event handler -type Handler struct { - transferRepository repository.Transfer - scheduleRepository repository.Schedule - bridgeAccount hedera.AccountID - payerAccount hedera.AccountID - transfersService service.Transfers - readOnlyService service.ReadOnly - logger *log.Entry -} - -func NewHandler( - bridgeAccount string, - payerAccount string, - transferRepository repository.Transfer, - scheduleRepository repository.Schedule, - readOnlyService service.ReadOnly, - transfersService service.Transfers) *Handler { - bridgeAcc, err := hedera.AccountIDFromString(bridgeAccount) - if err != nil { - log.Fatalf("Invalid account id [%s]. Error: [%s]", bridgeAccount, err) - } - payerAcc, err := hedera.AccountIDFromString(payerAccount) - if err != nil { - log.Fatalf("Invalid account id [%s]. Error: [%s]", payerAccount, err) - } - - return &Handler{ - bridgeAccount: bridgeAcc, - payerAccount: payerAcc, - transferRepository: transferRepository, - scheduleRepository: scheduleRepository, - readOnlyService: readOnlyService, - transfersService: transfersService, - logger: config.GetLoggerFor("Read-only Hedera NFT Transfer"), - } -} - -func (rnth Handler) Handle(p interface{}) { - transfer, ok := p.(*payload.Transfer) - if !ok { - rnth.logger.Errorf("Could not cast payload [%s]", p) - return - } - - transactionRecord, err := rnth.transfersService.InitiateNewTransfer(*transfer) - if err != nil { - rnth.logger.Errorf("[%s] - Error occurred while initiating processing. Error: [%s]", transfer.TransactionId, err) - return - } - - if transactionRecord.Status != status.Initial { - rnth.logger.Debugf("[%s] - Previously added with status [%s]. Skipping further execution.", transactionRecord.TransactionID, transactionRecord.Status) - return - } - - rnth.readOnlyService.FindScheduledNftAllowanceApprove( - transfer, - rnth.payerAccount, - func(transactionID, scheduleID, status string) error { - err := rnth.scheduleRepository.Create(&entity.Schedule{ - TransactionID: transactionID, - ScheduleID: scheduleID, - Operation: schedule.APPROVE, - Status: status, - HasReceiver: true, - TransferID: sql.NullString{ - String: transfer.TransactionId, - Valid: true, - }, - }) - if err != nil { - rnth.logger.Errorf("[%s] - Error to create scheduled entity. Error: [%s]", transactionID, err) - return err - } - return rnth.transferRepository.UpdateStatusCompleted(transfer.TransactionId) - }, - ) -} diff --git a/app/process/payload/transfer.go b/app/process/payload/transfer.go index 4f46648fa..2d2ba05c8 100644 --- a/app/process/payload/transfer.go +++ b/app/process/payload/transfer.go @@ -29,9 +29,6 @@ type Transfer struct { NativeAsset string Receiver string Amount string - SerialNum int64 - Metadata string - IsNft bool Originator string Timestamp time.Time NetworkTimestamp string @@ -52,26 +49,5 @@ func New(txId string, NativeAsset: nativeAsset, Receiver: receiver, Amount: amount, - IsNft: false, - } -} - -// NewNft instantiates a Transfer, consisting of serial num and metadata for a given NFT -func NewNft( - txId string, - sourceChainId, targetChainId, nativeChainId uint64, receiver, sourceAsset, targetAsset, nativeAsset string, serialNum int64, metadata string, fee int64) *Transfer { - return &Transfer{ - TransactionId: txId, - SourceChainId: sourceChainId, - TargetChainId: targetChainId, - NativeChainId: nativeChainId, - SourceAsset: sourceAsset, - TargetAsset: targetAsset, - NativeAsset: nativeAsset, - Receiver: receiver, - SerialNum: serialNum, - Metadata: metadata, - IsNft: true, - Fee: fee, } } diff --git a/app/process/payload/transfer_test.go b/app/process/payload/transfer_test.go index cb701f010..c675ef5d4 100644 --- a/app/process/payload/transfer_test.go +++ b/app/process/payload/transfer_test.go @@ -16,9 +16,6 @@ const ( sourceAsset = "0.0.123" nativeAsset = "0.0.123" targetAsset = "0xwrapped00123" - serialNum = 0 - metadata = "42" - nftFee = 10 ) func Test_New(t *testing.T) { @@ -43,35 +40,3 @@ func Test_New(t *testing.T) { amount) assert.Equal(t, expectedTransfer, actualTransfer) } - -func Test_NewNft(t *testing.T) { - expected := &Transfer{ - TransactionId: txId, - SourceChainId: sourceChainId, - TargetChainId: targetChainId, - NativeChainId: nativeChainId, - SourceAsset: sourceAsset, - TargetAsset: targetAsset, - NativeAsset: nativeAsset, - Receiver: receiver, - SerialNum: serialNum, - Metadata: metadata, - IsNft: true, - Amount: "", - NetworkTimestamp: "", - Fee: nftFee, - } - - actual := NewNft(txId, - sourceChainId, - targetChainId, - nativeChainId, - receiver, - sourceAsset, - targetAsset, - nativeAsset, - serialNum, - metadata, - nftFee) - assert.Equal(t, expected, actual) -} diff --git a/app/process/watcher/assets/watcher.go b/app/process/watcher/assets/watcher.go index ea65e6bce..f0a3eb290 100644 --- a/app/process/watcher/assets/watcher.go +++ b/app/process/watcher/assets/watcher.go @@ -40,7 +40,6 @@ var ( type Watcher struct { mirrorNode client.MirrorNode evmFungibleTokenClients map[uint64]map[string]client.EvmFungibleToken - evmNonFungibleTokenClients map[uint64]map[string]client.EvmNft bridgeCfg *config.Bridge assetsService service.Assets paused bool @@ -51,14 +50,12 @@ func NewWatcher( mirrorNode client.MirrorNode, bridgeCfg *config.Bridge, EvmFungibleTokenClients map[uint64]map[string]client.EvmFungibleToken, - EvmNonFungibleTokenClients map[uint64]map[string]client.EvmNft, assetsService service.Assets, ) *Watcher { instance := &Watcher{ mirrorNode: mirrorNode, evmFungibleTokenClients: EvmFungibleTokenClients, - evmNonFungibleTokenClients: EvmNonFungibleTokenClients, bridgeCfg: bridgeCfg, logger: config.GetLoggerFor(fmt.Sprintf("Assets Watcher on interval [%v]", sleepTime)), assetsService: assetsService, @@ -98,16 +95,14 @@ func (pw *Watcher) watchIteration() { hederaTokenBalances := bridgeAccount.Balance.GetAccountTokenBalancesByAddress() fungibleAssets := pw.assetsService.FungibleNetworkAssets() - nonFungibleAssets := pw.assetsService.NonFungibleNetworkAssets() - pw.updateAssetInfos(hederaTokenBalances, fungibleAssets, true) - pw.updateAssetInfos(hederaTokenBalances, nonFungibleAssets, false) + pw.updateAssetInfos(hederaTokenBalances, fungibleAssets) } -func (pw *Watcher) updateAssetInfos(hederaTokenBalances map[string]int, assets map[uint64][]string, isFungible bool) { +func (pw *Watcher) updateAssetInfos(hederaTokenBalances map[string]int, assets map[uint64][]string) { for networkId, networkAssets := range assets { for _, assetAddress := range networkAssets { IsNative := pw.assetsService.IsNative(networkId, assetAddress) - pw.updateAssetInfo(networkId, assetAddress, hederaTokenBalances, isFungible, IsNative) + pw.updateAssetInfo(networkId, assetAddress, hederaTokenBalances, IsNative) } } } @@ -121,32 +116,22 @@ func (pw *Watcher) getAccount(accountId string) (*account.AccountsResponse, erro return account, nil } -func (pw *Watcher) updateAssetInfo(networkId uint64, assetId string, hederaTokenBalances map[string]int, isFungible bool, isNative bool) { +func (pw *Watcher) updateAssetInfo(networkId uint64, assetId string, hederaTokenBalances map[string]int, isNative bool) { var ( reserveAmount *big.Int + err error ) - var err error if networkId == constants.HederaNetworkId { reserveAmount, err = pw.assetsService.FetchHederaTokenReserveAmount(assetId, pw.mirrorNode, isNative, hederaTokenBalances) } else { - if isFungible { // Fungible - reserveAmount, err = pw.assetsService.FetchEvmFungibleReserveAmount( - networkId, - assetId, - isNative, - pw.evmFungibleTokenClients[networkId][assetId], - pw.bridgeCfg.EVMs[networkId].RouterContractAddress, - ) - } else { // Non-Fungible - reserveAmount, err = pw.assetsService.FetchEvmNonFungibleReserveAmount( - networkId, - assetId, - isNative, - pw.evmNonFungibleTokenClients[networkId][assetId], - pw.bridgeCfg.EVMs[networkId].RouterContractAddress, - ) - } + reserveAmount, err = pw.assetsService.FetchEvmFungibleReserveAmount( + networkId, + assetId, + isNative, + pw.evmFungibleTokenClients[networkId][assetId], + pw.bridgeCfg.EVMs[networkId].RouterContractAddress, + ) } if err != nil { @@ -154,16 +139,9 @@ func (pw *Watcher) updateAssetInfo(networkId uint64, assetId string, hederaToken return } - if isFungible { - assetInfo, ok := pw.assetsService.FungibleAssetInfo(networkId, assetId) - if ok { - assetInfo.ReserveAmount = reserveAmount - } - } else { - assetInfo, ok := pw.assetsService.NonFungibleAssetInfo(networkId, assetId) - if ok { - assetInfo.ReserveAmount = reserveAmount - } + assetInfo, ok := pw.assetsService.FungibleAssetInfo(networkId, assetId) + if ok { + assetInfo.ReserveAmount = reserveAmount } } @@ -175,7 +153,6 @@ func bridgeCfgUpdateEventHandler(e event.Event, instance *Watcher) error { return errors.New(errMsg) } instance.evmFungibleTokenClients = params.EvmFungibleTokenClients - instance.evmNonFungibleTokenClients = params.EvmNFTClients instance.bridgeCfg = params.Bridge instance.watchIteration() diff --git a/app/process/watcher/evm/watcher.go b/app/process/watcher/evm/watcher.go index 338638335..f242064ed 100644 --- a/app/process/watcher/evm/watcher.go +++ b/app/process/watcher/evm/watcher.go @@ -86,7 +86,6 @@ type FilterConfig struct { burnHash common.Hash lockHash common.Hash unlockHash common.Hash - burnERC721Hash common.Hash memberUpdatedHash common.Hash maxLogsBlocks int64 } @@ -120,7 +119,6 @@ func NewWatcher( lockHash := abi.Events["Lock"].ID unlockHash := abi.Events["Unlock"].ID memberUpdatedHash := abi.Events["MemberUpdated"].ID - burnERC721Hash := abi.Events["BurnERC721"].ID topics := [][]common.Hash{ { @@ -129,7 +127,6 @@ func NewWatcher( lockHash, unlockHash, memberUpdatedHash, - burnERC721Hash, }, } @@ -149,7 +146,6 @@ func NewWatcher( burnHash: burnHash, lockHash: lockHash, unlockHash: unlockHash, - burnERC721Hash: burnERC721Hash, memberUpdatedHash: memberUpdatedHash, maxLogsBlocks: maxLogsBlocks, } @@ -317,13 +313,6 @@ func (ew Watcher) processLogs(fromBlock, endBlock int64, queue qi.Queue) error { ew.handleBurnLog(burn, queue) } else if log.Topics[0] == ew.filterConfig.memberUpdatedHash { go ew.contracts.ReloadMembers() - } else if log.Topics[0] == ew.filterConfig.burnERC721Hash { - event, err := ew.contracts.ParseBurnERC721Log(log) - if err != nil { - ew.logger.Errorf("Could not parse burn ERC-721 log [%s]. Error [%s].", event.Raw.TxHash.String(), err) - continue - } - ew.handleBurnERC721(event, queue) } } } @@ -579,94 +568,6 @@ func (ew *Watcher) handleLockLog(eventLog *router.RouterLock, q qi.Queue) { } } -func (ew *Watcher) handleBurnERC721(eventLog *router.RouterBurnERC721, q qi.Queue) { - ew.logger.Debugf("[%s] - New Burn ERC-721 Event Log received.", eventLog.Raw.TxHash) - - if eventLog.Raw.Removed { - ew.logger.Debugf("[%s] - Uncle block transaction was removed.", eventLog.Raw.TxHash) - return - } - - if len(eventLog.Receiver) == 0 { - ew.logger.Errorf("[%s] - Empty receiver account.", eventLog.Raw.TxHash) - return - } - - sourceChainId := ew.evmClient.GetChainID() - nativeAsset := ew.assetsService.WrappedToNative(eventLog.WrappedToken.String(), sourceChainId) - if nativeAsset == nil { - ew.logger.Errorf("[%s] - Failed to retrieve native asset of [%s].", eventLog.Raw.TxHash, eventLog.WrappedToken) - return - } - - targetAsset := nativeAsset.Asset - // This is the case when you are bridging wrapped to wrapped - if eventLog.TargetChain.Uint64() != nativeAsset.ChainId { - ew.logger.Errorf("[%s] - Wrapped to Wrapped transfers currently not supported [%s] - [%d] for [%d]", eventLog.Raw.TxHash, nativeAsset.Asset, nativeAsset.ChainId, eventLog.TargetChain.Int64()) - return - } - - recipientAccount := "" - if eventLog.TargetChain.Uint64() == constants.HederaNetworkId { - recipient, err := hedera.AccountIDFromBytes(eventLog.Receiver) - if err != nil { - ew.logger.Errorf("[%s] - Failed to parse account from bytes [%v]. Error: [%s].", eventLog.Raw.TxHash, eventLog.Receiver, err) - return - } - recipientAccount = recipient.String() - - } else { - recipientAccount = common.BytesToAddress(eventLog.Receiver).String() - } - - blockTimestamp := ew.evmClient.GetBlockTimestamp(big.NewInt(int64(eventLog.Raw.BlockNumber))) - - originator, err := ew.CheckBlacklistedOriginator(eventLog.Raw.TxHash) - if err != nil { - ew.logger.Error(err) - return - } - - transfer := &payload.Transfer{ - TransactionId: fmt.Sprintf("%s-%d", eventLog.Raw.TxHash, eventLog.Raw.Index), - SourceChainId: sourceChainId, - TargetChainId: eventLog.TargetChain.Uint64(), - NativeChainId: nativeAsset.ChainId, - SourceAsset: eventLog.WrappedToken.String(), - TargetAsset: targetAsset, - NativeAsset: nativeAsset.Asset, - Receiver: recipientAccount, - IsNft: true, - SerialNum: eventLog.TokenId.Int64(), - Originator: *originator, - Timestamp: time.Unix(int64(blockTimestamp), 0).UTC(), - } - - ew.logger.Infof("[%s] - New ERC-721Burn ERC-721 Event Log with TokenId [%d], Receiver Address [%s] has been found.", - eventLog.Raw.TxHash.String(), - eventLog.TokenId.Int64(), - recipientAccount) - - currentBlockNumber := eventLog.Raw.BlockNumber - - if ew.validator && currentBlockNumber >= ew.targetBlock { - if transfer.TargetChainId == constants.HederaNetworkId { - q.Push(&queue.Message{Payload: transfer, Topic: constants.HederaNftTransfer}) - } else { - ew.logger.Errorf("[%s] - NFT Transfer to TargetChain different than [%d]. Not supported.", transfer.TransactionId, constants.HederaNetworkId) - return - } - } else { - transfer.NetworkTimestamp = strconv.FormatUint(blockTimestamp, 10) - if transfer.TargetChainId == constants.HederaNetworkId { - q.Push(&queue.Message{Payload: transfer, Topic: constants.ReadOnlyHederaUnlockNftTransfer}) - } else { - ew.logger.Errorf("[%s] - Read-only NFT Transfer to TargetChain different than [%d]. Not supported.", transfer.TransactionId, constants.HederaNetworkId) - return - } - } -} - func (ew *Watcher) handleUnlockLog(eventLog *router.RouterUnlock) { ew.logger.Infof("[%s] - New Unlock Event Log received [%s].", eventLog.TransactionId, eventLog.Raw.TxHash) diff --git a/app/process/watcher/evm/watcher_test.go b/app/process/watcher/evm/watcher_test.go index 4a7514baa..fd1d38a55 100644 --- a/app/process/watcher/evm/watcher_test.go +++ b/app/process/watcher/evm/watcher_test.go @@ -70,7 +70,6 @@ var ( lockHash = common.HexToHash("aa3a3bc72b8c754ca6ee8425a5531bafec37569ec012d62d5f682ca909ae06f1") unlockHash = common.HexToHash("483dd9d090112259cd3c44a9af4b3386be4b4b87145e6bf85bc0964a06062a73") membersHash = common.HexToHash("30f1d11f11278ba2cc669fd4c95ee8d46ede2c82f6af0b74e4f427369b3522d3") - burnERC721Hash = common.HexToHash("eb703661daf51ce0c247ebbf71a8747e6a79f36b2e93a4e5a22f191321e5750e") topics = [][]common.Hash{ { mintHash, @@ -78,7 +77,6 @@ var ( lockHash, unlockHash, membersHash, - burnERC721Hash, }, } filterConfig = FilterConfig{ @@ -500,7 +498,6 @@ func TestNewWatcher(t *testing.T) { burnHashFromAbi := abi.Events["Burn"].ID lockHashFromAbi := abi.Events["Lock"].ID unlockHashFromAbi := abi.Events["Unlock"].ID - burnERC721HashAbi := abi.Events["BurnERC721"].ID memberUpdatedHash := abi.Events["MemberUpdated"].ID addresses := []common.Address{ @@ -515,7 +512,6 @@ func TestNewWatcher(t *testing.T) { burnHash: burnHashFromAbi, lockHash: lockHashFromAbi, unlockHash: unlockHashFromAbi, - burnERC721Hash: burnERC721HashAbi, memberUpdatedHash: memberUpdatedHash, maxLogsBlocks: 220, } diff --git a/app/process/watcher/prometheus/watcher.go b/app/process/watcher/prometheus/watcher.go index 9f856da63..4d994d74d 100644 --- a/app/process/watcher/prometheus/watcher.go +++ b/app/process/watcher/prometheus/watcher.go @@ -46,7 +46,6 @@ type Watcher struct { dashboardPolling time.Duration mirrorNode client.MirrorNode evmFungibleTokenClients map[uint64]map[string]client.EvmFungibleToken - evmNonFungibleTokenClients map[uint64]map[string]client.EvmNft bridgeCfg *config.Bridge prometheusService service.Prometheus logger *log.Entry @@ -71,14 +70,12 @@ func NewWatcher( bridgeCfg *config.Bridge, prometheusService service.Prometheus, EvmFungibleTokenClients map[uint64]map[string]client.EvmFungibleToken, - EvmNonFungibleTokenClients map[uint64]map[string]client.EvmNft, assetsService service.Assets, ) *Watcher { instance := &Watcher{ dashboardPolling: dashboardPolling, mirrorNode: mirrorNode, evmFungibleTokenClients: EvmFungibleTokenClients, - evmNonFungibleTokenClients: EvmNonFungibleTokenClients, bridgeCfg: bridgeCfg, prometheusService: prometheusService, logger: config.GetLoggerFor(fmt.Sprintf("Prometheus Metrics Watcher on interval [%s]", dashboardPolling)), @@ -164,12 +161,10 @@ func (pw *Watcher) beginWatching() { func (pw *Watcher) registerAllAssetsMetrics() { fungibleAssets := pw.assetsService.FungibleNetworkAssets() - nonFungibleAssets := pw.assetsService.NonFungibleNetworkAssets() - pw.registerAssetMetrics(fungibleAssets, true) - pw.registerAssetMetrics(nonFungibleAssets, false) + pw.registerAssetMetrics(fungibleAssets) } -func (pw *Watcher) registerAssetMetrics(assets map[uint64][]string, isFungible bool) { +func (pw *Watcher) registerAssetMetrics(assets map[uint64][]string) { for networkId, networkAssets := range assets { for _, assetAddress := range networkAssets { @@ -181,7 +176,6 @@ func (pw *Watcher) registerAssetMetrics(assets map[uint64][]string, isFungible b assetAddress, constants.BalanceAssetMetricNameSuffix, constants.BalanceAssetMetricHelpPrefix, - isFungible, ) wrappedFromNative := pw.assetsService.WrappedFromNative(networkId, assetAddress) @@ -193,7 +187,6 @@ func (pw *Watcher) registerAssetMetrics(assets map[uint64][]string, isFungible b wrappedAssetAddress, constants.SupplyAssetMetricNameSuffix, constants.SupplyAssetMetricsHelpPrefix, - isFungible, ) } } @@ -207,36 +200,20 @@ func (pw *Watcher) registerAssetMetric( assetAddress string, metricNameCnt string, metricHelpCnt string, - isFungible bool, ) { if assetAddress != constants.Hbar { // skip HBAR - var ( - name, symbol string - ) - if isFungible { - assetInfo, exist := pw.assetsService.FungibleAssetInfo(wrappedNetworkId, assetAddress) - if !exist { - return - } - name = assetInfo.Name - symbol = assetInfo.Symbol - } else { - assetInfo, exist := pw.assetsService.NonFungibleAssetInfo(wrappedNetworkId, assetAddress) - if !exist { - return - } - name = assetInfo.Name - symbol = assetInfo.Symbol + assetInfo, exist := pw.assetsService.FungibleAssetInfo(wrappedNetworkId, assetAddress) + if !exist { + return } metricName, metricHelp := getMetricData( nativeNetworkId, wrappedNetworkId, assetAddress, - name, + assetInfo.Name, metricNameCnt, metricHelpCnt, - isFungible, ) if pw.assetsMetrics[wrappedNetworkId] == nil { @@ -248,7 +225,7 @@ func (pw *Watcher) registerAssetMetric( Name: metricName, Help: metricHelp, ConstLabels: prometheus.Labels{ - constants.AssetMetricLabelKey: symbol, + constants.AssetMetricLabelKey: assetInfo.Symbol, }, }) } @@ -261,7 +238,6 @@ func getMetricData( assetName string, metricNameSuffix string, metricsHelpPrefix string, - isFungible bool, ) (string, string) { nativeNetworkName := constants.NetworksById[nativeNetworkId] @@ -272,15 +248,10 @@ func getMetricData( assetType = constants.Native } - fungleAddon := constants.FungibleAddon - if !isFungible { - fungleAddon = constants.NonFungibleAddon - } - name := fmt.Sprintf("%s_%s_%s_%s%s%s", assetType, nativeNetworkName, - fungleAddon, + constants.FungibleAddon, wrappedNetworkName, metricNameSuffix, metrics.AssetAddressToMetricName(assetAddress)) @@ -340,26 +311,23 @@ func (pw *Watcher) getAccountBalance(account *account.AccountsResponse) float64 func (pw *Watcher) setAllAssetsMetrics() { fungibleAssets := pw.assetsService.FungibleNetworkAssets() - nonFungibleAssets := pw.assetsService.NonFungibleNetworkAssets() - pw.setAssetsMetrics(fungibleAssets, true) - pw.setAssetsMetrics(nonFungibleAssets, false) + pw.setAssetsMetrics(fungibleAssets) } -func (pw Watcher) setAssetsMetrics(assets map[uint64][]string, isFungible bool) { +func (pw Watcher) setAssetsMetrics(assets map[uint64][]string) { for networkId, networkAssets := range assets { for _, assetAddress := range networkAssets { if assetAddress == constants.Hbar { // skip HBAR continue } isNative := pw.assetsService.IsNative(networkId, assetAddress) - pw.prepareAndSetAssetMetric(networkId, assetAddress, isFungible, isNative) + pw.prepareAndSetAssetMetric(networkId, assetAddress, isNative) } } } func (pw *Watcher) prepareAndSetAssetMetric(networkId uint64, assetAddress string, - isFungible, isNative bool, ) { var value float64 @@ -368,18 +336,10 @@ func (pw *Watcher) prepareAndSetAssetMetric(networkId uint64, ReserveAmountInLowestDenomination *big.Int decimals uint8 ) - if isFungible { - assetInfo, ok := pw.assetsService.FungibleAssetInfo(networkId, assetAddress) - if ok { - ReserveAmountInLowestDenomination = assetInfo.ReserveAmount - decimals = assetInfo.Decimals - } - } else { - decimals = 0 - assetInfo, ok := pw.assetsService.NonFungibleAssetInfo(networkId, assetAddress) - if ok { - ReserveAmountInLowestDenomination = assetInfo.ReserveAmount - } + assetInfo, ok := pw.assetsService.FungibleAssetInfo(networkId, assetAddress) + if ok { + ReserveAmountInLowestDenomination = assetInfo.ReserveAmount + decimals = assetInfo.Decimals } if decimals != 0 { @@ -409,7 +369,6 @@ func bridgeCfgUpdateEventHandler(e event.Event, instance *Watcher) error { return errors.New(errMsg) } instance.evmFungibleTokenClients = params.EvmFungibleTokenClients - instance.evmNonFungibleTokenClients = params.EvmNFTClients instance.bridgeCfg = params.Bridge // Clear All Metrics for _, metricsInNetwork := range instance.assetsMetrics { diff --git a/app/process/watcher/transfer/watcher.go b/app/process/watcher/transfer/watcher.go index 926e60c4a..2a1df2ea9 100644 --- a/app/process/watcher/transfer/watcher.go +++ b/app/process/watcher/transfer/watcher.go @@ -17,7 +17,6 @@ package cryptotransfer import ( - "encoding/base64" "errors" "fmt" "math/big" @@ -203,12 +202,6 @@ func (ctw Watcher) processTransaction(txID string, q qi.Queue) { } targetChainId := checkResult.ChainId - if checkResult.NftId == nil { - ctw.initSuccessRatePrometheusMetrics(tx, constants.HederaNetworkId, targetChainId, sourceAsset) - } else { - sourceAsset = checkResult.NftId.TokenID.String() - } - nativeAsset := &asset.NativeAsset{ ChainId: constants.HederaNetworkId, Asset: sourceAsset, @@ -230,29 +223,7 @@ func (ctw Watcher) processTransaction(txID string, q qi.Queue) { var transferMessage *payload.Transfer originator := hederaHelper.OriginatorFromTxId(tx.TransactionID) - if checkResult.NftId != nil { - nftAssetInfo, ok := ctw.assetsService.NonFungibleAssetInfo(constants.HederaNetworkId, sourceAsset) - if !ok { - ctw.logger.Errorf("[%s] - Failed to get asset info for NFT [%s] not found.", tx.TransactionID, sourceAsset) - return - } - - feeSent, found := tx.GetHBARTransfer(ctw.accountID.String()) - if !found { - ctw.logger.Errorf("[%s] - Transfer to [%s] not found.", tx.TransactionID, ctw.accountID.String()) - return - } - - feeForValidators, ok := ctw.validateNFTFeeSent(sourceAsset, tx, originator, nftAssetInfo, feeSent) - if !ok { - return - } - - transferMessage, err = ctw.createNonFungiblePayload(tx.TransactionID, checkResult.EvmAddress, sourceAsset, *nativeAsset, checkResult.NftId.SerialNumber, targetChainId, targetChainAsset, feeForValidators) - - } else { - transferMessage, err = ctw.createFungiblePayload(tx.TransactionID, checkResult.EvmAddress, sourceAsset, *nativeAsset, parsedTransfer.AmountOrSerialNum, targetChainId, targetChainAsset) - } + transferMessage, err = ctw.createFungiblePayload(tx.TransactionID, checkResult.EvmAddress, sourceAsset, *nativeAsset, parsedTransfer.Amount, targetChainId, targetChainAsset) if err != nil { ctw.logger.Errorf("[%s] - Failed to create payload. Error: [%s]", tx.TransactionID, err) @@ -271,31 +242,15 @@ func (ctw Watcher) processTransaction(txID string, q qi.Queue) { topic := "" if ctw.validator && transactionTimestamp > ctw.targetTimestamp { if nativeAsset.ChainId == constants.HederaNetworkId { - if checkResult.NftId != nil { - topic = constants.HederaNativeNftTransfer - } else { - topic = constants.HederaTransferMessageSubmission - } + topic = constants.HederaTransferMessageSubmission } else { - if checkResult.NftId != nil { - ctw.logger.Errorf("[%s] - NFT Transfer not supported", tx.TransactionID) - return - } topic = constants.HederaBurnMessageSubmission } } else { transferMessage.NetworkTimestamp = tx.ConsensusTimestamp if nativeAsset.ChainId == constants.HederaNetworkId { - if checkResult.NftId != nil { - topic = constants.ReadOnlyHederaNativeNftTransfer - } else { - topic = constants.ReadOnlyHederaFeeTransfer - } + topic = constants.ReadOnlyHederaFeeTransfer } else { - if checkResult.NftId != nil { - ctw.logger.Errorf("[%s] - NFT Read-only Transfer not supported", tx.TransactionID) - return - } topic = constants.ReadOnlyHederaBurn } } @@ -303,72 +258,6 @@ func (ctw Watcher) processTransaction(txID string, q qi.Queue) { q.Push(&queue.Message{Payload: transferMessage, Topic: topic}) } -func (ctw Watcher) validateNFTFeeSent(sourceAsset string, tx transaction.Transaction, originator string, nftAssetInfo *asset.NonFungibleAssetInfo, feeSent int64) (int64, bool) { - fee, feeIsFound := ctw.pricingService.GetHederaNftFee(sourceAsset) - if !feeIsFound { - ctw.logger.Errorf("[%s] - Fee for [%s] not found.", tx.TransactionID, sourceAsset) - return 0, false - } - - prevFee, prevFeeFound := ctw.pricingService.GetHederaNftPrevFee(sourceAsset) - - totalHbarFeeExpected := fee - totalHbarFeeExpectedWithPrev := prevFee - - feeForValidators := feeSent - if originator != nftAssetInfo.TreasuryAccountId { - // Custom Fees are expected only for Non-Treasury Account ID - totalHbarFeeExpected += nftAssetInfo.CustomFeeTotalAmounts.FallbackFeeAmountInHbar - totalHbarFeeExpectedWithPrev += nftAssetInfo.CustomFeeTotalAmounts.FallbackFeeAmountInHbar - - // Validate that the required Custom fees by Token ID are sent - if len(nftAssetInfo.CustomFeeTotalAmounts.FallbackFeeAmountsByTokenId) > 0 { - if !ctw.validateNftTokenCustomFees(nftAssetInfo, tx, sourceAsset) { - return 0, false - } - } - - feeForValidators = feeForValidators - nftAssetInfo.CustomFeeTotalAmounts.FallbackFeeAmountInHbar - } - - // Validate that the HBAR fee is sent (including the Custom Fee in HBAR) - if feeSent < totalHbarFeeExpected { - ctw.logger.Errorf("[%s] - Invalid provided NFT Fee for [%s] in HBARs. It should be [%d], but was [%d].", tx.TransactionID, sourceAsset, fee, feeSent) - - if prevFeeFound && fee != prevFee { - ctw.logger.Infof("[%s] - Trying to validate NFT Fee for [%s] in HBARs with previous price.", tx.TransactionID, sourceAsset) - if feeSent < totalHbarFeeExpectedWithPrev { - ctw.logger.Errorf("[%s] - Invalid provided NFT Fee for [%s] in HBARs with previous price. It should be [%d], but was [%d].", tx.TransactionID, sourceAsset, prevFee, feeSent) - return 0, false - } - } else { - return 0, false - } - } - - return feeForValidators, true -} - -func (ctw Watcher) validateNftTokenCustomFees(nftAssetInfo *asset.NonFungibleAssetInfo, tx transaction.Transaction, sourceAsset string) bool { - for tokenId := range nftAssetInfo.CustomFeeTotalAmounts.FallbackFeeAmountsByTokenId { - feeForToken := nftAssetInfo.CustomFeeTotalAmounts.FallbackFeeAmountsByTokenId[tokenId] - if feeForToken > 0 { - tokenFeeSent, ok := tx.GetTokenTransfer(ctw.accountID.String()) - if !ok { - ctw.logger.Errorf("[%s] - Transfer to [%s] not found.", tx.TransactionID, ctw.accountID.String()) - return false - } - - if tokenFeeSent < feeForToken { - ctw.logger.Errorf("[%s] - Invalid provided NFT Fee for [%s] in token [%s]. It should be [%d], but was [%d].", tx.TransactionID, sourceAsset, tokenId, feeForToken, tokenFeeSent) - return false - } - } - } - - return true -} - func (ctw Watcher) createFungiblePayload(transactionID string, receiver string, sourceAsset string, asset asset.NativeAsset, amount int64, targetChainId uint64, targetChainAsset string) (*payload.Transfer, error) { nativeAsset := ctw.assetsService.FungibleNativeAsset(asset.ChainId, asset.Asset) @@ -413,40 +302,6 @@ func (ctw Watcher) createFungiblePayload(transactionID string, receiver string, targetAmount.String()), nil } -func (ctw Watcher) createNonFungiblePayload( - transactionID string, - receiver string, - sourceAsset string, - nativeAsset asset.NativeAsset, - serialNum int64, - targetChainId uint64, - targetChainAsset string, - fee int64) (*payload.Transfer, error) { - - nftData, err := ctw.client.GetNft(sourceAsset, serialNum) - if err != nil { - return nil, err - } - - decodedMetadata, e := base64.StdEncoding.DecodeString(nftData.Metadata) - if e != nil { - return nil, fmt.Errorf("[%s] - Failed to decode metadata [%s]. Error [%s]", transactionID, nftData.Metadata, e) - } - - return payload.NewNft( - transactionID, - constants.HederaNetworkId, - targetChainId, - nativeAsset.ChainId, - receiver, - sourceAsset, - targetChainAsset, - nativeAsset.Asset, - serialNum, - string(decodedMetadata), - fee), nil -} - func (ctw Watcher) initSuccessRatePrometheusMetrics(tx transaction.Transaction, sourceChainId, targetChainId uint64, asset string) { if !ctw.prometheusService.GetIsMonitoringEnabled() { return diff --git a/app/process/watcher/transfer/watcher_test.go b/app/process/watcher/transfer/watcher_test.go index cde56ba2f..0ad954cd5 100644 --- a/app/process/watcher/transfer/watcher_test.go +++ b/app/process/watcher/transfer/watcher_test.go @@ -25,7 +25,6 @@ import ( "time" "github.com/limechain/hedera-eth-bridge-validator/app/model/transfer" - testConstants "github.com/limechain/hedera-eth-bridge-validator/test/constants" "github.com/stretchr/testify/assert" "github.com/hashgraph/hedera-sdk-go/v2" @@ -205,33 +204,6 @@ func Test_ProcessTransaction_Blacklist_Fails(t *testing.T) { mocks.MQueue.AssertNotCalled(t, "Push", mock.Anything) } -func Test_ProcessNFTTransaction_Blacklist_Fails(t *testing.T) { - tx_blacklist := transaction.Transaction{ - ConsensusTimestamp: "1631092491.483966000", - TransactionID: "0.0.111-1631092491-483966000", - } - - nftTransfer := transaction.NftTransfer{ - ReceiverAccountID: "0.0.111", - SenderAccountID: "0.0.333", - SerialNumber: 1, - Token: "0.0.21241241", - } - - tx_blacklist.NftTransfers = []transaction.NftTransfer{ - nftTransfer, - } - tx_blacklist.Transfers = []transaction.Transfer{} - tx_blacklist.TokenTransfers = []transaction.Transfer{} - - w := initializeWatcher() - mocks.MHederaMirrorClient.On("GetSuccessfulTransaction", tx_blacklist.TransactionID).Return(tx_blacklist, nil) - - w.processTransaction(tx_blacklist.TransactionID, mocks.MQueue) - - mocks.MQueue.AssertNotCalled(t, "Push", mock.Anything) -} - func Test_ProcessHbarTransaction_Blacklist_Fails(t *testing.T) { tx_blacklist := transaction.Transaction{ ConsensusTimestamp: "1631092491.483966000", @@ -247,7 +219,6 @@ func Test_ProcessHbarTransaction_Blacklist_Fails(t *testing.T) { tx_blacklist.Transfers = []transaction.Transfer{ transfer, } - tx_blacklist.NftTransfers = []transaction.NftTransfer{} tx_blacklist.TokenTransfers = []transaction.Transfer{} w := initializeWatcher() @@ -270,107 +241,6 @@ func Test_ProcessTransaction_GetIncomingTransfer_Fails(t *testing.T) { mocks.MTransferService.AssertNotCalled(t, "SanityCheckTransfer", mock.Anything) } -func Test_validateNFTFeeSent_ShouldNotValidateFee(t *testing.T) { - w := initializeWatcher() - - mocks.MPricingService.On("GetHederaNftFee", testConstants.NetworkHederaNonFungibleNativeToken).Return(int64(0), false) - - feeForValidators, ok := w.validateNFTFeeSent( - testConstants.NetworkHederaNonFungibleNativeToken, - tx, - "", - testConstants.NonFungibleAssetInfos[constants.HederaNetworkId][testConstants.NetworkHederaNonFungibleNativeToken], - 10, - ) - assert.Equal(t, int64(0), feeForValidators) - assert.False(t, ok) -} - -func Test_validateNFTFeeSent_ShouldValidateFee(t *testing.T) { - w := initializeWatcher() - - mocks.MPricingService.On("GetHederaNftFee", testConstants.NetworkHederaNonFungibleNativeToken).Return(int64(10), true) - mocks.MPricingService.On("GetHederaNftPrevFee", testConstants.NetworkHederaNonFungibleNativeToken).Return(int64(20), true) - - feeForValidators, ok := w.validateNFTFeeSent( - testConstants.NetworkHederaNonFungibleNativeToken, - tx, - "", - testConstants.NonFungibleAssetInfos[constants.HederaNetworkId][testConstants.NetworkHederaNonFungibleNativeToken], - 10, - ) - assert.Equal(t, int64(10), feeForValidators) - assert.True(t, ok) -} - -func Test_validateNFTFeeSent_ShouldValidatePrevFee(t *testing.T) { - w := initializeWatcher() - - mocks.MPricingService.On("GetHederaNftFee", testConstants.NetworkHederaNonFungibleNativeToken).Return(int64(10), true) - mocks.MPricingService.On("GetHederaNftPrevFee", testConstants.NetworkHederaNonFungibleNativeToken).Return(int64(20), true) - - feeForValidators, ok := w.validateNFTFeeSent( - testConstants.NetworkHederaNonFungibleNativeToken, - tx, - "", - testConstants.NonFungibleAssetInfos[constants.HederaNetworkId][testConstants.NetworkHederaNonFungibleNativeToken], - 20, - ) - assert.Equal(t, int64(20), feeForValidators) - assert.True(t, ok) -} - -func Test_validateNFTFeeSent_ShouldNotValidateAnyFee(t *testing.T) { - w := initializeWatcher() - - mocks.MPricingService.On("GetHederaNftFee", testConstants.NetworkHederaNonFungibleNativeToken).Return(int64(0), false) - mocks.MPricingService.On("GetHederaNftPrevFee", testConstants.NetworkHederaNonFungibleNativeToken).Return(int64(0), false) - - feeForValidators, ok := w.validateNFTFeeSent( - testConstants.NetworkHederaNonFungibleNativeToken, - tx, - "", - testConstants.NonFungibleAssetInfos[constants.HederaNetworkId][testConstants.NetworkHederaNonFungibleNativeToken], - 20, - ) - assert.Equal(t, int64(0), feeForValidators) - assert.False(t, ok) -} - -func Test_validateNFTFeeSent_ShouldNotValidateFeeWithOriginator(t *testing.T) { - w := initializeWatcher() - - mocks.MPricingService.On("GetHederaNftFee", testConstants.NetworkHederaNonFungibleNativeToken).Return(int64(10), true) - mocks.MPricingService.On("GetHederaNftPrevFee", testConstants.NetworkHederaNonFungibleNativeToken).Return(int64(20), true) - - feeForValidators, ok := w.validateNFTFeeSent( - testConstants.NetworkHederaNonFungibleNativeToken, - tx, - "different originator", - testConstants.NonFungibleAssetInfos[constants.HederaNetworkId][testConstants.NetworkHederaNonFungibleNativeToken], - 10, - ) - assert.Equal(t, int64(0), feeForValidators) - assert.False(t, ok) -} - -func Test_validateNFTFeeSent_ShouldValidateLargerFee(t *testing.T) { - w := initializeWatcher() - - mocks.MPricingService.On("GetHederaNftFee", testConstants.NetworkHederaNonFungibleNativeToken).Return(int64(10), true) - mocks.MPricingService.On("GetHederaNftPrevFee", testConstants.NetworkHederaNonFungibleNativeToken).Return(int64(20), true) - - feeForValidators, ok := w.validateNFTFeeSent( - testConstants.NetworkHederaNonFungibleNativeToken, - tx, - "", - testConstants.NonFungibleAssetInfos[constants.HederaNetworkId][testConstants.NetworkHederaNonFungibleNativeToken], - 30, - ) - assert.Equal(t, int64(30), feeForValidators) - assert.True(t, ok) -} - func Test_UpdateStatusTimestamp_Works(t *testing.T) { w := initializeWatcher() mocks.MStatusRepository.On("Update", txAccountId, int64(100)).Return(nil) @@ -394,34 +264,6 @@ func Test_ConsensusTimestamp_Fails(t *testing.T) { w.processTransaction(anotherTx.TransactionID, mocks.MQueue) } -func Test_validateNftTokenCustomFees(t *testing.T) { - w := initializeWatcher() - - ok := w.validateNftTokenCustomFees(testConstants.NonFungibleAssetInfos[constants.HederaNetworkId][testConstants.NetworkHederaNonFungibleNativeToken], tx, testConstants.NetworkHederaNonFungibleNativeToken) - - assert.True(t, ok) -} - -func Test_validateNftTokenCustomFees_ErrOnTransferForAccountNotFound(t *testing.T) { - w := initializeWatcher() - tx.TokenTransfers[0].Account = txAccountId + "1" - - ok := w.validateNftTokenCustomFees(testConstants.NonFungibleAssetInfos[constants.HederaNetworkId][testConstants.NetworkHederaNonFungibleNativeToken], tx, testConstants.NetworkHederaNonFungibleNativeToken) - tx.TokenTransfers[0].Account = txAccountId - - assert.False(t, ok) -} - -func Test_validateNftTokenCustomFees_ErrOnTransferForFeeLessThanExpected(t *testing.T) { - w := initializeWatcher() - tx.TokenTransfers[0].Amount = txAmount - 1 - - ok := w.validateNftTokenCustomFees(testConstants.NonFungibleAssetInfos[constants.HederaNetworkId][testConstants.NetworkHederaNonFungibleNativeToken], tx, testConstants.NetworkHederaNonFungibleNativeToken) - tx.TokenTransfers[0].Amount = txAmount - - assert.False(t, ok) -} - func Test_createFungiblePayload(t *testing.T) { w := initializeWatcher() diff --git a/app/router/assets/assets.go b/app/router/assets/assets.go index e87e31a1e..623e8dcb4 100644 --- a/app/router/assets/assets.go +++ b/app/router/assets/assets.go @@ -45,17 +45,9 @@ type feePercentageInfo struct { MaxPercentage int64 `json:"maxPercentage"` } -type nonFungibleBridgeDetails struct { - *asset.NonFungibleAssetInfo - Fee int64 `json:"fee"` - Networks map[uint64]string `json:"networks"` - ReserveAmount string `json:"reserveAmount"` - ReleaseTimestamp uint64 `json:"releaseTimestamp,omitempty"` -} type networkAssets struct { Fungible map[string]fungibleBridgeDetails `json:"fungible"` - NonFungible map[string]nonFungibleBridgeDetails `json:"nonFungible"` } // Router for assets @@ -77,11 +69,9 @@ func generateResponseContent(assetsService service.Assets, pricingService servic response := make(map[uint64]networkAssets) fungibleNetworkAssets := assetsService.FungibleNetworkAssets() - nonFungibleNetworkAssets := assetsService.NonFungibleNetworkAssets() for networkId := range constants.NetworksById { response[networkId] = networkAssets{ Fungible: map[string]fungibleBridgeDetails{}, - NonFungible: map[string]nonFungibleBridgeDetails{}, } // Fungible @@ -110,30 +100,6 @@ func generateResponseContent(assetsService service.Assets, pricingService servic response[networkId].Fungible[assetAddress] = fungibleAssetDetails } } - - // Non-Fungible - for _, assetAddress := range nonFungibleNetworkAssets[networkId] { - nonFungibleAssetInfo, exist := assetsService.NonFungibleAssetInfo(networkId, assetAddress) - if exist { - var nativeAddress string - if nonFungibleAssetInfo.IsNative { - nativeAddress = assetAddress - } else { - nativeAsset := assetsService.WrappedToNative(assetAddress, networkId) - nativeAddress = nativeAsset.Asset - } - - bridgeTokenInfo := bridgeCfg.Networks[networkId].Tokens.Nft[nativeAddress] - nonFungibleAssetDetails := nonFungibleBridgeDetails{ - NonFungibleAssetInfo: nonFungibleAssetInfo, - Fee: bridgeTokenInfo.Fee, - Networks: bridgeTokenInfo.Networks, - ReserveAmount: nonFungibleAssetInfo.ReserveAmount.String(), - ReleaseTimestamp: bridgeTokenInfo.ReleaseTimestamp, - } - response[networkId].NonFungible[assetAddress] = nonFungibleAssetDetails - } - } } return response diff --git a/app/router/assets/assets_test.go b/app/router/assets/assets_test.go index 66fb1ca55..bf28b604d 100644 --- a/app/router/assets/assets_test.go +++ b/app/router/assets/assets_test.go @@ -41,7 +41,6 @@ func Test_assetsResponse(t *testing.T) { enc := json.NewEncoder(buf) mocks.MAssetsService.On("FungibleNetworkAssets").Return(testConstants.FungibleNetworkAssets) - mocks.MAssetsService.On("NonFungibleNetworkAssets").Return(testConstants.NonFungibleNetworkAssets) for networkId, networkAssets := range testConstants.FungibleNetworkAssets { for _, networkAsset := range networkAssets { fungibleAssetInfo := testConstants.FungibleAssetInfos[networkId][networkAsset] @@ -58,17 +57,6 @@ func Test_assetsResponse(t *testing.T) { } } } - for networkId, networkAssets := range testConstants.NonFungibleNetworkAssets { - for _, networkAsset := range networkAssets { - nonFungibleAssetInfo := testConstants.NonFungibleAssetInfos[networkId][networkAsset] - mocks.MAssetsService.On("NonFungibleAssetInfo", networkId, networkAsset). - Return(nonFungibleAssetInfo, true) - if !nonFungibleAssetInfo.IsNative { - mocks.MAssetsService.On("WrappedToNative", networkAsset, networkId). - Return(testConstants.WrappedToNative[networkId][networkAsset], true) - } - } - } assetsResponseContent := generateResponseContent(mocks.MAssetsService, mocks.MPricingService, &testConstants.ParserBridge) var err error diff --git a/app/router/fees/fees-test.go b/app/router/fees/fees-test.go deleted file mode 100644 index fb894a8e2..000000000 --- a/app/router/fees/fees-test.go +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2022 LimeChain Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package fees - -import ( - "bytes" - "encoding/json" - testConstants "github.com/limechain/hedera-eth-bridge-validator/test/constants" - "github.com/limechain/hedera-eth-bridge-validator/test/mocks" - "github.com/stretchr/testify/assert" - "net/http" - "testing" -) - -func Test_NewRouter(t *testing.T) { - router := NewRouter(mocks.MPricingService) - - assert.NotNil(t, router) -} - -func Test_feesNftResponse(t *testing.T) { - mocks.Setup() - - buf := &bytes.Buffer{} - enc := json.NewEncoder(buf) - enc.SetEscapeHTML(true) - - var err error - if err := enc.Encode(testConstants.ParserBridge); err != nil { - http.Error(mocks.MResponseWriter, err.Error(), http.StatusInternalServerError) - return - } - bridgeConfigAsBytes := buf.Bytes() - mocks.MResponseWriter.On("Header").Return(http.Header{}) - mocks.MResponseWriter.On("Write", bridgeConfigAsBytes).Return(len(bridgeConfigAsBytes), nil) - - bridgeResponseHandler := feesNftResponse(mocks.MPricingService) - bridgeResponseHandler(mocks.MResponseWriter, new(http.Request)) - - assert.Nil(t, err) - assert.NotNil(t, bridgeResponseHandler) - assert.NotNil(t, bridgeConfigAsBytes) -} diff --git a/app/router/fees/fees.go b/app/router/fees/fees.go deleted file mode 100644 index 26daf6c99..000000000 --- a/app/router/fees/fees.go +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2022 LimeChain Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package fees - -import ( - "errors" - "github.com/limechain/hedera-eth-bridge-validator/app/router/response" - "net/http" - - "github.com/go-chi/chi" - "github.com/go-chi/render" - "github.com/limechain/hedera-eth-bridge-validator/app/domain/service" -) - -const Route = "/fees" - -func NewRouter(pricingService service.Pricing) http.Handler { - r := chi.NewRouter() - r.Get("/nft", feesNftResponse(pricingService)) - return r -} - -func feesNftResponse(pricingService service.Pricing) func(w http.ResponseWriter, r *http.Request) { - return func(w http.ResponseWriter, r *http.Request) { - res := pricingService.NftFees() - if len(res) == 0 { - err := errors.New("router resolved with an error. Error [No NFT fees records]") - render.Status(r, http.StatusInternalServerError) - render.JSON(w, r, response.ErrorResponse(err)) - return - } - - render.JSON(w, r, res) - } -} diff --git a/app/services/assets/assets.go b/app/services/assets/assets.go index fea14183f..55f75783c 100644 --- a/app/services/assets/assets.go +++ b/app/services/assets/assets.go @@ -19,7 +19,6 @@ package assets import ( "errors" "fmt" - "github.com/limechain/hedera-eth-bridge-validator/app/helper/fee" "math/big" "regexp" "strconv" @@ -49,10 +48,6 @@ type Service struct { fungibleNativeAssets map[uint64]map[string]*assetModel.NativeAsset // A mapping, storing name and symbol for fungible asset per network fungibleAssetInfos map[uint64]map[string]*assetModel.FungibleAssetInfo - // A mapping, storing all non-fungible tokens per network - nonFungibleNetworkAssets map[uint64][]string - // A mapping, storing name and symbol for non-fungible asset per network - nonFungibleAssetInfos map[uint64]map[string]*assetModel.NonFungibleAssetInfo bridgeAccountId string logger *log.Entry @@ -62,10 +57,6 @@ func (a *Service) FungibleNetworkAssets() map[uint64][]string { return a.fungibleNetworkAssets } -func (a *Service) NonFungibleNetworkAssets() map[uint64][]string { - return a.nonFungibleNetworkAssets -} - func (a *Service) NativeToWrappedAssets() map[uint64]map[string]map[uint64]string { return a.nativeToWrapped } @@ -119,12 +110,6 @@ func (a *Service) FungibleAssetInfo(networkId uint64, assetAddressOrId string) ( return assetInfo, exist } -func (a *Service) NonFungibleAssetInfo(networkId uint64, assetAddressOrId string) (assetInfo *assetModel.NonFungibleAssetInfo, exist bool) { - assetInfo, exist = a.nonFungibleAssetInfos[networkId][assetAddressOrId] - - return assetInfo, exist -} - func (a *Service) FetchEvmFungibleReserveAmount( networkId uint64, assetAddress string, @@ -148,31 +133,6 @@ func (a *Service) FetchEvmFungibleReserveAmount( return inLowestDenomination, err } -func (a *Service) FetchEvmNonFungibleReserveAmount( - networkId uint64, - assetAddress string, - isNative bool, - evmTokenClient client.EvmNft, - routerContractAddress string, -) (inLowestDenomination *big.Int, err error) { - if isNative { - inLowestDenomination, err = evmTokenClient.BalanceOf(&bind.CallOpts{}, common.HexToAddress(routerContractAddress)) - if err != nil { - a.logger.Errorf("EVM with networkId [%d] for asset [%s], and method BalanceOf - Error: [%s]", networkId, assetAddress, err) - return nil, err - } - } else { - // TODO: Remove the line below and uncomment the next one when we update the NFTs to extend ERC721Enumerable - inLowestDenomination = big.NewInt(0) - //inLowestDenomination, err = evmTokenClient.TotalSupply(&bind.CallOpts{}) - //if err != nil { - // a.logger.Errorf("EVM with networkId [%d] for asset [%s], and method TotalSupply - Error: [%s]", networkId, assetAddress, err) - // return nil, err - //} - } - return inLowestDenomination, err -} - func (a *Service) FetchHederaTokenReserveAmount( assetId string, mirrorNode client.MirrorNode, @@ -236,34 +196,6 @@ func (a *Service) fetchEvmFungibleAssetInfo( return assetInfo, err } -func (a *Service) fetchEvmNonFungibleAssetInfo( - networkId uint64, - assetAddress string, - evmTokenClients map[uint64]map[string]client.EvmNft, - isNative bool, - routerContractAddress string, -) (assetInfo *assetModel.NonFungibleAssetInfo, err error) { - assetInfo = &assetModel.NonFungibleAssetInfo{} - evmTokenClient := evmTokenClients[networkId][assetAddress] - name, err := evmTokenClient.Name(&bind.CallOpts{}) - if err != nil { - a.logger.Errorf("Failed to get Name for Asset [%s] for EVM with networkId [%d] - Error: [%s]", assetAddress, networkId, err) - return assetInfo, err - } - assetInfo.Name = name - - symbol, err := evmTokenClient.Symbol(&bind.CallOpts{}) - if err != nil { - a.logger.Errorf("EVM with networkId [%d] for Asset [%s], and method Symbol - Error: [%s]", networkId, assetAddress, err) - return assetInfo, err - } - assetInfo.Symbol = symbol - - assetInfo.ReserveAmount, err = a.FetchEvmNonFungibleReserveAmount(networkId, assetAddress, isNative, evmTokenClient, routerContractAddress) - - return assetInfo, err -} - func (a *Service) fetchHederaFungibleAssetInfo( assetId string, mirrorNode client.MirrorNode, @@ -295,29 +227,6 @@ func (a *Service) fetchHederaFungibleAssetInfo( return assetInfo, nil } -func (a *Service) fetchHederaNonFungibleAssetInfo( - assetId string, - mirrorNode client.MirrorNode, - isNative bool, - hederaTokenBalances map[string]int, -) (assetInfo *assetModel.NonFungibleAssetInfo, err error) { - - assetInfo = &assetModel.NonFungibleAssetInfo{} - assetInfoResponse, e := mirrorNode.GetToken(assetId) - if e != nil { - a.logger.Errorf("Hedera Mirror Node method GetToken for Asset [%s] - Error: [%s]", assetId, e) - } else { - assetInfo.Name = assetInfoResponse.Name - assetInfo.Symbol = assetInfoResponse.Symbol - assetInfo.ReserveAmount, err = a.getHederaTokenReserveAmount(assetId, isNative, hederaTokenBalances, assetInfoResponse) - assetInfo.CustomFees.InitFromResponse(assetInfoResponse.CustomFees) - assetInfo.CustomFeeTotalAmounts = fee.SumFallbackFeeAmounts(assetInfo.CustomFees) - assetInfo.TreasuryAccountId = assetInfoResponse.TreasuryAccountId - } - - return assetInfo, err -} - func (a *Service) loadFungibleAssetInfos( networks map[uint64]*parser.Network, mirrorNode client.MirrorNode, @@ -411,81 +320,6 @@ func (a *Service) fetchFungibleAssetInfo( return assetInfo, assetAddress, err } -func (a *Service) loadNonFungibleAssetInfos( - networks map[uint64]*parser.Network, - mirrorNode client.MirrorNode, - evmTokenClients map[uint64]map[string]client.EvmNft, - hederaTokenBalances map[string]int, -) { - a.nonFungibleAssetInfos = make(map[uint64]map[string]*assetModel.NonFungibleAssetInfo) - - for nativeChainId, networkInfo := range networks { - if len(networkInfo.Tokens.Nft) == 0 { - continue - } - - if _, ok := a.nonFungibleAssetInfos[nativeChainId]; !ok { - a.nonFungibleAssetInfos[nativeChainId] = make(map[string]*assetModel.NonFungibleAssetInfo) - } - - for nativeAsset, nativeAssetMapping := range networkInfo.Tokens.Nft { - assetInfo, nativeAsset, err := a.fetchNonFungibleAssetInfo(nativeChainId, nativeAsset, mirrorNode, evmTokenClients, true, hederaTokenBalances, networks[nativeChainId].RouterContractAddress) - if err != nil { - a.logger.Fatal(err) - } - a.nonFungibleAssetInfos[nativeChainId][nativeAsset] = assetInfo - - for wrappedChainId, wrappedAsset := range nativeAssetMapping.Networks { - if _, ok := a.nonFungibleAssetInfos[wrappedChainId]; !ok { - a.nonFungibleAssetInfos[wrappedChainId] = make(map[string]*assetModel.NonFungibleAssetInfo) - } - assetInfo, wrappedAsset, err = a.fetchNonFungibleAssetInfo(wrappedChainId, wrappedAsset, mirrorNode, evmTokenClients, false, hederaTokenBalances, networks[wrappedChainId].RouterContractAddress) - if err != nil { - a.logger.Fatal(err) - } - a.nonFungibleAssetInfos[wrappedChainId][wrappedAsset] = assetInfo - } - } - } -} - -func (a *Service) fetchNonFungibleAssetInfo( - chainId uint64, - assetAddress string, - mirrorNode client.MirrorNode, - evmTokenClients map[uint64]map[string]client.EvmNft, - isNative bool, - hederaTokenBalances map[string]int, - routerContractAddress string, -) (*assetModel.NonFungibleAssetInfo, string, error) { - var ( - err error - assetInfo *assetModel.NonFungibleAssetInfo - ) - - if chainId == constants.HederaNetworkId { // Hedera - assetInfo, err = a.fetchHederaNonFungibleAssetInfo(assetAddress, mirrorNode, isNative, hederaTokenBalances) - if err != nil { - err = fmt.Errorf("Failed to load Hedera Non-Fungible Asset Info. Error [%v]", err) - return assetInfo, assetAddress, err - } - } else { // EVM - re := regexp.MustCompile(constants.EvmCompatibleAddressPattern) - if isMatch := re.MatchString(assetAddress); isMatch { - assetAddress = common.HexToAddress(assetAddress).String() - } - assetAddress = common.HexToAddress(assetAddress).String() - assetInfo, err = a.fetchEvmNonFungibleAssetInfo(chainId, assetAddress, evmTokenClients, isNative, routerContractAddress) - if err != nil { - err = fmt.Errorf("Failed to load EVM NetworkId [%v] Non-Fungible Asset Info. Error [%v]", chainId, err) - return assetInfo, assetAddress, err - } - } - assetInfo.IsNative = isNative - - return assetInfo, assetAddress, err -} - func NewService( networks map[uint64]*parser.Network, bridgeAccountId string, @@ -493,7 +327,6 @@ func NewService( routerClients map[uint64]client.DiamondRouter, mirrorNode client.MirrorNode, evmTokenClients map[uint64]map[string]client.EvmFungibleToken, - evmNftClients map[uint64]map[string]client.EvmNft, ) *Service { instance := initialize( networks, @@ -502,7 +335,6 @@ func NewService( routerClients, mirrorNode, evmTokenClients, - evmNftClients, ) event.On(constants.EventBridgeConfigUpdate, event.ListenerFunc(func(e event.Event) error { @@ -512,11 +344,10 @@ func NewService( return instance } -func initialize(networks map[uint64]*parser.Network, bridgeAccountId string, HederaFeePercentages map[string]int64, routerClients map[uint64]client.DiamondRouter, mirrorNode client.MirrorNode, evmTokenClients map[uint64]map[string]client.EvmFungibleToken, evmNftClients map[uint64]map[string]client.EvmNft) *Service { +func initialize(networks map[uint64]*parser.Network, bridgeAccountId string, HederaFeePercentages map[string]int64, routerClients map[uint64]client.DiamondRouter, mirrorNode client.MirrorNode, evmTokenClients map[uint64]map[string]client.EvmFungibleToken) *Service { nativeToWrapped := make(map[uint64]map[string]map[uint64]string) wrappedToNative := make(map[uint64]map[string]*assetModel.NativeAsset) fungibleNetworkAssets := make(map[uint64][]string) - nonFungibleNetworkAssets := make(map[uint64][]string) fungibleNativeAssets := make(map[uint64]map[string]*assetModel.NativeAsset) re := regexp.MustCompile(constants.EvmCompatibleAddressPattern) @@ -579,35 +410,6 @@ func initialize(networks map[uint64]*parser.Network, bridgeAccountId string, Hed wrappedToNative[wrappedChainId][wrappedAsset] = asset } } - - for nativeAsset, nativeAssetMapping := range network.Tokens.Nft { - if nativeChainId != constants.HederaNetworkId { - nativeAsset = common.HexToAddress(nativeAsset).String() - } - - if nativeToWrapped[nativeChainId][nativeAsset] == nil { - nativeToWrapped[nativeChainId][nativeAsset] = make(map[uint64]string) - } - - nonFungibleNetworkAssets[nativeChainId] = append(nonFungibleNetworkAssets[nativeChainId], nativeAsset) - - for wrappedChainId, wrappedAsset := range nativeAssetMapping.Networks { - if isMatch := re.MatchString(wrappedAsset); isMatch { - wrappedAsset = common.HexToAddress(wrappedAsset).String() - } - - nativeToWrapped[nativeChainId][nativeAsset][wrappedChainId] = wrappedAsset - if wrappedToNative[wrappedChainId] == nil { - wrappedToNative[wrappedChainId] = make(map[string]*assetModel.NativeAsset) - } - - nonFungibleNetworkAssets[wrappedChainId] = append(nonFungibleNetworkAssets[wrappedChainId], wrappedAsset) - wrappedToNative[wrappedChainId][wrappedAsset] = &assetModel.NativeAsset{ - ChainId: nativeChainId, - Asset: nativeAsset, - } - } - } } logger := config.GetLoggerFor("Assets Service") @@ -616,7 +418,6 @@ func initialize(networks map[uint64]*parser.Network, bridgeAccountId string, Hed wrappedToNative: wrappedToNative, fungibleNativeAssets: fungibleNativeAssets, fungibleNetworkAssets: fungibleNetworkAssets, - nonFungibleNetworkAssets: nonFungibleNetworkAssets, bridgeAccountId: bridgeAccountId, logger: logger, } @@ -628,7 +429,6 @@ func initialize(networks map[uint64]*parser.Network, bridgeAccountId string, Hed } hederaTokenBalances := bridgeAccount.Balance.GetAccountTokenBalancesByAddress() instance.loadFungibleAssetInfos(networks, mirrorNode, evmTokenClients, hederaTokenBalances) - instance.loadNonFungibleAssetInfos(networks, mirrorNode, evmNftClients, hederaTokenBalances) return instance } @@ -648,7 +448,6 @@ func bridgeCfgUpdateEventHandler(e event.Event, mirrorNode client.MirrorNode, in params.RouterClients, mirrorNode, params.EvmFungibleTokenClients, - params.EvmNFTClients, ) *instance = *newInstance params.Bridge.LoadStaticMinAmountsForWrappedFungibleTokens(*params.ParsedBridge, instance) diff --git a/app/services/assets/assets_test.go b/app/services/assets/assets_test.go index a28ddc93e..94a155fb3 100644 --- a/app/services/assets/assets_test.go +++ b/app/services/assets/assets_test.go @@ -42,7 +42,6 @@ var ( evmClients = make(map[uint64]client.EVM) evmCoreClients = make(map[uint64]client.Core) evmFungibleTokenClients = make(map[uint64]map[string]client.EvmFungibleToken) - evmNftClients = make(map[uint64]map[string]client.EvmNft) hederaPercentages = make(map[string]int64) hederaAccount = account.AccountsResponse{ Account: testConstants.BridgeAccountId, @@ -60,24 +59,18 @@ func Test_New(t *testing.T) { setup() setupClientMocks() - actualService := NewService(testConstants.ParserBridge.Networks, testConstants.ParserBridge.Networks[constants.HederaNetworkId].BridgeAccount, hederaPercentages, routerClients, mocks.MHederaMirrorClient, evmFungibleTokenClients, evmNftClients) + actualService := NewService(testConstants.ParserBridge.Networks, testConstants.ParserBridge.Networks[constants.HederaNetworkId].BridgeAccount, hederaPercentages, routerClients, mocks.MHederaMirrorClient, evmFungibleTokenClients) assert.Equal(t, serviceInstance.nativeToWrapped, actualService.nativeToWrapped) assert.Equal(t, serviceInstance.wrappedToNative, actualService.wrappedToNative) assert.Equal(t, serviceInstance.fungibleNativeAssets, actualService.fungibleNativeAssets) assert.Equal(t, serviceInstance.fungibleAssetInfos, actualService.fungibleAssetInfos) - assert.Equal(t, serviceInstance.nonFungibleAssetInfos, actualService.nonFungibleAssetInfos) for networkId := range testConstants.Networks { // Fungible sort.Strings(serviceInstance.fungibleNetworkAssets[networkId]) sort.Strings(actualService.fungibleNetworkAssets[networkId]) assert.Equal(t, serviceInstance.fungibleNetworkAssets[networkId], actualService.fungibleNetworkAssets[networkId]) - - // Non-Fungible - sort.Strings(serviceInstance.nonFungibleNetworkAssets[networkId]) - sort.Strings(actualService.nonFungibleNetworkAssets[networkId]) - assert.Equal(t, serviceInstance.nonFungibleNetworkAssets[networkId], actualService.nonFungibleNetworkAssets[networkId]) } } @@ -146,16 +139,6 @@ func Test_FungibleNetworkAssets(t *testing.T) { assert.Equal(t, expected, actual) } -func Test_NonFungibleNetworkAssets(t *testing.T) { - setup() - - actual := serviceInstance.NonFungibleNetworkAssets() - expected := testConstants.NonFungibleNetworkAssets - - assert.NotNil(t, actual) - assert.Equal(t, expected, actual) -} - func Test_NativeToWrappedAssets(t *testing.T) { setup() @@ -207,17 +190,6 @@ func Test_FungibleAssetInfo(t *testing.T) { assert.Equal(t, expected, actual) } -func Test_NonFungibleAssetInfo(t *testing.T) { - setup() - - actual, exists := serviceInstance.NonFungibleAssetInfo(constants.HederaNetworkId, testConstants.NetworkHederaNonFungibleNativeToken) - expected := testConstants.NetworkHederaNonFungibleNativeTokenNonFungibleAssetInfo - - assert.NotNil(t, actual) - assert.True(t, exists) - assert.Equal(t, expected, actual) -} - func Test_FetchEvmFungibleReserveAmount_Native(t *testing.T) { setup() setupClientMocks() @@ -248,34 +220,6 @@ func Test_FetchEvmFungibleReserveAmount_Wrapped(t *testing.T) { assert.Equal(t, expectedReserveAmount, actual) } -func Test_FetchEvmNonFungibleReserveAmount_Native(t *testing.T) { - setup() - setupClientMocks() - - asset := testConstants.NetworkPolygonWrappedNonFungibleTokenForHedera - tokenClient := evmNftClients[testConstants.PolygonNetworkId][asset] - expectedReserveAmount := testConstants.ReserveAmountBigInt - tokenClient.(*testClient.MockEvmNonFungibleToken).On("BalanceOf", &bind.CallOpts{}, common.HexToAddress(routerContractAddress)).Return(expectedReserveAmount, nil) - - actual, err := serviceInstance.FetchEvmNonFungibleReserveAmount(testConstants.PolygonNetworkId, asset, true, tokenClient, routerContractAddress) - - assert.Nil(t, err) - assert.Equal(t, expectedReserveAmount, actual) -} - -func Test_FetchEvmNonFungibleReserveAmount_Wrapped(t *testing.T) { - setup() - setupClientMocks() - asset := testConstants.NetworkPolygonWrappedNonFungibleTokenForHedera - tokenClient := evmNftClients[testConstants.PolygonNetworkId][asset] - expectedReserveAmount := testConstants.ReserveAmountWrappedNFTBigInt - - actual, err := serviceInstance.FetchEvmNonFungibleReserveAmount(testConstants.PolygonNetworkId, asset, false, tokenClient, routerContractAddress) - - assert.Nil(t, err) - assert.Equal(t, expectedReserveAmount, actual) -} - func Test_FetchHederaTokenReserveAmount_Native(t *testing.T) { setup() setupClientMocks() @@ -313,12 +257,9 @@ func setup() { fungibleNativeAssets: testConstants.FungibleNativeAssets, fungibleNetworkAssets: testConstants.FungibleNetworkAssets, fungibleAssetInfos: testConstants.FungibleAssetInfos, - nonFungibleNetworkAssets: testConstants.NonFungibleNetworkAssets, - nonFungibleAssetInfos: testConstants.NonFungibleAssetInfos, bridgeAccountId: testConstants.BridgeAccountId, logger: config.GetLoggerFor("Assets Service"), } - fmt.Printf("%#v", testConstants.NonFungibleAssetInfos[constants.HederaNetworkId][testConstants.NetworkHederaNonFungibleNativeToken]) fmt.Println(serviceInstance) } @@ -326,7 +267,6 @@ func setupClientMocks() { for networkId, networkInfo := range testConstants.Networks { if networkId != constants.HederaNetworkId { evmFungibleTokenClients[networkId] = make(map[string]client.EvmFungibleToken) - evmNftClients[networkId] = make(map[string]client.EvmNft) evmClients[networkId] = &testClient.MockEVM{} evmCoreClients[networkId] = &testClient.MockEVMCore{} evmClients[networkId].(*testClient.MockEVM).On("GetClient").Return(evmCoreClients[networkId]) @@ -380,77 +320,6 @@ func setupClientMocks() { } routerClients[networkId].(*testClient.MockDiamondRouter).On("TokenFeeData", &bind.CallOpts{}, common.HexToAddress(asset)).Return(tokenFeeDataResult, nil) } - - // NON-FUNGIBLE // - nonFungibleAssets := testConstants.NonFungibleNetworkAssets[networkId] - for _, asset := range nonFungibleAssets { - assetInfo := testConstants.NonFungibleAssetInfos[networkId][asset] - isNative := assetInfo.IsNative - hederaPercentages[asset] = testConstants.FeePercentage - if networkId == constants.HederaNetworkId { - hederaTokenBalances[asset] = int(testConstants.ReserveAmount) - hederaAccount.Balance.Tokens = append(hederaAccount.Balance.Tokens, account.AccountToken{ - TokenID: asset, - Balance: int(testConstants.ReserveAmount), - }) - - // Hedera - tokenResponse := token.TokenResponse{ - TokenID: asset, - Name: asset, - Symbol: asset, - TotalSupply: testConstants.ReserveAmountStr, - CustomFees: token.CustomFees{ - CreatedTimestamp: "", - RoyaltyFees: []token.RoyaltyFee{ - { - Amount: token.Fraction{ - Numerator: 100, - Denominator: 100, - }, - FallbackFee: token.FixedFee{ - Amount: testConstants.NetworkHederaNFTRoyaltyFeeForToken.FallbackFee.Amount, - DenominatingTokenId: &testConstants.NetworkHederaFungibleNativeToken, - }, - CollectorAccountID: "", - }, - { - Amount: token.Fraction{ - Numerator: 100, - Denominator: 100, - }, - FallbackFee: token.FixedFee{ - Amount: testConstants.NetworkHederaNFTRoyaltyFeeHbarFallback.FallbackFee.Amount, - DenominatingTokenId: nil, - }, - CollectorAccountID: "", - }, - }, - }, - Decimals: "0", - } - mocks.MHederaMirrorClient.On("GetToken", asset).Return(&tokenResponse, nil) - continue - } - - // EVM - evmNftClients[networkId][asset] = new(testClient.MockEvmNonFungibleToken) - evmNftClients[networkId][asset].(*testClient.MockEvmNonFungibleToken).On("Name", &bind.CallOpts{}).Return(asset, nil) - evmNftClients[networkId][asset].(*testClient.MockEvmNonFungibleToken).On("Symbol", &bind.CallOpts{}).Return(asset, nil) - tokenFeeDataResult := struct { - ServiceFeePercentage *big.Int - FeesAccrued *big.Int - PreviousAccrued *big.Int - Accumulator *big.Int - }{big.NewInt(testConstants.FeePercentage), big.NewInt(0), big.NewInt(0), big.NewInt(0)} - routerClients[networkId].(*testClient.MockDiamondRouter).On("TokenFeeData", &bind.CallOpts{}, common.HexToAddress(asset)).Return(tokenFeeDataResult, nil) - if isNative { - evmNftClients[networkId][asset].(*testClient.MockEvmNonFungibleToken).On("BalanceOf", &bind.CallOpts{}, common.HexToAddress(networkInfo.RouterContractAddress)).Return(testConstants.ReserveAmountBigInt, nil) - } /* else { // TODO: Uncomment the line below when we update the NFTs to extend ERC721Enumerable - evmNftClients[networkId][asset].(*testClient.MockEvmFungibleToken).On("TotalSupply", &bind.CallOpts{}).Return(testConstants.ReserveAmountBigInt, nil) - } */ - } - } mocks.MHederaMirrorClient.On("GetAccount", testConstants.BridgeAccountId).Return(&hederaAccount, nil) diff --git a/app/services/bridge-config/service_test.go b/app/services/bridge-config/service_test.go index f11e26e2b..c49f09913 100644 --- a/app/services/bridge-config/service_test.go +++ b/app/services/bridge-config/service_test.go @@ -69,7 +69,6 @@ var ( Tokens: parser.Tokens{ Fungible: map[string]parser.Token{ "HBAR": { - Fee: 0, FeePercentage: 10000, MinFeeAmountInUsd: "0.001", MinAmount: nil, @@ -81,7 +80,6 @@ var ( CoinMarketCapId: "4642", }, }, - Nft: nil, }, }, }, diff --git a/app/services/contracts/service.go b/app/services/contracts/service.go index bc39119ce..a0e620d6d 100644 --- a/app/services/contracts/service.go +++ b/app/services/contracts/service.go @@ -94,11 +94,6 @@ func (bsc *Service) ParseUnlockLog(log types.Log) (*router.RouterUnlock, error) return bsc.contract.ParseUnlock(log) } -// ParseBurnERC721Log parses a general typed log to a BurnERC721event -func (bsc *Service) ParseBurnERC721Log(log types.Log) (*router.RouterBurnERC721, error) { - return bsc.contract.ParseBurnERC721(log) -} - // WatchBurnEventLogs creates a subscription for Burn Events emitted in the Bridge contract func (bsc *Service) WatchBurnEventLogs(opts *bind.WatchOpts, sink chan<- *router.RouterBurn) (event.Subscription, error) { return bsc.contract.WatchBurn(opts, sink) diff --git a/app/services/messages/service.go b/app/services/messages/service.go index 1bd9597e5..ce4e1d3af 100644 --- a/app/services/messages/service.go +++ b/app/services/messages/service.go @@ -119,27 +119,6 @@ func (ss *Service) SanityCheckFungibleSignature(topicMessage *proto_models.Topic return match, nil } -// SanityCheckNftSignature performs validation on the topic message metadata. -// Validates it against the Transaction Record metadata from DB -func (ss *Service) SanityCheckNftSignature(topicMessage *proto_models.TopicEthNftSignatureMessage) (bool, error) { - // In case a topic message for given transfer is being processed before the actual transfer - t, err := ss.awaitTransfer(topicMessage.TransferID) - if err != nil { - ss.logger.Errorf("[%s] - Failed to await incoming transfer and its fee. Error: [%s]", topicMessage.TransferID, err) - return false, err - } - - match := - topicMessage.Recipient == t.Receiver && - int64(topicMessage.TokenId) == t.SerialNumber && - topicMessage.Metadata == t.Metadata && - topicMessage.Asset == t.TargetAsset && - topicMessage.TargetChainId == t.TargetChainID && - topicMessage.SourceChainId == t.SourceChainID && - topicMessage.TransferID == t.TransactionID - return match, nil -} - func (ss Service) SignFungibleMessage(tm payload.Transfer) ([]byte, error) { authMsgHash, err := auth_message.EncodeFungibleBytesFrom(tm.SourceChainId, tm.TargetChainId, tm.TransactionId, tm.TargetAsset, tm.Receiver, tm.Amount) if err != nil { @@ -173,41 +152,6 @@ func (ss Service) SignFungibleMessage(tm payload.Transfer) ([]byte, error) { return bytes, nil } -func (ss Service) SignNftMessage(tm payload.Transfer) ([]byte, error) { - authMsgHash, err := auth_message.EncodeNftBytesFrom(tm.SourceChainId, tm.TargetChainId, tm.TransactionId, tm.TargetAsset, tm.SerialNum, tm.Metadata, tm.Receiver) - if err != nil { - ss.logger.Errorf("[%s] - Failed to encode the authorisation signature. Error: [%s]", tm.TransactionId, err) - return nil, err - } - - signatureBytes, err := ss.ethSigners[tm.TargetChainId].Sign(authMsgHash) - if err != nil { - ss.logger.Errorf("[%s] - Failed to sign the authorisation signature. Error: [%s]", tm.TransactionId, err) - return nil, err - } - signature := hex.EncodeToString(signatureBytes) - - topicMessage := &proto_models.TopicEthNftSignatureMessage{ - SourceChainId: tm.SourceChainId, - TargetChainId: tm.TargetChainId, - TransferID: tm.TransactionId, - Asset: tm.TargetAsset, - TokenId: uint64(tm.SerialNum), - Metadata: tm.Metadata, - Recipient: tm.Receiver, - Signature: signature, - } - msg := message.NewNftSignature(topicMessage) - - bytes, err := msg.ToBytes() - if err != nil { - ss.logger.Errorf("[%s] - Failed to marshal NFT Signature Message to bytes. Error [%s]", tm.TransactionId, err) - return nil, err - } - - return bytes, nil -} - // ProcessSignature processes the signature message, verifying and updating all necessary fields in the DB func (ss *Service) ProcessSignature(transferID, signature string, targetChainId uint64, timestamp int64, authMsg []byte) error { // Prepare Signature diff --git a/app/services/messages/service_test.go b/app/services/messages/service_test.go index 449d37f76..cae5af0d9 100644 --- a/app/services/messages/service_test.go +++ b/app/services/messages/service_test.go @@ -20,7 +20,6 @@ import ( "errors" "fmt" "testing" - "time" "github.com/hashgraph/hedera-sdk-go/v2" "github.com/limechain/hedera-eth-bridge-validator/app/domain/client" @@ -64,24 +63,6 @@ var ( }, }, } - - topicEthNftMessage = &proto.TopicEthNftSignatureMessage{ - Recipient: "0xb083879B1e10C8476802016CB12cd2F25a896691", - TokenId: 42, - Metadata: "nft-metadata", - Asset: asset, - TargetChainId: targetChainId, - SourceChainId: sourceChainId, - TransferID: "some-transfer-id", - } - - topicNftMessage = message.Message{ - TopicMessage: &proto.TopicMessage{ - Message: &proto.TopicMessage_NftSignatureMessage{ - NftSignatureMessage: topicEthNftMessage, - }, - }, - } ) func Test_NewService(t *testing.T) { @@ -141,36 +122,6 @@ func Test_SanityCheckFungibleSignature_ShouldReturnTrue(t *testing.T) { assert.Nil(t, err) } -func Test_SanityCheckNftSignature_ShouldReturnError(t *testing.T) { - setup() - - mocks.MTransferRepository.On("GetByTransactionId", topicEthNftMessage.TransferID).Return(nil, errors.New("some-error")) - - ok, err := serviceInstance.SanityCheckNftSignature(topicNftMessage.GetNftSignatureMessage()) - assert.False(t, ok) - assert.NotNil(t, err) -} - -func Test_SanityCheckNftSignature(t *testing.T) { - setup() - - transfer := &entity.Transfer{ - Receiver: topicEthNftMessage.Recipient, - SerialNumber: int64(topicEthNftMessage.TokenId), - Metadata: topicEthNftMessage.Metadata, - TargetAsset: topicEthNftMessage.Asset, - TargetChainID: topicEthNftMessage.TargetChainId, - SourceChainID: topicEthNftMessage.SourceChainId, - TransactionID: topicEthNftMessage.TransferID, - } - - mocks.MTransferRepository.On("GetByTransactionId", topicEthNftMessage.TransferID).Return(transfer, nil) - - ok, err := serviceInstance.SanityCheckNftSignature(topicNftMessage.GetNftSignatureMessage()) - assert.True(t, ok) - assert.Nil(t, err) -} - func Test_SignFungibleMessage_ShouldReturnError(t *testing.T) { setup() @@ -215,60 +166,6 @@ func Test_SignFungibleMessage(t *testing.T) { assert.Nil(t, err) } -func Test_SignNftMessage_ShouldReturnError(t *testing.T) { - setup() - - tm := payload.Transfer{ - SourceChainId: topicEthNftMessage.SourceChainId, - TargetChainId: topicEthNftMessage.TargetChainId, - TransactionId: topicEthNftMessage.TransferID, - TargetAsset: topicEthNftMessage.Asset, - Receiver: topicEthNftMessage.Recipient, - SerialNum: int64(topicEthNftMessage.TokenId), - IsNft: true, - } - - mocks.MSignerService.On("Sign", mock.Anything).Return(nil, errors.New("some-error")) - - bytes, err := serviceInstance.SignNftMessage(tm) - assert.Nil(t, bytes) - assert.NotNil(t, err) -} - -func Test_SignNftMessage(t *testing.T) { - setup() - - tm := payload.Transfer{ - SourceChainId: topicEthNftMessage.SourceChainId, - TargetChainId: topicEthNftMessage.TargetChainId, - TransactionId: topicEthNftMessage.TransferID, - TargetAsset: topicEthNftMessage.Asset, - Receiver: topicEthNftMessage.Recipient, - SerialNum: int64(topicEthNftMessage.TokenId), - IsNft: true, - } - - mocks.MSignerService.On("Sign", mock.Anything).Return([]byte{}, nil) - - bytes, err := serviceInstance.SignNftMessage(tm) - assert.NotNil(t, bytes) - assert.Nil(t, err) -} - -func Test_ProcessSignature(t *testing.T) { - setup() - - err := serviceInstance.ProcessSignature( - topicEthNftMessage.TransferID, - "signature", - topicEthNftMessage.TargetChainId, - time.Now().UnixNano(), - []byte{}, - ) - - assert.NotNil(t, err) -} - func setup() { mocks.Setup() diff --git a/app/services/pricing/service.go b/app/services/pricing/service.go index a10302cab..9e96b2a41 100644 --- a/app/services/pricing/service.go +++ b/app/services/pricing/service.go @@ -17,14 +17,10 @@ package pricing import ( - "errors" "fmt" "math/big" "sync" - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/common" - "github.com/gookit/event" "github.com/limechain/hedera-eth-bridge-validator/app/domain/client" "github.com/limechain/hedera-eth-bridge-validator/app/domain/service" @@ -45,17 +41,12 @@ type Service struct { coinMarketCapClient client.Pricing tokenPriceInfoMutex *sync.RWMutex minAmountsForApiMutex *sync.RWMutex - nftFeesForApiMutex *sync.RWMutex coinMarketCapIds map[uint64]map[string]string coinGeckoIds map[uint64]map[string]string tokensPriceInfo map[uint64]map[string]pricing.TokenPriceInfo minAmountsForApi map[uint64]map[string]string hbarFungibleAssetInfo *asset.FungibleAssetInfo hbarNativeAsset *asset.NativeAsset - hederaNftDynamicFees map[string]decimal.Decimal - hederaNftFees map[string]int64 - hederaNftPrevFees map[string]int64 - nftFeesForApi map[uint64]map[string]pricing.NonFungibleFee diamondRouters map[uint64]client.DiamondRouter logger *log.Entry } @@ -102,139 +93,6 @@ func (s *Service) FetchAndUpdateUsdPrices() error { return nil } -func (s *Service) fetchAndUpdateNftFeesForApi() error { - s.logger.Debugf("Populating NFT fees for API") - - res := make(map[uint64]map[string]pricing.NonFungibleFee) - assets := s.assetsService.NonFungibleNetworkAssets() - for networkId, nfts := range assets { - res[networkId] = make(map[string]pricing.NonFungibleFee) - for _, id := range nfts { - assetInfo, ok := s.assetsService.NonFungibleAssetInfo(networkId, id) - if !ok { - s.logger.Errorf("Failed to get asset info for [%s]", id) - return fmt.Errorf("failed to get asset info for [%s]", id) - } - - if networkId == constants.HederaNetworkId { - fee, err := s.hederaNativeNftFee(id, networkId, *assetInfo) - if err != nil { - return err - } - res[networkId][id] = *fee - continue - } - - diamondRouter, ok := s.diamondRouters[networkId] - if !ok { - return fmt.Errorf("could not get diamond router for network %d", networkId) - } - - if assetInfo.IsNative { - fee, err := s.evmNativeNftFee(id, diamondRouter) - if err != nil { - return err - } - res[networkId][id] = *fee - } else { - fee, err := s.evmWrappedNftFee(id, diamondRouter) - if err != nil { - return err - } - res[networkId][id] = *fee - } - } - } - - s.logger.Debugf("fetched all NFT fees and payment tokens successfully") - - s.nftFeesForApiMutex.Lock() - s.nftFeesForApi = res - s.nftFeesForApiMutex.Unlock() - - return nil -} - -func (s *Service) NftFees() map[uint64]map[string]pricing.NonFungibleFee { - s.nftFeesForApiMutex.RLock() - defer s.nftFeesForApiMutex.RUnlock() - - return s.nftFeesForApi -} - -func (s *Service) evmNativeNftFee(id string, diamondRouter client.DiamondRouter) (*pricing.NonFungibleFee, error) { - fee, ok := s.GetHederaNftFee(id) - if !ok { - return nil, fmt.Errorf("could not get fee for asset %s", id) - } - - nftFee := &pricing.NonFungibleFee{ - Fee: decimal.NewFromInt(fee), - } - - paymentToken, err := diamondRouter.Erc721Payment(&bind.CallOpts{}, common.HexToAddress(id)) - if err != nil { - s.logger.Errorf("Failed to get payment token for asset %s. Error [%s]", id, err) - return nil, err - } - - nftFee.PaymentToken = paymentToken.String() - nftFee.IsNative = true - - return nftFee, nil -} - -func (s *Service) evmWrappedNftFee(id string, diamondRouter client.DiamondRouter) (*pricing.NonFungibleFee, error) { - paymentToken, err := diamondRouter.Erc721Payment(&bind.CallOpts{}, common.HexToAddress(id)) - if err != nil { - s.logger.Errorf("Failed to get payment token for asset %s. Error [%s]", id, err) - return nil, err - } - - fee, err := diamondRouter.Erc721Fee(&bind.CallOpts{}, common.HexToAddress(id)) - if err != nil { - s.logger.Errorf("Failed to get fee for asset %s. Error [%s]", id, err) - return nil, err - } - - return &pricing.NonFungibleFee{ - IsNative: false, - PaymentToken: paymentToken.String(), - Fee: decimal.NewFromBigInt(fee, 0), - }, nil -} - -func (s *Service) hederaNativeNftFee(id string, networkId uint64, asset asset.NonFungibleAssetInfo) (*pricing.NonFungibleFee, error) { - fee, ok := s.hederaNftFees[id] - if !ok { - errMsg := fmt.Sprintf("No fee found for NFT [%s] on network [%d]", id, networkId) - s.logger.Errorf(errMsg) - return nil, errors.New(errMsg) - } - - var customFees []pricing.CustomFee - if asset.CustomFeeTotalAmounts.FallbackFeeAmountInHbar > 0 { - customFees = append(customFees, pricing.CustomFee{ - PaymentToken: constants.Hbar, - Fee: decimal.NewFromInt(asset.CustomFeeTotalAmounts.FallbackFeeAmountInHbar), - }) - } - - for token, fee := range asset.CustomFeeTotalAmounts.FallbackFeeAmountsByTokenId { - customFees = append(customFees, pricing.CustomFee{ - PaymentToken: token, - Fee: decimal.NewFromInt(fee), - }) - } - - return &pricing.NonFungibleFee{ - IsNative: true, - Fee: decimal.NewFromInt(fee), - PaymentToken: constants.Hbar, - CustomFees: customFees, - }, nil -} - func (s *Service) GetMinAmountsForAPI() map[uint64]map[string]string { s.minAmountsForApiMutex.RLock() defer s.minAmountsForApiMutex.RUnlock() @@ -242,22 +100,6 @@ func (s *Service) GetMinAmountsForAPI() map[uint64]map[string]string { return s.minAmountsForApi } -func (s *Service) GetHederaNftFee(token string) (int64, bool) { - s.tokenPriceInfoMutex.RLock() - defer s.tokenPriceInfoMutex.RUnlock() - - fee, exists := s.hederaNftFees[token] - return fee, exists -} - -func (s *Service) GetHederaNftPrevFee(token string) (int64, bool) { - s.tokenPriceInfoMutex.RLock() - defer s.tokenPriceInfoMutex.RUnlock() - - prevFee, exists := s.hederaNftPrevFees[token] - return prevFee, exists -} - func (s *Service) loadStaticMinAmounts(bridgeConfig *config.Bridge) { // This lock is used for more time than others to speed up things // as here, there is no other polling/locking operation @@ -315,12 +157,6 @@ func (s *Service) updateHbarPrice(results fetchResults) error { return fmt.Errorf("failed to update price info containers. Error: [%s]", err) } - s.updateHederaNftDynamicFeesBasedOnHbar(priceInUsd, s.hbarFungibleAssetInfo.Decimals) - err = s.fetchAndUpdateNftFeesForApi() - if err != nil { - return err - } - return nil } @@ -450,16 +286,6 @@ func (s *Service) updatePricesWithoutHbar(pricesByNetworkAndAddress map[uint64]m return nil } -func (s *Service) updateHederaNftDynamicFeesBasedOnHbar(priceInUsd decimal.Decimal, decimals uint8) { - for token, feeAmount := range s.hederaNftDynamicFees { - nftDynamicFee := decimalHelper.ToLowestDenomination(feeAmount.Div(priceInUsd), decimals).Int64() - s.hederaNftPrevFees[token] = s.hederaNftFees[token] - s.hederaNftFees[token] = nftDynamicFee - - s.logger.Debugf("Updating NFT Dynamic fee for [%s] to HBAR [%d], based on USD constant fee [%s] and HBAR/USD rate [%s]", token, nftDynamicFee, feeAmount, priceInUsd) - } -} - type fetchResults struct { HbarPrice decimal.Decimal HbarErr error @@ -518,15 +344,11 @@ func initialize(bridgeConfig *config.Bridge, assetsService service.Assets, mirro coinMarketCapClient: coinMarketCapClient, tokenPriceInfoMutex: new(sync.RWMutex), minAmountsForApiMutex: new(sync.RWMutex), - nftFeesForApiMutex: new(sync.RWMutex), assetsService: assetsService, coinGeckoIds: bridgeConfig.CoinGeckoIds, coinMarketCapIds: bridgeConfig.CoinMarketCapIds, hbarFungibleAssetInfo: hbarFungibleAssetInfo, hbarNativeAsset: hbarNativeAsset, - hederaNftFees: bridgeConfig.Hedera.NftConstantFees, - hederaNftPrevFees: make(map[string]int64), - hederaNftDynamicFees: bridgeConfig.Hedera.NftDynamicFees, diamondRouters: diamondRouters, logger: logger, } diff --git a/app/services/pricing/service_test.go b/app/services/pricing/service_test.go index 2110d7714..51c03aff0 100644 --- a/app/services/pricing/service_test.go +++ b/app/services/pricing/service_test.go @@ -24,12 +24,7 @@ import ( "testing" "time" - "github.com/ethereum/go-ethereum/common" - - "github.com/ethereum/go-ethereum/accounts/abi/bind" - validatorClient "github.com/limechain/hedera-eth-bridge-validator/app/domain/client" - decimalHelper "github.com/limechain/hedera-eth-bridge-validator/app/helper/decimal" "github.com/limechain/hedera-eth-bridge-validator/app/model/asset" "github.com/limechain/hedera-eth-bridge-validator/app/model/pricing" @@ -50,7 +45,6 @@ var ( coinMarketCapClient *client.MockPricingClient tokenPriceInfoMutex *sync.RWMutex minAmountsForApiMutex *sync.RWMutex - nftFeesForApiMutex *sync.RWMutex diamondRouters map[uint64]validatorClient.DiamondRouter ) @@ -59,9 +53,6 @@ func Test_New(t *testing.T) { actualService := NewService(test_config.TestConfig.Bridge, mocks.MAssetsService, diamondRouters, mocks.MHederaMirrorClient, coinGeckoClient, coinMarketCapClient) - // reset fields - serviceInstance.hederaNftDynamicFees = nil - assert.Equal(t, serviceInstance, actualService) } @@ -172,7 +163,7 @@ func Test_PriceFetchingServiceDown(t *testing.T) { DefaultMinAmount: big.NewInt(0), } - //Throws error since HBAR UsdPrice is used for a lot of calculations ( exmpl NFTs ) + //Throws error since HBAR UsdPrice is used for a lot of calculations err = serviceInstance.updateHbarPrice(FetchResults2) assert.Error(t, err) } @@ -203,14 +194,6 @@ func Test_GetTokenPriceInfo_WhileUpdating(t *testing.T) { }) } -func Test_NftFees_WhileUpdating(t *testing.T) { - setup(true, true) - - ExecuteWithUpdatingService(t, func() { - serviceInstance.NftFees() - }) -} - func Test_GetMinAmountsForAPI(t *testing.T) { setup(true, true) @@ -269,62 +252,12 @@ func Test_updatePricesWithoutHbar_NonExistingAddress(t *testing.T) { assert.Nil(t, err) } -func Test_GetHederaNftFee(t *testing.T) { - setup(true, true) - - priceInUsd := decimal.NewFromInt(400) - expectedFee := decimalHelper.ToLowestDenomination(testConstants.HederaNftDynamicFees[testConstants.NetworkHederaNonFungibleNativeToken].Div(priceInUsd), serviceInstance.hbarFungibleAssetInfo.Decimals).Int64() - - serviceInstance.updateHederaNftDynamicFeesBasedOnHbar(priceInUsd, serviceInstance.hbarFungibleAssetInfo.Decimals) - - fee, ok := serviceInstance.GetHederaNftFee(testConstants.NetworkHederaNonFungibleNativeToken) - assert.Equal(t, expectedFee, fee) - assert.True(t, ok) -} - -func Test_GetHederaNftPrevFee_ShouldExists(t *testing.T) { - setup(true, true) - - priceInUsd := decimal.NewFromInt(400) - expectedPrevFee := testConstants.HederaNftFees[testConstants.NetworkHederaNonFungibleNativeToken] - expectedFee := decimalHelper.ToLowestDenomination(testConstants.HederaNftDynamicFees[testConstants.NetworkHederaNonFungibleNativeToken].Div(priceInUsd), serviceInstance.hbarFungibleAssetInfo.Decimals).Int64() - - fee, ok := serviceInstance.GetHederaNftFee(testConstants.NetworkHederaNonFungibleNativeToken) - assert.Equal(t, testConstants.HederaNftFees[testConstants.NetworkHederaNonFungibleNativeToken], fee) - assert.True(t, ok) - - serviceInstance.updateHederaNftDynamicFeesBasedOnHbar(priceInUsd, serviceInstance.hbarFungibleAssetInfo.Decimals) - - fee, ok = serviceInstance.GetHederaNftFee(testConstants.NetworkHederaNonFungibleNativeToken) - assert.Equal(t, expectedFee, fee) - assert.True(t, ok) - - prevFee, ok := serviceInstance.GetHederaNftPrevFee(testConstants.NetworkHederaNonFungibleNativeToken) - assert.Equal(t, expectedPrevFee, prevFee) - assert.True(t, ok) -} - -func Test_GetHederaNftPrevFee_ShouldNotExists(t *testing.T) { - setup(true, true) - - prevFee, ok := serviceInstance.GetHederaNftPrevFee(testConstants.NetworkHederaNonFungibleNativeToken) - assert.Equal(t, int64(0), prevFee) - assert.False(t, ok) -} func ExecuteWithUpdatingService(t *testing.T, serviceCall func()) { expectedTime := time.Millisecond * 200 - waitTime := time.Second * 1 // Clear the mocks mocks.MDiamondRouter.ExpectedCalls = []*mock.Call{} - mocks.MDiamondRouter. - On("Erc721Payment", &bind.CallOpts{}, common.HexToAddress(testConstants.NetworkPolygonWrappedNonFungibleTokenForHedera)). - After(waitTime). - Return(common.HexToAddress(testConstants.NftFeesForApi[testConstants.PolygonNetworkId][testConstants.NetworkPolygonWrappedNonFungibleTokenForHedera].PaymentToken), nil). - On("Erc721Fee", &bind.CallOpts{}, common.HexToAddress(testConstants.NetworkPolygonWrappedNonFungibleTokenForHedera)). - Return(big.NewInt(testConstants.NftFeesForApi[testConstants.PolygonNetworkId][testConstants.NetworkPolygonWrappedNonFungibleTokenForHedera].Fee.IntPart()), nil) - wg := sync.WaitGroup{} wg.Add(1) @@ -350,7 +283,6 @@ func setup(setupMocks bool, setTokenPriceInfosAndMinAmounts bool) { coinMarketCapClient = new(client.MockPricingClient) tokenPriceInfoMutex = new(sync.RWMutex) minAmountsForApiMutex = new(sync.RWMutex) - nftFeesForApiMutex = new(sync.RWMutex) diamondRouters = map[uint64]validatorClient.DiamondRouter{ testConstants.PolygonNetworkId: mocks.MDiamondRouter, testConstants.EthereumNetworkId: mocks.MDiamondRouter, @@ -370,12 +302,6 @@ func setup(setupMocks bool, setTokenPriceInfosAndMinAmounts bool) { mocks.MAssetsService.On("FungibleAssetInfo", testConstants.EthereumNetworkId, testConstants.NetworkEthereumFungibleWrappedTokenForNetworkHedera).Return(testConstants.NetworkEthereumFungibleWrappedTokenForNetworkHederaFungibleAssetInfo, true) mocks.MAssetsService.On("NativeToWrapped", constants.Hbar, constants.HederaNetworkId, testConstants.PolygonNetworkId).Return(testConstants.NetworkPolygonFungibleWrappedTokenForNetworkHedera) mocks.MAssetsService.On("FungibleAssetInfo", testConstants.PolygonNetworkId, testConstants.NetworkPolygonFungibleWrappedTokenForNetworkHedera).Return(testConstants.NetworkPolygonFungibleWrappedTokenForNetworkHederaFungibleAssetInfo, true) - mocks.MAssetsService.On("NonFungibleNetworkAssets").Return(testConstants.NonFungibleNetworkAssets) - mocks.MAssetsService.On("NonFungibleAssetInfo", testConstants.PolygonNetworkId, testConstants.NetworkPolygonWrappedNonFungibleTokenForHedera).Return(testConstants.NetworkPolygonWrappedNonFungibleTokenForHederaNonFungibleAssetInfo, true) - mocks.MAssetsService.On("NonFungibleAssetInfo", testConstants.EthereumNetworkId, testConstants.NetworkEthereumNFTWrappedTokenForNetworkHedera).Return(testConstants.NetworkEthereumFungibleWrappedTokenForNetworkHederaFungibleAssetInfo, true) - mocks.MAssetsService.On("NonFungibleAssetInfo", constants.HederaNetworkId, testConstants.NetworkHederaNonFungibleNativeToken).Return(testConstants.NetworkHederaNonFungibleNativeTokenNonFungibleAssetInfo, true) - mocks.MDiamondRouter.On("Erc721Payment", &bind.CallOpts{}, common.HexToAddress(testConstants.NetworkPolygonWrappedNonFungibleTokenForHedera)).Return(common.HexToAddress(testConstants.NftFeesForApi[testConstants.PolygonNetworkId][testConstants.NetworkPolygonWrappedNonFungibleTokenForHedera].PaymentToken), nil) - mocks.MDiamondRouter.On("Erc721Fee", &bind.CallOpts{}, common.HexToAddress(testConstants.NetworkPolygonWrappedNonFungibleTokenForHedera)).Return(big.NewInt(testConstants.NftFeesForApi[testConstants.PolygonNetworkId][testConstants.NetworkPolygonWrappedNonFungibleTokenForHedera].Fee.IntPart()), nil) } var ( @@ -402,18 +328,13 @@ func setup(setupMocks bool, setTokenPriceInfosAndMinAmounts bool) { coinMarketCapClient: coinMarketCapClient, tokenPriceInfoMutex: tokenPriceInfoMutex, minAmountsForApiMutex: minAmountsForApiMutex, - nftFeesForApiMutex: nftFeesForApiMutex, coinMarketCapIds: test_config.TestConfig.Bridge.CoinMarketCapIds, coinGeckoIds: test_config.TestConfig.Bridge.CoinGeckoIds, tokensPriceInfo: tokensPriceInfo, minAmountsForApi: minAmountsForApi, hbarFungibleAssetInfo: testConstants.NetworkHederaFungibleNativeTokenFungibleAssetInfo, hbarNativeAsset: testConstants.NetworkHederaFungibleNativeAsset, - hederaNftDynamicFees: testConstants.HederaNftDynamicFees, - hederaNftFees: testConstants.HederaNftFees, - hederaNftPrevFees: make(map[string]int64), diamondRouters: diamondRouters, - nftFeesForApi: testConstants.NftFeesForApi, logger: config.GetLoggerFor("Pricing Service"), } diff --git a/app/services/read-only/service.go b/app/services/read-only/service.go index 2b53c5c55..664d418c0 100644 --- a/app/services/read-only/service.go +++ b/app/services/read-only/service.go @@ -19,8 +19,6 @@ package read_only import ( "time" - "github.com/limechain/hedera-eth-bridge-validator/app/process/payload" - "github.com/hashgraph/hedera-sdk-go/v2" mirrorNodeTransaction "github.com/limechain/hedera-eth-bridge-validator/app/clients/hedera/mirror-node/model/transaction" "github.com/limechain/hedera-eth-bridge-validator/app/domain/client" @@ -123,119 +121,6 @@ func (s Service) FindAssetTransfer( } } -func (s Service) FindScheduledNftAllowanceApprove( - t *payload.Transfer, - sender hedera.AccountID, - save func(transactionID, scheduleID, status string) error) { - transferID := t.TransactionId - for { - txs, err := s.mirrorNode.GetTransactionsAfterTimestamp(sender, t.Timestamp.UnixNano(), CryptoApproveAllowance) - if err != nil { - s.logger.Errorf("[%s] - Failed to get transactions after timestamp. Error: [%s]", transferID, err) - continue - } - - finished := false - for _, tx := range txs { - scheduledTx, err := s.mirrorNode.GetScheduledTransaction(tx.TransactionID) - if err != nil { - s.logger.Errorf("[%s] - Failed to retrieve scheduled transaction [%s]. Error: [%s]", transferID, tx.TransactionID, err) - continue - } - - found := false - for _, tx := range scheduledTx.Transactions { - if tx.Result == hedera.StatusSuccess.String() { - schedule, err := s.mirrorNode.GetSchedule(tx.EntityId) - if err != nil { - s.logger.Errorf("[%s] - Failed to get scheduled entity [%s]. Error: [%s]", transferID, schedule, err) - break - } - if schedule.Memo == transferID { - found = true - } - } - - if found { - s.logger.Infof("[%s] - Found a corresponding transaction [%s], ScheduleID [%s].", transferID, tx.TransactionID, tx.EntityId) - finished = true - txStatus := status.Completed - success := tx.Result == hedera.StatusSuccess.String() - if !success { - txStatus = status.Failed - } - - err := save(tx.TransactionID, tx.EntityId, txStatus) - if err != nil { - s.logger.Errorf("[%s] - Failed to save entity [%s]. Error: [%s]", transferID, tx.EntityId, err) - break - } - break - } - } - } - if finished { - break - } - - s.logger.Tracef("[%s] - No transfers found.", transferID) - time.Sleep(s.pollingInterval * time.Second) - } -} - -func (s Service) FindNftTransfer( - transferID string, tokenID string, serialNum int64, sender string, receiver string, - save func(transactionID, scheduleID, status string) error) { - for { - response, err := s.mirrorNode.GetNftTransactions(tokenID, serialNum) - if err != nil { - s.logger.Errorf("[%s] - Failed to get nft transactions after timestamp. Error: [%s]", transferID, err) - continue - } - - finished := false - for _, transaction := range response.Transactions { - if transaction.Type == CryptoTransfer && - transaction.ReceiverAccountID == receiver && - transaction.SenderAccountID == sender { - - scheduledTx, err := s.mirrorNode.GetScheduledTransaction(transaction.TransactionID) - if err != nil { - s.logger.Errorf("[%s] - Failed to retrieve scheduled transaction [%s]. Error: [%s]", transferID, transaction.TransactionID, err) - continue - } - for _, tx := range scheduledTx.Transactions { - if tx.Result == hedera.StatusSuccess.String() { - scheduleID, err := s.mirrorNode.GetSchedule(tx.EntityId) - if err != nil { - s.logger.Errorf("[%s] - Failed to get scheduled entity [%s]. Error: [%s]", transferID, scheduleID, err) - break - } - if scheduleID.Memo == transferID { - s.logger.Infof("[%s] - Found a corresponding transaction [%s], ScheduleID [%s].", transferID, transaction.TransactionID, tx.EntityId) - finished = true - txStatus := status.Completed - - err := save(transaction.TransactionID, tx.EntityId, txStatus) - if err != nil { - s.logger.Errorf("[%s] - Failed to save entity [%s]. Error: [%s]", transferID, tx.EntityId, err) - break - } - - break - } - } - } - } - } - if finished { - break - } - - time.Sleep(s.pollingInterval * time.Second) - } -} - func (s Service) FindTransfer( transferID string, fetch func() (*mirrorNodeTransaction.Response, error), diff --git a/app/services/scheduled/service.go b/app/services/scheduled/service.go index e8ea69a99..d42661ae8 100644 --- a/app/services/scheduled/service.go +++ b/app/services/scheduled/service.go @@ -60,45 +60,6 @@ func (s *Service) ExecuteScheduledTransferTransaction( } } -// ExecuteScheduledNftTransferTransaction submits a scheduled nft transaction and executes provided functions when necessary -func (s *Service) ExecuteScheduledNftTransferTransaction( - id string, nftID hedera.NftID, sender hedera.AccountID, receiving hedera.AccountID, approved bool, - onExecutionSuccess func(transactionID, scheduleID string), onExecutionFail, onSuccess, onFail func(transactionID string)) { - transactionResponse, err := s.hederaNodeClient.SubmitScheduledNftTransferTransaction(nftID, s.payerAccount, sender, receiving, id, approved) - if err != nil { - if transactionResponse != nil { - onExecutionFail(hederahelper.ToMirrorNodeTransactionID(transactionResponse.TransactionID.String())) - s.logger.Errorf("[%s] - Failed to submit scheduled transfer transaction at Node Account [%s]. Error [%s].", id, transactionResponse.NodeID.String(), err) - } else { - s.logger.Errorf("[%s] - Failed to submit scheduled transfer transaction. Error [%s].", id, err) - } - return - } - err = s.createOrSignScheduledTransaction(transactionResponse, id, onExecutionSuccess, onExecutionFail, onSuccess, onFail) - if err != nil { - s.logger.Errorf("[%s] - Failed to create/sign scheduled transfer transaction. Error [%s].", id, err) - return - } -} - -func (s *Service) ExecuteScheduledNftAllowTransaction( - id string, nftID hedera.NftID, owner hedera.AccountID, spender hedera.AccountID, - onExecutionSuccess func(txId, scheduleId string), onExecutionFail, onSuccess, onFail func(txId string)) { - tx, err := s.hederaNodeClient.SubmitScheduledNftApproveTransaction(s.payerAccount, id, nftID, owner, spender) - if err != nil { - s.logger.Errorf("[%s] - Failed to submit scheduled nft approve transaction. Error [%s].", id, err) - if tx != nil { - onExecutionFail(hederahelper.ToMirrorNodeTransactionID(tx.TransactionID.String())) - } - return - } - err = s.createOrSignScheduledTransaction(tx, id, onExecutionSuccess, onExecutionFail, onSuccess, onFail) - if err != nil { - s.logger.Errorf("[%s] - Failed to create/sign scheduled nft approve transaction. Error [%s].", id, err) - return - } -} - func (s *Service) executeScheduledTransfersTransaction(id, nativeAsset string, transfers []transfer.Hedera) (*hedera.TransactionResponse, error) { var tokenID hedera.TokenID var transactionResponse *hedera.TransactionResponse diff --git a/app/services/transfers/service.go b/app/services/transfers/service.go index 3d843a6ae..c60b530af 100644 --- a/app/services/transfers/service.go +++ b/app/services/transfers/service.go @@ -23,7 +23,6 @@ import ( "math/big" "strconv" "strings" - "sync" "github.com/hashgraph/hedera-sdk-go/v2" mirrorNodeTransaction "github.com/limechain/hedera-eth-bridge-validator/app/clients/hedera/mirror-node/model/transaction" @@ -125,14 +124,6 @@ func (ts *Service) SanityCheckTransfer(tx mirrorNodeTransaction.Transaction) mod result.ChainId = chainId evmAddress := memoArgs[1] result.EvmAddress = evmAddress - if len(memoArgs) > 2 { - nftId, e := hedera.NftIDFromString(memoArgs[2]) - if e != nil { - result.Err = fmt.Errorf("[%s] - Could not parse NftId in transaction memo [%s]. Error: [%s]", tx.TransactionID, tx.MemoBase64, e) - return result - } - result.NftId = &nftId - } return result } @@ -196,60 +187,6 @@ func (ts *Service) ProcessNativeTransfer(tm payload.Transfer) error { return ts.submitTopicMessageAndWaitForTransaction(tm.TransactionId, signatureMessage) } -func (ts *Service) ProcessNativeNftTransfer(tm payload.Transfer) error { - ts.logger.Infof("[%s] - Sending NFT to bridge account.", tm.TransactionId) - status, wg, err := ts.transferNftToBridgeAccount(tm) - if err != nil { - return err - } - - wg.Wait() - if *status == syncHelper.DONE { - ts.logger.Debugf("[%s] - Proceeding to process fee transfer to validators and mint wrapped NFT.", tm.TransactionId) - } else { - ts.logger.Errorf("[%s] - Scheduled Transaction for NFT transfer failed.", tm.TransactionId) - return errors.New("failed-scheduled-nft-transfer") - } - - feePerValidator := ts.distributor.ValidAmount(tm.Fee) - go ts.processFeeTransfer(feePerValidator, tm.SourceChainId, tm.TargetChainId, tm.TransactionId, constants.Hbar) - - signatureMessage, err := ts.messageService.SignNftMessage(tm) - if err != nil { - return err - } - - return ts.submitTopicMessageAndWaitForTransaction(tm.TransactionId, signatureMessage) -} - -func (ts *Service) transferNftToBridgeAccount(tm payload.Transfer) (status *string, wg *sync.WaitGroup, err error) { - status = new(string) - wg = new(sync.WaitGroup) - wg.Add(1) - onExecutionSuccess, onExecutionFail := hederaHelper.ScheduledNftTxExecutionCallbacks(ts.transferRepository, ts.scheduleRepository, ts.logger, tm.TransactionId, true, status, schedule.TRANSFER, wg) - onSuccess, onFail := hederaHelper.ScheduledNftTxMinedCallbacks(ts.transferRepository, ts.scheduleRepository, ts.logger, tm.TransactionId, status, wg) - - token, err := hedera.TokenIDFromString(tm.SourceAsset) - if err != nil { - ts.logger.Errorf("[%s] - Failed to parse token [%s]. Error [%s].", tm.TransactionId, tm.TargetAsset, err) - return nil, nil, err - } - - nftID := hedera.NftID{ - TokenID: token, - SerialNumber: tm.SerialNum, - } - - sender, err := hedera.AccountIDFromString(tm.Originator) - if err != nil { - ts.logger.Errorf("[%s] - Failed to parse receiver [%s]. Error [%s].", tm.TransactionId, tm.Receiver, err) - return nil, nil, err - } - - ts.scheduledService.ExecuteScheduledNftTransferTransaction(tm.TransactionId, nftID, sender, ts.bridgeAccountID, true, onExecutionSuccess, onExecutionFail, onSuccess, onFail) - return status, wg, err -} - func (ts *Service) ProcessWrappedTransfer(tm payload.Transfer) error { amount, err := big_numbers.ToBigInt(tm.Amount) if err != nil { @@ -319,7 +256,6 @@ func (ts *Service) TransferData(txId string) (interface{}, error) { } transferData := service.TransferData{ - IsNft: t.IsNft, Recipient: t.Receiver, RouterAddress: ts.contractServices[t.TargetChainID].Address().String(), SourceChainId: t.SourceChainID, @@ -345,32 +281,25 @@ func (ts *Service) TransferData(txId string) (interface{}, error) { transferData.Signatures = signatures transferData.Majority = reachedMajority - if !t.IsNft { - signedAmount := t.Amount - if t.NativeChainID == constants.HederaNetworkId { - amount, err := strconv.ParseInt(t.Amount, 10, 64) - if err != nil { - ts.logger.Errorf("[%s] - Failed to parse transfer amount. Error [%s]", t.TransactionID, err) - return nil, err - } - - feeAmount, err := strconv.ParseInt(t.Fee, 10, 64) - if err != nil { - ts.logger.Errorf("[%s] - Failed to parse fee amount. Error [%s]", t.TransactionID, err) - return nil, err - } - signedAmount = strconv.FormatInt(amount-feeAmount, 10) + signedAmount := t.Amount + if t.NativeChainID == constants.HederaNetworkId { + amount, err := strconv.ParseInt(t.Amount, 10, 64) + if err != nil { + ts.logger.Errorf("[%s] - Failed to parse transfer amount. Error [%s]", t.TransactionID, err) + return nil, err + } + + feeAmount, err := strconv.ParseInt(t.Fee, 10, 64) + if err != nil { + ts.logger.Errorf("[%s] - Failed to parse fee amount. Error [%s]", t.TransactionID, err) + return nil, err } - return service.FungibleTransferData{ - TransferData: transferData, - Amount: signedAmount, - }, nil + signedAmount = strconv.FormatInt(amount-feeAmount, 10) } - return service.NonFungibleTransferData{ + return service.FungibleTransferData{ TransferData: transferData, - TokenId: t.SerialNumber, - Metadata: t.Metadata, + Amount: signedAmount, }, nil } diff --git a/app/services/utils/service.go b/app/services/utils/service.go index 1c8c9f61e..9cd510023 100644 --- a/app/services/utils/service.go +++ b/app/services/utils/service.go @@ -33,7 +33,6 @@ type utilsService struct { evmClients map[uint64]client.EVM burnEvt service.BurnEvent burnHash common.Hash - burnErc721Hash common.Hash lockHash common.Hash log log.FieldLogger } @@ -49,7 +48,6 @@ func New(evmClients map[uint64]client.EVM, burnEvt service.BurnEvent) *utilsServ evmClients: evmClients, burnEvt: burnEvt, burnHash: bridgeAbi.Events["Burn"].ID, - burnErc721Hash: bridgeAbi.Events["BurnERC721"].ID, lockHash: bridgeAbi.Events["Lock"].ID, log: config.GetLoggerFor("Utils Service"), } @@ -70,7 +68,7 @@ func (s *utilsService) ConvertEvmHashToBridgeTxId(txId string, chainId uint64) ( var txIdWithLogIndex string for _, l := range receipt.Logs { switch l.Topics[0] { - case s.burnHash, s.burnErc721Hash, s.lockHash: + case s.burnHash, s.lockHash: txIdWithLogIndex = fmt.Sprintf("%s-%d", txId, l.Index) goto finish } diff --git a/app/services/utils/service_test.go b/app/services/utils/service_test.go index 6db1e0500..b7a657af1 100644 --- a/app/services/utils/service_test.go +++ b/app/services/utils/service_test.go @@ -40,7 +40,6 @@ var ( svc *utilsService lockHash common.Hash burnHash common.Hash - burnErc721 common.Hash someHash common.Hash evmTx = "0xa83be7d95c58f57e11f5c27dedd963217d47bdeab897bc98f2f5410d9f6c0026" evmTxHash = common.HexToHash(evmTx) @@ -85,7 +84,6 @@ func setup() { routerAbi, _ := abi.JSON(strings.NewReader(router.RouterABI)) burnHash = routerAbi.Events["Burn"].ID lockHash = routerAbi.Events["Lock"].ID - burnErc721 = routerAbi.Events["BurnERC721"].ID svc = &utilsService{ evmClients: map[uint64]client.EVM{ @@ -93,7 +91,6 @@ func setup() { }, burnEvt: mocks.MBurnService, burnHash: burnHash, - burnErc721Hash: burnErc721, lockHash: lockHash, log: config.GetLoggerFor("Utils Service"), } @@ -135,18 +132,6 @@ func Test_ConvertEvmHashToBridgeTxId_BurnEvent(t *testing.T) { assert.Equal(t, expectedResult, actual) } -func Test_ConvertEvmHashToBridgeTxId_BurnErc721Event(t *testing.T) { - setup() - mockReceipt.Logs[3].Topics[0] = burnErc721 - mocks.MEVMClient.On("WaitForTransactionReceipt", evmTxHash).Return(mockReceipt, nil) - mocks.MBurnService.On("TransactionID", fmt.Sprintf("%s-4", evmTx)).Return(expectedBridgeTx, nil) - - actual, err := svc.ConvertEvmHashToBridgeTxId(evmTx, 80001) - - assert.Nil(t, err) - assert.Equal(t, expectedResult, actual) -} - func Test_ConvertEvmHashToBridgeTxId_WithErrorFromWaitForTransactionReceipt(t *testing.T) { setup() mocks.MEVMClient.On("WaitForTransactionReceipt", evmTxHash).Return(nil, mockErr) diff --git a/bootstrap/clients.go b/bootstrap/clients.go index 3cead7154..d12f6a7b7 100644 --- a/bootstrap/clients.go +++ b/bootstrap/clients.go @@ -25,7 +25,6 @@ import ( coin_market_cap "github.com/limechain/hedera-eth-bridge-validator/app/clients/coin-market-cap" "github.com/limechain/hedera-eth-bridge-validator/app/clients/evm" "github.com/limechain/hedera-eth-bridge-validator/app/clients/evm/contracts/router" - "github.com/limechain/hedera-eth-bridge-validator/app/clients/evm/contracts/werc721" "github.com/limechain/hedera-eth-bridge-validator/app/clients/evm/contracts/wtoken" "github.com/limechain/hedera-eth-bridge-validator/app/clients/hedera" mirrornode "github.com/limechain/hedera-eth-bridge-validator/app/clients/hedera/mirror-node" @@ -46,7 +45,6 @@ type Clients struct { CoinMarketCap client.Pricing RouterClients map[uint64]client.DiamondRouter EvmFungibleTokenClients map[uint64]map[string]client.EvmFungibleToken - EvmNFTClients map[uint64]map[string]client.EvmNft ClientsConfig config.Clients } @@ -61,7 +59,6 @@ func PrepareClients(clientsCfg config.Clients, bridgeEvmsCfgs map[uint64]config. CoinMarketCap: coin_market_cap.NewClient(clientsCfg.CoinMarketCap), RouterClients: InitRouterClients(bridgeEvmsCfgs, EvmClients), EvmFungibleTokenClients: InitEvmFungibleTokenClients(networks, EvmClients), - EvmNFTClients: InitEvmNftClients(networks, EvmClients), ClientsConfig: clientsCfg, } @@ -79,7 +76,6 @@ func bridgeCfgEventHandler(e event.Event, instance *Clients) error { } instance.EvmClients = InitEVMClients(instance.ClientsConfig, params.ParsedBridge.Networks) evmFungibleTokenClients := InitEvmFungibleTokenClients(params.ParsedBridge.Networks, instance.EvmClients) - evmNFTClients := InitEvmNftClients(params.ParsedBridge.Networks, instance.EvmClients) routerClients := InitRouterClients(params.Bridge.EVMs, instance.EvmClients) for networkId, ftClients := range evmFungibleTokenClients { _, ok := instance.EvmFungibleTokenClients[networkId] @@ -91,22 +87,11 @@ func bridgeCfgEventHandler(e event.Event, instance *Clients) error { } } - for networkId, nftClients := range evmNFTClients { - _, ok := instance.EvmNFTClients[networkId] - if !ok { - instance.EvmNFTClients[networkId] = make(map[string]client.EvmNft) - } - for key, nftClient := range nftClients { - instance.EvmNFTClients[networkId][key] = nftClient - } - } - for networkId, routerClient := range routerClients { instance.RouterClients[networkId] = routerClient } params.EvmFungibleTokenClients = evmFungibleTokenClients - params.EvmNFTClients = evmNFTClients params.RouterClients = routerClients return nil @@ -204,48 +189,4 @@ func InitEvmFungibleTokenClients(networks map[uint64]*parser.Network, evmClients } return tokenClients -} - -func InitEvmNftClients(networks map[uint64]*parser.Network, evmClients map[uint64]client.EVM) map[uint64]map[string]client.EvmNft { - tokenClients := make(map[uint64]map[string]client.EvmNft) - for networkId, network := range networks { - - if networkId != constants.HederaNetworkId { - if _, ok := tokenClients[networkId]; !ok { - tokenClients[networkId] = make(map[string]client.EvmNft) - } - } - - // Native Tokens - for nonFungibleTokenAddress, tokenInfo := range network.Tokens.Nft { - - if networkId != constants.HederaNetworkId { - tokenInstance, err := werc721.NewWerc721(common.HexToAddress(nonFungibleTokenAddress), evmClients[networkId]) - if err != nil { - log.Fatalf("Failed to initialize Native EvmFungibleToken Contract Instance at token address [%s]. Error [%s]", nonFungibleTokenAddress, err) - } - tokenClients[networkId][nonFungibleTokenAddress] = tokenInstance - } - - // Wrapped tokens - for wrappedNetworkId, wrappedTokenAddress := range tokenInfo.Networks { - if wrappedNetworkId == constants.HederaNetworkId { - continue - } - - if _, ok := tokenClients[wrappedNetworkId]; !ok { - tokenClients[wrappedNetworkId] = make(map[string]client.EvmNft) - } - - wrappedTokenInstance, err := werc721.NewWerc721(common.HexToAddress(wrappedTokenAddress), evmClients[wrappedNetworkId]) - if err != nil { - log.Fatalf("Failed to initialize Wrapped EvmFungibleToken Contract Instance at token address [%s]. Error [%s]", wrappedTokenAddress, err) - } - tokenClients[wrappedNetworkId][wrappedTokenAddress] = wrappedTokenInstance - } - } - - } - - return tokenClients -} +} \ No newline at end of file diff --git a/bootstrap/router.go b/bootstrap/router.go index 602c36c09..fda955302 100644 --- a/bootstrap/router.go +++ b/bootstrap/router.go @@ -21,7 +21,6 @@ import ( "github.com/limechain/hedera-eth-bridge-validator/app/router/assets" burn_event "github.com/limechain/hedera-eth-bridge-validator/app/router/burn-event" config_bridge "github.com/limechain/hedera-eth-bridge-validator/app/router/config-bridge" - "github.com/limechain/hedera-eth-bridge-validator/app/router/fees" "github.com/limechain/hedera-eth-bridge-validator/app/router/healthcheck" min_amounts "github.com/limechain/hedera-eth-bridge-validator/app/router/min-amounts" "github.com/limechain/hedera-eth-bridge-validator/app/router/transfer" @@ -44,7 +43,6 @@ func InitializeAPIRouter(services *Services, bridgeConfig *parser.Bridge, nodeCo apiRouter.AddV1Router(min_amounts.Route, min_amounts.NewRouter(services.Pricing)) apiRouter.AddV1Router(assets.Route, assets.NewRouter(bridgeConfig, services.Assets, services.Pricing)) apiRouter.AddV1Router(utils.Route, utils.NewRouter(services.Utils)) - apiRouter.AddV1Router(fees.Route, fees.NewRouter(services.Pricing)) apiRouter.AddV1Router(transfer_reset.Route, transfer_reset.NewRouter(services.transfers, services.Prometheus, nodeConfig)) apiRouter.AddV1Router(validator_version.Route, validator_version.NewRouter()) return apiRouter diff --git a/bootstrap/server.go b/bootstrap/server.go index 5f4143812..723b2242d 100644 --- a/bootstrap/server.go +++ b/bootstrap/server.go @@ -28,14 +28,10 @@ import ( mh "github.com/limechain/hedera-eth-bridge-validator/app/process/handler/message" message_submission "github.com/limechain/hedera-eth-bridge-validator/app/process/handler/message-submission" mint_hts "github.com/limechain/hedera-eth-bridge-validator/app/process/handler/mint-hts" - nfmh "github.com/limechain/hedera-eth-bridge-validator/app/process/handler/nft/fee-message" - nth "github.com/limechain/hedera-eth-bridge-validator/app/process/handler/nft/transfer" rbh "github.com/limechain/hedera-eth-bridge-validator/app/process/handler/read-only/burn" rfh "github.com/limechain/hedera-eth-bridge-validator/app/process/handler/read-only/fee" rfth "github.com/limechain/hedera-eth-bridge-validator/app/process/handler/read-only/fee-transfer" rmth "github.com/limechain/hedera-eth-bridge-validator/app/process/handler/read-only/mint-hts" - rnfmh "github.com/limechain/hedera-eth-bridge-validator/app/process/handler/read-only/nft/fee" - rnth "github.com/limechain/hedera-eth-bridge-validator/app/process/handler/read-only/nft/transfer" rthh "github.com/limechain/hedera-eth-bridge-validator/app/process/handler/read-only/transfer" bridge_config "github.com/limechain/hedera-eth-bridge-validator/app/process/watcher/bridge-config" "github.com/limechain/hedera-eth-bridge-validator/app/process/watcher/evm" @@ -62,11 +58,6 @@ func InitializeServerPairs(server *server.Server, services *Services, repositori // Read-only handlers registerReadOnlyHandlers(server, services, repositories, clients, configuration) - // Hedera Native Nft handlers - registerHederaNativeNFTHandlers(server, services, repositories, clients, configuration) - - // Hedera Native unlock Nft Handlers - registerHederaNativeUnlockNftHandlers(server, services, repositories, configuration) // Assets Watcher registerAssetsWatcher(server, services, configuration, clients) @@ -177,7 +168,6 @@ func registerAssetsWatcher(server *server.Server, services *Services, configurat clients.MirrorNode, configuration, clients.EvmFungibleTokenClients, - clients.EvmNFTClients, services.Assets)) } @@ -191,48 +181,12 @@ func registerPrometheusWatcher(server *server.Server, services *Services, config configuration, services.Prometheus, clients.EvmFungibleTokenClients, - clients.EvmNFTClients, services.Assets)) } else { log.Infoln("Monitoring is disabled. No metrics will be added.") } } -func registerHederaNativeUnlockNftHandlers(server *server.Server, services *Services, repositories *Repositories, configuration *config.Config) { - // HederaNftTransfer - server.AddHandler(constants.HederaNftTransfer, nth.NewHandler( - configuration.Bridge.Hedera.BridgeAccount, - repositories.Transfer, - repositories.Schedule, - services.transfers, - services.Scheduled)) - - // ReadOnlyHederaUnlockNftTransfer - server.AddHandler(constants.ReadOnlyHederaUnlockNftTransfer, rnth.NewHandler( - configuration.Bridge.Hedera.BridgeAccount, - configuration.Bridge.Hedera.PayerAccount, - repositories.Transfer, - repositories.Schedule, - services.ReadOnly, - services.transfers)) -} - -func registerHederaNativeNFTHandlers(server *server.Server, services *Services, repositories *Repositories, clients *Clients, configuration *config.Config) { - // HederaNativeNftTransfer - server.AddHandler(constants.HederaNativeNftTransfer, nfmh.NewHandler(services.transfers)) - - // ReadOnlyHederaNativeNftTransfer - server.AddHandler(constants.ReadOnlyHederaNativeNftTransfer, rnfmh.NewHandler( - repositories.Transfer, - repositories.Fee, - repositories.Schedule, - clients.MirrorNode, - configuration.Bridge.Hedera.BridgeAccount, - services.Distributor, - services.transfers, - services.ReadOnly)) -} - func registerReadOnlyHandlers(server *server.Server, services *Services, repositories *Repositories, clients *Clients, configuration *config.Config) { // ReadOnlyHederaTransfer server.AddHandler(constants.ReadOnlyHederaTransfer, rfth.NewHandler( diff --git a/bootstrap/services.go b/bootstrap/services.go index 87a8f7bc4..8164ce869 100644 --- a/bootstrap/services.go +++ b/bootstrap/services.go @@ -80,7 +80,6 @@ func PrepareServices(c *config.Config, parsedBridge *parser.Bridge, clients *Cli clients.RouterClients, clients.MirrorNode, clients.EvmFungibleTokenClients, - clients.EvmNFTClients, ) c.Bridge.LoadStaticMinAmountsForWrappedFungibleTokens(*parsedBridge, assetsService) diff --git a/bootstrap/watchers.go b/bootstrap/watchers.go index cb57fe32d..c1f72353a 100644 --- a/bootstrap/watchers.go +++ b/bootstrap/watchers.go @@ -77,7 +77,6 @@ func createAssetsWatcher( mirrorNode client.MirrorNode, configuration *config.Config, evmFungibleTokenClients map[uint64]map[string]client.EvmFungibleToken, - evmNonFungibleTokenClients map[uint64]map[string]client.EvmNft, assetsService service.Assets, ) *aw.Watcher { @@ -86,7 +85,6 @@ func createAssetsWatcher( mirrorNode, configuration.Bridge, evmFungibleTokenClients, - evmNonFungibleTokenClients, assetsService) } @@ -96,7 +94,6 @@ func createPrometheusWatcher( configuration *config.Config, prometheusService service.Prometheus, evmFungibleTokenClients map[uint64]map[string]client.EvmFungibleToken, - evmNonFungibleTokenClients map[uint64]map[string]client.EvmNft, assetsService service.Assets, ) *pw.Watcher { @@ -107,6 +104,5 @@ func createPrometheusWatcher( configuration.Bridge, prometheusService, evmFungibleTokenClients, - evmNonFungibleTokenClients, assetsService) } diff --git a/config/bridge.go b/config/bridge.go index c2017c76f..985ad5575 100644 --- a/config/bridge.go +++ b/config/bridge.go @@ -19,10 +19,6 @@ package config import ( "math/big" - "github.com/shopspring/decimal" - - log "github.com/sirupsen/logrus" - "github.com/limechain/hedera-eth-bridge-validator/app/domain/service" decimalHelper "github.com/limechain/hedera-eth-bridge-validator/app/helper/decimal" "github.com/limechain/hedera-eth-bridge-validator/config/parser" @@ -57,12 +53,9 @@ type BridgeHedera struct { Members []string Tokens map[string]HederaToken FeePercentages map[string]int64 - NftConstantFees map[string]int64 - NftDynamicFees map[string]decimal.Decimal } type HederaToken struct { - Fee int64 FeePercentage int64 MinFeeAmountInUsd string MinAmount *big.Int @@ -72,7 +65,6 @@ type HederaToken struct { func NewHederaTokenFromToken(token parser.Token) HederaToken { return HederaToken{ - Fee: token.Fee, FeePercentage: token.FeePercentage, MinFeeAmountInUsd: token.MinFeeAmountInUsd, MinAmount: token.MinAmount, @@ -122,13 +114,8 @@ func NewBridge(bridge parser.Bridge) *Bridge { Tokens: make(map[string]HederaToken), } - for name, tokenInfo := range networkInfo.Tokens.Nft { - config.Hedera.Tokens[name] = NewHederaTokenFromToken(tokenInfo) - } fees := LoadHederaFees(networkInfo.Tokens) config.Hedera.FeePercentages = fees.FungiblePercentages - config.Hedera.NftConstantFees = fees.ConstantNftFees - config.Hedera.NftDynamicFees = fees.DynamicNftFees } else { config.EVMs[networkId] = BridgeEvm{ RouterContractAddress: networkInfo.RouterContractAddress, @@ -190,29 +177,12 @@ func (b Bridge) LoadStaticMinAmountsForWrappedFungibleTokens(parsedBridge parser func LoadHederaFees(tokens parser.Tokens) (res struct { FungiblePercentages map[string]int64 - ConstantNftFees map[string]int64 - DynamicNftFees map[string]decimal.Decimal }) { res.FungiblePercentages = make(map[string]int64) - res.ConstantNftFees = make(map[string]int64) - res.DynamicNftFees = make(map[string]decimal.Decimal) for token, value := range tokens.Fungible { res.FungiblePercentages[token] = value.FeePercentage } - for token, value := range tokens.Nft { - if value.Fee != 0 { - res.ConstantNftFees[token] = value.Fee - log.Infof("Skipping fee amount in usd for [%s]", token) - continue - } - - feeAmount, err := decimalHelper.ParseAmount(value.FeeAmountInUsd) - if err != nil { - log.Fatalf("[%s] - Failed to parse fee amount in usd [%s]. Error: [%s]", token, value.MinFeeAmountInUsd, err) - } - res.DynamicNftFees[token] = *feeAmount - } return res } diff --git a/config/bridge_test.go b/config/bridge_test.go index 743cb29e9..8ef2b67cd 100644 --- a/config/bridge_test.go +++ b/config/bridge_test.go @@ -51,9 +51,6 @@ var ( hbarCoinMarketCapId = "4642" networkHederaFungibleNativeToken = constants.Hbar - // Non-Fungible - - networkHederaNFTNativeToken = "0.0.111122" networkHederaFungibleNativeTokenFungibleAssetInfo = &asset.FungibleAssetInfo{ Name: networkHederaFungibleNativeToken, @@ -109,12 +106,6 @@ var ( MinAmount: big.NewInt(1000000), }, }, - Nft: map[string]parser.Token{ - networkHederaNFTNativeToken: { - Networks: map[uint64]string{}, - Fee: feePercentage, - }, - }, }, }, ethereumNetworkId: { @@ -128,7 +119,6 @@ var ( MinFeeAmountInUsd: minFeeAmountInUsd.String(), }, }, - Nft: nil, }, }, } diff --git a/config/parser/bridge.go b/config/parser/bridge.go index 074d24614..e7e5b7c71 100644 --- a/config/parser/bridge.go +++ b/config/parser/bridge.go @@ -55,12 +55,9 @@ type Network struct { type Tokens struct { Fungible map[string]Token `yaml:"fungible,omitempty" json:"fungible,omitempty"` - Nft map[string]Token `yaml:"nft,omitempty" json:"nft,omitempty"` } type Token struct { - Fee int64 `yaml:"fee,omitempty" json:"fee,omitempty"` // Represent a constant fee for Non-Fungible tokens. Applies only for Hedera Native Tokens - FeeAmountInUsd string `yaml:"fee_amount_in_usd,omitempty" json:"feeAmountInUsd,omitempty"` // Represent a dynamic fee amount in $USD for Non-Fungible tokens. Applies only for Hedera Native Tokens FeePercentage int64 `yaml:"fee_percentage,omitempty" json:"feePercentage,omitempty"` // Represents a constant fee for Fungible Tokens. Applies only for Hedera Native Tokens MinFeeAmountInUsd string `yaml:"min_fee_amount_in_usd,omitempty" json:"minFeeAmountInUsd,omitempty"` // Represents a constant minimum fee amount in USD which is needed for the validator not to be on a loss MinAmount *big.Int `yaml:"min_amount,omitempty" json:"minAmount,omitempty"` // Represents a constant for minimum amount which is used when there is no 'coin_gecko_id' or 'coin_market_cap_id' supplied in the config. diff --git a/constants/hedera.go b/constants/hedera.go index 63ee30485..47ac7ce49 100644 --- a/constants/hedera.go +++ b/constants/hedera.go @@ -33,8 +33,6 @@ const ( HederaTransferMessageSubmission = "HEDERA_TRANSFER_MSG_SUBMISSION" // NH -> WEVM HederaBurnMessageSubmission = "BURN_TOPIC_MSG_SUBMISSION" // WH -> NEVM HederaMintHtsTransfer = "HEDERA_MINT_HTS_TRANSFER" // NEVM -> WH - HederaNativeNftTransfer = "HEDERA_NATIVE_NFT_TRANSFER" // NH NFT -> WEVM - HederaNftTransfer = "HEDERA_NFT_TRANSFER" // WEVM NFT -> NH TopicMessageSubmission = "TOPIC_MSG_SUBMISSION" // WEVM -> WEVM TopicMessageValidation = "TOPIC_MSG_VALIDATION" // Messages coming from HCS Topic submission ) @@ -46,8 +44,6 @@ const ( ReadOnlyHederaBurn = "READ_ONLY_HEDERA_BURN" // WH -> NEVM ReadOnlyHederaMintHtsTransfer = "READ_ONLY_HEDERA_MINT_HTS_TRANSFER" // NEVM -> WH ReadOnlyTransferSave = "READ_ONLY_SAVE_TRANSFER" // WEVM -> WEVM - ReadOnlyHederaNativeNftTransfer = "READ_ONLY_HEDERA_NFT_TRANSFER" // NH NFT -> WEVM - ReadOnlyHederaUnlockNftTransfer = "READ_ONLY_HEDERA_UNLOCK_NFT_TRANSFER" // WEVM NFT -> NH ) const InvalidNodeAccount = "INVALID_NODE_ACCOUNT" diff --git a/constants/prometheus.go b/constants/prometheus.go index f0b0d5946..213a5e009 100644 --- a/constants/prometheus.go +++ b/constants/prometheus.go @@ -45,7 +45,6 @@ const ( AccountMetricLabelKey = "account_id" NameMetricLabelKey = "name" FungibleAddon = "Fungible" - NonFungibleAddon = "NonFungible" CreateDecimalPrefix = "1" CreateDecimalRepeat = "0" diff --git a/docs/api.md b/docs/api.md index 2eefc441e..9ba46546a 100644 --- a/docs/api.md +++ b/docs/api.md @@ -50,20 +50,6 @@ Example: } ``` -- `GET /fees/nft`: Returns the fees for porting/burning NFT assets grouped by network. Ex: -- ```json - { - "295": { - "tokenId or address": { - "isNative": true, - "paymentToken": "HBAR or address of the payment token", - "fee": "fee amount" - } - }, - ... - } - ``` - - `POST /transfer-reset`: Updates the stuck transfers to `COMPLETE` and `user_get_his_token` to 1 - ```bash curl --location --request POST 'http://localhost:9200/api/v1/transfer-reset' \ diff --git a/docs/configuration.md b/docs/configuration.md index 88d81ba27..fa1e11514 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -76,11 +76,6 @@ Configuration for `config/bridge.yml`: | `bridge.networks[i].tokens.fungible[j].coin_market_cap_id` | "" | CoinMarketCap id used for getting token info from the CoinMarketCap Web API | | `bridge.networks[i].tokens.fungible[j].min_amount` | "" | The static minimum amount for token used when there is no 'coin_gecko_id' and 'coin_market_cap_id' supplied for the token. | | `bridge.networks[i].tokens.fungible[j].release_timestamp` | 0 | The release timestamp to be returned from the api. | -| `bridge.networks[i].tokens.nft[j]` | "" | The Address/HBAR/Token ID of the native nft asset for the given network. Used as a key to for the following `bridge.networks[i].tokens.nft[j].*` configuration fields below. | -| `bridge.networks[i].tokens.nft[j].fee` | 0 | The HBAR fee (in tinybars), which validators take for every nft bridge transfer. Applies **only** for assets from Hedera networks. Default fee is 0, which is not supported. | -| `bridge.networks[i].tokens.nft[j].fee_amount_in_usd` | "" | The HBAR fee (in USD), which validators take for every nft bridge transfer. Applies **only** for assets from Hedera networks. Ignored if `bridge.networks[i].tokens.nft[j].fee` is provided. | -| `bridge.networks[i].tokens.nft[j].networks[k]` | "" | A key-value pair representing the id and wrapped asset to which the token `j` has a wrapped representation. Example: TokenID `0.0.2473688` (`j`) on Network `296` (`i`) has a wrapped version on `80001` (`k`), which is `0x95341E9cf3Bc3f69fEBfFC0E33E2B2EC14a6F969`. | -| `bridge.networks[i].tokens.nft[j].release_timestamp` | 0 | The release timestamp to be returned from the api. | Configuration for `.env`: diff --git a/docs/integration.md b/docs/integration.md index 9e880a1d5..1ee46c663 100644 --- a/docs/integration.md +++ b/docs/integration.md @@ -32,7 +32,6 @@ The response is in JSON format and contains the following data: ```json { - "isNft": false, "recipient": "0x700d8a76b37f672a06ab89fe1ec95acfba799f1c", "routerAddress": "0x", "amount": "100", @@ -49,7 +48,6 @@ The response is in JSON format and contains the following data: | Property | Description | |-------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| **isNft** | Whether the transfer is fungible or non-fungible | | **recipient** | EVM address of the receiver | | **routerAddress** | Address of the router contract | | **amount** | The transfer amount minus the services fee that is applied. If service fee is 1% and original transfer amount is 100 Hbars, the returned property will have 99 hbars. | @@ -315,7 +313,6 @@ The response is in JSON format and contains the following data: ```json { - "isNft": false, "recipient": "0x700d8a76b37f672a06ab89fe1ec95acfba799f1c", "routerAddress": "0x", "amount": "100", @@ -332,7 +329,6 @@ The response is in JSON format and contains the following data: | Property | Description | |-------------------|-------------------------------------------------------------------------| -| **isNft** | Whether the transfer is fungible or non-fungible | | **recipient** | EVM address of the receiver | | **routerAddress** | Address of the router contract | | **amount** | The burned amount | @@ -420,7 +416,6 @@ The response is in JSON format and contains the following data: ```json { - "isNft": false, "recipient": "0x700d8a76b37f672a06ab89fe1ec95acfba799f1c", "routerAddress": "0x", "amount": "100", @@ -437,7 +432,6 @@ The response is in JSON format and contains the following data: | Property | Description | |-------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| **isNft** | Whether the transfer is fungible or non-fungible | | **recipient** | EVM address of the receiver | | **routerAddress** | Address of the router contract | | **amount** | The transfer original transfer amount minus the services fee that is applied. If service fee is 1% and original transfer amount is 100 Hbars, the returned property will have 99 hbars. | @@ -596,7 +590,6 @@ where `burn_event_id` is the id of the Ethereum Burn event. It must be construct ```json { - "isNft": false, "recipient": "0x700d8a76b37f672a06ab89fe1ec95acfba799f1c", "routerAddress": "0x", "amount": "100", @@ -613,7 +606,6 @@ where `burn_event_id` is the id of the Ethereum Burn event. It must be construct | Property | Description | |-------------------|------------------------------------------------------------------------------| -| **isNft** | Whether the transfer is fungible or non-fungible | | **recipient** | EVM address of the receiver | | **routerAddress** | Address of the router contract | | **amount** | The transfer original transfer amount minus the services fee that is applied | @@ -635,162 +627,4 @@ The `unlock` operation can be constructed using the following arguments: | Argument | Description | |-------------------|------------------------| -| **transactionId** | `{TX-Hash}-{LogIndex}` | - -## NFT Transfers from Hedera to EVM -The steps below will showcase a bridge transfer from Hedera Native NFT to any EVM chain. - -### Step 1. Deposit Transaction - -In order to initiate transfer, user must submit `CryptoApproveAllowance` transaction for the given NFT, specifying the spender to be `Payer Account` of the bridge configuration. -Then to send a deposit transfer transaction for the `Bridge` flat fee and all the necessary `Royalty` (`Fallback Fee`) for the NFT asset to the `Bridge` Account -with memo in format `{targetChainId}-{receiverAddress}-{serial_number}@{token_id}`. -Similar to fungible transfers, the transfer **must** include a memo, in format `{targetChainId}-{receiverAddress}-{serialNumber}@{tokenId}`, where: - -* `targetChainId` - the chain id of the network to which the bridge transfer will go to. -* `receiverAddress` - the address to which the wrapped version of the NFT will be minted. -* `serialNumber` - the serial number of the transferred NFT to which the wrapped version of the NFT will be minted. -* `tokenId` - the token ID of the transferred NFT to which the wrapped version of the NFT will be minted. - - -Example of how to submit a `CryptoApproveAllowance` transaction for the `Payer Account` in Go using Hedera Go SDK: -```go -nftID, _ := hedera.NftIDFromString("11@0.0.15633470")// 11 - Hedera Token serial number, 0.0.15633470 - tokenID of the Hedera token -res, err := hedera.NewAccountAllowanceApproveTransaction(). - ApproveTokenNftAllowance( - nftID, - client.GetOperatorAccountID(), // The user's account ID - payerAccountID, // Payer's Account ID from the Bridge Config - ).Execute(client) -``` - -Example of how to submit a Deposit transaction to the Bridge account in Go using Hedera Go SDK: -```go -response, _ := hedera.NewTransferTransaction(). - SetTransactionMemo("80001-0x0000000000000000000000000000000000000002-11@0.0.15633470"). // 80001 - chainId of Polygon Mumbai Testnet, 0x0000000000000000000000000000000000000002 - receiver address, 11@0.0.15633470 - the NFT ID - AddHbarTransfer(bridgeAccount, hedera.HbarFrom(1, "hbar")). // Send the NFT bridge transfer fee to the bridge account (including the Royalty (Fallback Fee) in HBAR if the NFT has such in the Custom Fees) - AddHbarTransfer(client.GetOperatorAccountID(), hedera.HbarFrom(-1, "hbar")). // The negated transfer fee from the sender account (including the Royalty (Fallback Fee) in HBAR if the NFT has such in the Custom Fees) - Execute(client) -``` - -The corresponding `response.TransactionID` must be converted in the following format: `{accountID}-{validStartSeconds}-{validStartNanos}`. - -**Important: If** `validStartNanos` is **less** than 9 symbols, it has to be zero padded with `0` from the start, e.g. `14578` -> `000014578`. - -The transactionID is a unique identifier for the Bridge transfer operation and can be used to query the status of the Bridge transfer. - -### Step 2. Waiting for Signatures - -After the user has submitted the deposit transfer, he can begin to query a validator's API to see whether the necessary components for the transfer are met: - - GET {validator_url}/api/v1/transfers/{transaction_id} - -Where `transaction_id` is the Hedera `TransactionID` of the NFT transfer to the Bridge account. - -The response is in JSON format and contains the following data: - -```json -{ - "isNft": true, - "recipient": "0x700d8a76b37f672a06ab89fe1ec95acfba799f1c", - "routerAddress": "0x", - "sourceChainId": "", - "targetChainId": "", - "sourceAsset": "", - "nativeAsset": "", - "targetAsset": "", - "tokenId": "", - "metadata": "", - "signatures": [ - ], - "majority": false -} -``` - -| Property | Description | -|-------------------|-----------------------------------------------------------------------| -| **isNft** | Whether the transfer is fungible or non-fungible | -| **recipient** | EVM address of the receiver | -| **routerAddress** | Address of the router contract | -| **sourceChainId** | The chain ID from which the transfer has been initiated | -| **targetChainId** | The chain ID to which the transfer data and has to be submitted | -| **sourceAsset** | The asset from the source chain | -| **nativeAsset** | The native asset of the transferred asset | -| **targetAsset** | The target asset for the transfer | -| **tokenId** | The tokenId of the NFT | -| **metadata** | The metadata/tokenURI of the NFT | -| **signatures** | Array of all provided signatures by the validators | -| **majority** | True if supermajority is reached and the wrapped token may be claimed | - -### Step 3. Mint Wrapped Asset - -Once majority is reached, users can mint the _wrapped version_ of the NFT. In order to do that, users must submit a `mintERC721` transaction to the Bridge Router Contract. - -The mint operation can be constructed using the following arguments: - - mintERC721(uint256 sourceChainId, bytes transactionId, address targetAsset, uint256 tokenId, string metadata, address recipient, bytes[] signatures) - -| Argument | Description | -|-------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| **transactionId** | The Hedera `TransactionID` of the Deposit transaction. Converting the TX ID string to bytes for JS/TS: `Web3.utils.fromAscii(transactionId)` or `ethers.utils.toUtf8Bytes(transactionId)`. | -| **signatures** | Depending on the library chosen for EVM submission, it might be required to add to each signature a `0x` prefix. | - -## NFT Transfers from EVM back to Hedera -The steps below will showcase a bridge transfer of a wrapped NFT from any EVM back to Hedera. - -### Step 1. Burn the Wrapped NFT Asset -Wrapped NFT burn consists of the following actions: -* An ERC-20 fee for the ERC-721 is sent from the user to the Router contract. -* An ERC-721 tokenId is burnt from the user. - -Before user submits the burn transaction, two approvals will be needed: -* Approve ERC-20 bridge fee for Router contract: - * To find the ERC-721's ERC-20 fee token, call the router contract with the following method: - `const erc721PaymentTokenAddress = await routerContract.erc721Payment(address _wrappedERC721)`, [Router ABI](https://github.com/LimeChain/hashport-validator/blob/develop/app/clients/evm/contracts/router/diamond-router.go#L50). - * To find the ERC-721's required ERC-20 fee, call the router contract with the following method: - `const erc721Fee = await routerContract.erc721Fee(address _wrappedERC721)`, [Router ABI](https://github.com/LimeChain/hashport-validator/blob/develop/app/clients/evm/contracts/router/diamond-router.go#L50). - * Approve the Router contract with the ERC-20 token fee amount: - `await erc721PaymentTokenContract.approve(routerContractAddress, erc721Fee)` - A standard ERC-20 ABI can be used. -* Approve ERC-721 wrapped NFT for Router contract: - `await erc721Contract.approve(routerContractAddress, tokenId)` - A standard ERC-721 ABI can be used. -* Receiver of the native NFT **must** be manually or automatically associated with the given token on Hedera. - -Now that everything has been approved, users can execute a `burnERC721` transaction to the Router Contract. - - burnERC721(uint256 targetChainId, address erc721ContractAddress, uint256 tokenId, address paymentToken, uint256 fee, bytes receiver) - -| Argument | Description | -|---------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| **targetChainId** | The chain id of the Network to which the NFT is bridged. | -| **erc721ContractAddress** | The address of the wrapped ERC-721 Contract. | -| **tokenId** | The token ID to be bridged. | -| **paymentToken** | The address of the payment token. | -| **fee** | The fee amount for the bridge transfer. | -| **receiver** | The Account/Address to receive the native representation of the wrapped asset. If the transfer is to Hedera, the receiver must be encoded in the SDK `hedera.AccountID.toBytes()` protobuf format. | - -### Step 2. Find the corresponding transaction - GET {validator_url}/api/v1/events/{burn_erc721_id}/tx - -where `burn_erc721_id` is constructed in the following format: `{transactionHash}-{eventLogIndex}` - -| Argument | Description | -|---------------------|-----------------------------------------------------------------------| -| **transactionHash** | The transaction hash of the `burnERC721` transaction | -| **eventLogIndex** | The log index of the `BurnERC721` event from the transaction receipt. | - -### Step 3. Transfer the native Hedera NFT back to the user - -After the burn transaction has been mined, the NFT is approved for the user. Then, the user can submit a transfer transaction on Hedera to get it back. - -Example: - -```go -nftID := hedera.NftID{ - TokenID: tokenId, - SerialNumber: serialNum, -} -tx, err := hedera.NewTransferTransaction(). - AddApprovedNftTransfer(nftID, ownerAccId /* bridge account ID */, receiverAccId, true). - Execute(setupEnv.Clients.Hedera) -//... -``` \ No newline at end of file +| **transactionId** | `{TX-Hash}-{LogIndex}` | \ No newline at end of file diff --git a/docs/overview.md b/docs/overview.md index 1714fdfb6..5c76c0089 100644 --- a/docs/overview.md +++ b/docs/overview.md @@ -147,77 +147,3 @@ Each of the Validators sign the following authorisation message: Alice waits for a supermajority of the signatures. She can either watch the topic messages stream or fetch the data directly from Validator nodes. 6. **Unlocking the EVM native tokens** - Performed by the User Once supermajority is reached, Alice submits `unlock` transaction to the EVM chain. The transaction contains the raw data signed in the authorisation signatures, as-well as the signatures. The smart contract verifies the authenticity of the signatures, charges `service` fee and transfers the requested token to the specified `recipient` address. - -## Hedera Non-Fungible Native Assets - -### Hedera to EVM - -The transfer of NFT assets from Hedera to the EVM chain is described in the following sequence diagram. -
-
-
-
-