From 36abaecf6804b16fff07b595b0ebbde4978c73d2 Mon Sep 17 00:00:00 2001 From: tj327 Date: Wed, 20 Dec 2023 07:34:42 -0500 Subject: [PATCH 01/25] implement metamask send & eip712 signed transactions --- config/constants.go | 9 + gateway/kira/main.go | 2 + gateway/kira/metamask/cosmosaccountinfo.go | 31 + gateway/kira/metamask/cosmosblockinfo.go | 162 +++ gateway/kira/metamask/cosmostxinfo.go | 120 ++ gateway/kira/metamask/cosmostxsender.go | 1381 ++++++++++++++++++++ gateway/kira/metamask/ethtxgenerator.go | 112 ++ gateway/kira/metamask/ethtxinfo.go | 88 ++ gateway/kira/metamask/metamask.go | 335 +++++ gateway/kira/metamask/utils.go | 174 +++ go.mod | 6 + go.sum | 4 + 12 files changed, 2424 insertions(+) create mode 100644 gateway/kira/metamask/cosmosaccountinfo.go create mode 100644 gateway/kira/metamask/cosmosblockinfo.go create mode 100644 gateway/kira/metamask/cosmostxinfo.go create mode 100644 gateway/kira/metamask/cosmostxsender.go create mode 100644 gateway/kira/metamask/ethtxgenerator.go create mode 100644 gateway/kira/metamask/ethtxinfo.go create mode 100644 gateway/kira/metamask/metamask.go create mode 100644 gateway/kira/metamask/utils.go diff --git a/config/constants.go b/config/constants.go index 5870ab0..e29fb07 100755 --- a/config/constants.go +++ b/config/constants.go @@ -5,6 +5,15 @@ const ( SekaiVersion = "v0.3.38" CosmosVersion = "v0.47.5" + DefaultChainID = 8789 + DefaultKiraAddrPrefix = "kira" + DefaultKiraValAddrPrefix = "kiravaloper" + DefaultKiraDenom = "ukex" + + // TODO: change endpoint to api/kira/evm + MetamaskEndpoint = "/api/k/evm" + RegisterAddrEndpoint = "/api/kira/evm/register_address/{eth_addr}{cosmos_addr}" + QueryDashboard = "/api/dashboard" QueryAccounts = "/api/kira/accounts/{address}" diff --git a/gateway/kira/main.go b/gateway/kira/main.go index 4992465..ee4c5bf 100644 --- a/gateway/kira/main.go +++ b/gateway/kira/main.go @@ -1,6 +1,7 @@ package kira import ( + "github.com/KiraCore/interx/gateway/kira/metamask" "github.com/gorilla/mux" "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" ) @@ -18,4 +19,5 @@ func RegisterRequest(router *mux.Router, gwCosmosmux *runtime.ServeMux, rpcAddr RegisterKiraSpendingRoutes(router, gwCosmosmux, rpcAddr) RegisterKiraUbiRoutes(router, gwCosmosmux, rpcAddr) RegisterKiraMultiStakingRoutes(router, gwCosmosmux, rpcAddr) + metamask.RegisterKiraMetamaskRoutes(router, gwCosmosmux, rpcAddr) } diff --git a/gateway/kira/metamask/cosmosaccountinfo.go b/gateway/kira/metamask/cosmosaccountinfo.go new file mode 100644 index 0000000..351fdce --- /dev/null +++ b/gateway/kira/metamask/cosmosaccountinfo.go @@ -0,0 +1,31 @@ +package metamask + +import ( + "net/http" + + "github.com/KiraCore/interx/common" + interxtypes "github.com/KiraCore/interx/types" + "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" +) + +func GetAccountInfo(params EthGetTransactionCount, gwCosmosmux *runtime.ServeMux, r *http.Request) (uint64, uint64, error) { + bech32Addr, err := hex2bech32(params.From, TypeKiraAddr) + if err != nil { + return 0, 0, err + } + + accountNumber, sequence := common.GetAccountNumberSequence(gwCosmosmux, r, bech32Addr) + + return accountNumber, sequence, nil +} + +func GetBalance(params EthGetBalanceParams, gwCosmosmux *runtime.ServeMux, r *http.Request) []interxtypes.Coin { + bech32Addr, err := hex2bech32(params.From, TypeKiraAddr) + if err != nil { + return nil + } + + balances := common.GetAccountBalances(gwCosmosmux, r.Clone(r.Context()), bech32Addr) + + return balances +} diff --git a/gateway/kira/metamask/cosmosblockinfo.go b/gateway/kira/metamask/cosmosblockinfo.go new file mode 100644 index 0000000..0fc2471 --- /dev/null +++ b/gateway/kira/metamask/cosmosblockinfo.go @@ -0,0 +1,162 @@ +package metamask + +import ( + "crypto/sha256" + "encoding/base64" + "encoding/hex" + "encoding/json" + "fmt" + "strconv" + "strings" + "time" + + "github.com/KiraCore/interx/common" + types "github.com/cometbft/cometbft/proto/tendermint/types" +) + +const ( + BlockQueryByNumber = iota + BLockQueryByHash +) + +type PartSetHeader struct { + Total uint32 `json:"total,omitempty"` + Hash []byte `json:"hash,omitempty"` +} + +type BlockID struct { + Hash string `json:"hash,omitempty"` + PartSetHeader PartSetHeader `json:"part_set_header"` +} + +type Consensus struct { + Block uint64 `json:"block,string,omitempty"` + App uint64 `json:"app,string,omitempty"` +} + +type Header struct { + // basic block info + Version Consensus `json:"version"` + ChainID string `json:"chain_id,omitempty"` + Height int64 `json:"height,string,omitempty"` + Time time.Time `json:"time"` + // prev block info + LastBlockId types.BlockID `json:"last_block_id"` + // hashes of block data + LastCommitHash string `json:"last_commit_hash,omitempty"` + DataHash string `json:"data_hash,omitempty"` + // hashes from the app output from the prev block + ValidatorsHash string `json:"validators_hash,omitempty"` + NextValidatorsHash string `json:"next_validators_hash,omitempty"` + ConsensusHash string `json:"consensus_hash,omitempty"` + AppHash string `json:"app_hash,omitempty"` + LastResultsHash string `json:"last_results_hash,omitempty"` + // consensus info + EvidenceHash string `json:"evidence_hash,omitempty"` + // proposer_address is the original block proposer address, formatted as a Bech32 string. + // In Tendermint, this type is `bytes`, but in the SDK, we convert it to a Bech32 string + // for better UX. + ProposerAddress string `json:"proposer_address,omitempty"` +} + +type Commit struct { + Height int64 `json:"height,string,omitempty"` + Round int32 `json:"round,omitempty"` + BlockID BlockID `json:"block_id"` + Signatures []types.CommitSig `json:"signatures"` +} + +type Data struct { + // Txs that will be applied by state @ block.Height+1. + // NOTE: not all txs here are valid. We're just agreeing on the order first. + // This means that block.AppHash does not include these txs. + Txs []string `protobuf:"bytes,1,rep,name=txs,proto3" json:"txs,omitempty"` +} + +type Block struct { + Header Header `json:"header"` + Data Data `json:"data"` + Evidence types.EvidenceList `json:"evidence"` + LastCommit Commit `json:"last_commit,omitempty"` +} + +type CosmosBlockInfo struct { + BlockId BlockID `json:"block_id,omitempty"` + // Since: cosmos-sdk 0.47 + SdkBlock Block `json:"block,omitempty"` +} + +func GetBlockNumber(rpcAddr string) (int, error) { + sentryStatus := common.GetKiraStatus((rpcAddr)) + currentHeight, err := strconv.Atoi(sentryStatus.SyncInfo.LatestBlockHeight) + return currentHeight, err +} + +func GetBlockByNumberOrHash(blockParam string, rpcAddr string, queryType int) (CosmosBlockInfo, []string, interface{}) { + var responseData, blockErr interface{} + var statusCode int + if queryType == BlockQueryByNumber { + var blockNum int64 + var err error + if strings.Contains(blockParam, "0x") { + blockNum, err = hex2int64(blockParam) + } else { + blockNum, err = strconv.ParseInt(blockParam, 10, 64) + } + if err != nil { + return CosmosBlockInfo{}, nil, err + } + + responseData, blockErr, statusCode = queryBlockByHeight(rpcAddr, strconv.Itoa(int(blockNum))) + } else if queryType == BLockQueryByHash { + if !strings.Contains(blockParam, "0x") { + blockParam = "0x" + blockParam + } + responseData, blockErr, statusCode = queryBlockByHash(rpcAddr, blockParam) + } + if blockErr != nil { + return CosmosBlockInfo{}, nil, blockErr + } + + if statusCode != 200 { + return CosmosBlockInfo{}, nil, fmt.Errorf("request faield, status code - %d", statusCode) + } + + jsonData, err := json.Marshal(responseData) + if err != nil { + return CosmosBlockInfo{}, nil, err + } + + response := CosmosBlockInfo{} + err = json.Unmarshal(jsonData, &response) + if err != nil { + return CosmosBlockInfo{}, nil, err + } + + txhashes := []string{} + txs := response.SdkBlock.Data.Txs + for _, txStr := range txs { + txBz, err := base64.StdEncoding.DecodeString(txStr) + if err != nil { + return CosmosBlockInfo{}, nil, err + } + converted := []byte(txBz) + hasher := sha256.New() + hasher.Write(converted) + txhashes = append(txhashes, "0x"+hex.EncodeToString(hasher.Sum(nil))) + } + + return response, txhashes, nil +} + +func queryBlockByHeight(rpcAddr string, height string) (interface{}, interface{}, int) { + success, err, statusCode := common.MakeTendermintRPCRequest(rpcAddr, "/block", fmt.Sprintf("height=%s", height)) + + return success, err, statusCode +} + +func queryBlockByHash(rpcAddr string, height string) (interface{}, interface{}, int) { + success, err, statusCode := common.MakeTendermintRPCRequest(rpcAddr, "/block_by_hash", fmt.Sprintf("hash=%s", height)) + + return success, err, statusCode +} diff --git a/gateway/kira/metamask/cosmostxinfo.go b/gateway/kira/metamask/cosmostxinfo.go new file mode 100644 index 0000000..82869a8 --- /dev/null +++ b/gateway/kira/metamask/cosmostxinfo.go @@ -0,0 +1,120 @@ +package metamask + +import ( + "encoding/json" + "fmt" + "strings" + + "github.com/KiraCore/interx/common" +) + +// Attribute is a struct that represents an attribute in the JSON data +type Attribute struct { + Key string `json:"key"` + Value string `json:"value"` +} + +// Event is a struct that represents an event in the JSON data +type Event struct { + Type string `json:"type"` + Attributes []Attribute `json:"attributes"` +} + +// Msg is a struct that represents a message in the JSON data +type LogInfo struct { + MsgIndex int `json:"msg_index"` + Events []Event `json:"events"` +} + +// map[msgIndex][event_type][attribute_key] +type LogInfoForMap struct { + LogInfo map[int]map[string]map[string]string +} + +type Log struct { + logForMap map[int]LogInfoForMap + logForString string +} + +type TxInfo struct { + Hash string `json:"hash"` + Height string `json:"height"` + Index int `json:"index"` + TxResult struct { + Code int `json:"code"` + Data string `json:"data"` + Log string `json:"log"` + Info string `json:"info"` + GasWanted string `json:"gas_wanted"` + GasUsed string `json:"gas_used"` + Events []struct { + Type string `json:"type"` + Attributes []struct { + Key string `json:"key"` + Value string `json:"value"` + Index bool `json:"index"` + } `json:"attributes"` + } `json:"events"` + Codespace string `json:"codespace"` + } `json:"tx_result"` + Tx string `json:"tx"` +} + +func GetTxInfo(txHash string, rpcAddr string) (TxInfo, Log, interface{}) { + responseData, err, statusCode := queryTxByHash(rpcAddr, txHash) + logResult := Log{} + + if err != nil { + return TxInfo{}, logResult, err + } + + if statusCode != 200 { + return TxInfo{}, logResult, fmt.Errorf("request faield, status code - %d", statusCode) + } + + jsonData, err := json.Marshal(responseData) + if err != nil { + return TxInfo{}, logResult, err + } + + response := TxInfo{} + err = json.Unmarshal(jsonData, &response) + if err != nil { + return TxInfo{}, logResult, err + } + + var logInfos []LogInfo + + // Unmarshal the JSON data to the msgs slice + err = json.Unmarshal([]byte(response.TxResult.Log), &logInfos) + logResult.logForString = response.TxResult.Log + if err != nil { + return response, logResult, nil + } + + logInfosForMap := map[int]LogInfoForMap{} + for i, logInfo := range logInfos { + logInfosForMap[i] = LogInfoForMap{LogInfo: make(map[int]map[string]map[string]string)} + for _, event := range logInfo.Events { + if logInfosForMap[i].LogInfo[logInfo.MsgIndex] == nil { + logInfosForMap[i].LogInfo[logInfo.MsgIndex] = make(map[string]map[string]string) + } + if logInfosForMap[i].LogInfo[logInfo.MsgIndex][event.Type] == nil { + logInfosForMap[i].LogInfo[logInfo.MsgIndex][event.Type] = make(map[string]string) + } + for _, attribute := range event.Attributes { + logInfosForMap[i].LogInfo[logInfo.MsgIndex][event.Type][attribute.Key] = attribute.Value + } + } + } + + logResult.logForMap = logInfosForMap + return response, logResult, nil +} + +func queryTxByHash(rpcAddr string, hash string) (interface{}, interface{}, int) { + if !strings.HasPrefix(hash, "0x") { + hash = "0x" + hash + } + return common.MakeTendermintRPCRequest(rpcAddr, "/tx", fmt.Sprintf("hash=%s", hash)) +} diff --git a/gateway/kira/metamask/cosmostxsender.go b/gateway/kira/metamask/cosmostxsender.go new file mode 100644 index 0000000..c883605 --- /dev/null +++ b/gateway/kira/metamask/cosmostxsender.go @@ -0,0 +1,1381 @@ +package metamask + +import ( + "bytes" + "context" + "encoding/hex" + "encoding/json" + "errors" + "fmt" + "math" + "math/big" + "net/http" + "time" + + sdkmath "cosmossdk.io/math" + "github.com/KiraCore/interx/common" + "github.com/KiraCore/interx/config" + tx "github.com/KiraCore/interx/proto-gen/cosmos/tx/v1beta1" + custodytypes "github.com/KiraCore/sekai/x/custody/types" + evidencetypes "github.com/KiraCore/sekai/x/evidence/types" + customgovtypes "github.com/KiraCore/sekai/x/gov/types" + multistakingtypes "github.com/KiraCore/sekai/x/multistaking/types" + slashingtypes "github.com/KiraCore/sekai/x/slashing/types" + spendingtypes "github.com/KiraCore/sekai/x/spending/types" + tokenstypes "github.com/KiraCore/sekai/x/tokens/types" + clienttx "github.com/cosmos/cosmos-sdk/client/tx" + cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" + cosmostypes "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/tx/signing" + xauthsigning "github.com/cosmos/cosmos-sdk/x/auth/signing" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + ethcommon "github.com/ethereum/go-ethereum/common" + "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" + "google.golang.org/grpc" +) + +const ( + MsgBankSend = iota + // customgov + MsgSubmitEvidence + MsgSubmitProposal + MsgVoteProposal + MsgRegisterIdentityRecords + MsgDeleteIdentityRecord + MsgRequestIdentityRecordsVerify + MsgHandleIdentityRecordsVerifyRequest + MsgCancelIdentityRecordsVerifyRequest + MsgSetNetworkProperties + MsgSetExecutionFee + MsgClaimCouncilor + MsgWhitelistPermissions + MsgBlacklistPermissions + MsgCreateRole + MsgAssignRole + MsgUnassignRole + MsgWhitelistRolePermission + MsgBlacklistRolePermission + MsgRemoveWhitelistRolePermission + MsgRemoveBlacklistRolePermission + // staking + MsgClaimValidator + // tokens + MsgUpsertTokenAlias + MsgUpsertTokenRate + // slashing + MsgActivate + MsgPause + MsgUnpause + // spending + MsgCreateSpendingPool + MsgDepositSpendingPool + MsgRegisterSpendingPoolBeneficiary + MsgClaimSpendingPool + // multistaking + MsgUpsertStakingPool + MsgDelegate + MsgUndelegate + MsgClaimRewards + MsgClaimUndelegation + MsgSetCompoundInfo + MsgRegisterDelegator + // custody module + MsgCreateCustody + MsgAddToCustodyWhiteList + MsgAddToCustodyCustodians + MsgRemoveFromCustodyCustodians + MsgDropCustodyCustodians + MsgRemoveFromCustodyWhiteList + MsgDropCustodyWhiteList + MsgApproveCustodyTransaction + MsgDeclineCustodyTransaction +) + +var grpcConn *grpc.ClientConn + +func Decode256Bit(data *[]byte, params *[][]byte) { + *params = append(*params, (*data)[:32]) + *data = (*data)[32:] +} + +func DecodeString(data *[]byte, params *[][]byte) { + // offset := data[:32] // string value offset + *data = (*data)[32:] + + length, _ := bytes2uint64((*data)[:32]) + *data = (*data)[32:] + + *params = append(*params, (*data)[:length]) + *data = (*data)[(length/32+1)*32:] +} + +func DecodeStrings(data *[]byte, params *[][]byte, paramLen int) { + // remove offset of each string + *data = (*data)[32*paramLen:] + for i := 0; i < paramLen; i++ { + length, _ := bytes2uint64((*data)[:32]) + *data = (*data)[32:] + + *params = append(*params, (*data)[:length]) + *data = (*data)[(length/32+1)*32:] + } +} + +func DecodeStringArray(data *[]byte, params *[][]byte) { + // offset := data[:32] // string value offset + *data = (*data)[32:] + + length, _ := bytes2uint64((*data)[:32]) + *params = append(*params, (*data)[:32]) + *data = (*data)[32:] + + // remove offset of each string + *data = (*data)[32*length:] + for i := uint64(0); i < length; i++ { + length, _ := bytes2uint64((*data)[:32]) + *data = (*data)[32:] + + *params = append(*params, (*data)[:length]) + *data = (*data)[(length/32+1)*32:] + } +} + +func DecodeHexArray(data *[]byte, params *[][]byte) { + // offset := data[:32] // string value offset + *data = (*data)[32:] + + length, _ := bytes2uint64((*data)[:32]) + *data = (*data)[32:] + + *params = append(*params, (*data)[:length]) +} + +func DecodeParam(data []byte, txType int) [][]byte { + if txType == MsgBankSend { + return nil + } + + var params [][]byte + + // decode data field v, r, s, sender + for i := 0; i < 4; i++ { + Decode256Bit(&data, ¶ms) + } + + switch txType { + case MsgSubmitEvidence: // TODO: test + // height, power, time, consensusAddr + Decode256Bit(&data, ¶ms) + Decode256Bit(&data, ¶ms) + Decode256Bit(&data, ¶ms) + DecodeString(&data, ¶ms) + case MsgSubmitProposal: + case MsgVoteProposal: // TODO: test + // proposalID, option, slash + Decode256Bit(&data, ¶ms) + Decode256Bit(&data, ¶ms) + DecodeString(&data, ¶ms) + case MsgRegisterIdentityRecords: + // identityInfo, + DecodeString(&data, ¶ms) + case MsgDeleteIdentityRecord: + // len, keys + DecodeStringArray(&data, ¶ms) + case MsgRequestIdentityRecordsVerify: + // tip, verifier, recordIds + DecodeStrings(&data, ¶ms, 2) + + // recordIds + DecodeHexArray(&data, ¶ms) + case MsgHandleIdentityRecordsVerifyRequest: + // requestId, isApprove + Decode256Bit(&data, ¶ms) + Decode256Bit(&data, ¶ms) + case MsgCancelIdentityRecordsVerifyRequest: + // verifyRequestId + Decode256Bit(&data, ¶ms) + case MsgSetNetworkProperties: + // len, boolParamsList, len, uintParamsList, len, strParamsList, len, legacyDecParamsList + + // len, boolParamsList + DecodeHexArray(&data, ¶ms) + + // len, uintParamsList + DecodeHexArray(&data, ¶ms) + + // len, strParamsList + DecodeStringArray(&data, ¶ms) + + // len, legacyDecParamsList + DecodeStringArray(&data, ¶ms) + case MsgSetExecutionFee: + // executionFee, failureFee, timeout, defaultParams, transactionType + for i := 0; i < 4; i++ { + Decode256Bit(&data, ¶ms) + } + + // transactionType + DecodeString(&data, ¶ms) + case MsgClaimCouncilor: + // moniker string, username string, description string, social string, contact string, avatar string + DecodeStrings(&data, ¶ms, 6) + case MsgWhitelistPermissions: + // permission uint, controlledAddr address + Decode256Bit(&data, ¶ms) + DecodeString(&data, ¶ms) + case MsgBlacklistPermissions: + // permission uint, addr address + Decode256Bit(&data, ¶ms) + DecodeString(&data, ¶ms) + case MsgCreateRole: + // sid string, description string + DecodeString(&data, ¶ms) + DecodeString(&data, ¶ms) + case MsgAssignRole: + // roleid uint32, controller address + Decode256Bit(&data, ¶ms) + DecodeString(&data, ¶ms) + case MsgUnassignRole: + // roleid uint32, controller address + Decode256Bit(&data, ¶ms) + DecodeString(&data, ¶ms) + case MsgWhitelistRolePermission: + // permission uint32, roleIdentifier string + Decode256Bit(&data, ¶ms) + DecodeString(&data, ¶ms) + case MsgBlacklistRolePermission: + // permission uint32, roleIdentifier string + Decode256Bit(&data, ¶ms) + DecodeString(&data, ¶ms) + case MsgRemoveWhitelistRolePermission: + // permission uint32, roleIdentifier string + Decode256Bit(&data, ¶ms) + DecodeString(&data, ¶ms) + case MsgRemoveBlacklistRolePermission: + // permission uint32, roleIdentifier string + Decode256Bit(&data, ¶ms) + DecodeString(&data, ¶ms) + case MsgClaimValidator: + case MsgUpsertTokenAlias: + // invalidated bool, decimals uint32, symbol string, name string, icon string, len, denoms []string + Decode256Bit(&data, ¶ms) + Decode256Bit(&data, ¶ms) + DecodeStrings(&data, ¶ms, 3) + // denoms + DecodeStringArray(&data, ¶ms) + case MsgUpsertTokenRate: + // feePayments bool, stakeToken bool, invalidated bool, denom string, rate cosmostypes.Dec, + // stakeCap cosmostypes.Dec, stakeMin cosmostypes.Int + for i := 0; i < 3; i++ { + Decode256Bit(&data, ¶ms) + } + + DecodeStrings(&data, ¶ms, 4) + case MsgActivate: + case MsgPause: + case MsgUnpause: + case MsgCreateSpendingPool: + case MsgDepositSpendingPool: + // amount cosmostypes.Coins, name string + DecodeStrings(&data, ¶ms, 2) + case MsgRegisterSpendingPoolBeneficiary: + // name string + DecodeString(&data, ¶ms) + case MsgClaimSpendingPool: + // name string + DecodeString(&data, ¶ms) + case MsgUpsertStakingPool: + // enabled bool, validator string, commission cosmostypes.Dec + Decode256Bit(&data, ¶ms) + DecodeStrings(&data, ¶ms, 2) + case MsgDelegate: + // amount, validator + DecodeStrings(&data, ¶ms, 2) + case MsgUndelegate: + // amount, validator + DecodeStrings(&data, ¶ms, 2) + case MsgClaimRewards: + case MsgClaimUndelegation: + // undelegationId uint64 + Decode256Bit(&data, ¶ms) + case MsgSetCompoundInfo: + // allDenom bool, len, denoms []string + Decode256Bit(&data, ¶ms) + DecodeStringArray(&data, ¶ms) + case MsgRegisterDelegator: + case MsgCreateCustody: + // V, R, S, signer, custodyMode uint256, key string, nextController string, len, boolArr, len, strArr + for i := 0; i < 4; i++ { + Decode256Bit(&data, ¶ms) + } + + DecodeStrings(&data, ¶ms, 2) + + DecodeHexArray(&data, ¶ms) + DecodeStringArray(&data, ¶ms) + case MsgAddToCustodyWhiteList: + // oldKey string, newKey string, next string, target string, len, newAddr []string + DecodeStrings(&data, ¶ms, 4) + DecodeStringArray(&data, ¶ms) + case MsgAddToCustodyCustodians: + // oldKey string, newKey string, next string, target string, len, newAddr []string + DecodeStrings(&data, ¶ms, 4) + DecodeStringArray(&data, ¶ms) + case MsgRemoveFromCustodyCustodians: + // newAddr string, oldKey string, newKey string, next string, target string + DecodeStrings(&data, ¶ms, 5) + case MsgDropCustodyCustodians: + // oldKey string, newKey string, next string, target string + DecodeStrings(&data, ¶ms, 4) + case MsgRemoveFromCustodyWhiteList: + // newAddr string, oldKey string, newKey string, next string, target string + DecodeStrings(&data, ¶ms, 5) + case MsgDropCustodyWhiteList: + // oldKey string, newKey string, next string, target string + DecodeStrings(&data, ¶ms, 4) + case MsgApproveCustodyTransaction: + // to string, hash string + DecodeStrings(&data, ¶ms, 2) + case MsgDeclineCustodyTransaction: + // to string, hash string + DecodeStrings(&data, ¶ms, 2) + default: + + } + + return params +} + +func SendTx(txRawData string, gwCosmosmux *runtime.ServeMux, r *http.Request) (string, error) { + byteData, err := hex.DecodeString(txRawData[2:]) + if err != nil { + return "", err + } + + ethTxData, err := GetEthTxInfo(byteData) + + if err != nil { + return "", err + } + + var txBytes []byte + + submitEvidencePrefix, _ := hex.DecodeString("33104ff7") + submitProposalPrefix, _ := hex.DecodeString("00000000") + voteProposalPrefix, _ := hex.DecodeString("24d03a8b") + registerIdentityRecordsPrefix, _ := hex.DecodeString("bc05f106") + deleteIdentityRecordPrefix, _ := hex.DecodeString("2ac0ca03") + requestIdentityRecordsVerifyPrefix, _ := hex.DecodeString("f7c51612") + handleIdentityRecordsVerifyRequestPrefix, _ := hex.DecodeString("2facbfe8") + cancelIdentityRecordsVerifyRequestPrefix, _ := hex.DecodeString("9b66f097") + setNetworkPropertiesPrefix, _ := hex.DecodeString("3a91d2ba") + setExecutionFeePrefix, _ := hex.DecodeString("fa02785e") + claimCouncilorPrefix, _ := hex.DecodeString("9dd85dbf") + whitelistPermissionsPrefix, _ := hex.DecodeString("4db4bc0b") + blacklistPermissionsPrefix, _ := hex.DecodeString("675ed828") + createRolePrefix, _ := hex.DecodeString("7b0fadab") + assignRolePrefix, _ := hex.DecodeString("83b3d393") + unassignRolePrefix, _ := hex.DecodeString("2fa24c7a") + whitelistRolePermissionPrefix, _ := hex.DecodeString("557f0e63") + blacklistRolePermissionPrefix, _ := hex.DecodeString("7e7595fe") + removeWhitelistRolePermissionPrefix, _ := hex.DecodeString("e9830bd8") + removeBlacklistRolePermissionPrefix, _ := hex.DecodeString("45e2144c") + claimValidatorPrefix, _ := hex.DecodeString("00000000") + upsertTokenAliasPrefix, _ := hex.DecodeString("59122e45") + upsertTokenRatePrefix, _ := hex.DecodeString("fb7e4c17") + activatePrefix, _ := hex.DecodeString("a1374dc2") + pausePrefix, _ := hex.DecodeString("1371cf19") + unpausePrefix, _ := hex.DecodeString("b9179894") + createSpendingPoolPrefix, _ := hex.DecodeString("00000000") + depositSpendingPoolPrefix, _ := hex.DecodeString("9fff5508") + registerSpendingPoolBeneficiaryPrefix, _ := hex.DecodeString("7ab7eecf") + claimSpendingPoolPrefix, _ := hex.DecodeString("efeed4a0") + upsertStakingPoolPrefix, _ := hex.DecodeString("1f0da7b4") + delegatePrefix, _ := hex.DecodeString("4563230c") + undelegatePrefix, _ := hex.DecodeString("d8e05398") + claimRewardsPrefix, _ := hex.DecodeString("9e796524") + claimUndelegationPrefix, _ := hex.DecodeString("505b0330") + setCompoundInfoPrefix, _ := hex.DecodeString("fb1257e6") + registerDelegatorPrefix, _ := hex.DecodeString("99db185d") + createCustodyPrefix, _ := hex.DecodeString("d486e9de") + addToCustodyWhiteListPrefix, _ := hex.DecodeString("25d1857d") + addToCustodyCustodiansPrefix, _ := hex.DecodeString("9c4f31a9") + removeFromCustodyCustodiansPrefix, _ := hex.DecodeString("8ec62788") + dropCustodyCustodiansPrefix, _ := hex.DecodeString("07d33244") + removeFromCustodyWhiteListPrefix, _ := hex.DecodeString("b99abc7d") + dropCustodyWhiteListPrefix, _ := hex.DecodeString("4db07a4e") + approveCustodyTransactionPrefix, _ := hex.DecodeString("e6d41e78") + declineCustodyTransactionPrefix, _ := hex.DecodeString("21ebd09e") + + var msgType int + switch { + case ethTxData.Data == nil: + msgType = MsgBankSend + case bytes.Equal(ethTxData.Data[:4], delegatePrefix): + msgType = MsgDelegate + case bytes.Equal(ethTxData.Data[:4], undelegatePrefix): + msgType = MsgUndelegate + case bytes.Equal(ethTxData.Data[:4], submitEvidencePrefix): + msgType = MsgSubmitEvidence + case bytes.Equal(ethTxData.Data[:4], submitProposalPrefix): + msgType = MsgSubmitProposal + case bytes.Equal(ethTxData.Data[:4], voteProposalPrefix): + msgType = MsgVoteProposal + case bytes.Equal(ethTxData.Data[:4], registerIdentityRecordsPrefix): + msgType = MsgRegisterIdentityRecords + case bytes.Equal(ethTxData.Data[:4], deleteIdentityRecordPrefix): + msgType = MsgDeleteIdentityRecord + case bytes.Equal(ethTxData.Data[:4], requestIdentityRecordsVerifyPrefix): + msgType = MsgRequestIdentityRecordsVerify + case bytes.Equal(ethTxData.Data[:4], handleIdentityRecordsVerifyRequestPrefix): + msgType = MsgHandleIdentityRecordsVerifyRequest + case bytes.Equal(ethTxData.Data[:4], cancelIdentityRecordsVerifyRequestPrefix): + msgType = MsgCancelIdentityRecordsVerifyRequest + case bytes.Equal(ethTxData.Data[:4], setNetworkPropertiesPrefix): + msgType = MsgSetNetworkProperties + case bytes.Equal(ethTxData.Data[:4], setExecutionFeePrefix): + msgType = MsgSetExecutionFee + case bytes.Equal(ethTxData.Data[:4], claimCouncilorPrefix): + msgType = MsgClaimCouncilor + case bytes.Equal(ethTxData.Data[:4], whitelistPermissionsPrefix): + msgType = MsgWhitelistPermissions + case bytes.Equal(ethTxData.Data[:4], blacklistPermissionsPrefix): + msgType = MsgBlacklistPermissions + case bytes.Equal(ethTxData.Data[:4], createRolePrefix): + msgType = MsgCreateRole + case bytes.Equal(ethTxData.Data[:4], assignRolePrefix): + msgType = MsgAssignRole + case bytes.Equal(ethTxData.Data[:4], unassignRolePrefix): + msgType = MsgUnassignRole + case bytes.Equal(ethTxData.Data[:4], whitelistRolePermissionPrefix): + msgType = MsgWhitelistRolePermission + case bytes.Equal(ethTxData.Data[:4], blacklistRolePermissionPrefix): + msgType = MsgBlacklistRolePermission + case bytes.Equal(ethTxData.Data[:4], removeWhitelistRolePermissionPrefix): + msgType = MsgRemoveWhitelistRolePermission + case bytes.Equal(ethTxData.Data[:4], removeBlacklistRolePermissionPrefix): + msgType = MsgBlacklistRolePermission + case bytes.Equal(ethTxData.Data[:4], claimValidatorPrefix): + msgType = MsgClaimValidator + case bytes.Equal(ethTxData.Data[:4], upsertTokenAliasPrefix): + msgType = MsgUpsertTokenAlias + case bytes.Equal(ethTxData.Data[:4], upsertTokenRatePrefix): + msgType = MsgUpsertTokenRate + case bytes.Equal(ethTxData.Data[:4], activatePrefix): + msgType = MsgActivate + case bytes.Equal(ethTxData.Data[:4], pausePrefix): + msgType = MsgPause + case bytes.Equal(ethTxData.Data[:4], unpausePrefix): + msgType = MsgUnpause + case bytes.Equal(ethTxData.Data[:4], createSpendingPoolPrefix): + msgType = MsgCreateSpendingPool + case bytes.Equal(ethTxData.Data[:4], depositSpendingPoolPrefix): + msgType = MsgDepositSpendingPool + case bytes.Equal(ethTxData.Data[:4], registerSpendingPoolBeneficiaryPrefix): + msgType = MsgRegisterSpendingPoolBeneficiary + case bytes.Equal(ethTxData.Data[:4], claimSpendingPoolPrefix): + msgType = MsgClaimSpendingPool + case bytes.Equal(ethTxData.Data[:4], upsertStakingPoolPrefix): + msgType = MsgUpsertStakingPool + case bytes.Equal(ethTxData.Data[:4], claimRewardsPrefix): + msgType = MsgClaimRewards + case bytes.Equal(ethTxData.Data[:4], claimUndelegationPrefix): + msgType = MsgClaimUndelegation + case bytes.Equal(ethTxData.Data[:4], setCompoundInfoPrefix): + msgType = MsgSetCompoundInfo + case bytes.Equal(ethTxData.Data[:4], registerDelegatorPrefix): + msgType = MsgRegisterDelegator + case bytes.Equal(ethTxData.Data[:4], createCustodyPrefix): + msgType = MsgClaimSpendingPool + case bytes.Equal(ethTxData.Data[:4], addToCustodyWhiteListPrefix): + msgType = MsgAddToCustodyWhiteList + case bytes.Equal(ethTxData.Data[:4], addToCustodyCustodiansPrefix): + msgType = MsgAddToCustodyCustodians + case bytes.Equal(ethTxData.Data[:4], removeFromCustodyCustodiansPrefix): + msgType = MsgRemoveFromCustodyCustodians + case bytes.Equal(ethTxData.Data[:4], dropCustodyCustodiansPrefix): + msgType = MsgDropCustodyCustodians + case bytes.Equal(ethTxData.Data[:4], removeFromCustodyWhiteListPrefix): + msgType = MsgRemoveFromCustodyWhiteList + case bytes.Equal(ethTxData.Data[:4], dropCustodyWhiteListPrefix): + msgType = MsgDropCustodyWhiteList + case bytes.Equal(ethTxData.Data[:4], approveCustodyTransactionPrefix): + msgType = MsgApproveCustodyTransaction + case bytes.Equal(ethTxData.Data[:4], declineCustodyTransactionPrefix): + msgType = MsgDeclineCustodyTransaction + default: + return "", errors.New("no such functions") + } + + txBytes, err = SignTx(ethTxData, gwCosmosmux, r, msgType) + + if err != nil { + return "", err + } + + // if ethTxData + + txHash, err := sendTx(r.Context(), txBytes) + if err != nil { + return "", err + } + + return txHash, nil +} + +func ValidateEIP712Sign(v, r, s []byte, sender ethcommon.Address, amount int, transactionType int) bool { + // eip712DomainSeparator := crypto.Keccak256Hash( + // []byte("EIP712Domain(string name,string version,uint256 chainId)"), + // crypto.Keccak256([]byte("SetTest")), + // crypto.Keccak256([]byte("1")), + // intToBytes(config.DefaultChainID), + // ) + + // // Define the hash of the struct + // hashStruct := crypto.Keccak256Hash( + // []byte("delegate(uint amount, address sender)"), + // intToBytes(int64(amount)), + // sender.Bytes(), + // ) + + // // Define the final hash + // hash := crypto.Keccak256Hash( + // []byte("\x19\x01"), + // eip712DomainSeparator.Bytes(), + // hashStruct.Bytes(), + // ) + + // signature := append(append(r, s...), v...) + + // // Recover the public key from the signature + // pubKey, err := crypto.Ecrecover(hash.Bytes(), signature) + // if err != nil { + // return false + // } + + // // Derive the signer's address from the public key + // signerAddress := crypto.PubkeyToAddress(*pubKey) + + // if signerAddress != senderAddr { + // return false + // } + return true +} + +func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, txType int) ([]byte, error) { + // Create a new TxBuilder. + txBuilder := config.EncodingCg.TxConfig.NewTxBuilder() + + addr1, err := hex2bech32(ethTxData.From, TypeKiraAddr) + if err != nil { + return nil, err + } + cosmosAddr1, err := cosmostypes.AccAddressFromBech32(addr1) + if err != nil { + return nil, err + } + + params := DecodeParam(ethTxData.Data[4:], txType) + + var msg cosmostypes.Msg + + switch txType { + case MsgBankSend: + addr2, err := hex2bech32(ethTxData.To, TypeKiraAddr) + if err != nil { + return nil, err + } + cosmosAddr2, err := cosmostypes.AccAddressFromBech32(addr2) + if err != nil { + return nil, err + } + + balance := ethTxData.Value.Div(ðTxData.Value, big.NewInt(int64(math.Pow10(12)))) + msg = banktypes.NewMsgSend(cosmosAddr1, cosmosAddr2, + cosmostypes.NewCoins(cosmostypes.NewInt64Coin(config.DefaultKiraDenom, balance.Int64()))) + case MsgSubmitEvidence: + // V, R, S, signer, height, power, time, consensusAddr + from, err := bytes2cosmosAddr(params[3][12:]) + if err != nil { + return nil, err + } + + height, _ := bytes2int64(params[4]) + power, _ := bytes2int64(params[5]) + unixTime, _ := bytes2int64(params[6]) + + consensusAddr := string(params[7]) + + evidence := &evidencetypes.Equivocation{ + Height: height, + Power: power, + Time: time.UnixMicro(unixTime), + ConsensusAddress: consensusAddr, + } + + msg, err = evidencetypes.NewMsgSubmitEvidence(from, evidence) + if err != nil { + return nil, err + } + case MsgSubmitProposal: + // msg := customgovtypes.NewMsgSubmitProposal(from) + case MsgVoteProposal: + // V, R, S, signer, proposalID, option, slash + from, err := bytes2cosmosAddr(params[3][12:]) + if err != nil { + return nil, err + } + + proposalID, _ := bytes2uint64(params[4]) + option, _ := bytes2uint64(params[5]) + slash, _ := sdkmath.LegacyNewDecFromStr(string(params[6])) + + msg = customgovtypes.NewMsgVoteProposal(proposalID, from, customgovtypes.VoteOption(option), slash) + case MsgRegisterIdentityRecords: + // V, R, S, signer, identityInfo, + from, err := bytes2cosmosAddr(params[3][12:]) + if err != nil { + return nil, err + } + + var infosStr map[string]string + err = json.Unmarshal(params[4], &infosStr) + if err != nil { + return nil, err + } + + var infos []customgovtypes.IdentityInfoEntry + for key := range infosStr { + infos = append(infos, customgovtypes.IdentityInfoEntry{ + Key: key, + Info: infosStr[key], + }) + } + + msg = customgovtypes.NewMsgRegisterIdentityRecords(from, infos) + case MsgDeleteIdentityRecord: + // V, R, S, signer, len, keys, + from, err := bytes2cosmosAddr(params[3][12:]) + if err != nil { + return nil, err + } + + var keys []string + len, _ := bytes2uint64(params[4]) + for i := uint64(0); i < len; i++ { + keys = append(keys, string(params[5+i])) + } + + msg = customgovtypes.NewMsgDeleteIdentityRecords(from, keys) + case MsgRequestIdentityRecordsVerify: + // V, R, S, signer, tip, verifier, len, recordIds + from, err := bytes2cosmosAddr(params[3][12:]) + if err != nil { + return nil, err + } + + balance, err := cosmostypes.ParseCoinNormalized(string(params[4])) + if err != nil { + return nil, err + } + + verifier, err := string2cosmosAddr(params[5]) + if err != nil { + return nil, err + } + + var recordIds []uint64 + len, _ := bytes2int64(params[6]) + for i := 0; i < int(len); i++ { + recordId, _ := bytes2uint64(params[7+i]) + recordIds = append(recordIds, recordId) + } + + msg = customgovtypes.NewMsgRequestIdentityRecordsVerify(from, verifier, recordIds, balance) + case MsgHandleIdentityRecordsVerifyRequest: + // V, R, S, signer, requestId, isApprove + verifier, err := bytes2cosmosAddr(params[3][12:]) + if err != nil { + return nil, err + } + + isApprove := bytes2bool(params[5]) + requestId, _ := bytes2uint64(params[4]) + + msg = customgovtypes.NewMsgHandleIdentityRecordsVerifyRequest(verifier, requestId, isApprove) + case MsgCancelIdentityRecordsVerifyRequest: + // V, R, S, signer, verifyRequestId + executor, err := bytes2cosmosAddr(params[3][12:]) + if err != nil { + return nil, err + } + + verifyRequestId, _ := bytes2uint64(params[4]) + + msg = customgovtypes.NewMsgCancelIdentityRecordsVerifyRequest(executor, verifyRequestId) + case MsgSetNetworkProperties: + // V, R, S, signer, len, boolParamsList, len, uintParamsList, len, strParamsList, len, legacyDecParamsList + proposer, err := bytes2cosmosAddr(params[3][12:]) + if err != nil { + return nil, err + } + + var boolParams []bool + var uintParams []uint64 + var strParams []string + var legacyDecParams []sdkmath.LegacyDec + + boolLen, _ := bytes2uint64(params[4]) + for i := uint64(0); i < boolLen; i++ { + boolParams = append(boolParams, bytes2bool(params[5+i])) + } + + uintLen, _ := bytes2uint64(params[5+boolLen]) + for i := uint64(0); i < uintLen; i++ { + uintParam, _ := bytes2uint64(params[6+boolLen+i]) + uintParams = append(uintParams, uintParam) + } + + strLen, _ := bytes2uint64(params[6+boolLen+uintLen]) + for i := uint64(0); i < strLen; i++ { + strParams = append(strParams, string(params[7+boolLen+uintLen+i])) + } + + legacyDecLen, _ := bytes2uint64(params[7+boolLen+uintLen+strLen]) + for i := uint64(0); i < legacyDecLen; i++ { + legacyDecParam, _ := sdkmath.LegacyNewDecFromStr(string(params[8+boolLen+uintLen+strLen+i])) + legacyDecParams = append(legacyDecParams, legacyDecParam) + } + + networkProperties := customgovtypes.NetworkProperties{ + EnableForeignFeePayments: boolParams[0], + EnableTokenWhitelist: boolParams[1], + EnableTokenBlacklist: boolParams[2], + MinTxFee: uintParams[0], + MaxTxFee: uintParams[1], + VoteQuorum: uintParams[2], + MinimumProposalEndTime: uintParams[3], + ProposalEnactmentTime: uintParams[4], + MinProposalEndBlocks: uintParams[5], + MinProposalEnactmentBlocks: uintParams[6], + MaxMischance: uintParams[7], + MischanceConfidence: uintParams[8], + MinValidators: uintParams[9], + PoorNetworkMaxBankSend: uintParams[10], + UnjailMaxTime: uintParams[11], + MinIdentityApprovalTip: uintParams[12], + UbiHardcap: uintParams[13], + InflationPeriod: uintParams[14], + UnstakingPeriod: uintParams[15], + MaxDelegators: uintParams[16], + MinDelegationPushout: uintParams[17], + SlashingPeriod: uintParams[18], + MinCustodyReward: uintParams[19], + MaxCustodyBufferSize: uintParams[20], + MaxCustodyTxSize: uintParams[21], + AbstentionRankDecreaseAmount: uintParams[22], + MaxAbstention: uintParams[23], + MinCollectiveBond: uintParams[24], + MinCollectiveBondingTime: uintParams[25], + MaxCollectiveOutputs: uintParams[26], + MinCollectiveClaimPeriod: uintParams[27], + ValidatorRecoveryBond: uintParams[28], + MaxProposalTitleSize: uintParams[29], + MaxProposalDescriptionSize: uintParams[30], + MaxProposalPollOptionSize: uintParams[31], + MaxProposalPollOptionCount: uintParams[32], + MaxProposalReferenceSize: uintParams[33], + MaxProposalChecksumSize: uintParams[34], + MinDappBond: uintParams[35], + MaxDappBond: uintParams[36], + DappLiquidationThreshold: uintParams[37], + DappLiquidationPeriod: uintParams[38], + DappBondDuration: uintParams[39], + DappAutoDenounceTime: uintParams[40], + DappMaxMischance: uintParams[41], + DappInactiveRankDecreasePercent: uintParams[42], + MintingFtFee: uintParams[43], + MintingNftFee: uintParams[44], + UniqueIdentityKeys: strParams[0], + InactiveRankDecreasePercent: legacyDecParams[0], + ValidatorsFeeShare: legacyDecParams[1], + InflationRate: legacyDecParams[2], + MaxJailedPercentage: legacyDecParams[3], + MaxSlashingPercentage: legacyDecParams[4], + MaxAnnualInflation: legacyDecParams[5], + DappVerifierBond: legacyDecParams[6], + DappPoolSlippageDefault: legacyDecParams[7], + VetoThreshold: legacyDecParams[8], + } + + msg = customgovtypes.NewMsgSetNetworkProperties(proposer, &networkProperties) + case MsgSetExecutionFee: + // V, R, S, signer, executionFee, failureFee, timeout, defaultParams, transactionType + proposer, err := bytes2cosmosAddr(params[3][12:]) + executionFee, _ := bytes2uint64(params[4]) + failureFee, _ := bytes2uint64(params[5]) + timeout, _ := bytes2uint64(params[6]) + defaultParams, _ := bytes2uint64(params[7]) + if err != nil { + return nil, err + } + + msg = customgovtypes.NewMsgSetExecutionFee(string(params[8]), executionFee, failureFee, timeout, defaultParams, proposer) + case MsgClaimCouncilor: + // V, R, S, signer, moniker string, username string, description string, social string, contact string, avatar string + sender, err := bytes2cosmosAddr(params[3][12:]) + if err != nil { + return nil, err + } + + msg = customgovtypes.NewMsgClaimCouncilor(sender, string(params[4]), string(params[5]), string(params[6]), + string(params[7]), string(params[8]), string(params[9])) + case MsgWhitelistPermissions: + // V, R, S, signer, permission uint256, controlledAddr string + sender, err := bytes2cosmosAddr(params[3][12:]) + if err != nil { + return nil, err + } + + permission, _ := bytes2uint32(params[4]) + controlledAddr, err := string2cosmosAddr(params[5]) + if err != nil { + return nil, err + } + + msg = customgovtypes.NewMsgWhitelistPermissions(sender, controlledAddr, permission) + case MsgBlacklistPermissions: + // V, R, S, signer, permission uint256, controlledAddr string + sender, err := bytes2cosmosAddr(params[3][12:]) + if err != nil { + return nil, err + } + + permission, _ := bytes2uint32(params[4]) + controlledAddr, err := string2cosmosAddr(params[5]) + if err != nil { + return nil, err + } + + msg = customgovtypes.NewMsgBlacklistPermissions(sender, controlledAddr, permission) + case MsgCreateRole: + // V, R, S, signer, sid string, description string + sender, err := bytes2cosmosAddr(params[3][12:]) + if err != nil { + return nil, err + } + + msg = customgovtypes.NewMsgCreateRole(sender, string(params[4]), string(params[5])) + case MsgAssignRole: + // V, R, S, signer, roleid uint32, controller string + sender, err := bytes2cosmosAddr(params[3][12:]) + if err != nil { + return nil, err + } + + roleId, _ := bytes2uint32(params[4]) + controller, err := string2cosmosAddr(params[5]) + if err != nil { + return nil, err + } + + msg = customgovtypes.NewMsgAssignRole(sender, controller, roleId) + case MsgUnassignRole: + // V, R, S, signer, roleid uint32, controller address + sender, err := bytes2cosmosAddr(params[3][12:]) + if err != nil { + return nil, err + } + + roleId, _ := bytes2uint32(params[4]) + controller, err := string2cosmosAddr(params[5]) + if err != nil { + return nil, err + } + + msg = customgovtypes.NewMsgUnassignRole(sender, controller, roleId) + case MsgWhitelistRolePermission: + // V, R, S, signer, permission uint32, roleIdentifier string + sender, err := bytes2cosmosAddr(params[3][12:]) + if err != nil { + return nil, err + } + + permission, _ := bytes2uint32(params[4]) + + msg = customgovtypes.NewMsgWhitelistRolePermission(sender, string(params[5]), permission) + case MsgBlacklistRolePermission: + // V, R, S, signer, permission uint32, roleIdentifier string + sender, err := bytes2cosmosAddr(params[3][12:]) + if err != nil { + return nil, err + } + + permission, _ := bytes2uint32(params[4]) + + msg = customgovtypes.NewMsgBlacklistRolePermission(sender, string(params[5]), permission) + case MsgRemoveWhitelistRolePermission: + // V, R, S, signer, permission uint32, roleIdentifier string + sender, err := bytes2cosmosAddr(params[3][12:]) + if err != nil { + return nil, err + } + + permission, _ := bytes2uint32(params[4]) + + msg = customgovtypes.NewMsgRemoveWhitelistRolePermission(sender, string(params[5]), permission) + case MsgRemoveBlacklistRolePermission: + // V, R, S, signer, permission uint32, roleIdentifier string + sender, err := bytes2cosmosAddr(params[3][12:]) + if err != nil { + return nil, err + } + + permission, _ := bytes2uint32(params[4]) + + msg = customgovtypes.NewMsgRemoveBlacklistRolePermission(sender, string(params[5]), permission) + case MsgClaimValidator: + // V, R, S, signer, moniker string, valKey cosmostypes.ValAddress, pubKey cryptotypes.PubKey + + // valKey, err := cosmostypes.ValAddressFromBech32(string(params[5])) + // if err != nil { + // return nil, err + // } + + // TODO: get public key from str + // publicKey, err := secp256k1.PubKeySecp256k1([]byte(params[6])) + // msg, err := stakingtypes.NewMsgClaimValidator(string(params[4]), valKey, publicKey) + // if err != nil { + // return nil, err + // } + case MsgUpsertTokenAlias: + // V, R, S, signer, invalidated bool, decimals uint32, symbol string, name string, icon string, len, denoms []string + proposer, err := bytes2cosmosAddr(params[3][12:]) + if err != nil { + return nil, err + } + + isInvalidated := bytes2bool(params[4]) + decimals, _ := bytes2uint32(params[5]) + + var denoms []string + len, _ := bytes2int32(params[9]) + for i := int32(0); i < len; i++ { + denoms = append(denoms, string(params[i+10])) + } + + msg = tokenstypes.NewMsgUpsertTokenAlias(proposer, string(params[6]), string(params[7]), string(params[8]), + uint32(decimals), denoms, isInvalidated) + case MsgUpsertTokenRate: + // V, R, S, signer, feePayments bool, stakeToken bool, invalidated bool, denom string, rate cosmostypes.Dec, + // stakeCap cosmostypes.Dec, stakeMin cosmostypes.Int + proposer, err := bytes2cosmosAddr(params[3][12:]) + if err != nil { + return nil, err + } + + isFeePayments := bytes2bool(params[4]) + isStakeToken := bytes2bool(params[5]) + isInvalidated := bytes2bool(params[6]) + denom := string(params[7]) + rate, err := cosmostypes.NewDecFromStr(hex.EncodeToString(params[8])) + if err != nil { + return nil, err + } + stakeCap, err := cosmostypes.NewDecFromStr(hex.EncodeToString(params[9])) + if err != nil { + return nil, err + } + stakeMin, ok := cosmostypes.NewIntFromString(hex.EncodeToString(params[10])) + if !ok { + return nil, err + } + + msg = tokenstypes.NewMsgUpsertTokenRate(proposer, denom, rate, isFeePayments, stakeCap, stakeMin, + isStakeToken, isInvalidated) + case MsgActivate: + // V, R, S, signer + validator, err := bytes2cosmosValAddr(params[3][12:]) + if err != nil { + return nil, err + } + msg = slashingtypes.NewMsgActivate(validator) + case MsgPause: + // V, R, S, signer + validator, err := bytes2cosmosValAddr(params[3][12:]) + if err != nil { + return nil, err + } + msg = slashingtypes.NewMsgPause(validator) + case MsgUnpause: + // V, R, S, signer + validator, err := bytes2cosmosValAddr(params[3][12:]) + if err != nil { + return nil, err + } + msg = slashingtypes.NewMsgUnpause(validator) + case MsgCreateSpendingPool: + // V, R, S, signer, name string, claimStart uint64, claimEnd uint64, rates cosmostypes.DecCoins, voteQuorum uint64, + // votePeriod uint64, voteEnactment uint64, owners spendingtypes.PermInfo, beneficiaries spendingtypes.WeightedPermInfo, + // sender cosmostypes.AccAddress, dynamicRate bool, dynamicRatePeriod uint64 + + // msg = spendingtypes.NewMsgCreateSpendingPool() + case MsgDepositSpendingPool: + // V, R, S, signer, amount string, name string + sender, err := bytes2cosmosAddr(params[3][12:]) + if err != nil { + return nil, err + } + amount, err := cosmostypes.ParseCoinsNormalized(string(params[4])) + if err != nil { + return nil, err + } + + msg = spendingtypes.NewMsgDepositSpendingPool(string(params[5]), amount, sender) + case MsgRegisterSpendingPoolBeneficiary: + // V, R, S, signer, name string + sender, err := bytes2cosmosAddr(params[3][12:]) + if err != nil { + return nil, err + } + msg = spendingtypes.NewMsgRegisterSpendingPoolBeneficiary(string(params[4]), sender) + case MsgClaimSpendingPool: + // V, R, S, signer, name string + sender, err := bytes2cosmosAddr(params[3][12:]) + if err != nil { + return nil, err + } + msg = spendingtypes.NewMsgClaimSpendingPool(string(params[4]), sender) + case MsgUpsertStakingPool: + // V, R, S, signer, enabled bool, validator string, commission cosmostypes.Dec + from, err := hex2bech32(hex.EncodeToString(params[3][12:]), TypeKiraAddr) + if err != nil { + return nil, err + } + + enabled := bytes2bool(params[4]) + commission, err := cosmostypes.NewDecFromStr(string(params[5])) + if err != nil { + return nil, err + } + + msg = multistakingtypes.NewMsgUpsertStakingPool(from, string(params[5]), enabled, commission) + case MsgDelegate: + // TODO: check eip712 validation + // V, R, S, signer, amount, validator + // validateTx() + + balance, err := cosmostypes.ParseCoinsNormalized(string(params[4])) + if err != nil { + return nil, err + } + + from, err := hex2bech32(hex.EncodeToString(params[3][12:]), TypeKiraAddr) + if err != nil { + return nil, err + } + + to := string(params[5]) + + msg = multistakingtypes.NewMsgDelegate(from, to, balance) + case MsgUndelegate: + // V, R, S, signer, amount, validator + from, err := hex2bech32(hex.EncodeToString(params[3][12:]), TypeKiraAddr) + if err != nil { + return nil, err + } + balance, err := cosmostypes.ParseCoinsNormalized(string(params[4])) + if err != nil { + return nil, err + } + to := string(params[5]) + + msg = multistakingtypes.NewMsgUndelegate(from, to, balance) + case MsgClaimRewards: + // V, R, S, signer + from, err := hex2bech32(hex.EncodeToString(params[3][12:]), TypeKiraAddr) + if err != nil { + return nil, err + } + msg = multistakingtypes.NewMsgClaimRewards(from) + case MsgClaimUndelegation: + // V, R, S, signer, undelegationId uint64 + from, err := hex2bech32(hex.EncodeToString(params[3][12:]), TypeKiraAddr) + if err != nil { + return nil, err + } + undelegationId, _ := bytes2uint64(params[4]) + + msg = multistakingtypes.NewMsgClaimUndelegation(from, undelegationId) + case MsgSetCompoundInfo: + // V, R, S, signer, allDenom bool, len, denoms []string + from, err := hex2bech32(hex.EncodeToString(params[3][12:]), TypeKiraAddr) + if err != nil { + return nil, err + } + allDenom := bytes2bool(params[4]) + var denoms []string + len, _ := bytes2uint64(params[5]) + for i := uint64(0); i < len; i++ { + denoms = append(denoms, string(params[i+6])) + } + msg = multistakingtypes.NewMsgSetCompoundInfo(from, allDenom, denoms) + case MsgRegisterDelegator: + // V, R, S, signer + from, err := hex2bech32(hex.EncodeToString(params[3][12:]), TypeKiraAddr) + if err != nil { + return nil, err + } + + msg = multistakingtypes.NewMsgRegisterDelegator(from) + case MsgCreateCustody: + // V, R, S, signer, custodyMode uint256, key string, nextController string, len, boolArr, len, strArr + from, err := bytes2cosmosAddr(params[3][12:]) + if err != nil { + return nil, err + } + + custodyMode, _ := bytes2uint64(params[4]) + + var boolArr []bool + boolArrLen, _ := bytes2uint64(params[7]) + for i := uint64(0); i < boolArrLen; i++ { + boolParam := bytes2bool(params[i+8]) + boolArr = append(boolArr, boolParam) + } + + var strArr []string + strArrLen, _ := bytes2uint64(params[8+boolArrLen]) + for i := uint64(0); i < strArrLen; i++ { + param := string(params[i+9+boolArrLen]) + strArr = append(strArr, param) + } + + custodySettings := custodytypes.CustodySettings{ + CustodyEnabled: boolArr[0], + UsePassword: boolArr[1], + UseWhiteList: boolArr[2], + UseLimits: boolArr[3], + CustodyMode: custodyMode, + Key: string(params[5]), + NextController: string(params[6]), + } + msg = custodytypes.NewMsgCreateCustody(from, custodySettings, strArr[0], strArr[1], + strArr[2], strArr[3]) + case MsgAddToCustodyWhiteList: + // V, R, S, signer, oldKey string, newKey string, next string, target string + // len, newAddr []string, + from, err := bytes2cosmosAddr(params[3][12:]) + if err != nil { + return nil, err + } + var newAddrs []cosmostypes.AccAddress + len, _ := bytes2uint64(params[8]) + for i := uint64(0); i < len; i++ { + newddr, err := string2cosmosAddr(params[i+9]) + if err != nil { + return nil, err + } + newAddrs = append(newAddrs, newddr) + } + + msg = custodytypes.NewMsgAddToCustodyWhiteList(from, newAddrs, string(params[4]), string(params[5]), + string(params[6]), string(params[7])) + case MsgAddToCustodyCustodians: + // V, R, S, signer, oldKey string, newKey string, next string, target string + // len, newAddr []string + from, err := bytes2cosmosAddr(params[3][12:]) + if err != nil { + return nil, err + } + var newAddrs []cosmostypes.AccAddress + len, _ := bytes2uint64(params[8]) + for i := uint64(0); i < len; i++ { + newddr, err := string2cosmosAddr(params[i+9]) + if err != nil { + return nil, err + } + newAddrs = append(newAddrs, newddr) + } + + msg = custodytypes.NewMsgAddToCustodyCustodians(from, newAddrs, string(params[4]), string(params[5]), + string(params[6]), string(params[7])) + case MsgRemoveFromCustodyCustodians: + // V, R, S, signer, newAddr cosmostypes.AccAddress, + // oldKey string, newKey string, next string, target string + from, err := bytes2cosmosAddr(params[3][12:]) + if err != nil { + return nil, err + } + newAddr, err := string2cosmosAddr(params[4]) + if err != nil { + return nil, err + } + msg = custodytypes.NewMsgRemoveFromCustodyCustodians(from, newAddr, string(params[5]), string(params[6]), + string(params[7]), string(params[8])) + case MsgDropCustodyCustodians: + // V, R, S, signer + // oldKey string, newKey string, next string, target string + from, err := bytes2cosmosAddr(params[3][12:]) + if err != nil { + return nil, err + } + msg = custodytypes.NewMsgDropCustodyCustodians(from, string(params[4]), string(params[5]), + string(params[6]), string(params[7])) + case MsgRemoveFromCustodyWhiteList: + // V, R, S, signer, newAddr string, + // oldKey string, newKey string, next string, target string + from, err := bytes2cosmosAddr(params[3][12:]) + if err != nil { + return nil, err + } + newAddr, err := string2cosmosAddr(params[4]) + if err != nil { + return nil, err + } + msg = custodytypes.NewMsgRemoveFromCustodyWhiteList(from, newAddr, string(params[5]), string(params[6]), + string(params[7]), string(params[8])) + case MsgDropCustodyWhiteList: + // V, R, S, signer + // oldKey string, newKey string, next string, target string + from, err := bytes2cosmosAddr(params[3][12:]) + if err != nil { + return nil, err + } + msg = custodytypes.NewMsgDropCustodyWhiteList(from, string(params[4]), string(params[5]), + string(params[6]), string(params[7])) + case MsgApproveCustodyTransaction: + // V, R, S, signer, to string, hash string + from, err := bytes2cosmosAddr(params[3][12:]) + if err != nil { + return nil, err + } + to, err := string2cosmosAddr(params[4]) + if err != nil { + return nil, err + } + msg = custodytypes.NewMsgApproveCustodyTransaction(from, to, string(params[5])) + case MsgDeclineCustodyTransaction: + // V, R, S, signer, to string, hash string + from, err := bytes2cosmosAddr(params[3][12:]) + if err != nil { + return nil, err + } + to, err := string2cosmosAddr(params[4]) + if err != nil { + return nil, err + } + msg = custodytypes.NewMsgDeclineCustodyTransaction(from, to, string(params[5])) + } + err = txBuilder.SetMsgs(msg) + if err != nil { + return nil, err + } + txBuilder.SetGasLimit(ethTxData.GasLimit) + // TODO: set fee amount - how can I get the fee amount from eth transaction? or fix this? + txBuilder.SetFeeAmount(cosmostypes.NewCoins(cosmostypes.NewInt64Coin(config.DefaultKiraDenom, 200))) + // txBuilder.SetMemo() + // txBuilder.SetTimeoutHeight() + // txHash, err := sendTx(context.Background(), byteData) + + accNum, _ := common.GetAccountNumberSequence(gwCosmosmux, r, addr1) + + privs := []cryptotypes.PrivKey{config.Config.PrivKey} + accNums := []uint64{accNum} // The accounts' account numbers + accSeqs := []uint64{ethTxData.Nonce} // The accounts' sequence numbers + + // First round: gather all the signer infos + var sigsV2 []signing.SignatureV2 + for i, priv := range privs { + sigV2 := signing.SignatureV2{ + PubKey: priv.PubKey(), + Data: &signing.SingleSignatureData{ + SignMode: config.EncodingCg.TxConfig.SignModeHandler().DefaultMode(), + Signature: nil, + }, + Sequence: accSeqs[i], + } + + sigsV2 = append(sigsV2, sigV2) + } + + err = txBuilder.SetSignatures(sigsV2...) + if err != nil { + return nil, err + } + + interxStatus := common.GetInterxStatus("http://127.0.0.1:11000") + + // Second round: all signer infos are set, so each signer can sign. + sigsV2 = []signing.SignatureV2{} + for i, priv := range privs { + signerData := xauthsigning.SignerData{ + ChainID: interxStatus.InterxInfo.ChainID, + AccountNumber: accNums[i], + Sequence: accSeqs[i], + } + sigV2, err := clienttx.SignWithPrivKey( + config.EncodingCg.TxConfig.SignModeHandler().DefaultMode(), signerData, + txBuilder, priv, config.EncodingCg.TxConfig, accSeqs[i]) + if err != nil { + return nil, err + } + + sigsV2 = append(sigsV2, sigV2) + } + err = txBuilder.SetSignatures(sigsV2...) + if err != nil { + return nil, err + } + + txBytes, err := config.EncodingCg.TxConfig.TxEncoder()(txBuilder.GetTx()) + if err != nil { + return nil, err + } + + return txBytes, err +} + +func sendTx(ctx context.Context, txBytes []byte) (string, error) { + // --snip-- + + // Create a connection to the gRPC server. + if grpcConn == nil { + var err error + + grpcConn, err = grpc.Dial( + "127.0.0.1:9090", // Or your gRPC server address. + grpc.WithInsecure(), // The Cosmos SDK doesn't support any transport security mechanism. + ) + + if err != nil { + return "", err + } + + // defer grpcConn.Close() + } + + // Broadcast the tx via gRPC. We create a new client for the Protobuf Tx + // service. + txClient := tx.NewServiceClient(grpcConn) + // We then call the BroadcastTx method on this client. + grpcRes, err := txClient.BroadcastTx( + ctx, + &tx.BroadcastTxRequest{ + Mode: tx.BroadcastMode_BROADCAST_MODE_SYNC, + TxBytes: txBytes, // Proto-binary of the signed transaction, see previous step. + }, + ) + + if err != nil { + return "", err + } + + fmt.Println(grpcRes.TxResponse) + + if grpcRes.TxResponse.Code != 0 { + return "", errors.New(fmt.Sprintln("send tx failed - result code: ", grpcRes.TxResponse.Code)) + } + + return grpcRes.TxResponse.TxHash, nil +} diff --git a/gateway/kira/metamask/ethtxgenerator.go b/gateway/kira/metamask/ethtxgenerator.go new file mode 100644 index 0000000..1204d7d --- /dev/null +++ b/gateway/kira/metamask/ethtxgenerator.go @@ -0,0 +1,112 @@ +package metamask + +import ( + "math/big" + + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" +) + +// LogsBloom is a struct that represents a logsBloom field +type LogsBloom struct { + m int // size of the bit array + bits []bool // bit array +} + +// NewLogsBloom creates a new logsBloom field with the given size +func NewLogsBloom(m int) *LogsBloom { + return &LogsBloom{ + m: m, + bits: make([]bool, m), + } +} + +// hash is a helper function that hashes a byte slice using keccak256 algorithm +func hash(b []byte) []byte { + return crypto.Keccak256(b) +} + +// Add adds an element to the logsBloom field +func (lb *LogsBloom) Add(b []byte) { + h := hash(b) + for i := 0; i < 3; i++ { + // extract 11-bit segments from the first, third, and fifth 16-bit words of the hash + // https://github.com/ethereum/wiki/wiki/Design-Rationale#bloom-filter + seg := new(big.Int).SetBytes(h[i*2 : i*2+2]) + seg.Rsh(seg, uint(4-i)) + seg.And(seg, big.NewInt(2047)) + lb.bits[seg.Int64()] = true + } +} + +// Contains checks if an element is in the logsBloom field +func (lb *LogsBloom) Contains(b []byte) bool { + h := hash(b) + for i := 0; i < 3; i++ { + seg := new(big.Int).SetBytes(h[i*2 : i*2+2]) + seg.Rsh(seg, uint(4-i)) + seg.And(seg, big.NewInt(2047)) + if !lb.bits[seg.Int64()] { + return false + } + } + return true +} + +// Or performs a bitwise OR operation with another logsBloom field +func (lb *LogsBloom) Or(other *LogsBloom) { + for i := 0; i < lb.m; i++ { + lb.bits[i] = lb.bits[i] || other.bits[i] + } +} + +// CreateLogsBloomFromLogs creates a logsBloom field from a slice of ethereum tx logs +func CreateLogsBloomFromLogs(logs []*types.Log, m int) *LogsBloom { + lb := NewLogsBloom(m) + for _, log := range logs { + // add the topics and data to the logsBloom field + for _, topic := range log.Topics { + lb.Add(topic.Bytes()) + } + lb.Add(log.Data) + } + return lb +} + +func boolsToBytes(bools []bool) []byte { + bi := new(big.Int) // create a new big.Int + for i, b := range bools { + if b { + bi.SetBit(bi, i, 1) // set the ith bit to 1 + } + } + return bi.Bytes() // return the byte representation +} + +// func convertCosmosLog2EvmLog(logInfos []LogInfo) []types.Log { + +// var logs []types.Log + +// types.LegacyTx + +// for _, logInfo := range logInfos { +// log := &types.Log{ +// Address +// Topics: []common.Hash{ +// common.HexToHash("0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"), +// common.HexToHash("0x000000000000000000000000" + bech322hex(logInfo.Events[0].Attributes[1])), +// common.HexToHash("0x000000000000000000000000"), +// }, +// Data: common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000000"), +// } + +// logs = append(logs, *log) +// } +// } + +func GetLogsBloom(logs []*types.Log) []byte { + // create a logsBloom field from the log with 2048 bits + lb := CreateLogsBloomFromLogs(logs, 2048) + + return boolsToBytes(lb.bits) +} diff --git a/gateway/kira/metamask/ethtxinfo.go b/gateway/kira/metamask/ethtxinfo.go new file mode 100644 index 0000000..8c962e7 --- /dev/null +++ b/gateway/kira/metamask/ethtxinfo.go @@ -0,0 +1,88 @@ +package metamask + +import ( + "errors" + "log" + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + ethtypes "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/rlp" +) + +type EthTxData struct { + Nonce uint64 `json:"nonce"` + GasPrice big.Int `json:"gas_price"` + GasLimit uint64 `json:"gas_limit"` + From string `json:"from"` + To string `json:"to"` + Value big.Int `json:"value"` + Data []byte `json:"data"` + V big.Int `json:"signature_v"` + R big.Int `json:"signature_r"` + S big.Int `json:"signature_s"` +} + +func GetSenderAddrFromRawTxBytes(rawTxBytes []byte) (common.Address, error) { + var rawTx ethtypes.Transaction + if err := rlp.DecodeBytes(rawTxBytes, &rawTx); err != nil { + return common.Address{}, err + } + + signer := ethtypes.NewEIP155Signer(rawTx.ChainId()) + sender, err := signer.Sender(&rawTx) + if err != nil { + return common.Address{}, err + } + return sender, nil +} + +func validateTx(rawTxBytes []byte, sender common.Address) bool { + senderFromTx, err := GetSenderAddrFromRawTxBytes(rawTxBytes) + if err != nil { + return false + } + + if senderFromTx.Hex() == sender.Hex() { + return true + } + return false +} + +// SendRawTransaction send a raw Ethereum transaction. +func GetEthTxInfo(data hexutil.Bytes) (EthTxData, error) { + tx := new(ethtypes.Transaction) + rlp.DecodeBytes(data, &tx) + + msg, err := tx.AsMessage(ethtypes.NewEIP155Signer(tx.ChainId()), big.NewInt(1)) + if err != nil { + log.Fatal(err) + return EthTxData{}, errors.New("decoding transaction data is failed") + } + + v, r, s := tx.RawSignatureValues() + + // check the local node config in case unprotected txs are disabled + if !tx.Protected() { + // Ensure only eip155 signed transactions are submitted if EIP155Required is set. + return EthTxData{}, errors.New("only replay-protected (EIP-155) transactions allowed over RPC") + } + + if !validateTx(data, msg.From()) { + return EthTxData{}, errors.New("validation is failed") + } + + return EthTxData{ + Nonce: tx.Nonce(), + GasPrice: *tx.GasPrice(), + GasLimit: tx.Gas(), + From: msg.From().String(), + To: msg.To().String(), + Value: *tx.Value(), + Data: tx.Data(), + V: *v, + R: *r, + S: *s, + }, nil +} diff --git a/gateway/kira/metamask/metamask.go b/gateway/kira/metamask/metamask.go new file mode 100644 index 0000000..7348a3c --- /dev/null +++ b/gateway/kira/metamask/metamask.go @@ -0,0 +1,335 @@ +package metamask + +import ( + "encoding/hex" + "encoding/json" + "fmt" + "io" + "math" + "math/big" + "net/http" + + "github.com/KiraCore/interx/common" + "github.com/KiraCore/interx/config" + + "github.com/gorilla/mux" + "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" +) + +type EthMetamaskRequestBody struct { + ID interface{} `json:"id"` + Method string `json:"method"` + JsonRPC string `json:"jsonrpc"` + Params []interface{} `json:"params"` + // Add other fields from the request body if needed +} + +type EthMetamaskResponseBody struct { + ID interface{} `json:"id"` + JsonRPC string `json:"jsonrpc"` + Result interface{} `json:"result"` + // Add other fields from the request body if needed +} + +type EthEstimateGas struct { + From string `json:"from"` + Value string `json:"value"` + GasPrice string `json:"gasPrice"` + Data string `json:"data"` + To string `json:"to"` +} + +// balance of the account of given address +type EthGetBalanceParams struct { + From string + // integer block number, or the string "latest", "earliest" or "pending" + + // defaultBlock parameter: + // HEX String - an integer block number + // String "earliest" for the earliest/genesis block + // String "latest" - for the latest mined block + // String "safe" - for the latest safe head block + // String "finalized" - for the latest finalized block + // String "pending" - for the pending state/transactions + BlockNum string +} + +type EthGetBlockNumber struct { + BlockNum string + // If true it returns the full transaction objects, if false only the hashes of the transactions + Filter bool +} + +// number of transactions sent from an address. +type EthGetTransactionCount struct { + From string + // integer block number, or the string "latest", "earliest" or "pending" + BlockNum string +} + +func RegisterKiraMetamaskRoutes(r *mux.Router, gwCosmosmux *runtime.ServeMux, rpcAddr string) { + r.HandleFunc(config.MetamaskEndpoint, MetamaskRequestHandler(gwCosmosmux, rpcAddr)).Methods("POST") + // r.HandleFunc(config.RegisterAddrEndpoint, AddressRegisterHandler(gwCosmosmux, rpcAddr)).Methods("Get") + + common.AddRPCMethod("POST", config.MetamaskEndpoint, "This is an API to interact with metamask.", true) + // common.AddRPCMethod("POST", config.MetamaskEndpoint, "This is an API to interact with metamask.", true) +} + +func MetamaskRequestHandler(gwCosmosmux *runtime.ServeMux, rpcAddr string) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + byteData, err := io.ReadAll(r.Body) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + if r.Method != http.MethodPost { + http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) + return + } + + // Unmarshal the request body into a struct + var requestBody EthMetamaskRequestBody + err = json.Unmarshal(byteData, &requestBody) + if err != nil { + fmt.Println("unmarshal err:", err, byteData) + http.Error(w, "Failed to parse request body", http.StatusBadRequest) + return + } + + fmt.Println("eth method:", requestBody.Method) + // fmt.Println("eth params:", requestBody.Params) + + response := map[string]interface{}{ + "id": requestBody.ID, + "jsonrpc": requestBody.JsonRPC, + } + + var result interface{} + + switch requestBody.Method { + case "eth_chainId": + result = fmt.Sprintf("0x%x", config.DefaultChainID) + case "eth_getBalance": + params := EthGetBalanceParams{ + From: requestBody.Params[0].(string), + BlockNum: requestBody.Params[1].(string), + } + + balances := GetBalance(params, gwCosmosmux, r) + + result = "0x0" + if len(balances) > 0 { + for _, coin := range balances { + if coin.Denom == config.DefaultKiraDenom { + balance := new(big.Int) + balance.SetString(coin.Amount, 10) + balance = balance.Mul(balance, big.NewInt(int64(math.Pow10(12)))) + result = fmt.Sprintf("0x%x", balance) + } + } + } + case "eth_blockNumber": + currentHeight, err := GetBlockNumber(rpcAddr) + + if err != nil { + fmt.Println("eth_getBlockByNumber err:", err) + return + } + + result = fmt.Sprintf("0x%x", currentHeight) + case "net_version": + result = config.DefaultChainID + case "eth_getBlockByNumber": + blockNum := requestBody.Params[0].(string) + response, txs, err := GetBlockByNumberOrHash(blockNum, rpcAddr, BlockQueryByNumber) + if err != nil { + fmt.Println("eth_getBlockByNumber err:", err) + return + } + + result = map[string]interface{}{ + "extraData": "0x737061726b706f6f6c2d636e2d6e6f64652d3132", + "gasLimit": "0x1c9c380", + "gasUsed": "0x79ccd3", + "hash": "0x" + response.BlockId.Hash, + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "miner": "0x" + response.SdkBlock.Header.ProposerAddress, + // "mixHash": "0x3d1fdd16f15aeab72e7db1013b9f034ee33641d92f71c0736beab4e67d34c7a7", + // "nonce": "0x4db7a1c01d8a8072", + "number": "0x" + fmt.Sprintf("%x", response.SdkBlock.Header.Height), + "parentHash": "0x" + hex.EncodeToString(response.SdkBlock.Header.LastBlockId.Hash), + "receiptsRoot": "0x" + response.SdkBlock.Header.DataHash, + "size": "0x41c7", + "stateRoot": "0xddc8b0234c2e0cad087c8b389aa7ef01f7d79b2570bccb77ce48648aa61c904d", + "timestamp": fmt.Sprintf("0x%x", response.SdkBlock.Header.Time.UnixMilli()), + "totalDifficulty": "0x12ac11391a2f3872fcd", + "transactions": txs, + "transactionsRoot": "0x" + response.SdkBlock.Header.DataHash, + "sha3Uncles": "0x0000000000000000000000000000000000000000000000000000000000000000", + "uncles": []string{}, + } + case "eth_getBlockByHash": + blockHash := requestBody.Params[0].(string) + + response, txs, err := GetBlockByNumberOrHash(blockHash, rpcAddr, BLockQueryByHash) + if err != nil { + fmt.Println("eth_getBlockByNumber err:", err) + return + } + + result = map[string]interface{}{ + "extraData": "0x737061726b706f6f6c2d636e2d6e6f64652d3132", + "gasLimit": "0x1c9c380", + "gasUsed": "0x79ccd3", + "hash": "0x" + response.BlockId.Hash, + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "miner": "0x" + response.SdkBlock.Header.ProposerAddress, + // "mixHash": "0x3d1fdd16f15aeab72e7db1013b9f034ee33641d92f71c0736beab4e67d34c7a7", + // "nonce": "0x4db7a1c01d8a8072", + "number": "0x" + fmt.Sprintf("%x", response.SdkBlock.Header.Height), + "parentHash": "0x" + hex.EncodeToString(response.SdkBlock.Header.LastBlockId.Hash), + "receiptsRoot": "0x" + response.SdkBlock.Header.DataHash, + "size": "0x41c7", + "stateRoot": "0xddc8b0234c2e0cad087c8b389aa7ef01f7d79b2570bccb77ce48648aa61c904d", + "timestamp": fmt.Sprintf("0x%x", response.SdkBlock.Header.Time.UnixMilli()), + "totalDifficulty": "0x12ac11391a2f3872fcd", + "transactions": txs, + "transactionsRoot": "0x" + response.SdkBlock.Header.DataHash, + "sha3Uncles": "0x0000000000000000000000000000000000000000000000000000000000000000", + "uncles": []string{}, + } + + file, _ := json.MarshalIndent(result, "", " ") + fmt.Println("getblockbyhash:", string(file)) + case "eth_estimateGas": + var params EthEstimateGas + byteData, err := json.Marshal(requestBody.Params[0]) + if err != nil { + fmt.Println("Error:", err) + return + } + err = json.Unmarshal(byteData, ¶ms) + if err != nil { + fmt.Println("Error:", err) + return + } + result = "0x5cec" + case "eth_gasPrice": + result = "0x64" + case "eth_getCode": + result = "" + case "eth_getTransactionCount": + params := EthGetTransactionCount{ + From: requestBody.Params[0].(string), + BlockNum: requestBody.Params[1].(string), + } + + _, sequence, err := GetAccountInfo(params, gwCosmosmux, r) + if err != nil { + fmt.Println("eth_getTransactionCount err:", err) + return + } + + // TODO: check after token sending + result = fmt.Sprintf("0x%x", sequence) + case "eth_sendTransaction": + // var params EthSendTransaction + // byteData, err := json.Marshal(requestBody.Params[0]) + // if err != nil { + // fmt.Println("Error:", err) + // return + // } + // err = json.Unmarshal(byteData, ¶ms) + // if err != nil { + // fmt.Println("Error:", err) + // return + // } + // fmt.Println("eth_sendTransaction params:", params) + case "eth_sendRawTransaction": + fmt.Println("params:", requestBody.Params) + strData, ok := requestBody.Params[0].(string) + if !ok { + fmt.Println("eth_sendRawTransaction err: convert from interface{} to string failed") + return + } + + txHash, err := SendTx(strData, gwCosmosmux, r) + if err != nil { + fmt.Println("eth_sendRawTransaction err:", err) + return + } + + result = "0x" + txHash + + fmt.Println("sendrawtx:", result) + case "eth_getTransactionReceipt": + txHash := requestBody.Params[0].(string) + fmt.Println("eth_getTransactionReceipt", txHash) + txInfo, logInfos, err := GetTxInfo(txHash, rpcAddr) + var txStatus, txIndex int + blockInfo := CosmosBlockInfo{} + var fromAddr, toAddr string + + if err != nil { + txStatus = 0 + } else { + var txhashes []string + blockInfo, txhashes, err = GetBlockByNumberOrHash(txInfo.Height, rpcAddr, BlockQueryByNumber) + if err != nil { + fmt.Println("eth_getTransactionReceipt err:", err) + return + } + + if logInfos.logForString != "" { + fromAddr, err = bech322hex(logInfos.logForMap[0].LogInfo[0]["transfer"]["sender"]) + if err != nil { + fmt.Println("eth_getTransactionReceipt err:", err) + return + } + toAddr, err = bech322hex(logInfos.logForMap[0].LogInfo[0]["transfer"]["recipient"]) + if err != nil { + fmt.Println("eth_getTransactionReceipt err:", err) + return + } + } + + txIndex = 0 + for i, blockTxHash := range txhashes { + if blockTxHash == txHash { + txIndex = i + } + } + + txStatus = 1 + } + + result = map[string]interface{}{ + "blockHash": "0x" + blockInfo.BlockId.Hash, + "blockNumber": fmt.Sprintf("0x%x", blockInfo.SdkBlock.Header.Height), + "contractAddress": nil, // string of the address if it was created + "cumulativeGasUsed": "0x79ccd3", + "effectiveGasPrice": "0x64", + "from": "0x" + fromAddr, + "gasUsed": "0x5208", + "logs": []string{}, + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "status": fmt.Sprintf("0x%x", txStatus), + "to": "0x" + toAddr, + "transactionHash": "0x" + txInfo.Hash, + "transactionIndex": fmt.Sprintf("0x%x", txIndex), + "type": "0x2", + } + + file, _ := json.MarshalIndent(result, "", " ") + fmt.Println("gettxreceipt:", string(file)) + default: + fmt.Println("unknown method:", requestBody.Method) + } + + response["result"] = result + + w.Header().Set("Content-Type", "application/json") + json.NewEncoder(w).Encode(response) + } +} diff --git a/gateway/kira/metamask/utils.go b/gateway/kira/metamask/utils.go new file mode 100644 index 0000000..f55c7a1 --- /dev/null +++ b/gateway/kira/metamask/utils.go @@ -0,0 +1,174 @@ +package metamask + +import ( + "encoding/binary" + "encoding/hex" + "errors" + "fmt" + "strconv" + "strings" + + "github.com/KiraCore/interx/config" + cosmostypes "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/bech32" +) + +const ( + TypeKiraAddr = iota + TypeKiraValAddr +) + +func hex2bech32(hexAddr string, addrType int) (string, error) { + hexAddress := hexAddr + if strings.Contains(hexAddr, "0x") { + hexAddress = hexAddr[2:] + } + byteArray, err := hex.DecodeString(hexAddress) + if err != nil { + return "", err + } + + var bech32Addr string + switch addrType { + case TypeKiraAddr: + bech32Addr, err = bech32.ConvertAndEncode(config.DefaultKiraAddrPrefix, byteArray) + case TypeKiraValAddr: + bech32Addr, err = bech32.ConvertAndEncode(config.DefaultKiraValAddrPrefix, byteArray) + default: + err = errors.New(fmt.Sprintln("invalid addrType: ", addrType)) + } + if err != nil { + return "", err + } + return bech32Addr, nil +} + +func bech322hex(bech32Addr string) (string, error) { + _, data, err := bech32.DecodeAndConvert(bech32Addr) + if err != nil { + return "", nil + } + + // Encode the byte slice as a hex string + hexStr := hex.EncodeToString(data) + return hexStr, nil +} + +func hex2int64(hexStr string) (int64, error) { + hexString := hexStr + if strings.Contains(hexStr, "0x") { + hexString = hexStr[2:] + } + integer, err := strconv.ParseInt(hexString, 16, 64) + if err != nil { + return 0, err + } + return integer, nil +} + +func hex2int32(hexStr string) (int32, error) { + hexString := hexStr + if strings.Contains(hexStr, "0x") { + hexString = hexStr[2:] + } + integer, err := strconv.ParseInt(hexString, 16, 32) + if err != nil { + return 0, err + } + return int32(integer), nil +} + +func hex2uint64(hexStr string) (uint64, error) { + hexString := hexStr + if strings.Contains(hexStr, "0x") { + hexString = hexStr[2:] + } + integer, err := strconv.ParseUint(hexString, 16, 64) + if err != nil { + return 0, err + } + return integer, nil +} + +func hex2uint32(hexStr string) (uint32, error) { + hexString := hexStr + if strings.Contains(hexStr, "0x") { + hexString = hexStr[2:] + } + integer, err := strconv.ParseUint(hexString, 16, 32) + if err != nil { + return 0, err + } + return uint32(integer), nil +} + +func bytes2uint64(param []byte) (uint64, error) { + integer, err := strconv.ParseUint(hex.EncodeToString(param), 16, 64) + if err != nil { + return 0, err + } + return integer, nil +} + +func bytes2uint32(param []byte) (uint32, error) { + integer, err := strconv.ParseUint(hex.EncodeToString(param), 16, 32) + if err != nil { + return 0, err + } + return uint32(integer), nil +} + +func bytes2int64(param []byte) (int64, error) { + integer, err := strconv.ParseInt(hex.EncodeToString(param), 16, 64) + if err != nil { + return 0, err + } + return integer, nil +} + +func bytes2int32(param []byte) (int32, error) { + integer, err := strconv.ParseUint(hex.EncodeToString(param), 16, 32) + if err != nil { + return 0, err + } + return int32(integer), nil +} + +func intToBytes(num int64) []byte { + byteArr := make([]byte, 8) // Assuming int64, which is 8 bytes + binary.LittleEndian.PutUint64(byteArr, uint64(num)) + return byteArr +} + +func bytes2cosmosAddr(param []byte) (cosmostypes.AccAddress, error) { + addrBech32, err := hex2bech32(hex.EncodeToString(param), TypeKiraAddr) + if err != nil { + return nil, err + } + + addr, err := cosmostypes.AccAddressFromBech32(addrBech32) + if err != nil { + return nil, err + } + + return addr, nil +} + +func string2cosmosAddr(param []byte) (cosmostypes.AccAddress, error) { + addr, err := cosmostypes.AccAddressFromBech32(string(param)) + + return addr, err +} + +func bytes2cosmosValAddr(param []byte) (cosmostypes.ValAddress, error) { + addr, err := cosmostypes.ValAddressFromHex("0x" + hex.EncodeToString(param)) + if err != nil { + return nil, err + } + + return addr, nil +} + +func bytes2bool(param []byte) bool { + return (param[len(param)-1] == 0x01) +} diff --git a/go.mod b/go.mod index 5eb454d..6b6708b 100644 --- a/go.mod +++ b/go.mod @@ -29,6 +29,11 @@ require ( google.golang.org/protobuf v1.31.0 ) +require ( + github.com/google/uuid v1.3.0 // indirect + github.com/rjeczalik/notify v0.9.1 // indirect +) + require ( cosmossdk.io/api v0.3.1 // indirect cosmossdk.io/core v0.5.1 // indirect @@ -143,6 +148,7 @@ require ( github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/spf13/viper v1.14.0 // indirect + github.com/storyicon/sigverify v1.1.0 github.com/subosito/gotenv v1.4.1 // indirect github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c // indirect diff --git a/go.sum b/go.sum index 4253a6c..281afed 100644 --- a/go.sum +++ b/go.sum @@ -403,6 +403,7 @@ github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm4 github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= @@ -697,6 +698,7 @@ github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqn github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rjeczalik/notify v0.9.1 h1:CLCKso/QK1snAlnhNR/CNvNiFU2saUtjV0bx3EwNeCE= +github.com/rjeczalik/notify v0.9.1/go.mod h1:rKwnCoCGeuQnwBtTSPL9Dad03Vh2n40ePRrjvIXnJho= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= @@ -759,6 +761,8 @@ github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DM github.com/spf13/viper v1.14.0 h1:Rg7d3Lo706X9tHsJMUjdiwMpHB7W8WnSVOssIY+JElU= github.com/spf13/viper v1.14.0/go.mod h1:WT//axPky3FdvXHzGw33dNdXXXfFQqmEalje+egj8As= github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4 h1:Gb2Tyox57NRNuZ2d3rmvB3pcmbu7O1RS3m8WRx7ilrg= +github.com/storyicon/sigverify v1.1.0 h1:Fz153Jvloz1P0G3TrG7dHGyAlB3mpjmFeu5IszfJWQ0= +github.com/storyicon/sigverify v1.1.0/go.mod h1:q0qxvhdUsMIBAry3h7/IMW7BebRkiT8496TrQP1XW5s= github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= From 7132c5f4776985c0df363794f576da68d559e15e Mon Sep 17 00:00:00 2001 From: tj327 Date: Wed, 20 Dec 2023 07:40:57 -0500 Subject: [PATCH 02/25] upgrade interx version to v0.4.42 --- RELEASE.md | 4 ++-- config/constants.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/RELEASE.md b/RELEASE.md index dc79b9b..70c81cb 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -1,5 +1,5 @@ Features: -* Implement QueryUndelegations endpoint -* Bump sekai version to v0.3.38 \ No newline at end of file +* Implement KIP-87 : broadcast metamask coin send transaction to sekai +* Implement KIP-87 : broadcast eip-712 signed transaction to sekai \ No newline at end of file diff --git a/config/constants.go b/config/constants.go index e29fb07..ac93268 100755 --- a/config/constants.go +++ b/config/constants.go @@ -1,7 +1,7 @@ package config const ( - InterxVersion = "v0.4.41" + InterxVersion = "v0.4.42" SekaiVersion = "v0.3.38" CosmosVersion = "v0.47.5" From d7c81908aa31797287048d56ac3bb14f31f296c3 Mon Sep 17 00:00:00 2001 From: tj327 Date: Wed, 20 Dec 2023 08:01:13 -0500 Subject: [PATCH 03/25] add comments for decode functions --- config/constants.go | 3 +-- gateway/kira/metamask/cosmostxsender.go | 26 +++++++++++++++++++++++++ gateway/kira/metamask/metamask.go | 1 - 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/config/constants.go b/config/constants.go index ac93268..fc68d9f 100755 --- a/config/constants.go +++ b/config/constants.go @@ -10,8 +10,7 @@ const ( DefaultKiraValAddrPrefix = "kiravaloper" DefaultKiraDenom = "ukex" - // TODO: change endpoint to api/kira/evm - MetamaskEndpoint = "/api/k/evm" + MetamaskEndpoint = "api/kira/evm" RegisterAddrEndpoint = "/api/kira/evm/register_address/{eth_addr}{cosmos_addr}" QueryDashboard = "/api/dashboard" diff --git a/gateway/kira/metamask/cosmostxsender.go b/gateway/kira/metamask/cosmostxsender.go index c883605..665299f 100644 --- a/gateway/kira/metamask/cosmostxsender.go +++ b/gateway/kira/metamask/cosmostxsender.go @@ -93,11 +93,17 @@ const ( var grpcConn *grpc.ClientConn +// decode 256bit param like bool, uint, hex-typed address etc func Decode256Bit(data *[]byte, params *[][]byte) { *params = append(*params, (*data)[:32]) *data = (*data)[32:] } +// decode string-typed param +// structure: +// * offset - offset of the string in the data : 32byte +// * length - length of the string : 32byte +// * content - content of the string : (length/32+1)*32byte func DecodeString(data *[]byte, params *[][]byte) { // offset := data[:32] // string value offset *data = (*data)[32:] @@ -109,6 +115,13 @@ func DecodeString(data *[]byte, params *[][]byte) { *data = (*data)[(length/32+1)*32:] } +// decode string-typed params - if string-typed params are consecutive, offsets are placed on top +// and length, contents are placed in order +// structure: +// * offsets - offsets of the strings in the data : length*32byte +// * array of below data +// ** length - length of the string : 32byte +// ** content - content of the string : (length/32+1)*32byte func DecodeStrings(data *[]byte, params *[][]byte, paramLen int) { // remove offset of each string *data = (*data)[32*paramLen:] @@ -121,6 +134,13 @@ func DecodeStrings(data *[]byte, params *[][]byte, paramLen int) { } } +// decode string-array-typed param +// structure: +// * offset - offset of the strings in the data : 32byte +// * offsets - offsets of the string in the data : length*32byte +// * array of below data +// ** length - length of the string : 32byte +// ** content - content of the string : (length/32+1)*32byte func DecodeStringArray(data *[]byte, params *[][]byte) { // offset := data[:32] // string value offset *data = (*data)[32:] @@ -140,6 +160,12 @@ func DecodeStringArray(data *[]byte, params *[][]byte) { } } +// decode hex-array-typed param +// structure: +// * offset - offset of the hex-array in the data : 32byte +// * length - length of the hex : 32byte +// * array of below data +// ** content - content of the hex : 32byte func DecodeHexArray(data *[]byte, params *[][]byte) { // offset := data[:32] // string value offset *data = (*data)[32:] diff --git a/gateway/kira/metamask/metamask.go b/gateway/kira/metamask/metamask.go index 7348a3c..6a6cc28 100644 --- a/gateway/kira/metamask/metamask.go +++ b/gateway/kira/metamask/metamask.go @@ -231,7 +231,6 @@ func MetamaskRequestHandler(gwCosmosmux *runtime.ServeMux, rpcAddr string) http. return } - // TODO: check after token sending result = fmt.Sprintf("0x%x", sequence) case "eth_sendTransaction": // var params EthSendTransaction From b3f5d6b670338770f42ae66524dd047abdd95f9f Mon Sep 17 00:00:00 2001 From: tj327 Date: Thu, 21 Dec 2023 02:40:05 -0500 Subject: [PATCH 04/25] update endpoint&fix decodeparams issue --- config/constants.go | 2 +- gateway/kira/metamask/cosmostxsender.go | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/config/constants.go b/config/constants.go index fc68d9f..9c613d4 100755 --- a/config/constants.go +++ b/config/constants.go @@ -10,7 +10,7 @@ const ( DefaultKiraValAddrPrefix = "kiravaloper" DefaultKiraDenom = "ukex" - MetamaskEndpoint = "api/kira/evm" + MetamaskEndpoint = "/api/kira/evm" RegisterAddrEndpoint = "/api/kira/evm/register_address/{eth_addr}{cosmos_addr}" QueryDashboard = "/api/dashboard" diff --git a/gateway/kira/metamask/cosmostxsender.go b/gateway/kira/metamask/cosmostxsender.go index 665299f..24e6939 100644 --- a/gateway/kira/metamask/cosmostxsender.go +++ b/gateway/kira/metamask/cosmostxsender.go @@ -124,6 +124,7 @@ func DecodeString(data *[]byte, params *[][]byte) { // ** content - content of the string : (length/32+1)*32byte func DecodeStrings(data *[]byte, params *[][]byte, paramLen int) { // remove offset of each string + *data = (*data)[32:] *data = (*data)[32*paramLen:] for i := 0; i < paramLen; i++ { length, _ := bytes2uint64((*data)[:32]) @@ -142,9 +143,6 @@ func DecodeStrings(data *[]byte, params *[][]byte, paramLen int) { // ** length - length of the string : 32byte // ** content - content of the string : (length/32+1)*32byte func DecodeStringArray(data *[]byte, params *[][]byte) { - // offset := data[:32] // string value offset - *data = (*data)[32:] - length, _ := bytes2uint64((*data)[:32]) *params = append(*params, (*data)[:32]) *data = (*data)[32:] @@ -1293,6 +1291,8 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, } msg = custodytypes.NewMsgDeclineCustodyTransaction(from, to, string(params[5])) } + + fmt.Println(msg) err = txBuilder.SetMsgs(msg) if err != nil { return nil, err From f84baeab5b5ef2af7006a418f99367343b710133 Mon Sep 17 00:00:00 2001 From: tj327 Date: Fri, 5 Jan 2024 09:36:34 -0500 Subject: [PATCH 05/25] add verification of eip-712 signed transaction --- common/api.go | 1 + gateway/kira/metamask/cosmostxsender.go | 590 ++++++++++-------------- gateway/kira/metamask/metamask.go | 2 +- gateway/kira/metamask/utils.go | 48 +- 4 files changed, 296 insertions(+), 345 deletions(-) diff --git a/common/api.go b/common/api.go index 041b5d6..3ac2372 100644 --- a/common/api.go +++ b/common/api.go @@ -330,6 +330,7 @@ func GetTokenAliases(gwCosmosmux *runtime.ServeMux, r *http.Request) []types.Tok } result := TokenAliasesResponse{} + fmt.Println(resp.Body) err := json.NewDecoder(resp.Body).Decode(&result) if err != nil { GetLogger().Error("[grpc-call] Unable to decode response: ", err) diff --git a/gateway/kira/metamask/cosmostxsender.go b/gateway/kira/metamask/cosmostxsender.go index 24e6939..338ef60 100644 --- a/gateway/kira/metamask/cosmostxsender.go +++ b/gateway/kira/metamask/cosmostxsender.go @@ -29,7 +29,9 @@ import ( "github.com/cosmos/cosmos-sdk/types/tx/signing" xauthsigning "github.com/cosmos/cosmos-sdk/x/auth/signing" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + "github.com/ethereum/go-ethereum/accounts/abi" ethcommon "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" "google.golang.org/grpc" ) @@ -87,12 +89,27 @@ const ( MsgDropCustodyCustodians MsgRemoveFromCustodyWhiteList MsgDropCustodyWhiteList - MsgApproveCustodyTransaction - MsgDeclineCustodyTransaction + MsgApproveCustodyTx + MsgDeclineCustodyTx ) var grpcConn *grpc.ClientConn +type DelegateParam struct { + Amount string `json:"amount"` + // If true it returns the full transaction objects, if false only the hashes of the transactions + To string `json:"to"` +} + +type UpsertTokenAliasParam struct { + Symbol string `json:"symbol"` + Name string `json:"name"` + Icon string `json:"icon"` + Decimals uint32 `json:"decimals"` + Denoms []string `json:"denoms"` + Invalidated bool `json:"invalidated"` +} + // decode 256bit param like bool, uint, hex-typed address etc func Decode256Bit(data *[]byte, params *[][]byte) { *params = append(*params, (*data)[:32]) @@ -115,65 +132,6 @@ func DecodeString(data *[]byte, params *[][]byte) { *data = (*data)[(length/32+1)*32:] } -// decode string-typed params - if string-typed params are consecutive, offsets are placed on top -// and length, contents are placed in order -// structure: -// * offsets - offsets of the strings in the data : length*32byte -// * array of below data -// ** length - length of the string : 32byte -// ** content - content of the string : (length/32+1)*32byte -func DecodeStrings(data *[]byte, params *[][]byte, paramLen int) { - // remove offset of each string - *data = (*data)[32:] - *data = (*data)[32*paramLen:] - for i := 0; i < paramLen; i++ { - length, _ := bytes2uint64((*data)[:32]) - *data = (*data)[32:] - - *params = append(*params, (*data)[:length]) - *data = (*data)[(length/32+1)*32:] - } -} - -// decode string-array-typed param -// structure: -// * offset - offset of the strings in the data : 32byte -// * offsets - offsets of the string in the data : length*32byte -// * array of below data -// ** length - length of the string : 32byte -// ** content - content of the string : (length/32+1)*32byte -func DecodeStringArray(data *[]byte, params *[][]byte) { - length, _ := bytes2uint64((*data)[:32]) - *params = append(*params, (*data)[:32]) - *data = (*data)[32:] - - // remove offset of each string - *data = (*data)[32*length:] - for i := uint64(0); i < length; i++ { - length, _ := bytes2uint64((*data)[:32]) - *data = (*data)[32:] - - *params = append(*params, (*data)[:length]) - *data = (*data)[(length/32+1)*32:] - } -} - -// decode hex-array-typed param -// structure: -// * offset - offset of the hex-array in the data : 32byte -// * length - length of the hex : 32byte -// * array of below data -// ** content - content of the hex : 32byte -func DecodeHexArray(data *[]byte, params *[][]byte) { - // offset := data[:32] // string value offset - *data = (*data)[32:] - - length, _ := bytes2uint64((*data)[:32]) - *data = (*data)[32:] - - *params = append(*params, (*data)[:length]) -} - func DecodeParam(data []byte, txType int) [][]byte { if txType == MsgBankSend { return nil @@ -186,191 +144,13 @@ func DecodeParam(data []byte, txType int) [][]byte { Decode256Bit(&data, ¶ms) } - switch txType { - case MsgSubmitEvidence: // TODO: test - // height, power, time, consensusAddr - Decode256Bit(&data, ¶ms) - Decode256Bit(&data, ¶ms) - Decode256Bit(&data, ¶ms) - DecodeString(&data, ¶ms) - case MsgSubmitProposal: - case MsgVoteProposal: // TODO: test - // proposalID, option, slash - Decode256Bit(&data, ¶ms) - Decode256Bit(&data, ¶ms) - DecodeString(&data, ¶ms) - case MsgRegisterIdentityRecords: - // identityInfo, - DecodeString(&data, ¶ms) - case MsgDeleteIdentityRecord: - // len, keys - DecodeStringArray(&data, ¶ms) - case MsgRequestIdentityRecordsVerify: - // tip, verifier, recordIds - DecodeStrings(&data, ¶ms, 2) - - // recordIds - DecodeHexArray(&data, ¶ms) - case MsgHandleIdentityRecordsVerifyRequest: - // requestId, isApprove - Decode256Bit(&data, ¶ms) - Decode256Bit(&data, ¶ms) - case MsgCancelIdentityRecordsVerifyRequest: - // verifyRequestId - Decode256Bit(&data, ¶ms) - case MsgSetNetworkProperties: - // len, boolParamsList, len, uintParamsList, len, strParamsList, len, legacyDecParamsList - - // len, boolParamsList - DecodeHexArray(&data, ¶ms) - - // len, uintParamsList - DecodeHexArray(&data, ¶ms) - - // len, strParamsList - DecodeStringArray(&data, ¶ms) - - // len, legacyDecParamsList - DecodeStringArray(&data, ¶ms) - case MsgSetExecutionFee: - // executionFee, failureFee, timeout, defaultParams, transactionType - for i := 0; i < 4; i++ { - Decode256Bit(&data, ¶ms) - } - - // transactionType - DecodeString(&data, ¶ms) - case MsgClaimCouncilor: - // moniker string, username string, description string, social string, contact string, avatar string - DecodeStrings(&data, ¶ms, 6) - case MsgWhitelistPermissions: - // permission uint, controlledAddr address - Decode256Bit(&data, ¶ms) - DecodeString(&data, ¶ms) - case MsgBlacklistPermissions: - // permission uint, addr address - Decode256Bit(&data, ¶ms) - DecodeString(&data, ¶ms) - case MsgCreateRole: - // sid string, description string - DecodeString(&data, ¶ms) - DecodeString(&data, ¶ms) - case MsgAssignRole: - // roleid uint32, controller address - Decode256Bit(&data, ¶ms) - DecodeString(&data, ¶ms) - case MsgUnassignRole: - // roleid uint32, controller address - Decode256Bit(&data, ¶ms) - DecodeString(&data, ¶ms) - case MsgWhitelistRolePermission: - // permission uint32, roleIdentifier string - Decode256Bit(&data, ¶ms) - DecodeString(&data, ¶ms) - case MsgBlacklistRolePermission: - // permission uint32, roleIdentifier string - Decode256Bit(&data, ¶ms) - DecodeString(&data, ¶ms) - case MsgRemoveWhitelistRolePermission: - // permission uint32, roleIdentifier string - Decode256Bit(&data, ¶ms) - DecodeString(&data, ¶ms) - case MsgRemoveBlacklistRolePermission: - // permission uint32, roleIdentifier string - Decode256Bit(&data, ¶ms) - DecodeString(&data, ¶ms) - case MsgClaimValidator: - case MsgUpsertTokenAlias: - // invalidated bool, decimals uint32, symbol string, name string, icon string, len, denoms []string - Decode256Bit(&data, ¶ms) - Decode256Bit(&data, ¶ms) - DecodeStrings(&data, ¶ms, 3) - // denoms - DecodeStringArray(&data, ¶ms) - case MsgUpsertTokenRate: - // feePayments bool, stakeToken bool, invalidated bool, denom string, rate cosmostypes.Dec, - // stakeCap cosmostypes.Dec, stakeMin cosmostypes.Int - for i := 0; i < 3; i++ { - Decode256Bit(&data, ¶ms) - } - - DecodeStrings(&data, ¶ms, 4) - case MsgActivate: - case MsgPause: - case MsgUnpause: - case MsgCreateSpendingPool: - case MsgDepositSpendingPool: - // amount cosmostypes.Coins, name string - DecodeStrings(&data, ¶ms, 2) - case MsgRegisterSpendingPoolBeneficiary: - // name string - DecodeString(&data, ¶ms) - case MsgClaimSpendingPool: - // name string - DecodeString(&data, ¶ms) - case MsgUpsertStakingPool: - // enabled bool, validator string, commission cosmostypes.Dec - Decode256Bit(&data, ¶ms) - DecodeStrings(&data, ¶ms, 2) - case MsgDelegate: - // amount, validator - DecodeStrings(&data, ¶ms, 2) - case MsgUndelegate: - // amount, validator - DecodeStrings(&data, ¶ms, 2) - case MsgClaimRewards: - case MsgClaimUndelegation: - // undelegationId uint64 - Decode256Bit(&data, ¶ms) - case MsgSetCompoundInfo: - // allDenom bool, len, denoms []string - Decode256Bit(&data, ¶ms) - DecodeStringArray(&data, ¶ms) - case MsgRegisterDelegator: - case MsgCreateCustody: - // V, R, S, signer, custodyMode uint256, key string, nextController string, len, boolArr, len, strArr - for i := 0; i < 4; i++ { - Decode256Bit(&data, ¶ms) - } - - DecodeStrings(&data, ¶ms, 2) - - DecodeHexArray(&data, ¶ms) - DecodeStringArray(&data, ¶ms) - case MsgAddToCustodyWhiteList: - // oldKey string, newKey string, next string, target string, len, newAddr []string - DecodeStrings(&data, ¶ms, 4) - DecodeStringArray(&data, ¶ms) - case MsgAddToCustodyCustodians: - // oldKey string, newKey string, next string, target string, len, newAddr []string - DecodeStrings(&data, ¶ms, 4) - DecodeStringArray(&data, ¶ms) - case MsgRemoveFromCustodyCustodians: - // newAddr string, oldKey string, newKey string, next string, target string - DecodeStrings(&data, ¶ms, 5) - case MsgDropCustodyCustodians: - // oldKey string, newKey string, next string, target string - DecodeStrings(&data, ¶ms, 4) - case MsgRemoveFromCustodyWhiteList: - // newAddr string, oldKey string, newKey string, next string, target string - DecodeStrings(&data, ¶ms, 5) - case MsgDropCustodyWhiteList: - // oldKey string, newKey string, next string, target string - DecodeStrings(&data, ¶ms, 4) - case MsgApproveCustodyTransaction: - // to string, hash string - DecodeStrings(&data, ¶ms, 2) - case MsgDeclineCustodyTransaction: - // to string, hash string - DecodeStrings(&data, ¶ms, 2) - default: - - } + // decode param string + DecodeString(&data, ¶ms) return params } -func SendTx(txRawData string, gwCosmosmux *runtime.ServeMux, r *http.Request) (string, error) { +func sendTx(txRawData string, gwCosmosmux *runtime.ServeMux, r *http.Request) (string, error) { byteData, err := hex.DecodeString(txRawData[2:]) if err != nil { return "", err @@ -384,52 +164,52 @@ func SendTx(txRawData string, gwCosmosmux *runtime.ServeMux, r *http.Request) (s var txBytes []byte - submitEvidencePrefix, _ := hex.DecodeString("33104ff7") + submitEvidencePrefix, _ := hex.DecodeString("85db2453") submitProposalPrefix, _ := hex.DecodeString("00000000") - voteProposalPrefix, _ := hex.DecodeString("24d03a8b") + voteProposalPrefix, _ := hex.DecodeString("7f1f06dc") registerIdentityRecordsPrefix, _ := hex.DecodeString("bc05f106") - deleteIdentityRecordPrefix, _ := hex.DecodeString("2ac0ca03") - requestIdentityRecordsVerifyPrefix, _ := hex.DecodeString("f7c51612") - handleIdentityRecordsVerifyRequestPrefix, _ := hex.DecodeString("2facbfe8") - cancelIdentityRecordsVerifyRequestPrefix, _ := hex.DecodeString("9b66f097") - setNetworkPropertiesPrefix, _ := hex.DecodeString("3a91d2ba") - setExecutionFeePrefix, _ := hex.DecodeString("fa02785e") - claimCouncilorPrefix, _ := hex.DecodeString("9dd85dbf") - whitelistPermissionsPrefix, _ := hex.DecodeString("4db4bc0b") - blacklistPermissionsPrefix, _ := hex.DecodeString("675ed828") - createRolePrefix, _ := hex.DecodeString("7b0fadab") - assignRolePrefix, _ := hex.DecodeString("83b3d393") - unassignRolePrefix, _ := hex.DecodeString("2fa24c7a") - whitelistRolePermissionPrefix, _ := hex.DecodeString("557f0e63") - blacklistRolePermissionPrefix, _ := hex.DecodeString("7e7595fe") - removeWhitelistRolePermissionPrefix, _ := hex.DecodeString("e9830bd8") - removeBlacklistRolePermissionPrefix, _ := hex.DecodeString("45e2144c") + deleteIdentityRecordPrefix, _ := hex.DecodeString("25581f17") + requestIdentityRecordsVerifyPrefix, _ := hex.DecodeString("9765358e") + handleIdentityRecordsVerifyRequestPrefix, _ := hex.DecodeString("4335ed0c") + cancelIdentityRecordsVerifyRequestPrefix, _ := hex.DecodeString("eeaa0488") + setNetworkPropertiesPrefix, _ := hex.DecodeString("f8060fb5") + setExecutionFeePrefix, _ := hex.DecodeString("c7586de8") + claimCouncilorPrefix, _ := hex.DecodeString("b7b8ff46") + whitelistPermissionsPrefix, _ := hex.DecodeString("2f313ab8") + blacklistPermissionsPrefix, _ := hex.DecodeString("3864f845") + createRolePrefix, _ := hex.DecodeString("2d8abfdf") + assignRolePrefix, _ := hex.DecodeString("fcc121b5") + unassignRolePrefix, _ := hex.DecodeString("c79ca19d") + whitelistRolePermissionPrefix, _ := hex.DecodeString("59472362") + blacklistRolePermissionPrefix, _ := hex.DecodeString("99c557da") + removeWhitelistRolePermissionPrefix, _ := hex.DecodeString("2a11d702") + removeBlacklistRolePermissionPrefix, _ := hex.DecodeString("f5f865e4") claimValidatorPrefix, _ := hex.DecodeString("00000000") - upsertTokenAliasPrefix, _ := hex.DecodeString("59122e45") - upsertTokenRatePrefix, _ := hex.DecodeString("fb7e4c17") + upsertTokenAliasPrefix, _ := hex.DecodeString("f69a4787") + upsertTokenRatePrefix, _ := hex.DecodeString("3b30a97a") activatePrefix, _ := hex.DecodeString("a1374dc2") pausePrefix, _ := hex.DecodeString("1371cf19") unpausePrefix, _ := hex.DecodeString("b9179894") createSpendingPoolPrefix, _ := hex.DecodeString("00000000") - depositSpendingPoolPrefix, _ := hex.DecodeString("9fff5508") + depositSpendingPoolPrefix, _ := hex.DecodeString("e10c925c") registerSpendingPoolBeneficiaryPrefix, _ := hex.DecodeString("7ab7eecf") claimSpendingPoolPrefix, _ := hex.DecodeString("efeed4a0") - upsertStakingPoolPrefix, _ := hex.DecodeString("1f0da7b4") - delegatePrefix, _ := hex.DecodeString("4563230c") - undelegatePrefix, _ := hex.DecodeString("d8e05398") + upsertStakingPoolPrefix, _ := hex.DecodeString("fb24f5cc") + delegatePrefix, _ := hex.DecodeString("4b193c09") + undelegatePrefix, _ := hex.DecodeString("94574f0c") claimRewardsPrefix, _ := hex.DecodeString("9e796524") - claimUndelegationPrefix, _ := hex.DecodeString("505b0330") - setCompoundInfoPrefix, _ := hex.DecodeString("fb1257e6") + claimUndelegationPrefix, _ := hex.DecodeString("2f608d76") + setCompoundInfoPrefix, _ := hex.DecodeString("e2d6a093") registerDelegatorPrefix, _ := hex.DecodeString("99db185d") - createCustodyPrefix, _ := hex.DecodeString("d486e9de") - addToCustodyWhiteListPrefix, _ := hex.DecodeString("25d1857d") - addToCustodyCustodiansPrefix, _ := hex.DecodeString("9c4f31a9") - removeFromCustodyCustodiansPrefix, _ := hex.DecodeString("8ec62788") - dropCustodyCustodiansPrefix, _ := hex.DecodeString("07d33244") - removeFromCustodyWhiteListPrefix, _ := hex.DecodeString("b99abc7d") - dropCustodyWhiteListPrefix, _ := hex.DecodeString("4db07a4e") - approveCustodyTransactionPrefix, _ := hex.DecodeString("e6d41e78") - declineCustodyTransactionPrefix, _ := hex.DecodeString("21ebd09e") + createCustodyPrefix, _ := hex.DecodeString("bebde6d1") + addToCustodyWhiteListPrefix, _ := hex.DecodeString("25a1d834") + addToCustodyCustodiansPrefix, _ := hex.DecodeString("8c7fdb91") + removeFromCustodyCustodiansPrefix, _ := hex.DecodeString("90be51cf") + dropCustodyCustodiansPrefix, _ := hex.DecodeString("0ca697b4") + removeFromCustodyWhiteListPrefix, _ := hex.DecodeString("fa431c3e") + dropCustodyWhiteListPrefix, _ := hex.DecodeString("bc65010a") + approveCustodyTxPrefix, _ := hex.DecodeString("5da292d4") + declineCustodyTxPrefix, _ := hex.DecodeString("dce4399a") var msgType int switch { @@ -523,10 +303,10 @@ func SendTx(txRawData string, gwCosmosmux *runtime.ServeMux, r *http.Request) (s msgType = MsgRemoveFromCustodyWhiteList case bytes.Equal(ethTxData.Data[:4], dropCustodyWhiteListPrefix): msgType = MsgDropCustodyWhiteList - case bytes.Equal(ethTxData.Data[:4], approveCustodyTransactionPrefix): - msgType = MsgApproveCustodyTransaction - case bytes.Equal(ethTxData.Data[:4], declineCustodyTransactionPrefix): - msgType = MsgDeclineCustodyTransaction + case bytes.Equal(ethTxData.Data[:4], approveCustodyTxPrefix): + msgType = MsgApproveCustodyTx + case bytes.Equal(ethTxData.Data[:4], declineCustodyTxPrefix): + msgType = MsgDeclineCustodyTx default: return "", errors.New("no such functions") } @@ -539,7 +319,7 @@ func SendTx(txRawData string, gwCosmosmux *runtime.ServeMux, r *http.Request) (s // if ethTxData - txHash, err := sendTx(r.Context(), txBytes) + txHash, err := sendCosmosTx(r.Context(), txBytes) if err != nil { return "", err } @@ -547,43 +327,168 @@ func SendTx(txRawData string, gwCosmosmux *runtime.ServeMux, r *http.Request) (s return txHash, nil } -func ValidateEIP712Sign(v, r, s []byte, sender ethcommon.Address, amount int, transactionType int) bool { - // eip712DomainSeparator := crypto.Keccak256Hash( - // []byte("EIP712Domain(string name,string version,uint256 chainId)"), - // crypto.Keccak256([]byte("SetTest")), - // crypto.Keccak256([]byte("1")), - // intToBytes(config.DefaultChainID), - // ) - - // // Define the hash of the struct - // hashStruct := crypto.Keccak256Hash( - // []byte("delegate(uint amount, address sender)"), - // intToBytes(int64(amount)), - // sender.Bytes(), - // ) - - // // Define the final hash - // hash := crypto.Keccak256Hash( - // []byte("\x19\x01"), - // eip712DomainSeparator.Bytes(), - // hashStruct.Bytes(), - // ) - - // signature := append(append(r, s...), v...) - - // // Recover the public key from the signature - // pubKey, err := crypto.Ecrecover(hash.Bytes(), signature) - // if err != nil { - // return false - // } - - // // Derive the signer's address from the public key - // signerAddress := crypto.PubkeyToAddress(*pubKey) - - // if signerAddress != senderAddr { - // return false - // } - return true +func getStructHash(txType int, valParam string) ethcommon.Hash { + abiPack := abi.ABI{} + var structABIPack []byte + + var funcSig []byte + + switch txType { + case MsgSubmitEvidence: + funcSig = crypto.Keccak256([]byte("submitEvidence(string param)")) + case MsgSubmitProposal: + funcSig = crypto.Keccak256([]byte("submitProposal(string param)")) + case MsgVoteProposal: + funcSig = crypto.Keccak256([]byte("voteProposal(string param)")) + case MsgRegisterIdentityRecords: + funcSig = crypto.Keccak256([]byte("registerIdentityRecords(string param)")) + case MsgDeleteIdentityRecord: + funcSig = crypto.Keccak256([]byte("deleteIdentityRecord(string param)")) + case MsgRequestIdentityRecordsVerify: + funcSig = crypto.Keccak256([]byte("requestIdentityRecordsVerify(string param)")) + case MsgHandleIdentityRecordsVerifyRequest: + funcSig = crypto.Keccak256([]byte("handleIdentityRecordsVerifyRequest(string param)")) + case MsgCancelIdentityRecordsVerifyRequest: + funcSig = crypto.Keccak256([]byte("cancelIdentityRecordsVerifyRequest(string param)")) + case MsgSetNetworkProperties: + funcSig = crypto.Keccak256([]byte("setNetworkProperties(string param)")) + case MsgSetExecutionFee: + funcSig = crypto.Keccak256([]byte("setExecutionFee(string param)")) + case MsgClaimCouncilor: + funcSig = crypto.Keccak256([]byte("claimCouncilor(string param)")) + case MsgWhitelistPermissions: + funcSig = crypto.Keccak256([]byte("whitelistPermissions(string param)")) + case MsgBlacklistPermissions: + funcSig = crypto.Keccak256([]byte("blacklistPermissions(string param)")) + case MsgCreateRole: + funcSig = crypto.Keccak256([]byte("createRole(string param)")) + case MsgAssignRole: + funcSig = crypto.Keccak256([]byte("assignRole(string param)")) + case MsgUnassignRole: + funcSig = crypto.Keccak256([]byte("unassignRole(string param)")) + case MsgWhitelistRolePermission: + funcSig = crypto.Keccak256([]byte("whitelistRolePermission(string param)")) + case MsgBlacklistRolePermission: + funcSig = crypto.Keccak256([]byte("blacklistRolePermission(string param)")) + case MsgRemoveWhitelistRolePermission: + funcSig = crypto.Keccak256([]byte("removeWhitelistRolePermission(string param)")) + case MsgRemoveBlacklistRolePermission: + funcSig = crypto.Keccak256([]byte("removeBlacklistRolePermission(string param)")) + case MsgClaimValidator: + // funcSig = crypto.Keccak256([]byte("delegate(string param)")) + case MsgUpsertTokenAlias: + funcSig = crypto.Keccak256([]byte("upsertTokenAlias(string param)")) + case MsgUpsertTokenRate: + funcSig = crypto.Keccak256([]byte("upsertTokenRate(string param)")) + case MsgActivate: + funcSig = crypto.Keccak256([]byte("activate()")) + case MsgPause: + funcSig = crypto.Keccak256([]byte("pause()")) + case MsgUnpause: + funcSig = crypto.Keccak256([]byte("unpause()")) + case MsgCreateSpendingPool: + // funcSig = crypto.Keccak256([]byte("delegate(string param)")) + case MsgDepositSpendingPool: + funcSig = crypto.Keccak256([]byte("depositSpendingPool(string param)")) + case MsgRegisterSpendingPoolBeneficiary: + funcSig = crypto.Keccak256([]byte("registerSpendingPoolBeneficiary(string param)")) + case MsgClaimSpendingPool: + funcSig = crypto.Keccak256([]byte("claimSpendingPool(string param)")) + case MsgUpsertStakingPool: + funcSig = crypto.Keccak256([]byte("upsertStakingPool(string param)")) + case MsgDelegate: + funcSig = crypto.Keccak256([]byte("delegate(string param)")) + case MsgUndelegate: + funcSig = crypto.Keccak256([]byte("undelegate(string param)")) + case MsgClaimRewards: + funcSig = crypto.Keccak256([]byte("claimRewards()")) + case MsgClaimUndelegation: + funcSig = crypto.Keccak256([]byte("claimUndelegation(string param)")) + case MsgSetCompoundInfo: + funcSig = crypto.Keccak256([]byte("setCompoundInfo(string param)")) + case MsgRegisterDelegator: + funcSig = crypto.Keccak256([]byte("registerDelegator()")) + case MsgCreateCustody: + funcSig = crypto.Keccak256([]byte("createCustody(string param)")) + case MsgAddToCustodyWhiteList: + funcSig = crypto.Keccak256([]byte("addToCustodyWhiteList(string param)")) + case MsgAddToCustodyCustodians: + funcSig = crypto.Keccak256([]byte("addToCustodyCustodians(string param)")) + case MsgRemoveFromCustodyCustodians: + funcSig = crypto.Keccak256([]byte("removeFromCustodyCustodians(string param)")) + case MsgDropCustodyCustodians: + funcSig = crypto.Keccak256([]byte("dropCustodyCustodians(string param)")) + case MsgRemoveFromCustodyWhiteList: + funcSig = crypto.Keccak256([]byte("removeFromCustodyWhiteList(string param)")) + case MsgDropCustodyWhiteList: + funcSig = crypto.Keccak256([]byte("dropCustodyWhiteList(string param)")) + case MsgApproveCustodyTx: + funcSig = crypto.Keccak256([]byte("approveCustodyTransaction(string param)")) + case MsgDeclineCustodyTx: + funcSig = crypto.Keccak256([]byte("declineCustodyTransaction(string param)")) + default: + + } + + structJsonData := []byte(`[{"Type":"function","Name":"encode","Inputs":[{"Type":"bytes32","Name":"funcsig"},{"Type":"bytes32","Name":"param"}],"Outputs":[]}]`) + _ = abiPack.UnmarshalJSON(structJsonData) + + var funcSignature [32]byte + copy(funcSignature[:], funcSig) + + structABIPack, _ = PackABIParams(abiPack, + "encode", + convertByteArr2Bytes32(funcSig), + convertByteArr2Bytes32(crypto.Keccak256([]byte(valParam))), + ) + + structHash := crypto.Keccak256Hash(structABIPack) + + return structHash +} + +func ValidateEIP712Sign(v, r, s []byte, sender ethcommon.Address, valParam string, txType int) bool { + abiPack := abi.ABI{} + + // get EIP712DomainHash + jsonData := []byte(`[{"Type":"function","Name":"encode","Inputs":[{"Type":"bytes32","Name":"funcsig"},{"Type":"bytes32","Name":"name"},{"Type":"bytes32","Name":"version"},{"Type":"bytes32","Name":"chainId"}],"Outputs":[]}]`) + abiPack.UnmarshalJSON(jsonData) + funcSig := crypto.Keccak256([]byte("EIP712Domain(string name,string version,uint256 chainId)")) + + eip712DomainSeparatorABIPack, _ := PackABIParams(abiPack, + "encode", + convertByteArr2Bytes32(funcSig), + convertByteArr2Bytes32(crypto.Keccak256([]byte("Kira"))), + convertByteArr2Bytes32(crypto.Keccak256([]byte("1"))), + convertByteArr2Bytes32(uint32To32Bytes(8789)), + ) + eip712DomainSeparator := crypto.Keccak256Hash(eip712DomainSeparatorABIPack) + + // get StructHash + structHash := getStructHash(txType, valParam) + + // Define the final hash + hash := crypto.Keccak256Hash( + append(append([]byte("\x19\x01"), eip712DomainSeparator.Bytes()...), structHash.Bytes()...), + ) + + signature := getSignature(r, s, v) + + // Recover the public key from the signature + pubKey, err := crypto.SigToPub(hash.Bytes(), signature) + // pbBytes, err := crypto.Ecrecover(hash.Bytes(), signature) + // fmt.Println(string(pbBytes), err) + // pubKey, err := crypto.UnmarshalPubkey(pbBytes) + + if err != nil { + fmt.Println("eip712 err", err) + return false + } + + // Derive the signer's address from the public key + signerAddress := crypto.PubkeyToAddress(*pubKey) + + return signerAddress.Hex() == sender.Hex() } func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, txType int) ([]byte, error) { @@ -834,7 +739,7 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, msg = customgovtypes.NewMsgSetNetworkProperties(proposer, &networkProperties) case MsgSetExecutionFee: - // V, R, S, signer, executionFee, failureFee, timeout, defaultParams, transactionType + // V, R, S, signer, executionFee, failureFee, timeout, defaultParams, txType proposer, err := bytes2cosmosAddr(params[3][12:]) executionFee, _ := bytes2uint64(params[4]) failureFee, _ := bytes2uint64(params[5]) @@ -973,23 +878,18 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, // return nil, err // } case MsgUpsertTokenAlias: - // V, R, S, signer, invalidated bool, decimals uint32, symbol string, name string, icon string, len, denoms []string + // V, R, S, signer, param proposer, err := bytes2cosmosAddr(params[3][12:]) if err != nil { return nil, err } - isInvalidated := bytes2bool(params[4]) - decimals, _ := bytes2uint32(params[5]) - - var denoms []string - len, _ := bytes2int32(params[9]) - for i := int32(0); i < len; i++ { - denoms = append(denoms, string(params[i+10])) - } + var upsertTokenAliasParam UpsertTokenAliasParam + err = json.Unmarshal(params[4], &upsertTokenAliasParam) + fmt.Println(upsertTokenAliasParam, err) - msg = tokenstypes.NewMsgUpsertTokenAlias(proposer, string(params[6]), string(params[7]), string(params[8]), - uint32(decimals), denoms, isInvalidated) + msg = tokenstypes.NewMsgUpsertTokenAlias(proposer, upsertTokenAliasParam.Symbol, upsertTokenAliasParam.Name, + upsertTokenAliasParam.Icon, upsertTokenAliasParam.Decimals, upsertTokenAliasParam.Denoms, upsertTokenAliasParam.Invalidated) case MsgUpsertTokenRate: // V, R, S, signer, feePayments bool, stakeToken bool, invalidated bool, denom string, rate cosmostypes.Dec, // stakeCap cosmostypes.Dec, stakeMin cosmostypes.Int @@ -1086,10 +986,20 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, msg = multistakingtypes.NewMsgUpsertStakingPool(from, string(params[5]), enabled, commission) case MsgDelegate: // TODO: check eip712 validation - // V, R, S, signer, amount, validator - // validateTx() + // V, R, S, signer, param - balance, err := cosmostypes.ParseCoinsNormalized(string(params[4])) + valParam := string(params[4]) + + validation := ValidateEIP712Sign(params[0][len(params[0])-1:], params[1], params[2], ethcommon.BytesToAddress(params[3][12:]), valParam, txType) + if !validation { + return nil, errors.New("eip712 validation is failed") + } + + var delegateParam DelegateParam + err = json.Unmarshal(params[4], &delegateParam) + fmt.Println(delegateParam, err) + + balance, err := cosmostypes.ParseCoinsNormalized(delegateParam.Amount) if err != nil { return nil, err } @@ -1099,7 +1009,7 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, return nil, err } - to := string(params[5]) + to := delegateParam.To msg = multistakingtypes.NewMsgDelegate(from, to, balance) case MsgUndelegate: @@ -1268,7 +1178,7 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, } msg = custodytypes.NewMsgDropCustodyWhiteList(from, string(params[4]), string(params[5]), string(params[6]), string(params[7])) - case MsgApproveCustodyTransaction: + case MsgApproveCustodyTx: // V, R, S, signer, to string, hash string from, err := bytes2cosmosAddr(params[3][12:]) if err != nil { @@ -1279,7 +1189,7 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, return nil, err } msg = custodytypes.NewMsgApproveCustodyTransaction(from, to, string(params[5])) - case MsgDeclineCustodyTransaction: + case MsgDeclineCustodyTx: // V, R, S, signer, to string, hash string from, err := bytes2cosmosAddr(params[3][12:]) if err != nil { @@ -1298,7 +1208,7 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, return nil, err } txBuilder.SetGasLimit(ethTxData.GasLimit) - // TODO: set fee amount - how can I get the fee amount from eth transaction? or fix this? + // TODO: set fee amount - how can I get the fee amount from eth tx? or fix this? txBuilder.SetFeeAmount(cosmostypes.NewCoins(cosmostypes.NewInt64Coin(config.DefaultKiraDenom, 200))) // txBuilder.SetMemo() // txBuilder.SetTimeoutHeight() @@ -1362,7 +1272,7 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, return txBytes, err } -func sendTx(ctx context.Context, txBytes []byte) (string, error) { +func sendCosmosTx(ctx context.Context, txBytes []byte) (string, error) { // --snip-- // Create a connection to the gRPC server. @@ -1389,7 +1299,7 @@ func sendTx(ctx context.Context, txBytes []byte) (string, error) { ctx, &tx.BroadcastTxRequest{ Mode: tx.BroadcastMode_BROADCAST_MODE_SYNC, - TxBytes: txBytes, // Proto-binary of the signed transaction, see previous step. + TxBytes: txBytes, // Proto-binary of the signed tx, see previous step. }, ) diff --git a/gateway/kira/metamask/metamask.go b/gateway/kira/metamask/metamask.go index 6a6cc28..41b9ad8 100644 --- a/gateway/kira/metamask/metamask.go +++ b/gateway/kira/metamask/metamask.go @@ -253,7 +253,7 @@ func MetamaskRequestHandler(gwCosmosmux *runtime.ServeMux, rpcAddr string) http. return } - txHash, err := SendTx(strData, gwCosmosmux, r) + txHash, err := sendTx(strData, gwCosmosmux, r) if err != nil { fmt.Println("eth_sendRawTransaction err:", err) return diff --git a/gateway/kira/metamask/utils.go b/gateway/kira/metamask/utils.go index f55c7a1..105e3b8 100644 --- a/gateway/kira/metamask/utils.go +++ b/gateway/kira/metamask/utils.go @@ -11,6 +11,7 @@ import ( "github.com/KiraCore/interx/config" cosmostypes "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/bech32" + "github.com/ethereum/go-ethereum/accounts/abi" ) const ( @@ -134,10 +135,21 @@ func bytes2int32(param []byte) (int32, error) { return int32(integer), nil } -func intToBytes(num int64) []byte { - byteArr := make([]byte, 8) // Assuming int64, which is 8 bytes - binary.LittleEndian.PutUint64(byteArr, uint64(num)) - return byteArr +func uint32To32Bytes(val uint32) []byte { + byteArr := make([]byte, 4) + binary.BigEndian.PutUint32(byteArr, val) + + paddedByteArr := addPaddingTo32Bytes(byteArr) + + return paddedByteArr +} + +func addPaddingTo32Bytes(byteArr []byte) []byte { + // Pad the byte array with leading zeros to get the desired length + paddedByteArr := make([]byte, 32) + copy(paddedByteArr[32-len(byteArr):], byteArr) + + return paddedByteArr } func bytes2cosmosAddr(param []byte) (cosmostypes.AccAddress, error) { @@ -172,3 +184,31 @@ func bytes2cosmosValAddr(param []byte) (cosmostypes.ValAddress, error) { func bytes2bool(param []byte) bool { return (param[len(param)-1] == 0x01) } + +func PackABIParams(abi abi.ABI, name string, args ...interface{}) ([]byte, error) { + method, exist := abi.Methods[name] + if !exist { + return nil, fmt.Errorf("method '%s' not found", name) + } + arguments, err := method.Inputs.Pack(args...) + if err != nil { + return nil, err + } + // Pack up the method ID too if not a constructor and return + return arguments, nil +} + +func convertByteArr2Bytes32(val []byte) [32]byte { + var returnVal [32]byte + copy(returnVal[:], val) + return returnVal +} + +func getSignature(r, s, v []byte) []byte { + sig := make([]byte, 65) + copy(sig[:32], r) + copy(sig[32:64], s) + copy(sig[64:], v) + sig[64] = sig[64] - 27 + return sig +} From a0e7a32e71f92e1167f751593f36259094a15050 Mon Sep 17 00:00:00 2001 From: tj327 Date: Mon, 8 Jan 2024 07:16:18 -0500 Subject: [PATCH 06/25] check validation of eip-712 signed tx --- RELEASE.md | 3 +- gateway/kira/metamask/cosmostxsender.go | 381 +++++++++++++----------- gateway/kira/metamask/utils.go | 4 +- 3 files changed, 212 insertions(+), 176 deletions(-) diff --git a/RELEASE.md b/RELEASE.md index 70c81cb..1527ddd 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -2,4 +2,5 @@ Features: * Implement KIP-87 : broadcast metamask coin send transaction to sekai -* Implement KIP-87 : broadcast eip-712 signed transaction to sekai \ No newline at end of file +* Implement KIP-87 : broadcast eip-712 signed transaction to sekai +* Implement KIP-87 : check validation of eip-712 signed tx \ No newline at end of file diff --git a/gateway/kira/metamask/cosmostxsender.go b/gateway/kira/metamask/cosmostxsender.go index 338ef60..3d31536 100644 --- a/gateway/kira/metamask/cosmostxsender.go +++ b/gateway/kira/metamask/cosmostxsender.go @@ -10,7 +10,6 @@ import ( "math" "math/big" "net/http" - "time" sdkmath "cosmossdk.io/math" "github.com/KiraCore/interx/common" @@ -95,12 +94,6 @@ const ( var grpcConn *grpc.ClientConn -type DelegateParam struct { - Amount string `json:"amount"` - // If true it returns the full transaction objects, if false only the hashes of the transactions - To string `json:"to"` -} - type UpsertTokenAliasParam struct { Symbol string `json:"symbol"` Name string `json:"name"` @@ -110,6 +103,21 @@ type UpsertTokenAliasParam struct { Invalidated bool `json:"invalidated"` } +type ListRoleParam struct { + RoleIdentifier string `json:"role_identifier"` + Permission uint32 `json:"permission"` +} + +type PermissionsParam struct { + Permission uint32 `json:"permission"` + ControlledAddr string `json:"controlled_addr"` +} + +type RoleParam struct { + RoleId uint32 `json:"role_id"` + Controller string `json:"controller"` +} + // decode 256bit param like bool, uint, hex-typed address etc func Decode256Bit(data *[]byte, params *[][]byte) { *params = append(*params, (*data)[:32]) @@ -427,7 +435,6 @@ func getStructHash(txType int, valParam string) ethcommon.Hash { case MsgDeclineCustodyTx: funcSig = crypto.Keccak256([]byte("declineCustodyTransaction(string param)")) default: - } structJsonData := []byte(`[{"Type":"function","Name":"encode","Inputs":[{"Type":"bytes32","Name":"funcsig"},{"Type":"bytes32","Name":"param"}],"Outputs":[]}]`) @@ -506,6 +513,15 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, params := DecodeParam(ethTxData.Data[4:], txType) + if txType != MsgBankSend { + valParam := string(params[4]) + + validation := ValidateEIP712Sign(params[0][len(params[0])-1:], params[1], params[2], ethcommon.BytesToAddress(params[3][12:]), valParam, txType) + if !validation { + return nil, errors.New("eip712 validation is failed") + } + } + var msg cosmostypes.Msg switch txType { @@ -529,37 +545,40 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, return nil, err } - height, _ := bytes2int64(params[4]) - power, _ := bytes2int64(params[5]) - unixTime, _ := bytes2int64(params[6]) - - consensusAddr := string(params[7]) - - evidence := &evidencetypes.Equivocation{ - Height: height, - Power: power, - Time: time.UnixMicro(unixTime), - ConsensusAddress: consensusAddr, + var evidenceParam evidencetypes.Equivocation + err = json.Unmarshal(params[4], &evidenceParam) + if err != nil { + return nil, err } - msg, err = evidencetypes.NewMsgSubmitEvidence(from, evidence) + msg, err = evidencetypes.NewMsgSubmitEvidence(from, &evidenceParam) if err != nil { return nil, err } case MsgSubmitProposal: // msg := customgovtypes.NewMsgSubmitProposal(from) case MsgVoteProposal: - // V, R, S, signer, proposalID, option, slash + // V, R, S, signer, param from, err := bytes2cosmosAddr(params[3][12:]) if err != nil { return nil, err } - proposalID, _ := bytes2uint64(params[4]) - option, _ := bytes2uint64(params[5]) - slash, _ := sdkmath.LegacyNewDecFromStr(string(params[6])) + type VoteProposalParam struct { + ProposalID uint64 `json:"proposal_id"` + Option uint64 `json:"option"` + Slash string `json:"slash"` + } - msg = customgovtypes.NewMsgVoteProposal(proposalID, from, customgovtypes.VoteOption(option), slash) + var voteParam VoteProposalParam + err = json.Unmarshal(params[4], &voteParam) + if err != nil { + return nil, err + } + + slash, _ := sdkmath.LegacyNewDecFromStr(voteParam.Slash) + + msg = customgovtypes.NewMsgVoteProposal(voteParam.ProposalID, from, customgovtypes.VoteOption(voteParam.Option), slash) case MsgRegisterIdentityRecords: // V, R, S, signer, identityInfo, from, err := bytes2cosmosAddr(params[3][12:]) @@ -567,21 +586,17 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, return nil, err } - var infosStr map[string]string - err = json.Unmarshal(params[4], &infosStr) - if err != nil { - return nil, err + type IdentityRecordParam struct { + Infos []customgovtypes.IdentityInfoEntry `json:"identity_infos"` } - var infos []customgovtypes.IdentityInfoEntry - for key := range infosStr { - infos = append(infos, customgovtypes.IdentityInfoEntry{ - Key: key, - Info: infosStr[key], - }) + var recordParam IdentityRecordParam + err = json.Unmarshal(params[4], &recordParam) + if err != nil { + return nil, err } - msg = customgovtypes.NewMsgRegisterIdentityRecords(from, infos) + msg = customgovtypes.NewMsgRegisterIdentityRecords(from, recordParam.Infos) case MsgDeleteIdentityRecord: // V, R, S, signer, len, keys, from, err := bytes2cosmosAddr(params[3][12:]) @@ -589,13 +604,17 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, return nil, err } - var keys []string - len, _ := bytes2uint64(params[4]) - for i := uint64(0); i < len; i++ { - keys = append(keys, string(params[5+i])) + type IdentityRecordParam struct { + Keys []string `json:"keys"` } - msg = customgovtypes.NewMsgDeleteIdentityRecords(from, keys) + var recordParam IdentityRecordParam + err = json.Unmarshal(params[4], &recordParam) + if err != nil { + return nil, err + } + + msg = customgovtypes.NewMsgDeleteIdentityRecords(from, recordParam.Keys) case MsgRequestIdentityRecordsVerify: // V, R, S, signer, tip, verifier, len, recordIds from, err := bytes2cosmosAddr(params[3][12:]) @@ -603,24 +622,29 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, return nil, err } - balance, err := cosmostypes.ParseCoinNormalized(string(params[4])) + type IdentityRecordParam struct { + Balance string `json:"balance"` + Verifier string `json:"verifier"` + RecordIds []uint64 `json:"record_ids"` + } + + var recordParam IdentityRecordParam + err = json.Unmarshal(params[4], &recordParam) if err != nil { return nil, err } - verifier, err := string2cosmosAddr(params[5]) + balance, err := cosmostypes.ParseCoinNormalized(recordParam.Balance) if err != nil { return nil, err } - var recordIds []uint64 - len, _ := bytes2int64(params[6]) - for i := 0; i < int(len); i++ { - recordId, _ := bytes2uint64(params[7+i]) - recordIds = append(recordIds, recordId) + verifier, err := string2cosmosAddr(recordParam.Verifier) + if err != nil { + return nil, err } - msg = customgovtypes.NewMsgRequestIdentityRecordsVerify(from, verifier, recordIds, balance) + msg = customgovtypes.NewMsgRequestIdentityRecordsVerify(from, verifier, recordParam.RecordIds, balance) case MsgHandleIdentityRecordsVerifyRequest: // V, R, S, signer, requestId, isApprove verifier, err := bytes2cosmosAddr(params[3][12:]) @@ -628,10 +652,18 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, return nil, err } - isApprove := bytes2bool(params[5]) - requestId, _ := bytes2uint64(params[4]) + type IdentityRecordParam struct { + RequestID uint64 `json:"request_id"` + IsApproved bool `json:"is_approved"` + } + + var recordParam IdentityRecordParam + err = json.Unmarshal(params[4], &recordParam) + if err != nil { + return nil, err + } - msg = customgovtypes.NewMsgHandleIdentityRecordsVerifyRequest(verifier, requestId, isApprove) + msg = customgovtypes.NewMsgHandleIdentityRecordsVerifyRequest(verifier, recordParam.RequestID, recordParam.IsApproved) case MsgCancelIdentityRecordsVerifyRequest: // V, R, S, signer, verifyRequestId executor, err := bytes2cosmosAddr(params[3][12:]) @@ -639,117 +671,53 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, return nil, err } - verifyRequestId, _ := bytes2uint64(params[4]) + type IdentityRecordParam struct { + VerifyRequestId uint64 `json:"verify_request_id"` + } + + var recordParam IdentityRecordParam + err = json.Unmarshal(params[4], &recordParam) + if err != nil { + return nil, err + } - msg = customgovtypes.NewMsgCancelIdentityRecordsVerifyRequest(executor, verifyRequestId) + msg = customgovtypes.NewMsgCancelIdentityRecordsVerifyRequest(executor, recordParam.VerifyRequestId) case MsgSetNetworkProperties: - // V, R, S, signer, len, boolParamsList, len, uintParamsList, len, strParamsList, len, legacyDecParamsList + // V, R, S, signer, networkProperties proposer, err := bytes2cosmosAddr(params[3][12:]) if err != nil { return nil, err } - var boolParams []bool - var uintParams []uint64 - var strParams []string - var legacyDecParams []sdkmath.LegacyDec - - boolLen, _ := bytes2uint64(params[4]) - for i := uint64(0); i < boolLen; i++ { - boolParams = append(boolParams, bytes2bool(params[5+i])) - } - - uintLen, _ := bytes2uint64(params[5+boolLen]) - for i := uint64(0); i < uintLen; i++ { - uintParam, _ := bytes2uint64(params[6+boolLen+i]) - uintParams = append(uintParams, uintParam) - } - - strLen, _ := bytes2uint64(params[6+boolLen+uintLen]) - for i := uint64(0); i < strLen; i++ { - strParams = append(strParams, string(params[7+boolLen+uintLen+i])) - } - - legacyDecLen, _ := bytes2uint64(params[7+boolLen+uintLen+strLen]) - for i := uint64(0); i < legacyDecLen; i++ { - legacyDecParam, _ := sdkmath.LegacyNewDecFromStr(string(params[8+boolLen+uintLen+strLen+i])) - legacyDecParams = append(legacyDecParams, legacyDecParam) - } - - networkProperties := customgovtypes.NetworkProperties{ - EnableForeignFeePayments: boolParams[0], - EnableTokenWhitelist: boolParams[1], - EnableTokenBlacklist: boolParams[2], - MinTxFee: uintParams[0], - MaxTxFee: uintParams[1], - VoteQuorum: uintParams[2], - MinimumProposalEndTime: uintParams[3], - ProposalEnactmentTime: uintParams[4], - MinProposalEndBlocks: uintParams[5], - MinProposalEnactmentBlocks: uintParams[6], - MaxMischance: uintParams[7], - MischanceConfidence: uintParams[8], - MinValidators: uintParams[9], - PoorNetworkMaxBankSend: uintParams[10], - UnjailMaxTime: uintParams[11], - MinIdentityApprovalTip: uintParams[12], - UbiHardcap: uintParams[13], - InflationPeriod: uintParams[14], - UnstakingPeriod: uintParams[15], - MaxDelegators: uintParams[16], - MinDelegationPushout: uintParams[17], - SlashingPeriod: uintParams[18], - MinCustodyReward: uintParams[19], - MaxCustodyBufferSize: uintParams[20], - MaxCustodyTxSize: uintParams[21], - AbstentionRankDecreaseAmount: uintParams[22], - MaxAbstention: uintParams[23], - MinCollectiveBond: uintParams[24], - MinCollectiveBondingTime: uintParams[25], - MaxCollectiveOutputs: uintParams[26], - MinCollectiveClaimPeriod: uintParams[27], - ValidatorRecoveryBond: uintParams[28], - MaxProposalTitleSize: uintParams[29], - MaxProposalDescriptionSize: uintParams[30], - MaxProposalPollOptionSize: uintParams[31], - MaxProposalPollOptionCount: uintParams[32], - MaxProposalReferenceSize: uintParams[33], - MaxProposalChecksumSize: uintParams[34], - MinDappBond: uintParams[35], - MaxDappBond: uintParams[36], - DappLiquidationThreshold: uintParams[37], - DappLiquidationPeriod: uintParams[38], - DappBondDuration: uintParams[39], - DappAutoDenounceTime: uintParams[40], - DappMaxMischance: uintParams[41], - DappInactiveRankDecreasePercent: uintParams[42], - MintingFtFee: uintParams[43], - MintingNftFee: uintParams[44], - UniqueIdentityKeys: strParams[0], - InactiveRankDecreasePercent: legacyDecParams[0], - ValidatorsFeeShare: legacyDecParams[1], - InflationRate: legacyDecParams[2], - MaxJailedPercentage: legacyDecParams[3], - MaxSlashingPercentage: legacyDecParams[4], - MaxAnnualInflation: legacyDecParams[5], - DappVerifierBond: legacyDecParams[6], - DappPoolSlippageDefault: legacyDecParams[7], - VetoThreshold: legacyDecParams[8], - } - - msg = customgovtypes.NewMsgSetNetworkProperties(proposer, &networkProperties) + type NetworkPropertiesParam struct { + NetworkProperties customgovtypes.NetworkProperties `json:"network_properties"` + } + + var networkProperties NetworkPropertiesParam + err = json.Unmarshal(params[4], &networkProperties) + if err != nil { + return nil, err + } + + msg = customgovtypes.NewMsgSetNetworkProperties(proposer, &networkProperties.NetworkProperties) case MsgSetExecutionFee: - // V, R, S, signer, executionFee, failureFee, timeout, defaultParams, txType + // V, R, S, signer, executionFee, failureFee, timeout, defaultParams proposer, err := bytes2cosmosAddr(params[3][12:]) - executionFee, _ := bytes2uint64(params[4]) - failureFee, _ := bytes2uint64(params[5]) - timeout, _ := bytes2uint64(params[6]) - defaultParams, _ := bytes2uint64(params[7]) + + type ExecutionFeeParam struct { + ExecutionFee uint64 `json:"execution_fee"` + FailureFee uint64 `json:"failure_fee"` + Timeout uint64 `json:"timeout"` + DefaultParams uint64 `json:"default_params"` + } + + var feeParam ExecutionFeeParam + err = json.Unmarshal(params[4], &feeParam) if err != nil { return nil, err } - msg = customgovtypes.NewMsgSetExecutionFee(string(params[8]), executionFee, failureFee, timeout, defaultParams, proposer) + msg = customgovtypes.NewMsgSetExecutionFee(string(params[8]), feeParam.ExecutionFee, feeParam.FailureFee, feeParam.Timeout, feeParam.DefaultParams, proposer) case MsgClaimCouncilor: // V, R, S, signer, moniker string, username string, description string, social string, contact string, avatar string sender, err := bytes2cosmosAddr(params[3][12:]) @@ -757,8 +725,23 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, return nil, err } - msg = customgovtypes.NewMsgClaimCouncilor(sender, string(params[4]), string(params[5]), string(params[6]), - string(params[7]), string(params[8]), string(params[9])) + type ClaimCouncilorParam struct { + Moniker string `json:"moniker"` + Username string `json:"username"` + Description string `json:"description"` + Social string `json:"social"` + Contact string `json:"contact"` + Avatar string `json:"avatar"` + } + + var councilorParam ClaimCouncilorParam + err = json.Unmarshal(params[4], &councilorParam) + if err != nil { + return nil, err + } + + msg = customgovtypes.NewMsgClaimCouncilor(sender, councilorParam.Moniker, councilorParam.Username, councilorParam.Description, + councilorParam.Social, councilorParam.Contact, councilorParam.Avatar) case MsgWhitelistPermissions: // V, R, S, signer, permission uint256, controlledAddr string sender, err := bytes2cosmosAddr(params[3][12:]) @@ -766,13 +749,18 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, return nil, err } - permission, _ := bytes2uint32(params[4]) - controlledAddr, err := string2cosmosAddr(params[5]) + var permissionParam PermissionsParam + err = json.Unmarshal(params[4], &permissionParam) if err != nil { return nil, err } - msg = customgovtypes.NewMsgWhitelistPermissions(sender, controlledAddr, permission) + controlledAddr, err := string2cosmosAddr(permissionParam.ControlledAddr) + if err != nil { + return nil, err + } + + msg = customgovtypes.NewMsgWhitelistPermissions(sender, controlledAddr, permissionParam.Permission) case MsgBlacklistPermissions: // V, R, S, signer, permission uint256, controlledAddr string sender, err := bytes2cosmosAddr(params[3][12:]) @@ -780,13 +768,18 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, return nil, err } - permission, _ := bytes2uint32(params[4]) - controlledAddr, err := string2cosmosAddr(params[5]) + var permissionParam PermissionsParam + err = json.Unmarshal(params[4], &permissionParam) if err != nil { return nil, err } - msg = customgovtypes.NewMsgBlacklistPermissions(sender, controlledAddr, permission) + controlledAddr, err := string2cosmosAddr(permissionParam.ControlledAddr) + if err != nil { + return nil, err + } + + msg = customgovtypes.NewMsgBlacklistPermissions(sender, controlledAddr, permissionParam.Permission) case MsgCreateRole: // V, R, S, signer, sid string, description string sender, err := bytes2cosmosAddr(params[3][12:]) @@ -794,7 +787,18 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, return nil, err } - msg = customgovtypes.NewMsgCreateRole(sender, string(params[4]), string(params[5])) + type RoleParam struct { + Sid string `json:"sid"` + Description string `json:"description"` + } + + var roleParam RoleParam + err = json.Unmarshal(params[4], &roleParam) + if err != nil { + return nil, err + } + + msg = customgovtypes.NewMsgCreateRole(sender, roleParam.Sid, roleParam.Description) case MsgAssignRole: // V, R, S, signer, roleid uint32, controller string sender, err := bytes2cosmosAddr(params[3][12:]) @@ -802,13 +806,18 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, return nil, err } - roleId, _ := bytes2uint32(params[4]) - controller, err := string2cosmosAddr(params[5]) + var roleParam RoleParam + err = json.Unmarshal(params[4], &roleParam) + if err != nil { + return nil, err + } + + controller, err := string2cosmosAddr(roleParam.Controller) if err != nil { return nil, err } - msg = customgovtypes.NewMsgAssignRole(sender, controller, roleId) + msg = customgovtypes.NewMsgAssignRole(sender, controller, roleParam.RoleId) case MsgUnassignRole: // V, R, S, signer, roleid uint32, controller address sender, err := bytes2cosmosAddr(params[3][12:]) @@ -816,13 +825,18 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, return nil, err } - roleId, _ := bytes2uint32(params[4]) - controller, err := string2cosmosAddr(params[5]) + var roleParam RoleParam + err = json.Unmarshal(params[4], &roleParam) if err != nil { return nil, err } - msg = customgovtypes.NewMsgUnassignRole(sender, controller, roleId) + controller, err := string2cosmosAddr(roleParam.Controller) + if err != nil { + return nil, err + } + + msg = customgovtypes.NewMsgUnassignRole(sender, controller, roleParam.RoleId) case MsgWhitelistRolePermission: // V, R, S, signer, permission uint32, roleIdentifier string sender, err := bytes2cosmosAddr(params[3][12:]) @@ -830,9 +844,13 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, return nil, err } - permission, _ := bytes2uint32(params[4]) + var roleParam ListRoleParam + err = json.Unmarshal(params[4], &roleParam) + if err != nil { + return nil, err + } - msg = customgovtypes.NewMsgWhitelistRolePermission(sender, string(params[5]), permission) + msg = customgovtypes.NewMsgWhitelistRolePermission(sender, roleParam.RoleIdentifier, roleParam.Permission) case MsgBlacklistRolePermission: // V, R, S, signer, permission uint32, roleIdentifier string sender, err := bytes2cosmosAddr(params[3][12:]) @@ -840,9 +858,13 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, return nil, err } - permission, _ := bytes2uint32(params[4]) + var roleParam ListRoleParam + err = json.Unmarshal(params[4], &roleParam) + if err != nil { + return nil, err + } - msg = customgovtypes.NewMsgBlacklistRolePermission(sender, string(params[5]), permission) + msg = customgovtypes.NewMsgBlacklistRolePermission(sender, roleParam.RoleIdentifier, roleParam.Permission) case MsgRemoveWhitelistRolePermission: // V, R, S, signer, permission uint32, roleIdentifier string sender, err := bytes2cosmosAddr(params[3][12:]) @@ -850,9 +872,13 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, return nil, err } - permission, _ := bytes2uint32(params[4]) + var roleParam ListRoleParam + err = json.Unmarshal(params[4], &roleParam) + if err != nil { + return nil, err + } - msg = customgovtypes.NewMsgRemoveWhitelistRolePermission(sender, string(params[5]), permission) + msg = customgovtypes.NewMsgRemoveWhitelistRolePermission(sender, roleParam.RoleIdentifier, roleParam.Permission) case MsgRemoveBlacklistRolePermission: // V, R, S, signer, permission uint32, roleIdentifier string sender, err := bytes2cosmosAddr(params[3][12:]) @@ -860,9 +886,13 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, return nil, err } - permission, _ := bytes2uint32(params[4]) + var roleParam ListRoleParam + err = json.Unmarshal(params[4], &roleParam) + if err != nil { + return nil, err + } - msg = customgovtypes.NewMsgRemoveBlacklistRolePermission(sender, string(params[5]), permission) + msg = customgovtypes.NewMsgRemoveBlacklistRolePermission(sender, roleParam.RoleIdentifier, roleParam.Permission) case MsgClaimValidator: // V, R, S, signer, moniker string, valKey cosmostypes.ValAddress, pubKey cryptotypes.PubKey @@ -995,6 +1025,11 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, return nil, errors.New("eip712 validation is failed") } + type DelegateParam struct { + Amount string `json:"amount"` + To string `json:"to"` + } + var delegateParam DelegateParam err = json.Unmarshal(params[4], &delegateParam) fmt.Println(delegateParam, err) diff --git a/gateway/kira/metamask/utils.go b/gateway/kira/metamask/utils.go index 105e3b8..228e1f6 100644 --- a/gateway/kira/metamask/utils.go +++ b/gateway/kira/metamask/utils.go @@ -166,8 +166,8 @@ func bytes2cosmosAddr(param []byte) (cosmostypes.AccAddress, error) { return addr, nil } -func string2cosmosAddr(param []byte) (cosmostypes.AccAddress, error) { - addr, err := cosmostypes.AccAddressFromBech32(string(param)) +func string2cosmosAddr(param string) (cosmostypes.AccAddress, error) { + addr, err := cosmostypes.AccAddressFromBech32(param) return addr, err } From 91464ea49482b0a97b17d5bb52978f6a62cc7aee Mon Sep 17 00:00:00 2001 From: tj327 Date: Tue, 9 Jan 2024 03:23:01 -0500 Subject: [PATCH 07/25] finish validation of eip712-signed tx --- gateway/kira/metamask/cosmostxsender.go | 464 ++++++++++++++++-------- 1 file changed, 312 insertions(+), 152 deletions(-) diff --git a/gateway/kira/metamask/cosmostxsender.go b/gateway/kira/metamask/cosmostxsender.go index 3d31536..2deee25 100644 --- a/gateway/kira/metamask/cosmostxsender.go +++ b/gateway/kira/metamask/cosmostxsender.go @@ -21,6 +21,7 @@ import ( multistakingtypes "github.com/KiraCore/sekai/x/multistaking/types" slashingtypes "github.com/KiraCore/sekai/x/slashing/types" spendingtypes "github.com/KiraCore/sekai/x/spending/types" + stakingtypes "github.com/KiraCore/sekai/x/staking/types" tokenstypes "github.com/KiraCore/sekai/x/tokens/types" clienttx "github.com/cosmos/cosmos-sdk/client/tx" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" @@ -94,15 +95,6 @@ const ( var grpcConn *grpc.ClientConn -type UpsertTokenAliasParam struct { - Symbol string `json:"symbol"` - Name string `json:"name"` - Icon string `json:"icon"` - Decimals uint32 `json:"decimals"` - Denoms []string `json:"denoms"` - Invalidated bool `json:"invalidated"` -} - type ListRoleParam struct { RoleIdentifier string `json:"role_identifier"` Permission uint32 `json:"permission"` @@ -118,10 +110,27 @@ type RoleParam struct { Controller string `json:"controller"` } +type DelegateParam struct { + Amounts cosmostypes.Coins `json:"amounts"` + To string `json:"to"` +} + +type CustodianParam struct { + NewAddrs []cosmostypes.AccAddress `json:"new_addrs"` + OldKey string `json:"old_key"` + NewKey string `json:"new_key"` + Next string `json:"next"` + Target string `json:"target"` +} + // decode 256bit param like bool, uint, hex-typed address etc -func Decode256Bit(data *[]byte, params *[][]byte) { +func Decode256Bit(data *[]byte, params *[][]byte) error { + if len(*data) < 32 { + return errors.New("decoding 256bit failed, not enough length") + } *params = append(*params, (*data)[:32]) *data = (*data)[32:] + return nil } // decode string-typed param @@ -129,33 +138,40 @@ func Decode256Bit(data *[]byte, params *[][]byte) { // * offset - offset of the string in the data : 32byte // * length - length of the string : 32byte // * content - content of the string : (length/32+1)*32byte -func DecodeString(data *[]byte, params *[][]byte) { +func DecodeString(data *[]byte, params *[][]byte) error { // offset := data[:32] // string value offset *data = (*data)[32:] - length, _ := bytes2uint64((*data)[:32]) + length, err := bytes2uint64((*data)[:32]) + if err != nil { + return err + } *data = (*data)[32:] *params = append(*params, (*data)[:length]) *data = (*data)[(length/32+1)*32:] + return nil } -func DecodeParam(data []byte, txType int) [][]byte { +func DecodeParam(data []byte, txType int) ([][]byte, error) { if txType == MsgBankSend { - return nil + return nil, nil } var params [][]byte // decode data field v, r, s, sender for i := 0; i < 4; i++ { - Decode256Bit(&data, ¶ms) + err := Decode256Bit(&data, ¶ms) + if err != nil { + return nil, err + } } // decode param string - DecodeString(&data, ¶ms) + err := DecodeString(&data, ¶ms) - return params + return params, err } func sendTx(txRawData string, gwCosmosmux *runtime.ServeMux, r *http.Request) (string, error) { @@ -511,7 +527,10 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, return nil, err } - params := DecodeParam(ethTxData.Data[4:], txType) + params, err := DecodeParam(ethTxData.Data[4:], txType) + if err != nil { + return nil, err + } if txType != MsgBankSend { valParam := string(params[4]) @@ -556,7 +575,27 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, return nil, err } case MsgSubmitProposal: - // msg := customgovtypes.NewMsgSubmitProposal(from) + // from, err := bytes2cosmosAddr(params[3][12:]) + // if err != nil { + // return nil, err + // } + + // type SubmitProposalParam struct { + // Title string `json:"title"` + // Description string `json:"description"` + // Content string `json:"content"` + // } + + // var proposalParam SubmitProposalParam + // err = json.Unmarshal(params[4], &proposalParam) + // if err != nil { + // return nil, err + // } + + // msg, err := customgovtypes.NewMsgSubmitProposal(from) + // if err != nil { + // return nil, err + // } case MsgVoteProposal: // V, R, S, signer, param from, err := bytes2cosmosAddr(params[3][12:]) @@ -570,15 +609,18 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, Slash string `json:"slash"` } - var voteParam VoteProposalParam - err = json.Unmarshal(params[4], &voteParam) + var proposalParam VoteProposalParam + err = json.Unmarshal(params[4], &proposalParam) if err != nil { return nil, err } - slash, _ := sdkmath.LegacyNewDecFromStr(voteParam.Slash) + slash, err := sdkmath.LegacyNewDecFromStr(proposalParam.Slash) + if err != nil { + return nil, err + } - msg = customgovtypes.NewMsgVoteProposal(voteParam.ProposalID, from, customgovtypes.VoteOption(voteParam.Option), slash) + msg = customgovtypes.NewMsgVoteProposal(proposalParam.ProposalID, from, customgovtypes.VoteOption(proposalParam.Option), slash) case MsgRegisterIdentityRecords: // V, R, S, signer, identityInfo, from, err := bytes2cosmosAddr(params[3][12:]) @@ -703,12 +745,16 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, case MsgSetExecutionFee: // V, R, S, signer, executionFee, failureFee, timeout, defaultParams proposer, err := bytes2cosmosAddr(params[3][12:]) + if err != nil { + return nil, err + } type ExecutionFeeParam struct { - ExecutionFee uint64 `json:"execution_fee"` - FailureFee uint64 `json:"failure_fee"` - Timeout uint64 `json:"timeout"` - DefaultParams uint64 `json:"default_params"` + TransactionType string `json:"transaction_type"` + ExecutionFee uint64 `json:"execution_fee"` + FailureFee uint64 `json:"failure_fee"` + Timeout uint64 `json:"timeout"` + DefaultParams uint64 `json:"default_params"` } var feeParam ExecutionFeeParam @@ -717,7 +763,8 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, return nil, err } - msg = customgovtypes.NewMsgSetExecutionFee(string(params[8]), feeParam.ExecutionFee, feeParam.FailureFee, feeParam.Timeout, feeParam.DefaultParams, proposer) + msg = customgovtypes.NewMsgSetExecutionFee(feeParam.TransactionType, feeParam.ExecutionFee, feeParam.FailureFee, + feeParam.Timeout, feeParam.DefaultParams, proposer) case MsgClaimCouncilor: // V, R, S, signer, moniker string, username string, description string, social string, contact string, avatar string sender, err := bytes2cosmosAddr(params[3][12:]) @@ -896,17 +943,27 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, case MsgClaimValidator: // V, R, S, signer, moniker string, valKey cosmostypes.ValAddress, pubKey cryptotypes.PubKey - // valKey, err := cosmostypes.ValAddressFromBech32(string(params[5])) - // if err != nil { - // return nil, err - // } + type ClaimParam struct { + Moniker string `json:"moniker"` + ValKey string `json:"val_key"` + PubKey cryptotypes.PubKey `json:"pub_key"` + } - // TODO: get public key from str - // publicKey, err := secp256k1.PubKeySecp256k1([]byte(params[6])) - // msg, err := stakingtypes.NewMsgClaimValidator(string(params[4]), valKey, publicKey) - // if err != nil { - // return nil, err - // } + var claimParam ClaimParam + err = json.Unmarshal(params[4], &claimParam) + if err != nil { + return nil, err + } + + valKey, err := cosmostypes.ValAddressFromBech32(claimParam.ValKey) + if err != nil { + return nil, err + } + + msg, err = stakingtypes.NewMsgClaimValidator(claimParam.Moniker, valKey, claimParam.PubKey) + if err != nil { + return nil, err + } case MsgUpsertTokenAlias: // V, R, S, signer, param proposer, err := bytes2cosmosAddr(params[3][12:]) @@ -914,9 +971,20 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, return nil, err } + type UpsertTokenAliasParam struct { + Symbol string `json:"symbol"` + Name string `json:"name"` + Icon string `json:"icon"` + Decimals uint32 `json:"decimals"` + Denoms []string `json:"denoms"` + Invalidated bool `json:"invalidated"` + } + var upsertTokenAliasParam UpsertTokenAliasParam err = json.Unmarshal(params[4], &upsertTokenAliasParam) - fmt.Println(upsertTokenAliasParam, err) + if err != nil { + return nil, err + } msg = tokenstypes.NewMsgUpsertTokenAlias(proposer, upsertTokenAliasParam.Symbol, upsertTokenAliasParam.Name, upsertTokenAliasParam.Icon, upsertTokenAliasParam.Decimals, upsertTokenAliasParam.Denoms, upsertTokenAliasParam.Invalidated) @@ -928,25 +996,24 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, return nil, err } - isFeePayments := bytes2bool(params[4]) - isStakeToken := bytes2bool(params[5]) - isInvalidated := bytes2bool(params[6]) - denom := string(params[7]) - rate, err := cosmostypes.NewDecFromStr(hex.EncodeToString(params[8])) - if err != nil { - return nil, err + type UpsertTokenRateParam struct { + Denom string `json:"denom"` + Rate cosmostypes.Dec `json:"rate"` + IsFeePayments bool `json:"is_fee_payments"` + StakeCap cosmostypes.Dec `json:"stake_cap"` + StakeMin cosmostypes.Int `json:"stake_min"` + IsStakeToken bool `json:"is_stake_token"` + Invalidated bool `json:"invalidated"` } - stakeCap, err := cosmostypes.NewDecFromStr(hex.EncodeToString(params[9])) + + var upsertParam UpsertTokenRateParam + err = json.Unmarshal(params[4], &upsertParam) if err != nil { return nil, err } - stakeMin, ok := cosmostypes.NewIntFromString(hex.EncodeToString(params[10])) - if !ok { - return nil, err - } - msg = tokenstypes.NewMsgUpsertTokenRate(proposer, denom, rate, isFeePayments, stakeCap, stakeMin, - isStakeToken, isInvalidated) + msg = tokenstypes.NewMsgUpsertTokenRate(proposer, upsertParam.Denom, upsertParam.Rate, upsertParam.IsFeePayments, + upsertParam.StakeCap, upsertParam.StakeMin, upsertParam.IsStakeToken, upsertParam.Invalidated) case MsgActivate: // V, R, S, signer validator, err := bytes2cosmosValAddr(params[3][12:]) @@ -972,34 +1039,89 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, // V, R, S, signer, name string, claimStart uint64, claimEnd uint64, rates cosmostypes.DecCoins, voteQuorum uint64, // votePeriod uint64, voteEnactment uint64, owners spendingtypes.PermInfo, beneficiaries spendingtypes.WeightedPermInfo, // sender cosmostypes.AccAddress, dynamicRate bool, dynamicRatePeriod uint64 + sender, err := bytes2cosmosAddr(params[3][12:]) + if err != nil { + return nil, err + } + + type SpendingPoolParam struct { + Name string `json:"name"` + ClaimStart uint64 `json:"claim_start"` + ClaimEnd uint64 `json:"claim_end"` + Rates cosmostypes.DecCoins `json:"rates"` + VoteQuorum uint64 `json:"vote_quorum"` + VotePeriod uint64 `json:"vote_period"` + VoteEnactment uint64 `json:"vote_enactment"` + Owners spendingtypes.PermInfo `json:"owners"` + Beneficiaries spendingtypes.WeightedPermInfo `json:"beneficiaries"` + IsDynamicRate bool `json:"is_dynamic_rate"` + DynamicRatePeriod uint64 `json:"dynamic_rate_period"` + } + + var poolParam SpendingPoolParam + err = json.Unmarshal(params[4], &poolParam) + if err != nil { + return nil, err + } - // msg = spendingtypes.NewMsgCreateSpendingPool() + msg = spendingtypes.NewMsgCreateSpendingPool(poolParam.Name, poolParam.ClaimStart, poolParam.ClaimEnd, poolParam.Rates, + poolParam.VoteQuorum, poolParam.VotePeriod, poolParam.VoteEnactment, poolParam.Owners, poolParam.Beneficiaries, + sender, poolParam.IsDynamicRate, poolParam.DynamicRatePeriod) case MsgDepositSpendingPool: // V, R, S, signer, amount string, name string sender, err := bytes2cosmosAddr(params[3][12:]) if err != nil { return nil, err } - amount, err := cosmostypes.ParseCoinsNormalized(string(params[4])) + + type SpendingPoolParam struct { + Name string `json:"Name"` + Amount cosmostypes.Coins `json:"Amount"` + } + + var poolParam SpendingPoolParam + err = json.Unmarshal(params[4], &poolParam) if err != nil { return nil, err } - msg = spendingtypes.NewMsgDepositSpendingPool(string(params[5]), amount, sender) + msg = spendingtypes.NewMsgDepositSpendingPool(poolParam.Name, poolParam.Amount, sender) case MsgRegisterSpendingPoolBeneficiary: // V, R, S, signer, name string sender, err := bytes2cosmosAddr(params[3][12:]) if err != nil { return nil, err } - msg = spendingtypes.NewMsgRegisterSpendingPoolBeneficiary(string(params[4]), sender) + + type SpendingPoolParam struct { + Name string `json:"Name"` + } + + var poolParam SpendingPoolParam + err = json.Unmarshal(params[4], &poolParam) + if err != nil { + return nil, err + } + + msg = spendingtypes.NewMsgRegisterSpendingPoolBeneficiary(poolParam.Name, sender) case MsgClaimSpendingPool: // V, R, S, signer, name string sender, err := bytes2cosmosAddr(params[3][12:]) if err != nil { return nil, err } - msg = spendingtypes.NewMsgClaimSpendingPool(string(params[4]), sender) + + type SpendingPoolParam struct { + Name string `json:"Name"` + } + + var poolParam SpendingPoolParam + err = json.Unmarshal(params[4], &poolParam) + if err != nil { + return nil, err + } + + msg = spendingtypes.NewMsgClaimSpendingPool(poolParam.Name, sender) case MsgUpsertStakingPool: // V, R, S, signer, enabled bool, validator string, commission cosmostypes.Dec from, err := hex2bech32(hex.EncodeToString(params[3][12:]), TypeKiraAddr) @@ -1007,59 +1129,47 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, return nil, err } - enabled := bytes2bool(params[4]) - commission, err := cosmostypes.NewDecFromStr(string(params[5])) + type StakingPoolParam struct { + Validator string `json:"validator"` + Enabled bool `json:"enabled"` + Commission cosmostypes.Dec `json:"commission"` + } + + var poolParam StakingPoolParam + err = json.Unmarshal(params[4], &poolParam) if err != nil { return nil, err } - msg = multistakingtypes.NewMsgUpsertStakingPool(from, string(params[5]), enabled, commission) + msg = multistakingtypes.NewMsgUpsertStakingPool(from, poolParam.Validator, poolParam.Enabled, poolParam.Commission) case MsgDelegate: - // TODO: check eip712 validation // V, R, S, signer, param - - valParam := string(params[4]) - - validation := ValidateEIP712Sign(params[0][len(params[0])-1:], params[1], params[2], ethcommon.BytesToAddress(params[3][12:]), valParam, txType) - if !validation { - return nil, errors.New("eip712 validation is failed") - } - - type DelegateParam struct { - Amount string `json:"amount"` - To string `json:"to"` - } - - var delegateParam DelegateParam - err = json.Unmarshal(params[4], &delegateParam) - fmt.Println(delegateParam, err) - - balance, err := cosmostypes.ParseCoinsNormalized(delegateParam.Amount) + from, err := hex2bech32(hex.EncodeToString(params[3][12:]), TypeKiraAddr) if err != nil { return nil, err } - from, err := hex2bech32(hex.EncodeToString(params[3][12:]), TypeKiraAddr) + var delegateParam DelegateParam + err = json.Unmarshal(params[4], &delegateParam) if err != nil { return nil, err } - to := delegateParam.To - - msg = multistakingtypes.NewMsgDelegate(from, to, balance) + msg = multistakingtypes.NewMsgDelegate(from, delegateParam.To, delegateParam.Amounts) case MsgUndelegate: // V, R, S, signer, amount, validator from, err := hex2bech32(hex.EncodeToString(params[3][12:]), TypeKiraAddr) if err != nil { return nil, err } - balance, err := cosmostypes.ParseCoinsNormalized(string(params[4])) + + var delegateParam DelegateParam + err = json.Unmarshal(params[4], &delegateParam) if err != nil { return nil, err } - to := string(params[5]) - msg = multistakingtypes.NewMsgUndelegate(from, to, balance) + msg = multistakingtypes.NewMsgUndelegate(from, delegateParam.To, delegateParam.Amounts) case MsgClaimRewards: // V, R, S, signer from, err := hex2bech32(hex.EncodeToString(params[3][12:]), TypeKiraAddr) @@ -1073,22 +1183,37 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, if err != nil { return nil, err } - undelegationId, _ := bytes2uint64(params[4]) - msg = multistakingtypes.NewMsgClaimUndelegation(from, undelegationId) + type UndelegationParam struct { + UndelegationId uint64 `json:"undelegation_id"` + } + + var undelegationParam UndelegationParam + err = json.Unmarshal(params[4], &undelegationParam) + if err != nil { + return nil, err + } + + msg = multistakingtypes.NewMsgClaimUndelegation(from, undelegationParam.UndelegationId) case MsgSetCompoundInfo: // V, R, S, signer, allDenom bool, len, denoms []string from, err := hex2bech32(hex.EncodeToString(params[3][12:]), TypeKiraAddr) if err != nil { return nil, err } - allDenom := bytes2bool(params[4]) - var denoms []string - len, _ := bytes2uint64(params[5]) - for i := uint64(0); i < len; i++ { - denoms = append(denoms, string(params[i+6])) + + type UndelegationParam struct { + IsAllDenom bool `json:"is_all_denom"` + Denoms []string `json:"denoms"` + } + + var undelegationParam UndelegationParam + err = json.Unmarshal(params[4], &undelegationParam) + if err != nil { + return nil, err } - msg = multistakingtypes.NewMsgSetCompoundInfo(from, allDenom, denoms) + + msg = multistakingtypes.NewMsgSetCompoundInfo(from, undelegationParam.IsAllDenom, undelegationParam.Denoms) case MsgRegisterDelegator: // V, R, S, signer from, err := hex2bech32(hex.EncodeToString(params[3][12:]), TypeKiraAddr) @@ -1104,33 +1229,22 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, return nil, err } - custodyMode, _ := bytes2uint64(params[4]) - - var boolArr []bool - boolArrLen, _ := bytes2uint64(params[7]) - for i := uint64(0); i < boolArrLen; i++ { - boolParam := bytes2bool(params[i+8]) - boolArr = append(boolArr, boolParam) + type CustodyParam struct { + CustodySettings custodytypes.CustodySettings `json:"custody_settings"` + OldKey string `json:"old_key"` + NewKey string `json:"new_key"` + Next string `json:"next"` + Target string `json:"target"` } - var strArr []string - strArrLen, _ := bytes2uint64(params[8+boolArrLen]) - for i := uint64(0); i < strArrLen; i++ { - param := string(params[i+9+boolArrLen]) - strArr = append(strArr, param) + var custodyParam CustodyParam + err = json.Unmarshal(params[4], &custodyParam) + if err != nil { + return nil, err } - custodySettings := custodytypes.CustodySettings{ - CustodyEnabled: boolArr[0], - UsePassword: boolArr[1], - UseWhiteList: boolArr[2], - UseLimits: boolArr[3], - CustodyMode: custodyMode, - Key: string(params[5]), - NextController: string(params[6]), - } - msg = custodytypes.NewMsgCreateCustody(from, custodySettings, strArr[0], strArr[1], - strArr[2], strArr[3]) + msg = custodytypes.NewMsgCreateCustody(from, custodyParam.CustodySettings, custodyParam.OldKey, custodyParam.NewKey, + custodyParam.Next, custodyParam.Target) case MsgAddToCustodyWhiteList: // V, R, S, signer, oldKey string, newKey string, next string, target string // len, newAddr []string, @@ -1138,18 +1252,15 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, if err != nil { return nil, err } - var newAddrs []cosmostypes.AccAddress - len, _ := bytes2uint64(params[8]) - for i := uint64(0); i < len; i++ { - newddr, err := string2cosmosAddr(params[i+9]) - if err != nil { - return nil, err - } - newAddrs = append(newAddrs, newddr) + + var custodyParam CustodianParam + err = json.Unmarshal(params[4], &custodyParam) + if err != nil { + return nil, err } - msg = custodytypes.NewMsgAddToCustodyWhiteList(from, newAddrs, string(params[4]), string(params[5]), - string(params[6]), string(params[7])) + msg = custodytypes.NewMsgAddToCustodyWhiteList(from, custodyParam.NewAddrs, custodyParam.OldKey, custodyParam.NewKey, + custodyParam.Next, custodyParam.Target) case MsgAddToCustodyCustodians: // V, R, S, signer, oldKey string, newKey string, next string, target string // len, newAddr []string @@ -1157,18 +1268,15 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, if err != nil { return nil, err } - var newAddrs []cosmostypes.AccAddress - len, _ := bytes2uint64(params[8]) - for i := uint64(0); i < len; i++ { - newddr, err := string2cosmosAddr(params[i+9]) - if err != nil { - return nil, err - } - newAddrs = append(newAddrs, newddr) + + var custodyParam CustodianParam + err = json.Unmarshal(params[4], &custodyParam) + if err != nil { + return nil, err } - msg = custodytypes.NewMsgAddToCustodyCustodians(from, newAddrs, string(params[4]), string(params[5]), - string(params[6]), string(params[7])) + msg = custodytypes.NewMsgAddToCustodyCustodians(from, custodyParam.NewAddrs, custodyParam.OldKey, custodyParam.NewKey, + custodyParam.Next, custodyParam.Target) case MsgRemoveFromCustodyCustodians: // V, R, S, signer, newAddr cosmostypes.AccAddress, // oldKey string, newKey string, next string, target string @@ -1176,12 +1284,23 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, if err != nil { return nil, err } - newAddr, err := string2cosmosAddr(params[4]) + + type CustodianParam struct { + NewAddr cosmostypes.AccAddress `json:"new_addr"` + OldKey string `json:"old_key"` + NewKey string `json:"new_key"` + Next string `json:"next"` + Target string `json:"target"` + } + + var custodyParam CustodianParam + err = json.Unmarshal(params[4], &custodyParam) if err != nil { return nil, err } - msg = custodytypes.NewMsgRemoveFromCustodyCustodians(from, newAddr, string(params[5]), string(params[6]), - string(params[7]), string(params[8])) + + msg = custodytypes.NewMsgRemoveFromCustodyCustodians(from, custodyParam.NewAddr, custodyParam.OldKey, custodyParam.NewKey, + custodyParam.Next, custodyParam.Target) case MsgDropCustodyCustodians: // V, R, S, signer // oldKey string, newKey string, next string, target string @@ -1189,8 +1308,15 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, if err != nil { return nil, err } - msg = custodytypes.NewMsgDropCustodyCustodians(from, string(params[4]), string(params[5]), - string(params[6]), string(params[7])) + + var custodyParam CustodianParam + err = json.Unmarshal(params[4], &custodyParam) + if err != nil { + return nil, err + } + + msg = custodytypes.NewMsgDropCustodyCustodians(from, custodyParam.OldKey, custodyParam.NewKey, + custodyParam.Next, custodyParam.Target) case MsgRemoveFromCustodyWhiteList: // V, R, S, signer, newAddr string, // oldKey string, newKey string, next string, target string @@ -1198,12 +1324,23 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, if err != nil { return nil, err } - newAddr, err := string2cosmosAddr(params[4]) + + type CustodianParam struct { + NewAddr cosmostypes.AccAddress `json:"new_addr"` + OldKey string `json:"old_key"` + NewKey string `json:"new_key"` + Next string `json:"next"` + Target string `json:"target"` + } + + var custodyParam CustodianParam + err = json.Unmarshal(params[4], &custodyParam) if err != nil { return nil, err } - msg = custodytypes.NewMsgRemoveFromCustodyWhiteList(from, newAddr, string(params[5]), string(params[6]), - string(params[7]), string(params[8])) + + msg = custodytypes.NewMsgRemoveFromCustodyWhiteList(from, custodyParam.NewAddr, custodyParam.OldKey, custodyParam.NewKey, + custodyParam.Next, custodyParam.Target) case MsgDropCustodyWhiteList: // V, R, S, signer // oldKey string, newKey string, next string, target string @@ -1211,30 +1348,53 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, if err != nil { return nil, err } - msg = custodytypes.NewMsgDropCustodyWhiteList(from, string(params[4]), string(params[5]), - string(params[6]), string(params[7])) + + var custodyParam CustodianParam + err = json.Unmarshal(params[4], &custodyParam) + if err != nil { + return nil, err + } + + msg = custodytypes.NewMsgDropCustodyWhiteList(from, custodyParam.OldKey, custodyParam.NewKey, + custodyParam.Next, custodyParam.Target) case MsgApproveCustodyTx: // V, R, S, signer, to string, hash string from, err := bytes2cosmosAddr(params[3][12:]) if err != nil { return nil, err } - to, err := string2cosmosAddr(params[4]) + + type CustodianParam struct { + To cosmostypes.AccAddress `json:"to"` + Hash string `json:"hash"` + } + + var custodyParam CustodianParam + err = json.Unmarshal(params[4], &custodyParam) if err != nil { return nil, err } - msg = custodytypes.NewMsgApproveCustodyTransaction(from, to, string(params[5])) + + msg = custodytypes.NewMsgApproveCustodyTransaction(from, custodyParam.To, custodyParam.Hash) case MsgDeclineCustodyTx: // V, R, S, signer, to string, hash string from, err := bytes2cosmosAddr(params[3][12:]) if err != nil { return nil, err } - to, err := string2cosmosAddr(params[4]) + + type CustodianParam struct { + To cosmostypes.AccAddress `json:"to"` + Hash string `json:"hash"` + } + + var custodyParam CustodianParam + err = json.Unmarshal(params[4], &custodyParam) if err != nil { return nil, err } - msg = custodytypes.NewMsgDeclineCustodyTransaction(from, to, string(params[5])) + + msg = custodytypes.NewMsgDeclineCustodyTransaction(from, custodyParam.To, custodyParam.Hash) } fmt.Println(msg) From d26bf952c5c0cdb3f5b73426fac2c1ba59ce617e Mon Sep 17 00:00:00 2001 From: tj327 Date: Wed, 10 Jan 2024 03:57:18 -0500 Subject: [PATCH 08/25] fix unsupported type while unmarshalling --- gateway/kira/metamask/cosmostxsender.go | 564 +++++++++++++++++++----- 1 file changed, 448 insertions(+), 116 deletions(-) diff --git a/gateway/kira/metamask/cosmostxsender.go b/gateway/kira/metamask/cosmostxsender.go index 2deee25..bbae725 100644 --- a/gateway/kira/metamask/cosmostxsender.go +++ b/gateway/kira/metamask/cosmostxsender.go @@ -10,6 +10,8 @@ import ( "math" "math/big" "net/http" + "strconv" + "time" sdkmath "cosmossdk.io/math" "github.com/KiraCore/interx/common" @@ -21,7 +23,6 @@ import ( multistakingtypes "github.com/KiraCore/sekai/x/multistaking/types" slashingtypes "github.com/KiraCore/sekai/x/slashing/types" spendingtypes "github.com/KiraCore/sekai/x/spending/types" - stakingtypes "github.com/KiraCore/sekai/x/staking/types" tokenstypes "github.com/KiraCore/sekai/x/tokens/types" clienttx "github.com/cosmos/cosmos-sdk/client/tx" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" @@ -97,30 +98,43 @@ var grpcConn *grpc.ClientConn type ListRoleParam struct { RoleIdentifier string `json:"role_identifier"` - Permission uint32 `json:"permission"` + Permission uint32 `json:"permission,string"` } type PermissionsParam struct { - Permission uint32 `json:"permission"` + Permission uint32 `json:"permission,string"` ControlledAddr string `json:"controlled_addr"` } type RoleParam struct { - RoleId uint32 `json:"role_id"` + RoleId uint32 `json:"role_id,string"` Controller string `json:"controller"` } type DelegateParam struct { - Amounts cosmostypes.Coins `json:"amounts"` - To string `json:"to"` + Amounts string `json:"amounts"` + To string `json:"to"` } type CustodianParam struct { - NewAddrs []cosmostypes.AccAddress `json:"new_addrs"` - OldKey string `json:"old_key"` - NewKey string `json:"new_key"` - Next string `json:"next"` - Target string `json:"target"` + NewAddrs []string `json:"new_addrs"` + OldKey string `json:"old_key"` + NewKey string `json:"new_key"` + Next string `json:"next"` + Target string `json:"target"` +} + +type SingleCustodianParam struct { + NewAddr string `json:"new_addr"` + OldKey string `json:"old_key"` + NewKey string `json:"new_key"` + Next string `json:"next"` + Target string `json:"target"` +} + +type CustodyParam struct { + To string `json:"to"` + Hash string `json:"hash"` } // decode 256bit param like bool, uint, hex-typed address etc @@ -130,6 +144,7 @@ func Decode256Bit(data *[]byte, params *[][]byte) error { } *params = append(*params, (*data)[:32]) *data = (*data)[32:] + return nil } @@ -564,12 +579,26 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, return nil, err } - var evidenceParam evidencetypes.Equivocation - err = json.Unmarshal(params[4], &evidenceParam) + type Equivocation struct { + Height int64 `json:"height,string"` + Time time.Time `json:"time"` + Power int64 `json:"power,string"` + ConsensusAddress string `json:"consensus_address"` + } + + var evidenceJsonParam Equivocation + err = json.Unmarshal(params[4], &evidenceJsonParam) if err != nil { return nil, err } + evidenceParam := evidencetypes.Equivocation{ + Height: evidenceJsonParam.Height, + Time: evidenceJsonParam.Time, + Power: evidenceJsonParam.Power, + ConsensusAddress: evidenceJsonParam.ConsensusAddress, + } + msg, err = evidencetypes.NewMsgSubmitEvidence(from, &evidenceParam) if err != nil { return nil, err @@ -604,8 +633,8 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, } type VoteProposalParam struct { - ProposalID uint64 `json:"proposal_id"` - Option uint64 `json:"option"` + ProposalID uint64 `json:"proposal_id,string"` + Option uint64 `json:"option,string"` Slash string `json:"slash"` } @@ -667,7 +696,7 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, type IdentityRecordParam struct { Balance string `json:"balance"` Verifier string `json:"verifier"` - RecordIds []uint64 `json:"record_ids"` + RecordIds []string `json:"record_ids"` } var recordParam IdentityRecordParam @@ -686,7 +715,16 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, return nil, err } - msg = customgovtypes.NewMsgRequestIdentityRecordsVerify(from, verifier, recordParam.RecordIds, balance) + var recordIds []uint64 + for _, idStr := range recordParam.RecordIds { + id, err := strconv.ParseUint(idStr, 10, 64) + if err != nil { + return nil, err + } + recordIds = append(recordIds, id) + } + + msg = customgovtypes.NewMsgRequestIdentityRecordsVerify(from, verifier, recordIds, balance) case MsgHandleIdentityRecordsVerifyRequest: // V, R, S, signer, requestId, isApprove verifier, err := bytes2cosmosAddr(params[3][12:]) @@ -695,7 +733,7 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, } type IdentityRecordParam struct { - RequestID uint64 `json:"request_id"` + RequestID uint64 `json:"request_id,string"` IsApproved bool `json:"is_approved"` } @@ -714,7 +752,7 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, } type IdentityRecordParam struct { - VerifyRequestId uint64 `json:"verify_request_id"` + VerifyRequestId uint64 `json:"verify_request_id,string"` } var recordParam IdentityRecordParam @@ -731,8 +769,71 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, return nil, err } + type NetworkProperties struct { + MinTxFee uint64 `json:"min_tx_fee,string"` + MaxTxFee uint64 `json:"max_tx_fee,string"` + VoteQuorum uint64 `json:"vote_quorum,string"` + MinimumProposalEndTime uint64 `json:"minimum_proposal_end_time,string"` + ProposalEnactmentTime uint64 `json:"proposal_enactment_time,string"` + MinProposalEndBlocks uint64 `json:"min_proposal_end_blocks,string"` + MinProposalEnactmentBlocks uint64 `json:"min_proposal_enactment_blocks,string"` + EnableForeignFeePayments bool `json:"enable_foreign_fee_payments,string"` + MischanceRankDecreaseAmount uint64 `json:"mischance_rank_decrease_amount,string"` + MaxMischance uint64 `json:"max_mischance,string"` + MischanceConfidence uint64 `json:"mischance_confidence,string"` + InactiveRankDecreasePercent string `json:"inactive_rank_decrease_percent"` + MinValidators uint64 `json:"min_validators,string"` + PoorNetworkMaxBankSend uint64 `json:"poor_network_max_bank_send,string"` + UnjailMaxTime uint64 `json:"unjail_max_time,string"` + EnableTokenWhitelist bool `json:"enable_token_whitelist,string"` + EnableTokenBlacklist bool `json:"enable_token_blacklist,string"` + MinIdentityApprovalTip uint64 `json:"min_identity_approval_tip,string"` + UniqueIdentityKeys string `json:"unique_identity_keys,string"` + UbiHardcap uint64 `json:"ubi_hardcap,string"` + ValidatorsFeeShare string `json:"validators_fee_share"` + InflationRate string `json:"inflation_rate"` + InflationPeriod uint64 `json:"inflation_period,string"` + UnstakingPeriod uint64 `json:"unstaking_period,string"` + MaxDelegators uint64 `json:"max_delegators,string"` + MinDelegationPushout uint64 `json:"min_delegation_pushout,string"` + SlashingPeriod uint64 `json:"slashing_period,string"` + MaxJailedPercentage string `json:"max_jailed_percentage"` + MaxSlashingPercentage string `json:"max_slashing_percentage"` + MinCustodyReward uint64 `json:"min_custody_reward,string"` + MaxCustodyBufferSize uint64 `json:"max_custody_buffer_size,string"` + MaxCustodyTxSize uint64 `json:"max_custody_tx_size,string"` + AbstentionRankDecreaseAmount uint64 `json:"abstention_rank_decrease_amount,string"` + MaxAbstention uint64 `json:"max_abstention,string"` + MinCollectiveBond uint64 `json:"min_collective_bond,string"` + MinCollectiveBondingTime uint64 `json:"min_collective_bonding_time,string"` + MaxCollectiveOutputs uint64 `json:"max_collective_outputs,string"` + MinCollectiveClaimPeriod uint64 `json:"min_collective_claim_period,string"` + ValidatorRecoveryBond uint64 `json:"validator_recovery_bond,string"` + MaxAnnualInflation string `json:"max_annual_inflation"` + MaxProposalTitleSize uint64 `json:"max_proposal_title_size,string"` + MaxProposalDescriptionSize uint64 `json:"max_proposal_description_size,string"` + MaxProposalPollOptionSize uint64 `json:"max_proposal_poll_option_size,string"` + MaxProposalPollOptionCount uint64 `json:"max_proposal_poll_option_count,string"` + MaxProposalReferenceSize uint64 `json:"max_proposal_reference_size,string"` + MaxProposalChecksumSize uint64 `json:"max_proposal_checksum_size,string"` + MinDappBond uint64 `json:"min_dapp_bond,string"` + MaxDappBond uint64 `json:"max_dapp_bond,string"` + DappLiquidationThreshold uint64 `json:"dapp_liquidation_threshold,string"` + DappLiquidationPeriod uint64 `json:"dapp_liquidation_period,string"` + DappBondDuration uint64 `json:"dapp_bond_duration,string"` + DappVerifierBond string `json:"dapp_verifier_bond"` + DappAutoDenounceTime uint64 `json:"dapp_auto_denounce_time,string"` + DappMischanceRankDecreaseAmount uint64 `json:"dapp_mischance_rank_decrease_amount,string"` + DappMaxMischance uint64 `json:"dapp_max_mischance,string"` + DappInactiveRankDecreasePercent uint64 `json:"dapp_inactive_rank_decrease_percent,string"` + DappPoolSlippageDefault string `json:"dapp_pool_slippage_default"` + MintingFtFee uint64 `json:"minting_ft_fee,string"` + MintingNftFee uint64 `json:"minting_nft_fee,string"` + VetoThreshold string `json:"veto_threshold"` + } + type NetworkPropertiesParam struct { - NetworkProperties customgovtypes.NetworkProperties `json:"network_properties"` + NetworkProperties NetworkProperties `json:"network_properties"` } var networkProperties NetworkPropertiesParam @@ -741,7 +842,107 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, return nil, err } - msg = customgovtypes.NewMsgSetNetworkProperties(proposer, &networkProperties.NetworkProperties) + inActiveRankDecreasePercent, err := cosmostypes.NewDecFromStr(networkProperties.NetworkProperties.InactiveRankDecreasePercent) + if err != nil { + return nil, err + } + validatorsFeeShare, err := cosmostypes.NewDecFromStr(networkProperties.NetworkProperties.ValidatorsFeeShare) + if err != nil { + return nil, err + } + inflationRate, err := cosmostypes.NewDecFromStr(networkProperties.NetworkProperties.InflationRate) + if err != nil { + return nil, err + } + maxJailedPercentage, err := cosmostypes.NewDecFromStr(networkProperties.NetworkProperties.MaxJailedPercentage) + if err != nil { + return nil, err + } + maxSlashingPercentage, err := cosmostypes.NewDecFromStr(networkProperties.NetworkProperties.MaxSlashingPercentage) + if err != nil { + return nil, err + } + maxAnnualInflation, err := cosmostypes.NewDecFromStr(networkProperties.NetworkProperties.MaxAnnualInflation) + if err != nil { + return nil, err + } + dappVerifierBond, err := cosmostypes.NewDecFromStr(networkProperties.NetworkProperties.DappVerifierBond) + if err != nil { + return nil, err + } + dappPoolSlippageDefault, err := cosmostypes.NewDecFromStr(networkProperties.NetworkProperties.DappPoolSlippageDefault) + if err != nil { + return nil, err + } + vetoThreshold, err := cosmostypes.NewDecFromStr(networkProperties.NetworkProperties.VetoThreshold) + if err != nil { + return nil, err + } + + networkPropertiesParam := customgovtypes.NetworkProperties{ + MinTxFee: networkProperties.NetworkProperties.MinTxFee, + MaxTxFee: networkProperties.NetworkProperties.MaxTxFee, + VoteQuorum: networkProperties.NetworkProperties.VoteQuorum, + MinimumProposalEndTime: networkProperties.NetworkProperties.MinimumProposalEndTime, + ProposalEnactmentTime: networkProperties.NetworkProperties.ProposalEnactmentTime, + MinProposalEndBlocks: networkProperties.NetworkProperties.MinProposalEndBlocks, + MinProposalEnactmentBlocks: networkProperties.NetworkProperties.MinProposalEnactmentBlocks, + EnableForeignFeePayments: networkProperties.NetworkProperties.EnableForeignFeePayments, + MischanceRankDecreaseAmount: networkProperties.NetworkProperties.MischanceRankDecreaseAmount, + MaxMischance: networkProperties.NetworkProperties.MaxMischance, + MischanceConfidence: networkProperties.NetworkProperties.MischanceConfidence, + InactiveRankDecreasePercent: inActiveRankDecreasePercent, + MinValidators: networkProperties.NetworkProperties.MinValidators, + PoorNetworkMaxBankSend: networkProperties.NetworkProperties.PoorNetworkMaxBankSend, + UnjailMaxTime: networkProperties.NetworkProperties.UnjailMaxTime, + EnableTokenWhitelist: networkProperties.NetworkProperties.EnableTokenWhitelist, + EnableTokenBlacklist: networkProperties.NetworkProperties.EnableTokenBlacklist, + MinIdentityApprovalTip: networkProperties.NetworkProperties.MinIdentityApprovalTip, + UniqueIdentityKeys: networkProperties.NetworkProperties.UniqueIdentityKeys, + UbiHardcap: networkProperties.NetworkProperties.UbiHardcap, + ValidatorsFeeShare: validatorsFeeShare, + InflationRate: inflationRate, + InflationPeriod: networkProperties.NetworkProperties.InflationPeriod, + UnstakingPeriod: networkProperties.NetworkProperties.UnstakingPeriod, + MaxDelegators: networkProperties.NetworkProperties.MaxDelegators, + MinDelegationPushout: networkProperties.NetworkProperties.MinDelegationPushout, + SlashingPeriod: networkProperties.NetworkProperties.SlashingPeriod, + MaxJailedPercentage: maxJailedPercentage, + MaxSlashingPercentage: maxSlashingPercentage, + MinCustodyReward: networkProperties.NetworkProperties.MinCustodyReward, + MaxCustodyBufferSize: networkProperties.NetworkProperties.MaxCustodyBufferSize, + MaxCustodyTxSize: networkProperties.NetworkProperties.MaxCustodyTxSize, + AbstentionRankDecreaseAmount: networkProperties.NetworkProperties.AbstentionRankDecreaseAmount, + MaxAbstention: networkProperties.NetworkProperties.MaxAbstention, + MinCollectiveBond: networkProperties.NetworkProperties.MinCollectiveBond, + MinCollectiveBondingTime: networkProperties.NetworkProperties.MinCollectiveBondingTime, + MaxCollectiveOutputs: networkProperties.NetworkProperties.MaxCollectiveOutputs, + MinCollectiveClaimPeriod: networkProperties.NetworkProperties.MinCollectiveClaimPeriod, + ValidatorRecoveryBond: networkProperties.NetworkProperties.ValidatorRecoveryBond, + MaxAnnualInflation: maxAnnualInflation, + MaxProposalTitleSize: networkProperties.NetworkProperties.MaxProposalTitleSize, + MaxProposalDescriptionSize: networkProperties.NetworkProperties.MaxProposalDescriptionSize, + MaxProposalPollOptionSize: networkProperties.NetworkProperties.MaxProposalPollOptionSize, + MaxProposalPollOptionCount: networkProperties.NetworkProperties.MaxProposalPollOptionCount, + MaxProposalReferenceSize: networkProperties.NetworkProperties.MaxProposalReferenceSize, + MaxProposalChecksumSize: networkProperties.NetworkProperties.MaxProposalChecksumSize, + MinDappBond: networkProperties.NetworkProperties.MinDappBond, + MaxDappBond: networkProperties.NetworkProperties.MaxDappBond, + DappLiquidationThreshold: networkProperties.NetworkProperties.DappLiquidationThreshold, + DappLiquidationPeriod: networkProperties.NetworkProperties.DappLiquidationPeriod, + DappBondDuration: networkProperties.NetworkProperties.DappBondDuration, + DappVerifierBond: dappVerifierBond, + DappAutoDenounceTime: networkProperties.NetworkProperties.DappAutoDenounceTime, + DappMischanceRankDecreaseAmount: networkProperties.NetworkProperties.DappMischanceRankDecreaseAmount, + DappMaxMischance: networkProperties.NetworkProperties.DappMaxMischance, + DappInactiveRankDecreasePercent: networkProperties.NetworkProperties.DappInactiveRankDecreasePercent, + DappPoolSlippageDefault: dappPoolSlippageDefault, + MintingFtFee: networkProperties.NetworkProperties.MintingFtFee, + MintingNftFee: networkProperties.NetworkProperties.MintingNftFee, + VetoThreshold: vetoThreshold, + } + + msg = customgovtypes.NewMsgSetNetworkProperties(proposer, &networkPropertiesParam) case MsgSetExecutionFee: // V, R, S, signer, executionFee, failureFee, timeout, defaultParams proposer, err := bytes2cosmosAddr(params[3][12:]) @@ -751,10 +952,10 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, type ExecutionFeeParam struct { TransactionType string `json:"transaction_type"` - ExecutionFee uint64 `json:"execution_fee"` - FailureFee uint64 `json:"failure_fee"` - Timeout uint64 `json:"timeout"` - DefaultParams uint64 `json:"default_params"` + ExecutionFee uint64 `json:"execution_fee,string"` + FailureFee uint64 `json:"failure_fee,string"` + Timeout uint64 `json:"timeout,string"` + DefaultParams uint64 `json:"default_params,string"` } var feeParam ExecutionFeeParam @@ -943,27 +1144,30 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, case MsgClaimValidator: // V, R, S, signer, moniker string, valKey cosmostypes.ValAddress, pubKey cryptotypes.PubKey - type ClaimParam struct { - Moniker string `json:"moniker"` - ValKey string `json:"val_key"` - PubKey cryptotypes.PubKey `json:"pub_key"` - } + // type ClaimParam struct { + // Moniker string `json:"moniker"` + // ValKey string `json:"val_key"` + // PubKey string `json:"pub_key"` + // } - var claimParam ClaimParam - err = json.Unmarshal(params[4], &claimParam) - if err != nil { - return nil, err - } + // var claimParam ClaimParam + // err = json.Unmarshal(params[4], &claimParam) + // if err != nil { + // return nil, err + // } - valKey, err := cosmostypes.ValAddressFromBech32(claimParam.ValKey) - if err != nil { - return nil, err - } + // valKey, err := cosmostypes.ValAddressFromBech32(claimParam.ValKey) + // if err != nil { + // return nil, err + // } - msg, err = stakingtypes.NewMsgClaimValidator(claimParam.Moniker, valKey, claimParam.PubKey) - if err != nil { - return nil, err - } + // // how to get pub key from string? + // cryptotypes + + // msg, err = stakingtypes.NewMsgClaimValidator(claimParam.Moniker, valKey, claimParam.PubKey) + // if err != nil { + // return nil, err + // } case MsgUpsertTokenAlias: // V, R, S, signer, param proposer, err := bytes2cosmosAddr(params[3][12:]) @@ -975,7 +1179,7 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, Symbol string `json:"symbol"` Name string `json:"name"` Icon string `json:"icon"` - Decimals uint32 `json:"decimals"` + Decimals uint32 `json:"decimals,string"` Denoms []string `json:"denoms"` Invalidated bool `json:"invalidated"` } @@ -997,13 +1201,13 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, } type UpsertTokenRateParam struct { - Denom string `json:"denom"` - Rate cosmostypes.Dec `json:"rate"` - IsFeePayments bool `json:"is_fee_payments"` - StakeCap cosmostypes.Dec `json:"stake_cap"` - StakeMin cosmostypes.Int `json:"stake_min"` - IsStakeToken bool `json:"is_stake_token"` - Invalidated bool `json:"invalidated"` + Denom string `json:"denom"` + Rate string `json:"rate"` + IsFeePayments bool `json:"is_fee_payments"` + StakeCap string `json:"stake_cap"` + StakeMin string `json:"stake_min"` + IsStakeToken bool `json:"is_stake_token"` + Invalidated bool `json:"invalidated"` } var upsertParam UpsertTokenRateParam @@ -1012,8 +1216,21 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, return nil, err } - msg = tokenstypes.NewMsgUpsertTokenRate(proposer, upsertParam.Denom, upsertParam.Rate, upsertParam.IsFeePayments, - upsertParam.StakeCap, upsertParam.StakeMin, upsertParam.IsStakeToken, upsertParam.Invalidated) + rate, err := cosmostypes.NewDecFromStr(upsertParam.Rate) + if err != nil { + return nil, err + } + stakeCap, err := cosmostypes.NewDecFromStr(upsertParam.StakeCap) + if err != nil { + return nil, err + } + stakeMin, ok := cosmostypes.NewIntFromString(upsertParam.StakeMin) + if !ok { + return nil, errors.New(fmt.Sprintln("StakeMin - decoding from string to Int type is failed:", upsertParam.StakeMin)) + } + + msg = tokenstypes.NewMsgUpsertTokenRate(proposer, upsertParam.Denom, rate, upsertParam.IsFeePayments, + stakeCap, stakeMin, upsertParam.IsStakeToken, upsertParam.Invalidated) case MsgActivate: // V, R, S, signer validator, err := bytes2cosmosValAddr(params[3][12:]) @@ -1044,18 +1261,38 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, return nil, err } + type PermInfo struct { + OwnerRoles []string `json:"owner_roles"` + OwnerAccounts []string `json:"owner_accounts"` + } + + type WeightedRole struct { + Role uint64 `json:"role,string"` + Weight string `json:"weight"` + } + + type WeightedAccount struct { + Account string `json:"account"` + Weight string `json:"weight"` + } + + type WeightedPermInfo struct { + Roles []WeightedRole `json:"roles"` + Accounts []WeightedAccount `json:"accounts"` + } + type SpendingPoolParam struct { - Name string `json:"name"` - ClaimStart uint64 `json:"claim_start"` - ClaimEnd uint64 `json:"claim_end"` - Rates cosmostypes.DecCoins `json:"rates"` - VoteQuorum uint64 `json:"vote_quorum"` - VotePeriod uint64 `json:"vote_period"` - VoteEnactment uint64 `json:"vote_enactment"` - Owners spendingtypes.PermInfo `json:"owners"` - Beneficiaries spendingtypes.WeightedPermInfo `json:"beneficiaries"` - IsDynamicRate bool `json:"is_dynamic_rate"` - DynamicRatePeriod uint64 `json:"dynamic_rate_period"` + Name string `json:"name"` + ClaimStart uint64 `json:"claim_start,string"` + ClaimEnd uint64 `json:"claim_end,string"` + Rates []string `json:"rates"` + VoteQuorum uint64 `json:"vote_quorum,string"` + VotePeriod uint64 `json:"vote_period,string"` + VoteEnactment uint64 `json:"vote_enactment,string"` + Owners PermInfo `json:"owners"` + Beneficiaries WeightedPermInfo `json:"beneficiaries"` + IsDynamicRate bool `json:"is_dynamic_rate"` + DynamicRatePeriod uint64 `json:"dynamic_rate_period,string"` } var poolParam SpendingPoolParam @@ -1064,8 +1301,51 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, return nil, err } - msg = spendingtypes.NewMsgCreateSpendingPool(poolParam.Name, poolParam.ClaimStart, poolParam.ClaimEnd, poolParam.Rates, - poolParam.VoteQuorum, poolParam.VotePeriod, poolParam.VoteEnactment, poolParam.Owners, poolParam.Beneficiaries, + var rates cosmostypes.DecCoins + for _, rate := range poolParam.Rates { + coin, err := cosmostypes.ParseDecCoin(rate) + if err != nil { + return nil, err + } + rates.Add(coin) + } + + var permInfo spendingtypes.PermInfo + for _, roleStr := range poolParam.Owners.OwnerRoles { + role, err := strconv.ParseUint(roleStr, 10, 64) + if err != nil { + return nil, err + } + permInfo.OwnerRoles = append(permInfo.OwnerRoles, role) + } + permInfo.OwnerAccounts = append(permInfo.OwnerAccounts, poolParam.Owners.OwnerAccounts...) + + var beneficiaries spendingtypes.WeightedPermInfo + for _, account := range poolParam.Beneficiaries.Accounts { + weight, err := cosmostypes.NewDecFromStr(account.Weight) + if err != nil { + return nil, err + } + weightedAccount := spendingtypes.WeightedAccount{ + Account: account.Account, + Weight: weight, + } + beneficiaries.Accounts = append(beneficiaries.Accounts, weightedAccount) + } + for _, role := range poolParam.Beneficiaries.Roles { + weight, err := cosmostypes.NewDecFromStr(role.Weight) + if err != nil { + return nil, err + } + weightedRole := spendingtypes.WeightedRole{ + Role: role.Role, + Weight: weight, + } + beneficiaries.Roles = append(beneficiaries.Roles, weightedRole) + } + + msg = spendingtypes.NewMsgCreateSpendingPool(poolParam.Name, poolParam.ClaimStart, poolParam.ClaimEnd, rates, + poolParam.VoteQuorum, poolParam.VotePeriod, poolParam.VoteEnactment, permInfo, beneficiaries, sender, poolParam.IsDynamicRate, poolParam.DynamicRatePeriod) case MsgDepositSpendingPool: // V, R, S, signer, amount string, name string @@ -1075,8 +1355,8 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, } type SpendingPoolParam struct { - Name string `json:"Name"` - Amount cosmostypes.Coins `json:"Amount"` + Name string `json:"name"` + Amounts string `json:"amounts"` } var poolParam SpendingPoolParam @@ -1085,7 +1365,12 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, return nil, err } - msg = spendingtypes.NewMsgDepositSpendingPool(poolParam.Name, poolParam.Amount, sender) + amounts, err := cosmostypes.ParseCoinsNormalized(poolParam.Amounts) + if err != nil { + return nil, err + } + + msg = spendingtypes.NewMsgDepositSpendingPool(poolParam.Name, amounts, sender) case MsgRegisterSpendingPoolBeneficiary: // V, R, S, signer, name string sender, err := bytes2cosmosAddr(params[3][12:]) @@ -1130,9 +1415,9 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, } type StakingPoolParam struct { - Validator string `json:"validator"` - Enabled bool `json:"enabled"` - Commission cosmostypes.Dec `json:"commission"` + Validator string `json:"validator"` + Enabled bool `json:"enabled"` + Commission string `json:"commission"` } var poolParam StakingPoolParam @@ -1141,7 +1426,12 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, return nil, err } - msg = multistakingtypes.NewMsgUpsertStakingPool(from, poolParam.Validator, poolParam.Enabled, poolParam.Commission) + commission, err := cosmostypes.NewDecFromStr(poolParam.Commission) + if err != nil { + return nil, err + } + + msg = multistakingtypes.NewMsgUpsertStakingPool(from, poolParam.Validator, poolParam.Enabled, commission) case MsgDelegate: // V, R, S, signer, param from, err := hex2bech32(hex.EncodeToString(params[3][12:]), TypeKiraAddr) @@ -1155,7 +1445,12 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, return nil, err } - msg = multistakingtypes.NewMsgDelegate(from, delegateParam.To, delegateParam.Amounts) + amounts, err := cosmostypes.ParseCoinsNormalized(delegateParam.Amounts) + if err != nil { + return nil, err + } + + msg = multistakingtypes.NewMsgDelegate(from, delegateParam.To, amounts) case MsgUndelegate: // V, R, S, signer, amount, validator from, err := hex2bech32(hex.EncodeToString(params[3][12:]), TypeKiraAddr) @@ -1169,7 +1464,12 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, return nil, err } - msg = multistakingtypes.NewMsgUndelegate(from, delegateParam.To, delegateParam.Amounts) + amounts, err := cosmostypes.ParseCoinsNormalized(delegateParam.Amounts) + if err != nil { + return nil, err + } + + msg = multistakingtypes.NewMsgUndelegate(from, delegateParam.To, amounts) case MsgClaimRewards: // V, R, S, signer from, err := hex2bech32(hex.EncodeToString(params[3][12:]), TypeKiraAddr) @@ -1185,7 +1485,7 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, } type UndelegationParam struct { - UndelegationId uint64 `json:"undelegation_id"` + UndelegationId uint64 `json:"undelegation_id,string"` } var undelegationParam UndelegationParam @@ -1229,12 +1529,22 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, return nil, err } + type CustodySettings struct { + CustodyEnabled bool `json:"custody_enabled"` + CustodyMode uint64 `json:"custody_mode,string"` + UsePassword bool `json:"use_password"` + UseWhiteList bool `json:"use_white_list"` + UseLimits bool `json:"use_limits"` + Key string `json:"key"` + NextController string `json:"next_controller"` + } + type CustodyParam struct { - CustodySettings custodytypes.CustodySettings `json:"custody_settings"` - OldKey string `json:"old_key"` - NewKey string `json:"new_key"` - Next string `json:"next"` - Target string `json:"target"` + CustodySettings CustodySettings `json:"custody_settings"` + OldKey string `json:"old_key"` + NewKey string `json:"new_key"` + Next string `json:"next"` + Target string `json:"target"` } var custodyParam CustodyParam @@ -1243,7 +1553,17 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, return nil, err } - msg = custodytypes.NewMsgCreateCustody(from, custodyParam.CustodySettings, custodyParam.OldKey, custodyParam.NewKey, + custodySettings := custodytypes.CustodySettings{ + CustodyEnabled: custodyParam.CustodySettings.CustodyEnabled, + CustodyMode: custodyParam.CustodySettings.CustodyMode, + UsePassword: custodyParam.CustodySettings.UsePassword, + UseWhiteList: custodyParam.CustodySettings.UseWhiteList, + UseLimits: custodyParam.CustodySettings.UseLimits, + Key: custodyParam.CustodySettings.Key, + NextController: custodyParam.CustodySettings.NextController, + } + + msg = custodytypes.NewMsgCreateCustody(from, custodySettings, custodyParam.OldKey, custodyParam.NewKey, custodyParam.Next, custodyParam.Target) case MsgAddToCustodyWhiteList: // V, R, S, signer, oldKey string, newKey string, next string, target string @@ -1259,7 +1579,16 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, return nil, err } - msg = custodytypes.NewMsgAddToCustodyWhiteList(from, custodyParam.NewAddrs, custodyParam.OldKey, custodyParam.NewKey, + var newAddrs []cosmostypes.AccAddress + for _, addrStr := range custodyParam.NewAddrs { + addr, err := cosmostypes.AccAddressFromBech32(addrStr) + if err != nil { + return nil, err + } + newAddrs = append(newAddrs, addr) + } + + msg = custodytypes.NewMsgAddToCustodyWhiteList(from, newAddrs, custodyParam.OldKey, custodyParam.NewKey, custodyParam.Next, custodyParam.Target) case MsgAddToCustodyCustodians: // V, R, S, signer, oldKey string, newKey string, next string, target string @@ -1275,7 +1604,16 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, return nil, err } - msg = custodytypes.NewMsgAddToCustodyCustodians(from, custodyParam.NewAddrs, custodyParam.OldKey, custodyParam.NewKey, + var newAddrs []cosmostypes.AccAddress + for _, addrStr := range custodyParam.NewAddrs { + addr, err := cosmostypes.AccAddressFromBech32(addrStr) + if err != nil { + return nil, err + } + newAddrs = append(newAddrs, addr) + } + + msg = custodytypes.NewMsgAddToCustodyCustodians(from, newAddrs, custodyParam.OldKey, custodyParam.NewKey, custodyParam.Next, custodyParam.Target) case MsgRemoveFromCustodyCustodians: // V, R, S, signer, newAddr cosmostypes.AccAddress, @@ -1285,21 +1623,18 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, return nil, err } - type CustodianParam struct { - NewAddr cosmostypes.AccAddress `json:"new_addr"` - OldKey string `json:"old_key"` - NewKey string `json:"new_key"` - Next string `json:"next"` - Target string `json:"target"` + var custodyParam SingleCustodianParam + err = json.Unmarshal(params[4], &custodyParam) + if err != nil { + return nil, err } - var custodyParam CustodianParam - err = json.Unmarshal(params[4], &custodyParam) + newAddr, err := cosmostypes.AccAddressFromBech32(custodyParam.NewAddr) if err != nil { return nil, err } - msg = custodytypes.NewMsgRemoveFromCustodyCustodians(from, custodyParam.NewAddr, custodyParam.OldKey, custodyParam.NewKey, + msg = custodytypes.NewMsgRemoveFromCustodyCustodians(from, newAddr, custodyParam.OldKey, custodyParam.NewKey, custodyParam.Next, custodyParam.Target) case MsgDropCustodyCustodians: // V, R, S, signer @@ -1325,21 +1660,18 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, return nil, err } - type CustodianParam struct { - NewAddr cosmostypes.AccAddress `json:"new_addr"` - OldKey string `json:"old_key"` - NewKey string `json:"new_key"` - Next string `json:"next"` - Target string `json:"target"` + var custodyParam SingleCustodianParam + err = json.Unmarshal(params[4], &custodyParam) + if err != nil { + return nil, err } - var custodyParam CustodianParam - err = json.Unmarshal(params[4], &custodyParam) + newAddr, err := cosmostypes.AccAddressFromBech32(custodyParam.NewAddr) if err != nil { return nil, err } - msg = custodytypes.NewMsgRemoveFromCustodyWhiteList(from, custodyParam.NewAddr, custodyParam.OldKey, custodyParam.NewKey, + msg = custodytypes.NewMsgRemoveFromCustodyWhiteList(from, newAddr, custodyParam.OldKey, custodyParam.NewKey, custodyParam.Next, custodyParam.Target) case MsgDropCustodyWhiteList: // V, R, S, signer @@ -1364,18 +1696,18 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, return nil, err } - type CustodianParam struct { - To cosmostypes.AccAddress `json:"to"` - Hash string `json:"hash"` + var custodyParam CustodyParam + err = json.Unmarshal(params[4], &custodyParam) + if err != nil { + return nil, err } - var custodyParam CustodianParam - err = json.Unmarshal(params[4], &custodyParam) + to, err := cosmostypes.AccAddressFromBech32(custodyParam.To) if err != nil { return nil, err } - msg = custodytypes.NewMsgApproveCustodyTransaction(from, custodyParam.To, custodyParam.Hash) + msg = custodytypes.NewMsgApproveCustodyTransaction(from, to, custodyParam.Hash) case MsgDeclineCustodyTx: // V, R, S, signer, to string, hash string from, err := bytes2cosmosAddr(params[3][12:]) @@ -1383,21 +1715,21 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, return nil, err } - type CustodianParam struct { - To cosmostypes.AccAddress `json:"to"` - Hash string `json:"hash"` + var custodyParam CustodyParam + err = json.Unmarshal(params[4], &custodyParam) + if err != nil { + return nil, err } - var custodyParam CustodianParam - err = json.Unmarshal(params[4], &custodyParam) + to, err := cosmostypes.AccAddressFromBech32(custodyParam.To) if err != nil { return nil, err } - msg = custodytypes.NewMsgDeclineCustodyTransaction(from, custodyParam.To, custodyParam.Hash) + msg = custodytypes.NewMsgDeclineCustodyTransaction(from, to, custodyParam.Hash) } - fmt.Println(msg) + // fmt.Println(msg) err = txBuilder.SetMsgs(msg) if err != nil { return nil, err @@ -1502,7 +1834,7 @@ func sendCosmosTx(ctx context.Context, txBytes []byte) (string, error) { return "", err } - fmt.Println(grpcRes.TxResponse) + // fmt.Println(grpcRes.TxResponse) if grpcRes.TxResponse.Code != 0 { return "", errors.New(fmt.Sprintln("send tx failed - result code: ", grpcRes.TxResponse.Code)) From d05225269c14987d9451a028ceabe5e410faed27 Mon Sep 17 00:00:00 2001 From: tj327 Date: Thu, 11 Jan 2024 04:09:28 -0500 Subject: [PATCH 09/25] fix validation issues --- gateway/kira/metamask/cosmostxsender.go | 369 ++++++++++-------------- 1 file changed, 156 insertions(+), 213 deletions(-) diff --git a/gateway/kira/metamask/cosmostxsender.go b/gateway/kira/metamask/cosmostxsender.go index bbae725..55512e4 100644 --- a/gateway/kira/metamask/cosmostxsender.go +++ b/gateway/kira/metamask/cosmostxsender.go @@ -10,7 +10,6 @@ import ( "math" "math/big" "net/http" - "strconv" "time" sdkmath "cosmossdk.io/math" @@ -98,16 +97,16 @@ var grpcConn *grpc.ClientConn type ListRoleParam struct { RoleIdentifier string `json:"role_identifier"` - Permission uint32 `json:"permission,string"` + Permission uint32 `json:"permission"` } type PermissionsParam struct { - Permission uint32 `json:"permission,string"` + Permission uint32 `json:"permission"` ControlledAddr string `json:"controlled_addr"` } type RoleParam struct { - RoleId uint32 `json:"role_id,string"` + RoleId uint32 `json:"role_id"` Controller string `json:"controller"` } @@ -137,6 +136,11 @@ type CustodyParam struct { Hash string `json:"hash"` } +type SpendingPoolParam struct { + Name string `json:"name"` + Amounts string `json:"amounts"` +} + // decode 256bit param like bool, uint, hex-typed address etc func Decode256Bit(data *[]byte, params *[][]byte) error { if len(*data) < 32 { @@ -229,7 +233,7 @@ func sendTx(txRawData string, gwCosmosmux *runtime.ServeMux, r *http.Request) (s activatePrefix, _ := hex.DecodeString("a1374dc2") pausePrefix, _ := hex.DecodeString("1371cf19") unpausePrefix, _ := hex.DecodeString("b9179894") - createSpendingPoolPrefix, _ := hex.DecodeString("00000000") + createSpendingPoolPrefix, _ := hex.DecodeString("4ed8a0a2") depositSpendingPoolPrefix, _ := hex.DecodeString("e10c925c") registerSpendingPoolBeneficiaryPrefix, _ := hex.DecodeString("7ab7eecf") claimSpendingPoolPrefix, _ := hex.DecodeString("efeed4a0") @@ -329,7 +333,7 @@ func sendTx(txRawData string, gwCosmosmux *runtime.ServeMux, r *http.Request) (s case bytes.Equal(ethTxData.Data[:4], registerDelegatorPrefix): msgType = MsgRegisterDelegator case bytes.Equal(ethTxData.Data[:4], createCustodyPrefix): - msgType = MsgClaimSpendingPool + msgType = MsgCreateCustody case bytes.Equal(ethTxData.Data[:4], addToCustodyWhiteListPrefix): msgType = MsgAddToCustodyWhiteList case bytes.Equal(ethTxData.Data[:4], addToCustodyCustodiansPrefix): @@ -426,7 +430,7 @@ func getStructHash(txType int, valParam string) ethcommon.Hash { case MsgUnpause: funcSig = crypto.Keccak256([]byte("unpause()")) case MsgCreateSpendingPool: - // funcSig = crypto.Keccak256([]byte("delegate(string param)")) + funcSig = crypto.Keccak256([]byte("createSpendingPool(string param)")) case MsgDepositSpendingPool: funcSig = crypto.Keccak256([]byte("depositSpendingPool(string param)")) case MsgRegisterSpendingPoolBeneficiary: @@ -580,9 +584,9 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, } type Equivocation struct { - Height int64 `json:"height,string"` + Height int64 `json:"height"` Time time.Time `json:"time"` - Power int64 `json:"power,string"` + Power int64 `json:"power"` ConsensusAddress string `json:"consensus_address"` } @@ -633,8 +637,8 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, } type VoteProposalParam struct { - ProposalID uint64 `json:"proposal_id,string"` - Option uint64 `json:"option,string"` + ProposalID uint64 `json:"proposal_id"` + Option uint64 `json:"option"` Slash string `json:"slash"` } @@ -696,7 +700,7 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, type IdentityRecordParam struct { Balance string `json:"balance"` Verifier string `json:"verifier"` - RecordIds []string `json:"record_ids"` + RecordIds []uint64 `json:"record_ids"` } var recordParam IdentityRecordParam @@ -715,16 +719,7 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, return nil, err } - var recordIds []uint64 - for _, idStr := range recordParam.RecordIds { - id, err := strconv.ParseUint(idStr, 10, 64) - if err != nil { - return nil, err - } - recordIds = append(recordIds, id) - } - - msg = customgovtypes.NewMsgRequestIdentityRecordsVerify(from, verifier, recordIds, balance) + msg = customgovtypes.NewMsgRequestIdentityRecordsVerify(from, verifier, recordParam.RecordIds, balance) case MsgHandleIdentityRecordsVerifyRequest: // V, R, S, signer, requestId, isApprove verifier, err := bytes2cosmosAddr(params[3][12:]) @@ -733,7 +728,7 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, } type IdentityRecordParam struct { - RequestID uint64 `json:"request_id,string"` + RequestID uint64 `json:"request_id"` IsApproved bool `json:"is_approved"` } @@ -752,7 +747,7 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, } type IdentityRecordParam struct { - VerifyRequestId uint64 `json:"verify_request_id,string"` + VerifyRequestId uint64 `json:"verify_request_id"` } var recordParam IdentityRecordParam @@ -770,175 +765,171 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, } type NetworkProperties struct { - MinTxFee uint64 `json:"min_tx_fee,string"` - MaxTxFee uint64 `json:"max_tx_fee,string"` - VoteQuorum uint64 `json:"vote_quorum,string"` - MinimumProposalEndTime uint64 `json:"minimum_proposal_end_time,string"` - ProposalEnactmentTime uint64 `json:"proposal_enactment_time,string"` - MinProposalEndBlocks uint64 `json:"min_proposal_end_blocks,string"` - MinProposalEnactmentBlocks uint64 `json:"min_proposal_enactment_blocks,string"` - EnableForeignFeePayments bool `json:"enable_foreign_fee_payments,string"` - MischanceRankDecreaseAmount uint64 `json:"mischance_rank_decrease_amount,string"` - MaxMischance uint64 `json:"max_mischance,string"` - MischanceConfidence uint64 `json:"mischance_confidence,string"` + MinTxFee uint64 `json:"min_tx_fee"` + MaxTxFee uint64 `json:"max_tx_fee"` + VoteQuorum uint64 `json:"vote_quorum"` + MinimumProposalEndTime uint64 `json:"minimum_proposal_end_time"` + ProposalEnactmentTime uint64 `json:"proposal_enactment_time"` + MinProposalEndBlocks uint64 `json:"min_proposal_end_blocks"` + MinProposalEnactmentBlocks uint64 `json:"min_proposal_enactment_blocks"` + EnableForeignFeePayments bool `json:"enable_foreign_fee_payments"` + MischanceRankDecreaseAmount uint64 `json:"mischance_rank_decrease_amount"` + MaxMischance uint64 `json:"max_mischance"` + MischanceConfidence uint64 `json:"mischance_confidence"` InactiveRankDecreasePercent string `json:"inactive_rank_decrease_percent"` - MinValidators uint64 `json:"min_validators,string"` - PoorNetworkMaxBankSend uint64 `json:"poor_network_max_bank_send,string"` - UnjailMaxTime uint64 `json:"unjail_max_time,string"` - EnableTokenWhitelist bool `json:"enable_token_whitelist,string"` - EnableTokenBlacklist bool `json:"enable_token_blacklist,string"` - MinIdentityApprovalTip uint64 `json:"min_identity_approval_tip,string"` - UniqueIdentityKeys string `json:"unique_identity_keys,string"` - UbiHardcap uint64 `json:"ubi_hardcap,string"` + MinValidators uint64 `json:"min_validators"` + PoorNetworkMaxBankSend uint64 `json:"poor_network_max_bank_send"` + UnjailMaxTime uint64 `json:"unjail_max_time"` + EnableTokenWhitelist bool `json:"enable_token_whitelist"` + EnableTokenBlacklist bool `json:"enable_token_blacklist"` + MinIdentityApprovalTip uint64 `json:"min_identity_approval_tip"` + UniqueIdentityKeys string `json:"unique_identity_keys"` + UbiHardcap uint64 `json:"ubi_hardcap"` ValidatorsFeeShare string `json:"validators_fee_share"` InflationRate string `json:"inflation_rate"` - InflationPeriod uint64 `json:"inflation_period,string"` - UnstakingPeriod uint64 `json:"unstaking_period,string"` - MaxDelegators uint64 `json:"max_delegators,string"` - MinDelegationPushout uint64 `json:"min_delegation_pushout,string"` - SlashingPeriod uint64 `json:"slashing_period,string"` + InflationPeriod uint64 `json:"inflation_period"` + UnstakingPeriod uint64 `json:"unstaking_period"` + MaxDelegators uint64 `json:"max_delegators"` + MinDelegationPushout uint64 `json:"min_delegation_pushout"` + SlashingPeriod uint64 `json:"slashing_period"` MaxJailedPercentage string `json:"max_jailed_percentage"` MaxSlashingPercentage string `json:"max_slashing_percentage"` - MinCustodyReward uint64 `json:"min_custody_reward,string"` - MaxCustodyBufferSize uint64 `json:"max_custody_buffer_size,string"` - MaxCustodyTxSize uint64 `json:"max_custody_tx_size,string"` - AbstentionRankDecreaseAmount uint64 `json:"abstention_rank_decrease_amount,string"` - MaxAbstention uint64 `json:"max_abstention,string"` - MinCollectiveBond uint64 `json:"min_collective_bond,string"` - MinCollectiveBondingTime uint64 `json:"min_collective_bonding_time,string"` - MaxCollectiveOutputs uint64 `json:"max_collective_outputs,string"` - MinCollectiveClaimPeriod uint64 `json:"min_collective_claim_period,string"` - ValidatorRecoveryBond uint64 `json:"validator_recovery_bond,string"` + MinCustodyReward uint64 `json:"min_custody_reward"` + MaxCustodyBufferSize uint64 `json:"max_custody_buffer_size"` + MaxCustodyTxSize uint64 `json:"max_custody_tx_size"` + AbstentionRankDecreaseAmount uint64 `json:"abstention_rank_decrease_amount"` + MaxAbstention uint64 `json:"max_abstention"` + MinCollectiveBond uint64 `json:"min_collective_bond"` + MinCollectiveBondingTime uint64 `json:"min_collective_bonding_time"` + MaxCollectiveOutputs uint64 `json:"max_collective_outputs"` + MinCollectiveClaimPeriod uint64 `json:"min_collective_claim_period"` + ValidatorRecoveryBond uint64 `json:"validator_recovery_bond"` MaxAnnualInflation string `json:"max_annual_inflation"` - MaxProposalTitleSize uint64 `json:"max_proposal_title_size,string"` - MaxProposalDescriptionSize uint64 `json:"max_proposal_description_size,string"` - MaxProposalPollOptionSize uint64 `json:"max_proposal_poll_option_size,string"` - MaxProposalPollOptionCount uint64 `json:"max_proposal_poll_option_count,string"` - MaxProposalReferenceSize uint64 `json:"max_proposal_reference_size,string"` - MaxProposalChecksumSize uint64 `json:"max_proposal_checksum_size,string"` - MinDappBond uint64 `json:"min_dapp_bond,string"` - MaxDappBond uint64 `json:"max_dapp_bond,string"` - DappLiquidationThreshold uint64 `json:"dapp_liquidation_threshold,string"` - DappLiquidationPeriod uint64 `json:"dapp_liquidation_period,string"` - DappBondDuration uint64 `json:"dapp_bond_duration,string"` + MaxProposalTitleSize uint64 `json:"max_proposal_title_size"` + MaxProposalDescriptionSize uint64 `json:"max_proposal_description_size"` + MaxProposalPollOptionSize uint64 `json:"max_proposal_poll_option_size"` + MaxProposalPollOptionCount uint64 `json:"max_proposal_poll_option_count"` + MaxProposalReferenceSize uint64 `json:"max_proposal_reference_size"` + MaxProposalChecksumSize uint64 `json:"max_proposal_checksum_size"` + MinDappBond uint64 `json:"min_dapp_bond"` + MaxDappBond uint64 `json:"max_dapp_bond"` + DappLiquidationThreshold uint64 `json:"dapp_liquidation_threshold"` + DappLiquidationPeriod uint64 `json:"dapp_liquidation_period"` + DappBondDuration uint64 `json:"dapp_bond_duration"` DappVerifierBond string `json:"dapp_verifier_bond"` - DappAutoDenounceTime uint64 `json:"dapp_auto_denounce_time,string"` - DappMischanceRankDecreaseAmount uint64 `json:"dapp_mischance_rank_decrease_amount,string"` - DappMaxMischance uint64 `json:"dapp_max_mischance,string"` - DappInactiveRankDecreasePercent uint64 `json:"dapp_inactive_rank_decrease_percent,string"` + DappAutoDenounceTime uint64 `json:"dapp_auto_denounce_time"` + DappMischanceRankDecreaseAmount uint64 `json:"dapp_mischance_rank_decrease_amount"` + DappMaxMischance uint64 `json:"dapp_max_mischance"` + DappInactiveRankDecreasePercent uint64 `json:"dapp_inactive_rank_decrease_percent"` DappPoolSlippageDefault string `json:"dapp_pool_slippage_default"` - MintingFtFee uint64 `json:"minting_ft_fee,string"` - MintingNftFee uint64 `json:"minting_nft_fee,string"` + MintingFtFee uint64 `json:"minting_ft_fee"` + MintingNftFee uint64 `json:"minting_nft_fee"` VetoThreshold string `json:"veto_threshold"` } - type NetworkPropertiesParam struct { - NetworkProperties NetworkProperties `json:"network_properties"` - } - - var networkProperties NetworkPropertiesParam + var networkProperties NetworkProperties err = json.Unmarshal(params[4], &networkProperties) if err != nil { return nil, err } - inActiveRankDecreasePercent, err := cosmostypes.NewDecFromStr(networkProperties.NetworkProperties.InactiveRankDecreasePercent) + inActiveRankDecreasePercent, err := cosmostypes.NewDecFromStr(networkProperties.InactiveRankDecreasePercent) if err != nil { return nil, err } - validatorsFeeShare, err := cosmostypes.NewDecFromStr(networkProperties.NetworkProperties.ValidatorsFeeShare) + validatorsFeeShare, err := cosmostypes.NewDecFromStr(networkProperties.ValidatorsFeeShare) if err != nil { return nil, err } - inflationRate, err := cosmostypes.NewDecFromStr(networkProperties.NetworkProperties.InflationRate) + inflationRate, err := cosmostypes.NewDecFromStr(networkProperties.InflationRate) if err != nil { return nil, err } - maxJailedPercentage, err := cosmostypes.NewDecFromStr(networkProperties.NetworkProperties.MaxJailedPercentage) + maxJailedPercentage, err := cosmostypes.NewDecFromStr(networkProperties.MaxJailedPercentage) if err != nil { return nil, err } - maxSlashingPercentage, err := cosmostypes.NewDecFromStr(networkProperties.NetworkProperties.MaxSlashingPercentage) + maxSlashingPercentage, err := cosmostypes.NewDecFromStr(networkProperties.MaxSlashingPercentage) if err != nil { return nil, err } - maxAnnualInflation, err := cosmostypes.NewDecFromStr(networkProperties.NetworkProperties.MaxAnnualInflation) + maxAnnualInflation, err := cosmostypes.NewDecFromStr(networkProperties.MaxAnnualInflation) if err != nil { return nil, err } - dappVerifierBond, err := cosmostypes.NewDecFromStr(networkProperties.NetworkProperties.DappVerifierBond) + dappVerifierBond, err := cosmostypes.NewDecFromStr(networkProperties.DappVerifierBond) if err != nil { return nil, err } - dappPoolSlippageDefault, err := cosmostypes.NewDecFromStr(networkProperties.NetworkProperties.DappPoolSlippageDefault) + dappPoolSlippageDefault, err := cosmostypes.NewDecFromStr(networkProperties.DappPoolSlippageDefault) if err != nil { return nil, err } - vetoThreshold, err := cosmostypes.NewDecFromStr(networkProperties.NetworkProperties.VetoThreshold) + vetoThreshold, err := cosmostypes.NewDecFromStr(networkProperties.VetoThreshold) if err != nil { return nil, err } networkPropertiesParam := customgovtypes.NetworkProperties{ - MinTxFee: networkProperties.NetworkProperties.MinTxFee, - MaxTxFee: networkProperties.NetworkProperties.MaxTxFee, - VoteQuorum: networkProperties.NetworkProperties.VoteQuorum, - MinimumProposalEndTime: networkProperties.NetworkProperties.MinimumProposalEndTime, - ProposalEnactmentTime: networkProperties.NetworkProperties.ProposalEnactmentTime, - MinProposalEndBlocks: networkProperties.NetworkProperties.MinProposalEndBlocks, - MinProposalEnactmentBlocks: networkProperties.NetworkProperties.MinProposalEnactmentBlocks, - EnableForeignFeePayments: networkProperties.NetworkProperties.EnableForeignFeePayments, - MischanceRankDecreaseAmount: networkProperties.NetworkProperties.MischanceRankDecreaseAmount, - MaxMischance: networkProperties.NetworkProperties.MaxMischance, - MischanceConfidence: networkProperties.NetworkProperties.MischanceConfidence, + MinTxFee: networkProperties.MinTxFee, + MaxTxFee: networkProperties.MaxTxFee, + VoteQuorum: networkProperties.VoteQuorum, + MinimumProposalEndTime: networkProperties.MinimumProposalEndTime, + ProposalEnactmentTime: networkProperties.ProposalEnactmentTime, + MinProposalEndBlocks: networkProperties.MinProposalEndBlocks, + MinProposalEnactmentBlocks: networkProperties.MinProposalEnactmentBlocks, + EnableForeignFeePayments: networkProperties.EnableForeignFeePayments, + MischanceRankDecreaseAmount: networkProperties.MischanceRankDecreaseAmount, + MaxMischance: networkProperties.MaxMischance, + MischanceConfidence: networkProperties.MischanceConfidence, InactiveRankDecreasePercent: inActiveRankDecreasePercent, - MinValidators: networkProperties.NetworkProperties.MinValidators, - PoorNetworkMaxBankSend: networkProperties.NetworkProperties.PoorNetworkMaxBankSend, - UnjailMaxTime: networkProperties.NetworkProperties.UnjailMaxTime, - EnableTokenWhitelist: networkProperties.NetworkProperties.EnableTokenWhitelist, - EnableTokenBlacklist: networkProperties.NetworkProperties.EnableTokenBlacklist, - MinIdentityApprovalTip: networkProperties.NetworkProperties.MinIdentityApprovalTip, - UniqueIdentityKeys: networkProperties.NetworkProperties.UniqueIdentityKeys, - UbiHardcap: networkProperties.NetworkProperties.UbiHardcap, + MinValidators: networkProperties.MinValidators, + PoorNetworkMaxBankSend: networkProperties.PoorNetworkMaxBankSend, + UnjailMaxTime: networkProperties.UnjailMaxTime, + EnableTokenWhitelist: networkProperties.EnableTokenWhitelist, + EnableTokenBlacklist: networkProperties.EnableTokenBlacklist, + MinIdentityApprovalTip: networkProperties.MinIdentityApprovalTip, + UniqueIdentityKeys: networkProperties.UniqueIdentityKeys, + UbiHardcap: networkProperties.UbiHardcap, ValidatorsFeeShare: validatorsFeeShare, InflationRate: inflationRate, - InflationPeriod: networkProperties.NetworkProperties.InflationPeriod, - UnstakingPeriod: networkProperties.NetworkProperties.UnstakingPeriod, - MaxDelegators: networkProperties.NetworkProperties.MaxDelegators, - MinDelegationPushout: networkProperties.NetworkProperties.MinDelegationPushout, - SlashingPeriod: networkProperties.NetworkProperties.SlashingPeriod, + InflationPeriod: networkProperties.InflationPeriod, + UnstakingPeriod: networkProperties.UnstakingPeriod, + MaxDelegators: networkProperties.MaxDelegators, + MinDelegationPushout: networkProperties.MinDelegationPushout, + SlashingPeriod: networkProperties.SlashingPeriod, MaxJailedPercentage: maxJailedPercentage, MaxSlashingPercentage: maxSlashingPercentage, - MinCustodyReward: networkProperties.NetworkProperties.MinCustodyReward, - MaxCustodyBufferSize: networkProperties.NetworkProperties.MaxCustodyBufferSize, - MaxCustodyTxSize: networkProperties.NetworkProperties.MaxCustodyTxSize, - AbstentionRankDecreaseAmount: networkProperties.NetworkProperties.AbstentionRankDecreaseAmount, - MaxAbstention: networkProperties.NetworkProperties.MaxAbstention, - MinCollectiveBond: networkProperties.NetworkProperties.MinCollectiveBond, - MinCollectiveBondingTime: networkProperties.NetworkProperties.MinCollectiveBondingTime, - MaxCollectiveOutputs: networkProperties.NetworkProperties.MaxCollectiveOutputs, - MinCollectiveClaimPeriod: networkProperties.NetworkProperties.MinCollectiveClaimPeriod, - ValidatorRecoveryBond: networkProperties.NetworkProperties.ValidatorRecoveryBond, + MinCustodyReward: networkProperties.MinCustodyReward, + MaxCustodyBufferSize: networkProperties.MaxCustodyBufferSize, + MaxCustodyTxSize: networkProperties.MaxCustodyTxSize, + AbstentionRankDecreaseAmount: networkProperties.AbstentionRankDecreaseAmount, + MaxAbstention: networkProperties.MaxAbstention, + MinCollectiveBond: networkProperties.MinCollectiveBond, + MinCollectiveBondingTime: networkProperties.MinCollectiveBondingTime, + MaxCollectiveOutputs: networkProperties.MaxCollectiveOutputs, + MinCollectiveClaimPeriod: networkProperties.MinCollectiveClaimPeriod, + ValidatorRecoveryBond: networkProperties.ValidatorRecoveryBond, MaxAnnualInflation: maxAnnualInflation, - MaxProposalTitleSize: networkProperties.NetworkProperties.MaxProposalTitleSize, - MaxProposalDescriptionSize: networkProperties.NetworkProperties.MaxProposalDescriptionSize, - MaxProposalPollOptionSize: networkProperties.NetworkProperties.MaxProposalPollOptionSize, - MaxProposalPollOptionCount: networkProperties.NetworkProperties.MaxProposalPollOptionCount, - MaxProposalReferenceSize: networkProperties.NetworkProperties.MaxProposalReferenceSize, - MaxProposalChecksumSize: networkProperties.NetworkProperties.MaxProposalChecksumSize, - MinDappBond: networkProperties.NetworkProperties.MinDappBond, - MaxDappBond: networkProperties.NetworkProperties.MaxDappBond, - DappLiquidationThreshold: networkProperties.NetworkProperties.DappLiquidationThreshold, - DappLiquidationPeriod: networkProperties.NetworkProperties.DappLiquidationPeriod, - DappBondDuration: networkProperties.NetworkProperties.DappBondDuration, + MaxProposalTitleSize: networkProperties.MaxProposalTitleSize, + MaxProposalDescriptionSize: networkProperties.MaxProposalDescriptionSize, + MaxProposalPollOptionSize: networkProperties.MaxProposalPollOptionSize, + MaxProposalPollOptionCount: networkProperties.MaxProposalPollOptionCount, + MaxProposalReferenceSize: networkProperties.MaxProposalReferenceSize, + MaxProposalChecksumSize: networkProperties.MaxProposalChecksumSize, + MinDappBond: networkProperties.MinDappBond, + MaxDappBond: networkProperties.MaxDappBond, + DappLiquidationThreshold: networkProperties.DappLiquidationThreshold, + DappLiquidationPeriod: networkProperties.DappLiquidationPeriod, + DappBondDuration: networkProperties.DappBondDuration, DappVerifierBond: dappVerifierBond, - DappAutoDenounceTime: networkProperties.NetworkProperties.DappAutoDenounceTime, - DappMischanceRankDecreaseAmount: networkProperties.NetworkProperties.DappMischanceRankDecreaseAmount, - DappMaxMischance: networkProperties.NetworkProperties.DappMaxMischance, - DappInactiveRankDecreasePercent: networkProperties.NetworkProperties.DappInactiveRankDecreasePercent, + DappAutoDenounceTime: networkProperties.DappAutoDenounceTime, + DappMischanceRankDecreaseAmount: networkProperties.DappMischanceRankDecreaseAmount, + DappMaxMischance: networkProperties.DappMaxMischance, + DappInactiveRankDecreasePercent: networkProperties.DappInactiveRankDecreasePercent, DappPoolSlippageDefault: dappPoolSlippageDefault, - MintingFtFee: networkProperties.NetworkProperties.MintingFtFee, - MintingNftFee: networkProperties.NetworkProperties.MintingNftFee, + MintingFtFee: networkProperties.MintingFtFee, + MintingNftFee: networkProperties.MintingNftFee, VetoThreshold: vetoThreshold, } @@ -952,10 +943,10 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, type ExecutionFeeParam struct { TransactionType string `json:"transaction_type"` - ExecutionFee uint64 `json:"execution_fee,string"` - FailureFee uint64 `json:"failure_fee,string"` - Timeout uint64 `json:"timeout,string"` - DefaultParams uint64 `json:"default_params,string"` + ExecutionFee uint64 `json:"execution_fee"` + FailureFee uint64 `json:"failure_fee"` + Timeout uint64 `json:"timeout"` + DefaultParams uint64 `json:"default_params"` } var feeParam ExecutionFeeParam @@ -1179,7 +1170,7 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, Symbol string `json:"symbol"` Name string `json:"name"` Icon string `json:"icon"` - Decimals uint32 `json:"decimals,string"` + Decimals uint32 `json:"decimals"` Denoms []string `json:"denoms"` Invalidated bool `json:"invalidated"` } @@ -1261,13 +1252,8 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, return nil, err } - type PermInfo struct { - OwnerRoles []string `json:"owner_roles"` - OwnerAccounts []string `json:"owner_accounts"` - } - type WeightedRole struct { - Role uint64 `json:"role,string"` + Role uint64 `json:"role"` Weight string `json:"weight"` } @@ -1282,17 +1268,17 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, } type SpendingPoolParam struct { - Name string `json:"name"` - ClaimStart uint64 `json:"claim_start,string"` - ClaimEnd uint64 `json:"claim_end,string"` - Rates []string `json:"rates"` - VoteQuorum uint64 `json:"vote_quorum,string"` - VotePeriod uint64 `json:"vote_period,string"` - VoteEnactment uint64 `json:"vote_enactment,string"` - Owners PermInfo `json:"owners"` - Beneficiaries WeightedPermInfo `json:"beneficiaries"` - IsDynamicRate bool `json:"is_dynamic_rate"` - DynamicRatePeriod uint64 `json:"dynamic_rate_period,string"` + Name string `json:"name"` + ClaimStart uint64 `json:"claim_start"` + ClaimEnd uint64 `json:"claim_end"` + Rates []string `json:"rates"` + VoteQuorum uint64 `json:"vote_quorum"` + VotePeriod uint64 `json:"vote_period"` + VoteEnactment uint64 `json:"vote_enactment"` + Owners spendingtypes.PermInfo `json:"owners"` + Beneficiaries WeightedPermInfo `json:"beneficiaries"` + IsDynamicRate bool `json:"is_dynamic_rate"` + DynamicRatePeriod uint64 `json:"dynamic_rate_period"` } var poolParam SpendingPoolParam @@ -1310,16 +1296,6 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, rates.Add(coin) } - var permInfo spendingtypes.PermInfo - for _, roleStr := range poolParam.Owners.OwnerRoles { - role, err := strconv.ParseUint(roleStr, 10, 64) - if err != nil { - return nil, err - } - permInfo.OwnerRoles = append(permInfo.OwnerRoles, role) - } - permInfo.OwnerAccounts = append(permInfo.OwnerAccounts, poolParam.Owners.OwnerAccounts...) - var beneficiaries spendingtypes.WeightedPermInfo for _, account := range poolParam.Beneficiaries.Accounts { weight, err := cosmostypes.NewDecFromStr(account.Weight) @@ -1345,7 +1321,7 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, } msg = spendingtypes.NewMsgCreateSpendingPool(poolParam.Name, poolParam.ClaimStart, poolParam.ClaimEnd, rates, - poolParam.VoteQuorum, poolParam.VotePeriod, poolParam.VoteEnactment, permInfo, beneficiaries, + poolParam.VoteQuorum, poolParam.VotePeriod, poolParam.VoteEnactment, poolParam.Owners, beneficiaries, sender, poolParam.IsDynamicRate, poolParam.DynamicRatePeriod) case MsgDepositSpendingPool: // V, R, S, signer, amount string, name string @@ -1354,11 +1330,6 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, return nil, err } - type SpendingPoolParam struct { - Name string `json:"name"` - Amounts string `json:"amounts"` - } - var poolParam SpendingPoolParam err = json.Unmarshal(params[4], &poolParam) if err != nil { @@ -1378,10 +1349,6 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, return nil, err } - type SpendingPoolParam struct { - Name string `json:"Name"` - } - var poolParam SpendingPoolParam err = json.Unmarshal(params[4], &poolParam) if err != nil { @@ -1396,10 +1363,6 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, return nil, err } - type SpendingPoolParam struct { - Name string `json:"Name"` - } - var poolParam SpendingPoolParam err = json.Unmarshal(params[4], &poolParam) if err != nil { @@ -1485,7 +1448,7 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, } type UndelegationParam struct { - UndelegationId uint64 `json:"undelegation_id,string"` + UndelegationId uint64 `json:"undelegation_id"` } var undelegationParam UndelegationParam @@ -1529,22 +1492,12 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, return nil, err } - type CustodySettings struct { - CustodyEnabled bool `json:"custody_enabled"` - CustodyMode uint64 `json:"custody_mode,string"` - UsePassword bool `json:"use_password"` - UseWhiteList bool `json:"use_white_list"` - UseLimits bool `json:"use_limits"` - Key string `json:"key"` - NextController string `json:"next_controller"` - } - type CustodyParam struct { - CustodySettings CustodySettings `json:"custody_settings"` - OldKey string `json:"old_key"` - NewKey string `json:"new_key"` - Next string `json:"next"` - Target string `json:"target"` + CustodySettings custodytypes.CustodySettings `json:"custody_settings"` + OldKey string `json:"old_key"` + NewKey string `json:"new_key"` + Next string `json:"next"` + Target string `json:"target"` } var custodyParam CustodyParam @@ -1553,17 +1506,7 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, return nil, err } - custodySettings := custodytypes.CustodySettings{ - CustodyEnabled: custodyParam.CustodySettings.CustodyEnabled, - CustodyMode: custodyParam.CustodySettings.CustodyMode, - UsePassword: custodyParam.CustodySettings.UsePassword, - UseWhiteList: custodyParam.CustodySettings.UseWhiteList, - UseLimits: custodyParam.CustodySettings.UseLimits, - Key: custodyParam.CustodySettings.Key, - NextController: custodyParam.CustodySettings.NextController, - } - - msg = custodytypes.NewMsgCreateCustody(from, custodySettings, custodyParam.OldKey, custodyParam.NewKey, + msg = custodytypes.NewMsgCreateCustody(from, custodyParam.CustodySettings, custodyParam.OldKey, custodyParam.NewKey, custodyParam.Next, custodyParam.Target) case MsgAddToCustodyWhiteList: // V, R, S, signer, oldKey string, newKey string, next string, target string From b69ef2dcd9b4e4cf10e2720ecdb8e470bd86839d Mon Sep 17 00:00:00 2001 From: tj327 Date: Wed, 8 May 2024 10:46:07 -0400 Subject: [PATCH 10/25] metamask tx submission update --- common/api.go | 8 +- gateway/kira/metamask/cosmostxsender.go | 1524 ++-------------- gateway/kira/metamask/ethtxinfo.go | 2 + .../kira/metamask/legacy_cosmostxsender.go | 1585 +++++++++++++++++ gateway/kira/metamask/utils.go | 8 + go.mod | 10 +- go.sum | 4 - 7 files changed, 1765 insertions(+), 1376 deletions(-) create mode 100644 gateway/kira/metamask/legacy_cosmostxsender.go diff --git a/common/api.go b/common/api.go index 4691795..35c834f 100644 --- a/common/api.go +++ b/common/api.go @@ -145,10 +145,10 @@ func GetAccountNumberSequence(gwCosmosmux *runtime.ServeMux, r *http.Request, be type QueryAccountResponse struct { Account struct { - Address string `json:"addresss"` - PubKey string `json:"pubKey"` - AccountNumber string `json:"accountNumber"` - Sequence string `json:"sequence"` + Address string `json:"addresss"` + PubKey interface{} `json:"pubKey"` + AccountNumber string `json:"accountNumber"` + Sequence string `json:"sequence"` } `json:"account"` } result := QueryAccountResponse{} diff --git a/gateway/kira/metamask/cosmostxsender.go b/gateway/kira/metamask/cosmostxsender.go index 55512e4..a35d49d 100644 --- a/gateway/kira/metamask/cosmostxsender.go +++ b/gateway/kira/metamask/cosmostxsender.go @@ -7,31 +7,21 @@ import ( "encoding/json" "errors" "fmt" - "math" - "math/big" "net/http" - "time" - sdkmath "cosmossdk.io/math" - "github.com/KiraCore/interx/common" "github.com/KiraCore/interx/config" tx "github.com/KiraCore/interx/proto-gen/cosmos/tx/v1beta1" custodytypes "github.com/KiraCore/sekai/x/custody/types" evidencetypes "github.com/KiraCore/sekai/x/evidence/types" customgovtypes "github.com/KiraCore/sekai/x/gov/types" multistakingtypes "github.com/KiraCore/sekai/x/multistaking/types" - slashingtypes "github.com/KiraCore/sekai/x/slashing/types" + customslashingtypes "github.com/KiraCore/sekai/x/slashing/types" spendingtypes "github.com/KiraCore/sekai/x/spending/types" + customstakingtypes "github.com/KiraCore/sekai/x/staking/types" tokenstypes "github.com/KiraCore/sekai/x/tokens/types" - clienttx "github.com/cosmos/cosmos-sdk/client/tx" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" cosmostypes "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/tx/signing" - xauthsigning "github.com/cosmos/cosmos-sdk/x/auth/signing" - banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" - "github.com/ethereum/go-ethereum/accounts/abi" - ethcommon "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" "google.golang.org/grpc" ) @@ -43,7 +33,7 @@ const ( MsgSubmitProposal MsgVoteProposal MsgRegisterIdentityRecords - MsgDeleteIdentityRecord + MsgDeleteIdentityRecords MsgRequestIdentityRecordsVerify MsgHandleIdentityRecordsVerifyRequest MsgCancelIdentityRecordsVerifyRequest @@ -200,18 +190,29 @@ func sendTx(txRawData string, gwCosmosmux *runtime.ServeMux, r *http.Request) (s } ethTxData, err := GetEthTxInfo(byteData) + if err != nil { + return "", err + } + + txBytes, err := SignTx(ethTxData, byteData, gwCosmosmux, r) + if err != nil { + return "", err + } + txHash, err := sendCosmosTx(r.Context(), txBytes) if err != nil { return "", err } - var txBytes []byte + return txHash, nil +} +func getTxType(txData []byte) (int, error) { submitEvidencePrefix, _ := hex.DecodeString("85db2453") submitProposalPrefix, _ := hex.DecodeString("00000000") voteProposalPrefix, _ := hex.DecodeString("7f1f06dc") registerIdentityRecordsPrefix, _ := hex.DecodeString("bc05f106") - deleteIdentityRecordPrefix, _ := hex.DecodeString("25581f17") + deleteIdentityRecordsPrefix, _ := hex.DecodeString("2dbad8e8") requestIdentityRecordsVerifyPrefix, _ := hex.DecodeString("9765358e") handleIdentityRecordsVerifyRequestPrefix, _ := hex.DecodeString("4335ed0c") cancelIdentityRecordsVerifyRequestPrefix, _ := hex.DecodeString("eeaa0488") @@ -240,7 +241,7 @@ func sendTx(txRawData string, gwCosmosmux *runtime.ServeMux, r *http.Request) (s upsertStakingPoolPrefix, _ := hex.DecodeString("fb24f5cc") delegatePrefix, _ := hex.DecodeString("4b193c09") undelegatePrefix, _ := hex.DecodeString("94574f0c") - claimRewardsPrefix, _ := hex.DecodeString("9e796524") + claimRewardsPrefix, _ := hex.DecodeString("9838bc2f") claimUndelegationPrefix, _ := hex.DecodeString("2f608d76") setCompoundInfoPrefix, _ := hex.DecodeString("e2d6a093") registerDelegatorPrefix, _ := hex.DecodeString("99db185d") @@ -256,284 +257,208 @@ func sendTx(txRawData string, gwCosmosmux *runtime.ServeMux, r *http.Request) (s var msgType int switch { - case ethTxData.Data == nil: + case txData == nil: msgType = MsgBankSend - case bytes.Equal(ethTxData.Data[:4], delegatePrefix): + case len(txData) == 0: + msgType = MsgBankSend + case bytes.Equal(txData, delegatePrefix): msgType = MsgDelegate - case bytes.Equal(ethTxData.Data[:4], undelegatePrefix): + case bytes.Equal(txData, undelegatePrefix): msgType = MsgUndelegate - case bytes.Equal(ethTxData.Data[:4], submitEvidencePrefix): + case bytes.Equal(txData, submitEvidencePrefix): msgType = MsgSubmitEvidence - case bytes.Equal(ethTxData.Data[:4], submitProposalPrefix): + case bytes.Equal(txData, submitProposalPrefix): msgType = MsgSubmitProposal - case bytes.Equal(ethTxData.Data[:4], voteProposalPrefix): + case bytes.Equal(txData, voteProposalPrefix): msgType = MsgVoteProposal - case bytes.Equal(ethTxData.Data[:4], registerIdentityRecordsPrefix): + case bytes.Equal(txData, registerIdentityRecordsPrefix): msgType = MsgRegisterIdentityRecords - case bytes.Equal(ethTxData.Data[:4], deleteIdentityRecordPrefix): - msgType = MsgDeleteIdentityRecord - case bytes.Equal(ethTxData.Data[:4], requestIdentityRecordsVerifyPrefix): + case bytes.Equal(txData, deleteIdentityRecordsPrefix): + msgType = MsgDeleteIdentityRecords + case bytes.Equal(txData, requestIdentityRecordsVerifyPrefix): msgType = MsgRequestIdentityRecordsVerify - case bytes.Equal(ethTxData.Data[:4], handleIdentityRecordsVerifyRequestPrefix): + case bytes.Equal(txData, handleIdentityRecordsVerifyRequestPrefix): msgType = MsgHandleIdentityRecordsVerifyRequest - case bytes.Equal(ethTxData.Data[:4], cancelIdentityRecordsVerifyRequestPrefix): + case bytes.Equal(txData, cancelIdentityRecordsVerifyRequestPrefix): msgType = MsgCancelIdentityRecordsVerifyRequest - case bytes.Equal(ethTxData.Data[:4], setNetworkPropertiesPrefix): + case bytes.Equal(txData, setNetworkPropertiesPrefix): msgType = MsgSetNetworkProperties - case bytes.Equal(ethTxData.Data[:4], setExecutionFeePrefix): + case bytes.Equal(txData, setExecutionFeePrefix): msgType = MsgSetExecutionFee - case bytes.Equal(ethTxData.Data[:4], claimCouncilorPrefix): + case bytes.Equal(txData, claimCouncilorPrefix): msgType = MsgClaimCouncilor - case bytes.Equal(ethTxData.Data[:4], whitelistPermissionsPrefix): + case bytes.Equal(txData, whitelistPermissionsPrefix): msgType = MsgWhitelistPermissions - case bytes.Equal(ethTxData.Data[:4], blacklistPermissionsPrefix): + case bytes.Equal(txData, blacklistPermissionsPrefix): msgType = MsgBlacklistPermissions - case bytes.Equal(ethTxData.Data[:4], createRolePrefix): + case bytes.Equal(txData, createRolePrefix): msgType = MsgCreateRole - case bytes.Equal(ethTxData.Data[:4], assignRolePrefix): + case bytes.Equal(txData, assignRolePrefix): msgType = MsgAssignRole - case bytes.Equal(ethTxData.Data[:4], unassignRolePrefix): + case bytes.Equal(txData, unassignRolePrefix): msgType = MsgUnassignRole - case bytes.Equal(ethTxData.Data[:4], whitelistRolePermissionPrefix): + case bytes.Equal(txData, whitelistRolePermissionPrefix): msgType = MsgWhitelistRolePermission - case bytes.Equal(ethTxData.Data[:4], blacklistRolePermissionPrefix): + case bytes.Equal(txData, blacklistRolePermissionPrefix): msgType = MsgBlacklistRolePermission - case bytes.Equal(ethTxData.Data[:4], removeWhitelistRolePermissionPrefix): + case bytes.Equal(txData, removeWhitelistRolePermissionPrefix): msgType = MsgRemoveWhitelistRolePermission - case bytes.Equal(ethTxData.Data[:4], removeBlacklistRolePermissionPrefix): + case bytes.Equal(txData, removeBlacklistRolePermissionPrefix): msgType = MsgBlacklistRolePermission - case bytes.Equal(ethTxData.Data[:4], claimValidatorPrefix): + case bytes.Equal(txData, claimValidatorPrefix): msgType = MsgClaimValidator - case bytes.Equal(ethTxData.Data[:4], upsertTokenAliasPrefix): + case bytes.Equal(txData, upsertTokenAliasPrefix): msgType = MsgUpsertTokenAlias - case bytes.Equal(ethTxData.Data[:4], upsertTokenRatePrefix): + case bytes.Equal(txData, upsertTokenRatePrefix): msgType = MsgUpsertTokenRate - case bytes.Equal(ethTxData.Data[:4], activatePrefix): + case bytes.Equal(txData, activatePrefix): msgType = MsgActivate - case bytes.Equal(ethTxData.Data[:4], pausePrefix): + case bytes.Equal(txData, pausePrefix): msgType = MsgPause - case bytes.Equal(ethTxData.Data[:4], unpausePrefix): + case bytes.Equal(txData, unpausePrefix): msgType = MsgUnpause - case bytes.Equal(ethTxData.Data[:4], createSpendingPoolPrefix): + case bytes.Equal(txData, createSpendingPoolPrefix): msgType = MsgCreateSpendingPool - case bytes.Equal(ethTxData.Data[:4], depositSpendingPoolPrefix): + case bytes.Equal(txData, depositSpendingPoolPrefix): msgType = MsgDepositSpendingPool - case bytes.Equal(ethTxData.Data[:4], registerSpendingPoolBeneficiaryPrefix): + case bytes.Equal(txData, registerSpendingPoolBeneficiaryPrefix): msgType = MsgRegisterSpendingPoolBeneficiary - case bytes.Equal(ethTxData.Data[:4], claimSpendingPoolPrefix): + case bytes.Equal(txData, claimSpendingPoolPrefix): msgType = MsgClaimSpendingPool - case bytes.Equal(ethTxData.Data[:4], upsertStakingPoolPrefix): + case bytes.Equal(txData, upsertStakingPoolPrefix): msgType = MsgUpsertStakingPool - case bytes.Equal(ethTxData.Data[:4], claimRewardsPrefix): + case bytes.Equal(txData, claimRewardsPrefix): msgType = MsgClaimRewards - case bytes.Equal(ethTxData.Data[:4], claimUndelegationPrefix): + case bytes.Equal(txData, claimUndelegationPrefix): msgType = MsgClaimUndelegation - case bytes.Equal(ethTxData.Data[:4], setCompoundInfoPrefix): + case bytes.Equal(txData, setCompoundInfoPrefix): msgType = MsgSetCompoundInfo - case bytes.Equal(ethTxData.Data[:4], registerDelegatorPrefix): + case bytes.Equal(txData, registerDelegatorPrefix): msgType = MsgRegisterDelegator - case bytes.Equal(ethTxData.Data[:4], createCustodyPrefix): + case bytes.Equal(txData, createCustodyPrefix): msgType = MsgCreateCustody - case bytes.Equal(ethTxData.Data[:4], addToCustodyWhiteListPrefix): + case bytes.Equal(txData, addToCustodyWhiteListPrefix): msgType = MsgAddToCustodyWhiteList - case bytes.Equal(ethTxData.Data[:4], addToCustodyCustodiansPrefix): + case bytes.Equal(txData, addToCustodyCustodiansPrefix): msgType = MsgAddToCustodyCustodians - case bytes.Equal(ethTxData.Data[:4], removeFromCustodyCustodiansPrefix): + case bytes.Equal(txData, removeFromCustodyCustodiansPrefix): msgType = MsgRemoveFromCustodyCustodians - case bytes.Equal(ethTxData.Data[:4], dropCustodyCustodiansPrefix): + case bytes.Equal(txData, dropCustodyCustodiansPrefix): msgType = MsgDropCustodyCustodians - case bytes.Equal(ethTxData.Data[:4], removeFromCustodyWhiteListPrefix): + case bytes.Equal(txData, removeFromCustodyWhiteListPrefix): msgType = MsgRemoveFromCustodyWhiteList - case bytes.Equal(ethTxData.Data[:4], dropCustodyWhiteListPrefix): + case bytes.Equal(txData, dropCustodyWhiteListPrefix): msgType = MsgDropCustodyWhiteList - case bytes.Equal(ethTxData.Data[:4], approveCustodyTxPrefix): + case bytes.Equal(txData, approveCustodyTxPrefix): msgType = MsgApproveCustodyTx - case bytes.Equal(ethTxData.Data[:4], declineCustodyTxPrefix): + case bytes.Equal(txData, declineCustodyTxPrefix): msgType = MsgDeclineCustodyTx default: - return "", errors.New("no such functions") - } - - txBytes, err = SignTx(ethTxData, gwCosmosmux, r, msgType) - - if err != nil { - return "", err + return 0, errors.New("no such functions") } - - // if ethTxData - - txHash, err := sendCosmosTx(r.Context(), txBytes) - if err != nil { - return "", err - } - - return txHash, nil + return msgType, nil } -func getStructHash(txType int, valParam string) ethcommon.Hash { - abiPack := abi.ABI{} - var structABIPack []byte - - var funcSig []byte - +func getInstanceOfTx(txType int) cosmostypes.Msg { switch txType { case MsgSubmitEvidence: - funcSig = crypto.Keccak256([]byte("submitEvidence(string param)")) + return &evidencetypes.MsgSubmitEvidence{} case MsgSubmitProposal: - funcSig = crypto.Keccak256([]byte("submitProposal(string param)")) + return &customgovtypes.MsgSubmitProposal{} case MsgVoteProposal: - funcSig = crypto.Keccak256([]byte("voteProposal(string param)")) + return &customgovtypes.MsgVoteProposal{} case MsgRegisterIdentityRecords: - funcSig = crypto.Keccak256([]byte("registerIdentityRecords(string param)")) - case MsgDeleteIdentityRecord: - funcSig = crypto.Keccak256([]byte("deleteIdentityRecord(string param)")) + return &customgovtypes.MsgRegisterIdentityRecords{} + case MsgDeleteIdentityRecords: + return &customgovtypes.MsgDeleteIdentityRecords{} case MsgRequestIdentityRecordsVerify: - funcSig = crypto.Keccak256([]byte("requestIdentityRecordsVerify(string param)")) + return &customgovtypes.MsgRequestIdentityRecordsVerify{} case MsgHandleIdentityRecordsVerifyRequest: - funcSig = crypto.Keccak256([]byte("handleIdentityRecordsVerifyRequest(string param)")) + return &customgovtypes.MsgHandleIdentityRecordsVerifyRequest{} case MsgCancelIdentityRecordsVerifyRequest: - funcSig = crypto.Keccak256([]byte("cancelIdentityRecordsVerifyRequest(string param)")) + return &customgovtypes.MsgCancelIdentityRecordsVerifyRequest{} case MsgSetNetworkProperties: - funcSig = crypto.Keccak256([]byte("setNetworkProperties(string param)")) + return &customgovtypes.MsgSetNetworkProperties{} case MsgSetExecutionFee: - funcSig = crypto.Keccak256([]byte("setExecutionFee(string param)")) + return &customgovtypes.MsgSetExecutionFee{} case MsgClaimCouncilor: - funcSig = crypto.Keccak256([]byte("claimCouncilor(string param)")) + return &customgovtypes.MsgClaimCouncilor{} case MsgWhitelistPermissions: - funcSig = crypto.Keccak256([]byte("whitelistPermissions(string param)")) + return &customgovtypes.MsgWhitelistPermissions{} case MsgBlacklistPermissions: - funcSig = crypto.Keccak256([]byte("blacklistPermissions(string param)")) + return &customgovtypes.MsgBlacklistPermissions{} case MsgCreateRole: - funcSig = crypto.Keccak256([]byte("createRole(string param)")) + return &customgovtypes.MsgCreateRole{} case MsgAssignRole: - funcSig = crypto.Keccak256([]byte("assignRole(string param)")) + return &customgovtypes.MsgAssignRole{} case MsgUnassignRole: - funcSig = crypto.Keccak256([]byte("unassignRole(string param)")) + return &customgovtypes.MsgUnassignRole{} case MsgWhitelistRolePermission: - funcSig = crypto.Keccak256([]byte("whitelistRolePermission(string param)")) + return &customgovtypes.MsgWhitelistRolePermission{} case MsgBlacklistRolePermission: - funcSig = crypto.Keccak256([]byte("blacklistRolePermission(string param)")) + return &customgovtypes.MsgBlacklistRolePermission{} case MsgRemoveWhitelistRolePermission: - funcSig = crypto.Keccak256([]byte("removeWhitelistRolePermission(string param)")) + return &customgovtypes.MsgRemoveWhitelistRolePermission{} case MsgRemoveBlacklistRolePermission: - funcSig = crypto.Keccak256([]byte("removeBlacklistRolePermission(string param)")) + return &customgovtypes.MsgRemoveBlacklistRolePermission{} case MsgClaimValidator: - // funcSig = crypto.Keccak256([]byte("delegate(string param)")) + return &customstakingtypes.MsgClaimValidator{} case MsgUpsertTokenAlias: - funcSig = crypto.Keccak256([]byte("upsertTokenAlias(string param)")) + return &tokenstypes.MsgUpsertTokenAlias{} case MsgUpsertTokenRate: - funcSig = crypto.Keccak256([]byte("upsertTokenRate(string param)")) + return &tokenstypes.MsgUpsertTokenRate{} case MsgActivate: - funcSig = crypto.Keccak256([]byte("activate()")) + return &customslashingtypes.MsgActivate{} case MsgPause: - funcSig = crypto.Keccak256([]byte("pause()")) + return &customslashingtypes.MsgPause{} case MsgUnpause: - funcSig = crypto.Keccak256([]byte("unpause()")) + return &customslashingtypes.MsgUnpause{} case MsgCreateSpendingPool: - funcSig = crypto.Keccak256([]byte("createSpendingPool(string param)")) + return &spendingtypes.MsgCreateSpendingPool{} case MsgDepositSpendingPool: - funcSig = crypto.Keccak256([]byte("depositSpendingPool(string param)")) + return &spendingtypes.MsgDepositSpendingPool{} case MsgRegisterSpendingPoolBeneficiary: - funcSig = crypto.Keccak256([]byte("registerSpendingPoolBeneficiary(string param)")) + return &spendingtypes.MsgRegisterSpendingPoolBeneficiary{} case MsgClaimSpendingPool: - funcSig = crypto.Keccak256([]byte("claimSpendingPool(string param)")) + return &spendingtypes.MsgClaimSpendingPool{} case MsgUpsertStakingPool: - funcSig = crypto.Keccak256([]byte("upsertStakingPool(string param)")) + return &multistakingtypes.MsgUpsertStakingPool{} case MsgDelegate: - funcSig = crypto.Keccak256([]byte("delegate(string param)")) + return &multistakingtypes.MsgDelegate{} case MsgUndelegate: - funcSig = crypto.Keccak256([]byte("undelegate(string param)")) + return &multistakingtypes.MsgUndelegate{} case MsgClaimRewards: - funcSig = crypto.Keccak256([]byte("claimRewards()")) + return &multistakingtypes.MsgClaimRewards{} case MsgClaimUndelegation: - funcSig = crypto.Keccak256([]byte("claimUndelegation(string param)")) + return &multistakingtypes.MsgClaimUndelegation{} case MsgSetCompoundInfo: - funcSig = crypto.Keccak256([]byte("setCompoundInfo(string param)")) + return &multistakingtypes.MsgSetCompoundInfo{} case MsgRegisterDelegator: - funcSig = crypto.Keccak256([]byte("registerDelegator()")) + return &multistakingtypes.MsgRegisterDelegator{} case MsgCreateCustody: - funcSig = crypto.Keccak256([]byte("createCustody(string param)")) + return &custodytypes.MsgCreateCustodyRecord{} case MsgAddToCustodyWhiteList: - funcSig = crypto.Keccak256([]byte("addToCustodyWhiteList(string param)")) + return &custodytypes.MsgAddToCustodyWhiteList{} case MsgAddToCustodyCustodians: - funcSig = crypto.Keccak256([]byte("addToCustodyCustodians(string param)")) + return &custodytypes.MsgAddToCustodyCustodians{} case MsgRemoveFromCustodyCustodians: - funcSig = crypto.Keccak256([]byte("removeFromCustodyCustodians(string param)")) + return &custodytypes.MsgRemoveFromCustodyCustodians{} case MsgDropCustodyCustodians: - funcSig = crypto.Keccak256([]byte("dropCustodyCustodians(string param)")) + return &custodytypes.MsgDropCustodyCustodians{} case MsgRemoveFromCustodyWhiteList: - funcSig = crypto.Keccak256([]byte("removeFromCustodyWhiteList(string param)")) + return &custodytypes.MsgRemoveFromCustodyWhiteList{} case MsgDropCustodyWhiteList: - funcSig = crypto.Keccak256([]byte("dropCustodyWhiteList(string param)")) + return &custodytypes.MsgDropCustodyWhiteList{} case MsgApproveCustodyTx: - funcSig = crypto.Keccak256([]byte("approveCustodyTransaction(string param)")) + return &custodytypes.MsgApproveCustodyTransaction{} case MsgDeclineCustodyTx: - funcSig = crypto.Keccak256([]byte("declineCustodyTransaction(string param)")) + return &custodytypes.MsgDeclineCustodyTransaction{} default: + return nil } - - structJsonData := []byte(`[{"Type":"function","Name":"encode","Inputs":[{"Type":"bytes32","Name":"funcsig"},{"Type":"bytes32","Name":"param"}],"Outputs":[]}]`) - _ = abiPack.UnmarshalJSON(structJsonData) - - var funcSignature [32]byte - copy(funcSignature[:], funcSig) - - structABIPack, _ = PackABIParams(abiPack, - "encode", - convertByteArr2Bytes32(funcSig), - convertByteArr2Bytes32(crypto.Keccak256([]byte(valParam))), - ) - - structHash := crypto.Keccak256Hash(structABIPack) - - return structHash -} - -func ValidateEIP712Sign(v, r, s []byte, sender ethcommon.Address, valParam string, txType int) bool { - abiPack := abi.ABI{} - - // get EIP712DomainHash - jsonData := []byte(`[{"Type":"function","Name":"encode","Inputs":[{"Type":"bytes32","Name":"funcsig"},{"Type":"bytes32","Name":"name"},{"Type":"bytes32","Name":"version"},{"Type":"bytes32","Name":"chainId"}],"Outputs":[]}]`) - abiPack.UnmarshalJSON(jsonData) - funcSig := crypto.Keccak256([]byte("EIP712Domain(string name,string version,uint256 chainId)")) - - eip712DomainSeparatorABIPack, _ := PackABIParams(abiPack, - "encode", - convertByteArr2Bytes32(funcSig), - convertByteArr2Bytes32(crypto.Keccak256([]byte("Kira"))), - convertByteArr2Bytes32(crypto.Keccak256([]byte("1"))), - convertByteArr2Bytes32(uint32To32Bytes(8789)), - ) - eip712DomainSeparator := crypto.Keccak256Hash(eip712DomainSeparatorABIPack) - - // get StructHash - structHash := getStructHash(txType, valParam) - - // Define the final hash - hash := crypto.Keccak256Hash( - append(append([]byte("\x19\x01"), eip712DomainSeparator.Bytes()...), structHash.Bytes()...), - ) - - signature := getSignature(r, s, v) - - // Recover the public key from the signature - pubKey, err := crypto.SigToPub(hash.Bytes(), signature) - // pbBytes, err := crypto.Ecrecover(hash.Bytes(), signature) - // fmt.Println(string(pbBytes), err) - // pubKey, err := crypto.UnmarshalPubkey(pbBytes) - - if err != nil { - fmt.Println("eip712 err", err) - return false - } - - // Derive the signer's address from the public key - signerAddress := crypto.PubkeyToAddress(*pubKey) - - return signerAddress.Hex() == sender.Hex() } -func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, txType int) ([]byte, error) { +func SignTx(ethTxData EthTxData, ethTxBytes []byte, gwCosmosmux *runtime.ServeMux, r *http.Request) ([]byte, error) { // Create a new TxBuilder. txBuilder := config.EncodingCg.TxConfig.NewTxBuilder() @@ -541,1194 +466,71 @@ func SignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, if err != nil { return nil, err } - cosmosAddr1, err := cosmostypes.AccAddressFromBech32(addr1) - if err != nil { - return nil, err - } - - params, err := DecodeParam(ethTxData.Data[4:], txType) - if err != nil { - return nil, err - } - if txType != MsgBankSend { - valParam := string(params[4]) - - validation := ValidateEIP712Sign(params[0][len(params[0])-1:], params[1], params[2], ethcommon.BytesToAddress(params[3][12:]), valParam, txType) - if !validation { - return nil, errors.New("eip712 validation is failed") - } + var msg cosmostypes.Msg = &tokenstypes.MsgEthereumTx{ + TxType: "NativeSend", + Sender: addr1, + Hash: ethTxData.Hash, + Data: ethTxBytes, } - var msg cosmostypes.Msg - - switch txType { - case MsgBankSend: - addr2, err := hex2bech32(ethTxData.To, TypeKiraAddr) - if err != nil { - return nil, err - } - cosmosAddr2, err := cosmostypes.AccAddressFromBech32(addr2) - if err != nil { - return nil, err - } - - balance := ethTxData.Value.Div(ðTxData.Value, big.NewInt(int64(math.Pow10(12)))) - msg = banktypes.NewMsgSend(cosmosAddr1, cosmosAddr2, - cosmostypes.NewCoins(cosmostypes.NewInt64Coin(config.DefaultKiraDenom, balance.Int64()))) - case MsgSubmitEvidence: - // V, R, S, signer, height, power, time, consensusAddr - from, err := bytes2cosmosAddr(params[3][12:]) - if err != nil { - return nil, err - } - - type Equivocation struct { - Height int64 `json:"height"` - Time time.Time `json:"time"` - Power int64 `json:"power"` - ConsensusAddress string `json:"consensus_address"` - } - - var evidenceJsonParam Equivocation - err = json.Unmarshal(params[4], &evidenceJsonParam) - if err != nil { - return nil, err - } - - evidenceParam := evidencetypes.Equivocation{ - Height: evidenceJsonParam.Height, - Time: evidenceJsonParam.Time, - Power: evidenceJsonParam.Power, - ConsensusAddress: evidenceJsonParam.ConsensusAddress, - } - - msg, err = evidencetypes.NewMsgSubmitEvidence(from, &evidenceParam) - if err != nil { - return nil, err - } - case MsgSubmitProposal: - // from, err := bytes2cosmosAddr(params[3][12:]) - // if err != nil { - // return nil, err - // } - - // type SubmitProposalParam struct { - // Title string `json:"title"` - // Description string `json:"description"` - // Content string `json:"content"` - // } - - // var proposalParam SubmitProposalParam - // err = json.Unmarshal(params[4], &proposalParam) - // if err != nil { - // return nil, err - // } - - // msg, err := customgovtypes.NewMsgSubmitProposal(from) - // if err != nil { - // return nil, err - // } - case MsgVoteProposal: - // V, R, S, signer, param - from, err := bytes2cosmosAddr(params[3][12:]) - if err != nil { - return nil, err - } - - type VoteProposalParam struct { - ProposalID uint64 `json:"proposal_id"` - Option uint64 `json:"option"` - Slash string `json:"slash"` - } - - var proposalParam VoteProposalParam - err = json.Unmarshal(params[4], &proposalParam) - if err != nil { - return nil, err - } - - slash, err := sdkmath.LegacyNewDecFromStr(proposalParam.Slash) - if err != nil { - return nil, err - } - - msg = customgovtypes.NewMsgVoteProposal(proposalParam.ProposalID, from, customgovtypes.VoteOption(proposalParam.Option), slash) - case MsgRegisterIdentityRecords: - // V, R, S, signer, identityInfo, - from, err := bytes2cosmosAddr(params[3][12:]) - if err != nil { - return nil, err - } - - type IdentityRecordParam struct { - Infos []customgovtypes.IdentityInfoEntry `json:"identity_infos"` - } - - var recordParam IdentityRecordParam - err = json.Unmarshal(params[4], &recordParam) - if err != nil { - return nil, err - } - - msg = customgovtypes.NewMsgRegisterIdentityRecords(from, recordParam.Infos) - case MsgDeleteIdentityRecord: - // V, R, S, signer, len, keys, - from, err := bytes2cosmosAddr(params[3][12:]) - if err != nil { - return nil, err - } - - type IdentityRecordParam struct { - Keys []string `json:"keys"` - } - - var recordParam IdentityRecordParam - err = json.Unmarshal(params[4], &recordParam) - if err != nil { - return nil, err - } - - msg = customgovtypes.NewMsgDeleteIdentityRecords(from, recordParam.Keys) - case MsgRequestIdentityRecordsVerify: - // V, R, S, signer, tip, verifier, len, recordIds - from, err := bytes2cosmosAddr(params[3][12:]) - if err != nil { - return nil, err - } - - type IdentityRecordParam struct { - Balance string `json:"balance"` - Verifier string `json:"verifier"` - RecordIds []uint64 `json:"record_ids"` - } - - var recordParam IdentityRecordParam - err = json.Unmarshal(params[4], &recordParam) + var signature []byte + if len(ethTxData.Data) >= 4 { + txType, err := getTxType(ethTxData.Data[:4]) if err != nil { return nil, err } - - balance, err := cosmostypes.ParseCoinNormalized(recordParam.Balance) - if err != nil { - return nil, err - } - - verifier, err := string2cosmosAddr(recordParam.Verifier) - if err != nil { - return nil, err - } - - msg = customgovtypes.NewMsgRequestIdentityRecordsVerify(from, verifier, recordParam.RecordIds, balance) - case MsgHandleIdentityRecordsVerifyRequest: - // V, R, S, signer, requestId, isApprove - verifier, err := bytes2cosmosAddr(params[3][12:]) - if err != nil { - return nil, err - } - - type IdentityRecordParam struct { - RequestID uint64 `json:"request_id"` - IsApproved bool `json:"is_approved"` - } - - var recordParam IdentityRecordParam - err = json.Unmarshal(params[4], &recordParam) - if err != nil { - return nil, err - } - - msg = customgovtypes.NewMsgHandleIdentityRecordsVerifyRequest(verifier, recordParam.RequestID, recordParam.IsApproved) - case MsgCancelIdentityRecordsVerifyRequest: - // V, R, S, signer, verifyRequestId - executor, err := bytes2cosmosAddr(params[3][12:]) - if err != nil { - return nil, err - } - - type IdentityRecordParam struct { - VerifyRequestId uint64 `json:"verify_request_id"` - } - - var recordParam IdentityRecordParam - err = json.Unmarshal(params[4], &recordParam) - if err != nil { - return nil, err - } - - msg = customgovtypes.NewMsgCancelIdentityRecordsVerifyRequest(executor, recordParam.VerifyRequestId) - case MsgSetNetworkProperties: - // V, R, S, signer, networkProperties - proposer, err := bytes2cosmosAddr(params[3][12:]) - if err != nil { - return nil, err - } - - type NetworkProperties struct { - MinTxFee uint64 `json:"min_tx_fee"` - MaxTxFee uint64 `json:"max_tx_fee"` - VoteQuorum uint64 `json:"vote_quorum"` - MinimumProposalEndTime uint64 `json:"minimum_proposal_end_time"` - ProposalEnactmentTime uint64 `json:"proposal_enactment_time"` - MinProposalEndBlocks uint64 `json:"min_proposal_end_blocks"` - MinProposalEnactmentBlocks uint64 `json:"min_proposal_enactment_blocks"` - EnableForeignFeePayments bool `json:"enable_foreign_fee_payments"` - MischanceRankDecreaseAmount uint64 `json:"mischance_rank_decrease_amount"` - MaxMischance uint64 `json:"max_mischance"` - MischanceConfidence uint64 `json:"mischance_confidence"` - InactiveRankDecreasePercent string `json:"inactive_rank_decrease_percent"` - MinValidators uint64 `json:"min_validators"` - PoorNetworkMaxBankSend uint64 `json:"poor_network_max_bank_send"` - UnjailMaxTime uint64 `json:"unjail_max_time"` - EnableTokenWhitelist bool `json:"enable_token_whitelist"` - EnableTokenBlacklist bool `json:"enable_token_blacklist"` - MinIdentityApprovalTip uint64 `json:"min_identity_approval_tip"` - UniqueIdentityKeys string `json:"unique_identity_keys"` - UbiHardcap uint64 `json:"ubi_hardcap"` - ValidatorsFeeShare string `json:"validators_fee_share"` - InflationRate string `json:"inflation_rate"` - InflationPeriod uint64 `json:"inflation_period"` - UnstakingPeriod uint64 `json:"unstaking_period"` - MaxDelegators uint64 `json:"max_delegators"` - MinDelegationPushout uint64 `json:"min_delegation_pushout"` - SlashingPeriod uint64 `json:"slashing_period"` - MaxJailedPercentage string `json:"max_jailed_percentage"` - MaxSlashingPercentage string `json:"max_slashing_percentage"` - MinCustodyReward uint64 `json:"min_custody_reward"` - MaxCustodyBufferSize uint64 `json:"max_custody_buffer_size"` - MaxCustodyTxSize uint64 `json:"max_custody_tx_size"` - AbstentionRankDecreaseAmount uint64 `json:"abstention_rank_decrease_amount"` - MaxAbstention uint64 `json:"max_abstention"` - MinCollectiveBond uint64 `json:"min_collective_bond"` - MinCollectiveBondingTime uint64 `json:"min_collective_bonding_time"` - MaxCollectiveOutputs uint64 `json:"max_collective_outputs"` - MinCollectiveClaimPeriod uint64 `json:"min_collective_claim_period"` - ValidatorRecoveryBond uint64 `json:"validator_recovery_bond"` - MaxAnnualInflation string `json:"max_annual_inflation"` - MaxProposalTitleSize uint64 `json:"max_proposal_title_size"` - MaxProposalDescriptionSize uint64 `json:"max_proposal_description_size"` - MaxProposalPollOptionSize uint64 `json:"max_proposal_poll_option_size"` - MaxProposalPollOptionCount uint64 `json:"max_proposal_poll_option_count"` - MaxProposalReferenceSize uint64 `json:"max_proposal_reference_size"` - MaxProposalChecksumSize uint64 `json:"max_proposal_checksum_size"` - MinDappBond uint64 `json:"min_dapp_bond"` - MaxDappBond uint64 `json:"max_dapp_bond"` - DappLiquidationThreshold uint64 `json:"dapp_liquidation_threshold"` - DappLiquidationPeriod uint64 `json:"dapp_liquidation_period"` - DappBondDuration uint64 `json:"dapp_bond_duration"` - DappVerifierBond string `json:"dapp_verifier_bond"` - DappAutoDenounceTime uint64 `json:"dapp_auto_denounce_time"` - DappMischanceRankDecreaseAmount uint64 `json:"dapp_mischance_rank_decrease_amount"` - DappMaxMischance uint64 `json:"dapp_max_mischance"` - DappInactiveRankDecreasePercent uint64 `json:"dapp_inactive_rank_decrease_percent"` - DappPoolSlippageDefault string `json:"dapp_pool_slippage_default"` - MintingFtFee uint64 `json:"minting_ft_fee"` - MintingNftFee uint64 `json:"minting_nft_fee"` - VetoThreshold string `json:"veto_threshold"` - } - - var networkProperties NetworkProperties - err = json.Unmarshal(params[4], &networkProperties) - if err != nil { - return nil, err - } - - inActiveRankDecreasePercent, err := cosmostypes.NewDecFromStr(networkProperties.InactiveRankDecreasePercent) - if err != nil { - return nil, err - } - validatorsFeeShare, err := cosmostypes.NewDecFromStr(networkProperties.ValidatorsFeeShare) - if err != nil { - return nil, err - } - inflationRate, err := cosmostypes.NewDecFromStr(networkProperties.InflationRate) - if err != nil { - return nil, err - } - maxJailedPercentage, err := cosmostypes.NewDecFromStr(networkProperties.MaxJailedPercentage) - if err != nil { - return nil, err - } - maxSlashingPercentage, err := cosmostypes.NewDecFromStr(networkProperties.MaxSlashingPercentage) - if err != nil { - return nil, err - } - maxAnnualInflation, err := cosmostypes.NewDecFromStr(networkProperties.MaxAnnualInflation) - if err != nil { - return nil, err - } - dappVerifierBond, err := cosmostypes.NewDecFromStr(networkProperties.DappVerifierBond) - if err != nil { - return nil, err - } - dappPoolSlippageDefault, err := cosmostypes.NewDecFromStr(networkProperties.DappPoolSlippageDefault) - if err != nil { - return nil, err - } - vetoThreshold, err := cosmostypes.NewDecFromStr(networkProperties.VetoThreshold) - if err != nil { - return nil, err - } - - networkPropertiesParam := customgovtypes.NetworkProperties{ - MinTxFee: networkProperties.MinTxFee, - MaxTxFee: networkProperties.MaxTxFee, - VoteQuorum: networkProperties.VoteQuorum, - MinimumProposalEndTime: networkProperties.MinimumProposalEndTime, - ProposalEnactmentTime: networkProperties.ProposalEnactmentTime, - MinProposalEndBlocks: networkProperties.MinProposalEndBlocks, - MinProposalEnactmentBlocks: networkProperties.MinProposalEnactmentBlocks, - EnableForeignFeePayments: networkProperties.EnableForeignFeePayments, - MischanceRankDecreaseAmount: networkProperties.MischanceRankDecreaseAmount, - MaxMischance: networkProperties.MaxMischance, - MischanceConfidence: networkProperties.MischanceConfidence, - InactiveRankDecreasePercent: inActiveRankDecreasePercent, - MinValidators: networkProperties.MinValidators, - PoorNetworkMaxBankSend: networkProperties.PoorNetworkMaxBankSend, - UnjailMaxTime: networkProperties.UnjailMaxTime, - EnableTokenWhitelist: networkProperties.EnableTokenWhitelist, - EnableTokenBlacklist: networkProperties.EnableTokenBlacklist, - MinIdentityApprovalTip: networkProperties.MinIdentityApprovalTip, - UniqueIdentityKeys: networkProperties.UniqueIdentityKeys, - UbiHardcap: networkProperties.UbiHardcap, - ValidatorsFeeShare: validatorsFeeShare, - InflationRate: inflationRate, - InflationPeriod: networkProperties.InflationPeriod, - UnstakingPeriod: networkProperties.UnstakingPeriod, - MaxDelegators: networkProperties.MaxDelegators, - MinDelegationPushout: networkProperties.MinDelegationPushout, - SlashingPeriod: networkProperties.SlashingPeriod, - MaxJailedPercentage: maxJailedPercentage, - MaxSlashingPercentage: maxSlashingPercentage, - MinCustodyReward: networkProperties.MinCustodyReward, - MaxCustodyBufferSize: networkProperties.MaxCustodyBufferSize, - MaxCustodyTxSize: networkProperties.MaxCustodyTxSize, - AbstentionRankDecreaseAmount: networkProperties.AbstentionRankDecreaseAmount, - MaxAbstention: networkProperties.MaxAbstention, - MinCollectiveBond: networkProperties.MinCollectiveBond, - MinCollectiveBondingTime: networkProperties.MinCollectiveBondingTime, - MaxCollectiveOutputs: networkProperties.MaxCollectiveOutputs, - MinCollectiveClaimPeriod: networkProperties.MinCollectiveClaimPeriod, - ValidatorRecoveryBond: networkProperties.ValidatorRecoveryBond, - MaxAnnualInflation: maxAnnualInflation, - MaxProposalTitleSize: networkProperties.MaxProposalTitleSize, - MaxProposalDescriptionSize: networkProperties.MaxProposalDescriptionSize, - MaxProposalPollOptionSize: networkProperties.MaxProposalPollOptionSize, - MaxProposalPollOptionCount: networkProperties.MaxProposalPollOptionCount, - MaxProposalReferenceSize: networkProperties.MaxProposalReferenceSize, - MaxProposalChecksumSize: networkProperties.MaxProposalChecksumSize, - MinDappBond: networkProperties.MinDappBond, - MaxDappBond: networkProperties.MaxDappBond, - DappLiquidationThreshold: networkProperties.DappLiquidationThreshold, - DappLiquidationPeriod: networkProperties.DappLiquidationPeriod, - DappBondDuration: networkProperties.DappBondDuration, - DappVerifierBond: dappVerifierBond, - DappAutoDenounceTime: networkProperties.DappAutoDenounceTime, - DappMischanceRankDecreaseAmount: networkProperties.DappMischanceRankDecreaseAmount, - DappMaxMischance: networkProperties.DappMaxMischance, - DappInactiveRankDecreasePercent: networkProperties.DappInactiveRankDecreasePercent, - DappPoolSlippageDefault: dappPoolSlippageDefault, - MintingFtFee: networkProperties.MintingFtFee, - MintingNftFee: networkProperties.MintingNftFee, - VetoThreshold: vetoThreshold, - } - - msg = customgovtypes.NewMsgSetNetworkProperties(proposer, &networkPropertiesParam) - case MsgSetExecutionFee: - // V, R, S, signer, executionFee, failureFee, timeout, defaultParams - proposer, err := bytes2cosmosAddr(params[3][12:]) - if err != nil { - return nil, err - } - - type ExecutionFeeParam struct { - TransactionType string `json:"transaction_type"` - ExecutionFee uint64 `json:"execution_fee"` - FailureFee uint64 `json:"failure_fee"` - Timeout uint64 `json:"timeout"` - DefaultParams uint64 `json:"default_params"` - } - - var feeParam ExecutionFeeParam - err = json.Unmarshal(params[4], &feeParam) + params, err := DecodeParam(ethTxData.Data[4:], txType) if err != nil { return nil, err } - - msg = customgovtypes.NewMsgSetExecutionFee(feeParam.TransactionType, feeParam.ExecutionFee, feeParam.FailureFee, - feeParam.Timeout, feeParam.DefaultParams, proposer) - case MsgClaimCouncilor: - // V, R, S, signer, moniker string, username string, description string, social string, contact string, avatar string - sender, err := bytes2cosmosAddr(params[3][12:]) - if err != nil { - return nil, err + if len(params) < 5 { + return nil, errors.New("insufficient number of params") } - type ClaimCouncilorParam struct { - Moniker string `json:"moniker"` - Username string `json:"username"` - Description string `json:"description"` - Social string `json:"social"` - Contact string `json:"contact"` - Avatar string `json:"avatar"` - } + v, r, s := params[0][len(params[0])-1:], params[1], params[2] + signature = getSignatureV2(r, s, v) - var councilorParam ClaimCouncilorParam - err = json.Unmarshal(params[4], &councilorParam) - if err != nil { - return nil, err + msg = getInstanceOfTx(txType) + if msg == nil { + return nil, fmt.Errorf("unrecognized transaction type: %d", txType) } - - msg = customgovtypes.NewMsgClaimCouncilor(sender, councilorParam.Moniker, councilorParam.Username, councilorParam.Description, - councilorParam.Social, councilorParam.Contact, councilorParam.Avatar) - case MsgWhitelistPermissions: - // V, R, S, signer, permission uint256, controlledAddr string - sender, err := bytes2cosmosAddr(params[3][12:]) + err = json.Unmarshal(params[4], &msg) if err != nil { return nil, err } + } - var permissionParam PermissionsParam - err = json.Unmarshal(params[4], &permissionParam) - if err != nil { - return nil, err - } + // fmt.Println(msg) + err = txBuilder.SetMsgs(msg) + if err != nil { + return nil, err + } + txBuilder.SetGasLimit(ethTxData.GasLimit) + // TODO: set fee amount - how can I get the fee amount from eth tx? or fix this? + txBuilder.SetFeeAmount(cosmostypes.NewCoins(cosmostypes.NewInt64Coin(config.DefaultKiraDenom, 200))) + // txBuilder.SetMemo() + // txBuilder.SetTimeoutHeight() + // txHash, err := sendTx(context.Background(), byteData) - controlledAddr, err := string2cosmosAddr(permissionParam.ControlledAddr) - if err != nil { - return nil, err - } + privs := []cryptotypes.PrivKey{config.Config.PrivKey} + accSeqs := []uint64{ethTxData.Nonce} // The accounts' sequence numbers - msg = customgovtypes.NewMsgWhitelistPermissions(sender, controlledAddr, permissionParam.Permission) - case MsgBlacklistPermissions: - // V, R, S, signer, permission uint256, controlledAddr string - sender, err := bytes2cosmosAddr(params[3][12:]) - if err != nil { - return nil, err + // First round: gather all the signer infos + var sigsV2 []signing.SignatureV2 + for i, priv := range privs { + sigV2 := signing.SignatureV2{ + PubKey: priv.PubKey(), + Data: &signing.SingleSignatureData{ + SignMode: config.EncodingCg.TxConfig.SignModeHandler().DefaultMode(), + Signature: signature, + }, + Sequence: accSeqs[i], } - var permissionParam PermissionsParam - err = json.Unmarshal(params[4], &permissionParam) - if err != nil { - return nil, err - } + sigsV2 = append(sigsV2, sigV2) + } - controlledAddr, err := string2cosmosAddr(permissionParam.ControlledAddr) - if err != nil { - return nil, err - } - - msg = customgovtypes.NewMsgBlacklistPermissions(sender, controlledAddr, permissionParam.Permission) - case MsgCreateRole: - // V, R, S, signer, sid string, description string - sender, err := bytes2cosmosAddr(params[3][12:]) - if err != nil { - return nil, err - } - - type RoleParam struct { - Sid string `json:"sid"` - Description string `json:"description"` - } - - var roleParam RoleParam - err = json.Unmarshal(params[4], &roleParam) - if err != nil { - return nil, err - } - - msg = customgovtypes.NewMsgCreateRole(sender, roleParam.Sid, roleParam.Description) - case MsgAssignRole: - // V, R, S, signer, roleid uint32, controller string - sender, err := bytes2cosmosAddr(params[3][12:]) - if err != nil { - return nil, err - } - - var roleParam RoleParam - err = json.Unmarshal(params[4], &roleParam) - if err != nil { - return nil, err - } - - controller, err := string2cosmosAddr(roleParam.Controller) - if err != nil { - return nil, err - } - - msg = customgovtypes.NewMsgAssignRole(sender, controller, roleParam.RoleId) - case MsgUnassignRole: - // V, R, S, signer, roleid uint32, controller address - sender, err := bytes2cosmosAddr(params[3][12:]) - if err != nil { - return nil, err - } - - var roleParam RoleParam - err = json.Unmarshal(params[4], &roleParam) - if err != nil { - return nil, err - } - - controller, err := string2cosmosAddr(roleParam.Controller) - if err != nil { - return nil, err - } - - msg = customgovtypes.NewMsgUnassignRole(sender, controller, roleParam.RoleId) - case MsgWhitelistRolePermission: - // V, R, S, signer, permission uint32, roleIdentifier string - sender, err := bytes2cosmosAddr(params[3][12:]) - if err != nil { - return nil, err - } - - var roleParam ListRoleParam - err = json.Unmarshal(params[4], &roleParam) - if err != nil { - return nil, err - } - - msg = customgovtypes.NewMsgWhitelistRolePermission(sender, roleParam.RoleIdentifier, roleParam.Permission) - case MsgBlacklistRolePermission: - // V, R, S, signer, permission uint32, roleIdentifier string - sender, err := bytes2cosmosAddr(params[3][12:]) - if err != nil { - return nil, err - } - - var roleParam ListRoleParam - err = json.Unmarshal(params[4], &roleParam) - if err != nil { - return nil, err - } - - msg = customgovtypes.NewMsgBlacklistRolePermission(sender, roleParam.RoleIdentifier, roleParam.Permission) - case MsgRemoveWhitelistRolePermission: - // V, R, S, signer, permission uint32, roleIdentifier string - sender, err := bytes2cosmosAddr(params[3][12:]) - if err != nil { - return nil, err - } - - var roleParam ListRoleParam - err = json.Unmarshal(params[4], &roleParam) - if err != nil { - return nil, err - } - - msg = customgovtypes.NewMsgRemoveWhitelistRolePermission(sender, roleParam.RoleIdentifier, roleParam.Permission) - case MsgRemoveBlacklistRolePermission: - // V, R, S, signer, permission uint32, roleIdentifier string - sender, err := bytes2cosmosAddr(params[3][12:]) - if err != nil { - return nil, err - } - - var roleParam ListRoleParam - err = json.Unmarshal(params[4], &roleParam) - if err != nil { - return nil, err - } - - msg = customgovtypes.NewMsgRemoveBlacklistRolePermission(sender, roleParam.RoleIdentifier, roleParam.Permission) - case MsgClaimValidator: - // V, R, S, signer, moniker string, valKey cosmostypes.ValAddress, pubKey cryptotypes.PubKey - - // type ClaimParam struct { - // Moniker string `json:"moniker"` - // ValKey string `json:"val_key"` - // PubKey string `json:"pub_key"` - // } - - // var claimParam ClaimParam - // err = json.Unmarshal(params[4], &claimParam) - // if err != nil { - // return nil, err - // } - - // valKey, err := cosmostypes.ValAddressFromBech32(claimParam.ValKey) - // if err != nil { - // return nil, err - // } - - // // how to get pub key from string? - // cryptotypes - - // msg, err = stakingtypes.NewMsgClaimValidator(claimParam.Moniker, valKey, claimParam.PubKey) - // if err != nil { - // return nil, err - // } - case MsgUpsertTokenAlias: - // V, R, S, signer, param - proposer, err := bytes2cosmosAddr(params[3][12:]) - if err != nil { - return nil, err - } - - type UpsertTokenAliasParam struct { - Symbol string `json:"symbol"` - Name string `json:"name"` - Icon string `json:"icon"` - Decimals uint32 `json:"decimals"` - Denoms []string `json:"denoms"` - Invalidated bool `json:"invalidated"` - } - - var upsertTokenAliasParam UpsertTokenAliasParam - err = json.Unmarshal(params[4], &upsertTokenAliasParam) - if err != nil { - return nil, err - } - - msg = tokenstypes.NewMsgUpsertTokenAlias(proposer, upsertTokenAliasParam.Symbol, upsertTokenAliasParam.Name, - upsertTokenAliasParam.Icon, upsertTokenAliasParam.Decimals, upsertTokenAliasParam.Denoms, upsertTokenAliasParam.Invalidated) - case MsgUpsertTokenRate: - // V, R, S, signer, feePayments bool, stakeToken bool, invalidated bool, denom string, rate cosmostypes.Dec, - // stakeCap cosmostypes.Dec, stakeMin cosmostypes.Int - proposer, err := bytes2cosmosAddr(params[3][12:]) - if err != nil { - return nil, err - } - - type UpsertTokenRateParam struct { - Denom string `json:"denom"` - Rate string `json:"rate"` - IsFeePayments bool `json:"is_fee_payments"` - StakeCap string `json:"stake_cap"` - StakeMin string `json:"stake_min"` - IsStakeToken bool `json:"is_stake_token"` - Invalidated bool `json:"invalidated"` - } - - var upsertParam UpsertTokenRateParam - err = json.Unmarshal(params[4], &upsertParam) - if err != nil { - return nil, err - } - - rate, err := cosmostypes.NewDecFromStr(upsertParam.Rate) - if err != nil { - return nil, err - } - stakeCap, err := cosmostypes.NewDecFromStr(upsertParam.StakeCap) - if err != nil { - return nil, err - } - stakeMin, ok := cosmostypes.NewIntFromString(upsertParam.StakeMin) - if !ok { - return nil, errors.New(fmt.Sprintln("StakeMin - decoding from string to Int type is failed:", upsertParam.StakeMin)) - } - - msg = tokenstypes.NewMsgUpsertTokenRate(proposer, upsertParam.Denom, rate, upsertParam.IsFeePayments, - stakeCap, stakeMin, upsertParam.IsStakeToken, upsertParam.Invalidated) - case MsgActivate: - // V, R, S, signer - validator, err := bytes2cosmosValAddr(params[3][12:]) - if err != nil { - return nil, err - } - msg = slashingtypes.NewMsgActivate(validator) - case MsgPause: - // V, R, S, signer - validator, err := bytes2cosmosValAddr(params[3][12:]) - if err != nil { - return nil, err - } - msg = slashingtypes.NewMsgPause(validator) - case MsgUnpause: - // V, R, S, signer - validator, err := bytes2cosmosValAddr(params[3][12:]) - if err != nil { - return nil, err - } - msg = slashingtypes.NewMsgUnpause(validator) - case MsgCreateSpendingPool: - // V, R, S, signer, name string, claimStart uint64, claimEnd uint64, rates cosmostypes.DecCoins, voteQuorum uint64, - // votePeriod uint64, voteEnactment uint64, owners spendingtypes.PermInfo, beneficiaries spendingtypes.WeightedPermInfo, - // sender cosmostypes.AccAddress, dynamicRate bool, dynamicRatePeriod uint64 - sender, err := bytes2cosmosAddr(params[3][12:]) - if err != nil { - return nil, err - } - - type WeightedRole struct { - Role uint64 `json:"role"` - Weight string `json:"weight"` - } - - type WeightedAccount struct { - Account string `json:"account"` - Weight string `json:"weight"` - } - - type WeightedPermInfo struct { - Roles []WeightedRole `json:"roles"` - Accounts []WeightedAccount `json:"accounts"` - } - - type SpendingPoolParam struct { - Name string `json:"name"` - ClaimStart uint64 `json:"claim_start"` - ClaimEnd uint64 `json:"claim_end"` - Rates []string `json:"rates"` - VoteQuorum uint64 `json:"vote_quorum"` - VotePeriod uint64 `json:"vote_period"` - VoteEnactment uint64 `json:"vote_enactment"` - Owners spendingtypes.PermInfo `json:"owners"` - Beneficiaries WeightedPermInfo `json:"beneficiaries"` - IsDynamicRate bool `json:"is_dynamic_rate"` - DynamicRatePeriod uint64 `json:"dynamic_rate_period"` - } - - var poolParam SpendingPoolParam - err = json.Unmarshal(params[4], &poolParam) - if err != nil { - return nil, err - } - - var rates cosmostypes.DecCoins - for _, rate := range poolParam.Rates { - coin, err := cosmostypes.ParseDecCoin(rate) - if err != nil { - return nil, err - } - rates.Add(coin) - } - - var beneficiaries spendingtypes.WeightedPermInfo - for _, account := range poolParam.Beneficiaries.Accounts { - weight, err := cosmostypes.NewDecFromStr(account.Weight) - if err != nil { - return nil, err - } - weightedAccount := spendingtypes.WeightedAccount{ - Account: account.Account, - Weight: weight, - } - beneficiaries.Accounts = append(beneficiaries.Accounts, weightedAccount) - } - for _, role := range poolParam.Beneficiaries.Roles { - weight, err := cosmostypes.NewDecFromStr(role.Weight) - if err != nil { - return nil, err - } - weightedRole := spendingtypes.WeightedRole{ - Role: role.Role, - Weight: weight, - } - beneficiaries.Roles = append(beneficiaries.Roles, weightedRole) - } - - msg = spendingtypes.NewMsgCreateSpendingPool(poolParam.Name, poolParam.ClaimStart, poolParam.ClaimEnd, rates, - poolParam.VoteQuorum, poolParam.VotePeriod, poolParam.VoteEnactment, poolParam.Owners, beneficiaries, - sender, poolParam.IsDynamicRate, poolParam.DynamicRatePeriod) - case MsgDepositSpendingPool: - // V, R, S, signer, amount string, name string - sender, err := bytes2cosmosAddr(params[3][12:]) - if err != nil { - return nil, err - } - - var poolParam SpendingPoolParam - err = json.Unmarshal(params[4], &poolParam) - if err != nil { - return nil, err - } - - amounts, err := cosmostypes.ParseCoinsNormalized(poolParam.Amounts) - if err != nil { - return nil, err - } - - msg = spendingtypes.NewMsgDepositSpendingPool(poolParam.Name, amounts, sender) - case MsgRegisterSpendingPoolBeneficiary: - // V, R, S, signer, name string - sender, err := bytes2cosmosAddr(params[3][12:]) - if err != nil { - return nil, err - } - - var poolParam SpendingPoolParam - err = json.Unmarshal(params[4], &poolParam) - if err != nil { - return nil, err - } - - msg = spendingtypes.NewMsgRegisterSpendingPoolBeneficiary(poolParam.Name, sender) - case MsgClaimSpendingPool: - // V, R, S, signer, name string - sender, err := bytes2cosmosAddr(params[3][12:]) - if err != nil { - return nil, err - } - - var poolParam SpendingPoolParam - err = json.Unmarshal(params[4], &poolParam) - if err != nil { - return nil, err - } - - msg = spendingtypes.NewMsgClaimSpendingPool(poolParam.Name, sender) - case MsgUpsertStakingPool: - // V, R, S, signer, enabled bool, validator string, commission cosmostypes.Dec - from, err := hex2bech32(hex.EncodeToString(params[3][12:]), TypeKiraAddr) - if err != nil { - return nil, err - } - - type StakingPoolParam struct { - Validator string `json:"validator"` - Enabled bool `json:"enabled"` - Commission string `json:"commission"` - } - - var poolParam StakingPoolParam - err = json.Unmarshal(params[4], &poolParam) - if err != nil { - return nil, err - } - - commission, err := cosmostypes.NewDecFromStr(poolParam.Commission) - if err != nil { - return nil, err - } - - msg = multistakingtypes.NewMsgUpsertStakingPool(from, poolParam.Validator, poolParam.Enabled, commission) - case MsgDelegate: - // V, R, S, signer, param - from, err := hex2bech32(hex.EncodeToString(params[3][12:]), TypeKiraAddr) - if err != nil { - return nil, err - } - - var delegateParam DelegateParam - err = json.Unmarshal(params[4], &delegateParam) - if err != nil { - return nil, err - } - - amounts, err := cosmostypes.ParseCoinsNormalized(delegateParam.Amounts) - if err != nil { - return nil, err - } - - msg = multistakingtypes.NewMsgDelegate(from, delegateParam.To, amounts) - case MsgUndelegate: - // V, R, S, signer, amount, validator - from, err := hex2bech32(hex.EncodeToString(params[3][12:]), TypeKiraAddr) - if err != nil { - return nil, err - } - - var delegateParam DelegateParam - err = json.Unmarshal(params[4], &delegateParam) - if err != nil { - return nil, err - } - - amounts, err := cosmostypes.ParseCoinsNormalized(delegateParam.Amounts) - if err != nil { - return nil, err - } - - msg = multistakingtypes.NewMsgUndelegate(from, delegateParam.To, amounts) - case MsgClaimRewards: - // V, R, S, signer - from, err := hex2bech32(hex.EncodeToString(params[3][12:]), TypeKiraAddr) - if err != nil { - return nil, err - } - msg = multistakingtypes.NewMsgClaimRewards(from) - case MsgClaimUndelegation: - // V, R, S, signer, undelegationId uint64 - from, err := hex2bech32(hex.EncodeToString(params[3][12:]), TypeKiraAddr) - if err != nil { - return nil, err - } - - type UndelegationParam struct { - UndelegationId uint64 `json:"undelegation_id"` - } - - var undelegationParam UndelegationParam - err = json.Unmarshal(params[4], &undelegationParam) - if err != nil { - return nil, err - } - - msg = multistakingtypes.NewMsgClaimUndelegation(from, undelegationParam.UndelegationId) - case MsgSetCompoundInfo: - // V, R, S, signer, allDenom bool, len, denoms []string - from, err := hex2bech32(hex.EncodeToString(params[3][12:]), TypeKiraAddr) - if err != nil { - return nil, err - } - - type UndelegationParam struct { - IsAllDenom bool `json:"is_all_denom"` - Denoms []string `json:"denoms"` - } - - var undelegationParam UndelegationParam - err = json.Unmarshal(params[4], &undelegationParam) - if err != nil { - return nil, err - } - - msg = multistakingtypes.NewMsgSetCompoundInfo(from, undelegationParam.IsAllDenom, undelegationParam.Denoms) - case MsgRegisterDelegator: - // V, R, S, signer - from, err := hex2bech32(hex.EncodeToString(params[3][12:]), TypeKiraAddr) - if err != nil { - return nil, err - } - - msg = multistakingtypes.NewMsgRegisterDelegator(from) - case MsgCreateCustody: - // V, R, S, signer, custodyMode uint256, key string, nextController string, len, boolArr, len, strArr - from, err := bytes2cosmosAddr(params[3][12:]) - if err != nil { - return nil, err - } - - type CustodyParam struct { - CustodySettings custodytypes.CustodySettings `json:"custody_settings"` - OldKey string `json:"old_key"` - NewKey string `json:"new_key"` - Next string `json:"next"` - Target string `json:"target"` - } - - var custodyParam CustodyParam - err = json.Unmarshal(params[4], &custodyParam) - if err != nil { - return nil, err - } - - msg = custodytypes.NewMsgCreateCustody(from, custodyParam.CustodySettings, custodyParam.OldKey, custodyParam.NewKey, - custodyParam.Next, custodyParam.Target) - case MsgAddToCustodyWhiteList: - // V, R, S, signer, oldKey string, newKey string, next string, target string - // len, newAddr []string, - from, err := bytes2cosmosAddr(params[3][12:]) - if err != nil { - return nil, err - } - - var custodyParam CustodianParam - err = json.Unmarshal(params[4], &custodyParam) - if err != nil { - return nil, err - } - - var newAddrs []cosmostypes.AccAddress - for _, addrStr := range custodyParam.NewAddrs { - addr, err := cosmostypes.AccAddressFromBech32(addrStr) - if err != nil { - return nil, err - } - newAddrs = append(newAddrs, addr) - } - - msg = custodytypes.NewMsgAddToCustodyWhiteList(from, newAddrs, custodyParam.OldKey, custodyParam.NewKey, - custodyParam.Next, custodyParam.Target) - case MsgAddToCustodyCustodians: - // V, R, S, signer, oldKey string, newKey string, next string, target string - // len, newAddr []string - from, err := bytes2cosmosAddr(params[3][12:]) - if err != nil { - return nil, err - } - - var custodyParam CustodianParam - err = json.Unmarshal(params[4], &custodyParam) - if err != nil { - return nil, err - } - - var newAddrs []cosmostypes.AccAddress - for _, addrStr := range custodyParam.NewAddrs { - addr, err := cosmostypes.AccAddressFromBech32(addrStr) - if err != nil { - return nil, err - } - newAddrs = append(newAddrs, addr) - } - - msg = custodytypes.NewMsgAddToCustodyCustodians(from, newAddrs, custodyParam.OldKey, custodyParam.NewKey, - custodyParam.Next, custodyParam.Target) - case MsgRemoveFromCustodyCustodians: - // V, R, S, signer, newAddr cosmostypes.AccAddress, - // oldKey string, newKey string, next string, target string - from, err := bytes2cosmosAddr(params[3][12:]) - if err != nil { - return nil, err - } - - var custodyParam SingleCustodianParam - err = json.Unmarshal(params[4], &custodyParam) - if err != nil { - return nil, err - } - - newAddr, err := cosmostypes.AccAddressFromBech32(custodyParam.NewAddr) - if err != nil { - return nil, err - } - - msg = custodytypes.NewMsgRemoveFromCustodyCustodians(from, newAddr, custodyParam.OldKey, custodyParam.NewKey, - custodyParam.Next, custodyParam.Target) - case MsgDropCustodyCustodians: - // V, R, S, signer - // oldKey string, newKey string, next string, target string - from, err := bytes2cosmosAddr(params[3][12:]) - if err != nil { - return nil, err - } - - var custodyParam CustodianParam - err = json.Unmarshal(params[4], &custodyParam) - if err != nil { - return nil, err - } - - msg = custodytypes.NewMsgDropCustodyCustodians(from, custodyParam.OldKey, custodyParam.NewKey, - custodyParam.Next, custodyParam.Target) - case MsgRemoveFromCustodyWhiteList: - // V, R, S, signer, newAddr string, - // oldKey string, newKey string, next string, target string - from, err := bytes2cosmosAddr(params[3][12:]) - if err != nil { - return nil, err - } - - var custodyParam SingleCustodianParam - err = json.Unmarshal(params[4], &custodyParam) - if err != nil { - return nil, err - } - - newAddr, err := cosmostypes.AccAddressFromBech32(custodyParam.NewAddr) - if err != nil { - return nil, err - } - - msg = custodytypes.NewMsgRemoveFromCustodyWhiteList(from, newAddr, custodyParam.OldKey, custodyParam.NewKey, - custodyParam.Next, custodyParam.Target) - case MsgDropCustodyWhiteList: - // V, R, S, signer - // oldKey string, newKey string, next string, target string - from, err := bytes2cosmosAddr(params[3][12:]) - if err != nil { - return nil, err - } - - var custodyParam CustodianParam - err = json.Unmarshal(params[4], &custodyParam) - if err != nil { - return nil, err - } - - msg = custodytypes.NewMsgDropCustodyWhiteList(from, custodyParam.OldKey, custodyParam.NewKey, - custodyParam.Next, custodyParam.Target) - case MsgApproveCustodyTx: - // V, R, S, signer, to string, hash string - from, err := bytes2cosmosAddr(params[3][12:]) - if err != nil { - return nil, err - } - - var custodyParam CustodyParam - err = json.Unmarshal(params[4], &custodyParam) - if err != nil { - return nil, err - } - - to, err := cosmostypes.AccAddressFromBech32(custodyParam.To) - if err != nil { - return nil, err - } - - msg = custodytypes.NewMsgApproveCustodyTransaction(from, to, custodyParam.Hash) - case MsgDeclineCustodyTx: - // V, R, S, signer, to string, hash string - from, err := bytes2cosmosAddr(params[3][12:]) - if err != nil { - return nil, err - } - - var custodyParam CustodyParam - err = json.Unmarshal(params[4], &custodyParam) - if err != nil { - return nil, err - } - - to, err := cosmostypes.AccAddressFromBech32(custodyParam.To) - if err != nil { - return nil, err - } - - msg = custodytypes.NewMsgDeclineCustodyTransaction(from, to, custodyParam.Hash) - } - - // fmt.Println(msg) - err = txBuilder.SetMsgs(msg) - if err != nil { - return nil, err - } - txBuilder.SetGasLimit(ethTxData.GasLimit) - // TODO: set fee amount - how can I get the fee amount from eth tx? or fix this? - txBuilder.SetFeeAmount(cosmostypes.NewCoins(cosmostypes.NewInt64Coin(config.DefaultKiraDenom, 200))) - // txBuilder.SetMemo() - // txBuilder.SetTimeoutHeight() - // txHash, err := sendTx(context.Background(), byteData) - - accNum, _ := common.GetAccountNumberSequence(gwCosmosmux, r, addr1) - - privs := []cryptotypes.PrivKey{config.Config.PrivKey} - accNums := []uint64{accNum} // The accounts' account numbers - accSeqs := []uint64{ethTxData.Nonce} // The accounts' sequence numbers - - // First round: gather all the signer infos - var sigsV2 []signing.SignatureV2 - for i, priv := range privs { - sigV2 := signing.SignatureV2{ - PubKey: priv.PubKey(), - Data: &signing.SingleSignatureData{ - SignMode: config.EncodingCg.TxConfig.SignModeHandler().DefaultMode(), - Signature: nil, - }, - Sequence: accSeqs[i], - } - - sigsV2 = append(sigsV2, sigV2) - } - - err = txBuilder.SetSignatures(sigsV2...) - if err != nil { - return nil, err - } - - interxStatus := common.GetInterxStatus("http://127.0.0.1:11000") - - // Second round: all signer infos are set, so each signer can sign. - sigsV2 = []signing.SignatureV2{} - for i, priv := range privs { - signerData := xauthsigning.SignerData{ - ChainID: interxStatus.InterxInfo.ChainID, - AccountNumber: accNums[i], - Sequence: accSeqs[i], - } - sigV2, err := clienttx.SignWithPrivKey( - config.EncodingCg.TxConfig.SignModeHandler().DefaultMode(), signerData, - txBuilder, priv, config.EncodingCg.TxConfig, accSeqs[i]) - if err != nil { - return nil, err - } - - sigsV2 = append(sigsV2, sigV2) - } err = txBuilder.SetSignatures(sigsV2...) if err != nil { return nil, err @@ -1780,7 +582,7 @@ func sendCosmosTx(ctx context.Context, txBytes []byte) (string, error) { // fmt.Println(grpcRes.TxResponse) if grpcRes.TxResponse.Code != 0 { - return "", errors.New(fmt.Sprintln("send tx failed - result code: ", grpcRes.TxResponse.Code)) + return "", errors.New(fmt.Sprintln("send tx failed - result code: ", grpcRes.TxResponse.Code, grpcRes.TxResponse.RawLog)) } return grpcRes.TxResponse.TxHash, nil diff --git a/gateway/kira/metamask/ethtxinfo.go b/gateway/kira/metamask/ethtxinfo.go index 8c962e7..fdecb00 100644 --- a/gateway/kira/metamask/ethtxinfo.go +++ b/gateway/kira/metamask/ethtxinfo.go @@ -19,6 +19,7 @@ type EthTxData struct { To string `json:"to"` Value big.Int `json:"value"` Data []byte `json:"data"` + Hash string `json:"hash"` V big.Int `json:"signature_v"` R big.Int `json:"signature_r"` S big.Int `json:"signature_s"` @@ -81,6 +82,7 @@ func GetEthTxInfo(data hexutil.Bytes) (EthTxData, error) { To: msg.To().String(), Value: *tx.Value(), Data: tx.Data(), + Hash: tx.Hash().Hex(), V: *v, R: *r, S: *s, diff --git a/gateway/kira/metamask/legacy_cosmostxsender.go b/gateway/kira/metamask/legacy_cosmostxsender.go new file mode 100644 index 0000000..513b674 --- /dev/null +++ b/gateway/kira/metamask/legacy_cosmostxsender.go @@ -0,0 +1,1585 @@ +package metamask + +import ( + "bytes" + "encoding/hex" + "encoding/json" + "errors" + "fmt" + "math" + "math/big" + "net/http" + "time" + + sdkmath "cosmossdk.io/math" + "github.com/KiraCore/interx/common" + "github.com/KiraCore/interx/config" + custodytypes "github.com/KiraCore/sekai/x/custody/types" + evidencetypes "github.com/KiraCore/sekai/x/evidence/types" + customgovtypes "github.com/KiraCore/sekai/x/gov/types" + multistakingtypes "github.com/KiraCore/sekai/x/multistaking/types" + slashingtypes "github.com/KiraCore/sekai/x/slashing/types" + spendingtypes "github.com/KiraCore/sekai/x/spending/types" + tokenstypes "github.com/KiraCore/sekai/x/tokens/types" + clienttx "github.com/cosmos/cosmos-sdk/client/tx" + cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" + cosmostypes "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/tx/signing" + xauthsigning "github.com/cosmos/cosmos-sdk/x/auth/signing" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + "github.com/ethereum/go-ethereum/accounts/abi" + ethcommon "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" +) + +func legacySendTx(txRawData string, gwCosmosmux *runtime.ServeMux, r *http.Request) (string, error) { + byteData, err := hex.DecodeString(txRawData[2:]) + if err != nil { + return "", err + } + + ethTxData, err := GetEthTxInfo(byteData) + + if err != nil { + return "", err + } + + var txBytes []byte + + submitEvidencePrefix, _ := hex.DecodeString("85db2453") + submitProposalPrefix, _ := hex.DecodeString("00000000") + voteProposalPrefix, _ := hex.DecodeString("7f1f06dc") + registerIdentityRecordsPrefix, _ := hex.DecodeString("bc05f106") + deleteIdentityRecordPrefix, _ := hex.DecodeString("25581f17") + requestIdentityRecordsVerifyPrefix, _ := hex.DecodeString("9765358e") + handleIdentityRecordsVerifyRequestPrefix, _ := hex.DecodeString("4335ed0c") + cancelIdentityRecordsVerifyRequestPrefix, _ := hex.DecodeString("eeaa0488") + setNetworkPropertiesPrefix, _ := hex.DecodeString("f8060fb5") + setExecutionFeePrefix, _ := hex.DecodeString("c7586de8") + claimCouncilorPrefix, _ := hex.DecodeString("b7b8ff46") + whitelistPermissionsPrefix, _ := hex.DecodeString("2f313ab8") + blacklistPermissionsPrefix, _ := hex.DecodeString("3864f845") + createRolePrefix, _ := hex.DecodeString("2d8abfdf") + assignRolePrefix, _ := hex.DecodeString("fcc121b5") + unassignRolePrefix, _ := hex.DecodeString("c79ca19d") + whitelistRolePermissionPrefix, _ := hex.DecodeString("59472362") + blacklistRolePermissionPrefix, _ := hex.DecodeString("99c557da") + removeWhitelistRolePermissionPrefix, _ := hex.DecodeString("2a11d702") + removeBlacklistRolePermissionPrefix, _ := hex.DecodeString("f5f865e4") + claimValidatorPrefix, _ := hex.DecodeString("00000000") + upsertTokenAliasPrefix, _ := hex.DecodeString("f69a4787") + upsertTokenRatePrefix, _ := hex.DecodeString("3b30a97a") + activatePrefix, _ := hex.DecodeString("a1374dc2") + pausePrefix, _ := hex.DecodeString("1371cf19") + unpausePrefix, _ := hex.DecodeString("b9179894") + createSpendingPoolPrefix, _ := hex.DecodeString("4ed8a0a2") + depositSpendingPoolPrefix, _ := hex.DecodeString("e10c925c") + registerSpendingPoolBeneficiaryPrefix, _ := hex.DecodeString("7ab7eecf") + claimSpendingPoolPrefix, _ := hex.DecodeString("efeed4a0") + upsertStakingPoolPrefix, _ := hex.DecodeString("fb24f5cc") + delegatePrefix, _ := hex.DecodeString("4b193c09") + undelegatePrefix, _ := hex.DecodeString("94574f0c") + claimRewardsPrefix, _ := hex.DecodeString("9e796524") + claimUndelegationPrefix, _ := hex.DecodeString("2f608d76") + setCompoundInfoPrefix, _ := hex.DecodeString("e2d6a093") + registerDelegatorPrefix, _ := hex.DecodeString("99db185d") + createCustodyPrefix, _ := hex.DecodeString("bebde6d1") + addToCustodyWhiteListPrefix, _ := hex.DecodeString("25a1d834") + addToCustodyCustodiansPrefix, _ := hex.DecodeString("8c7fdb91") + removeFromCustodyCustodiansPrefix, _ := hex.DecodeString("90be51cf") + dropCustodyCustodiansPrefix, _ := hex.DecodeString("0ca697b4") + removeFromCustodyWhiteListPrefix, _ := hex.DecodeString("fa431c3e") + dropCustodyWhiteListPrefix, _ := hex.DecodeString("bc65010a") + approveCustodyTxPrefix, _ := hex.DecodeString("5da292d4") + declineCustodyTxPrefix, _ := hex.DecodeString("dce4399a") + + var msgType int + switch { + case ethTxData.Data == nil: + msgType = MsgBankSend + case len(ethTxData.Data) == 0: + msgType = MsgBankSend + case bytes.Equal(ethTxData.Data[:4], delegatePrefix): + msgType = MsgDelegate + case bytes.Equal(ethTxData.Data[:4], undelegatePrefix): + msgType = MsgUndelegate + case bytes.Equal(ethTxData.Data[:4], submitEvidencePrefix): + msgType = MsgSubmitEvidence + case bytes.Equal(ethTxData.Data[:4], submitProposalPrefix): + msgType = MsgSubmitProposal + case bytes.Equal(ethTxData.Data[:4], voteProposalPrefix): + msgType = MsgVoteProposal + case bytes.Equal(ethTxData.Data[:4], registerIdentityRecordsPrefix): + msgType = MsgRegisterIdentityRecords + case bytes.Equal(ethTxData.Data[:4], deleteIdentityRecordPrefix): + msgType = MsgDeleteIdentityRecords + case bytes.Equal(ethTxData.Data[:4], requestIdentityRecordsVerifyPrefix): + msgType = MsgRequestIdentityRecordsVerify + case bytes.Equal(ethTxData.Data[:4], handleIdentityRecordsVerifyRequestPrefix): + msgType = MsgHandleIdentityRecordsVerifyRequest + case bytes.Equal(ethTxData.Data[:4], cancelIdentityRecordsVerifyRequestPrefix): + msgType = MsgCancelIdentityRecordsVerifyRequest + case bytes.Equal(ethTxData.Data[:4], setNetworkPropertiesPrefix): + msgType = MsgSetNetworkProperties + case bytes.Equal(ethTxData.Data[:4], setExecutionFeePrefix): + msgType = MsgSetExecutionFee + case bytes.Equal(ethTxData.Data[:4], claimCouncilorPrefix): + msgType = MsgClaimCouncilor + case bytes.Equal(ethTxData.Data[:4], whitelistPermissionsPrefix): + msgType = MsgWhitelistPermissions + case bytes.Equal(ethTxData.Data[:4], blacklistPermissionsPrefix): + msgType = MsgBlacklistPermissions + case bytes.Equal(ethTxData.Data[:4], createRolePrefix): + msgType = MsgCreateRole + case bytes.Equal(ethTxData.Data[:4], assignRolePrefix): + msgType = MsgAssignRole + case bytes.Equal(ethTxData.Data[:4], unassignRolePrefix): + msgType = MsgUnassignRole + case bytes.Equal(ethTxData.Data[:4], whitelistRolePermissionPrefix): + msgType = MsgWhitelistRolePermission + case bytes.Equal(ethTxData.Data[:4], blacklistRolePermissionPrefix): + msgType = MsgBlacklistRolePermission + case bytes.Equal(ethTxData.Data[:4], removeWhitelistRolePermissionPrefix): + msgType = MsgRemoveWhitelistRolePermission + case bytes.Equal(ethTxData.Data[:4], removeBlacklistRolePermissionPrefix): + msgType = MsgBlacklistRolePermission + case bytes.Equal(ethTxData.Data[:4], claimValidatorPrefix): + msgType = MsgClaimValidator + case bytes.Equal(ethTxData.Data[:4], upsertTokenAliasPrefix): + msgType = MsgUpsertTokenAlias + case bytes.Equal(ethTxData.Data[:4], upsertTokenRatePrefix): + msgType = MsgUpsertTokenRate + case bytes.Equal(ethTxData.Data[:4], activatePrefix): + msgType = MsgActivate + case bytes.Equal(ethTxData.Data[:4], pausePrefix): + msgType = MsgPause + case bytes.Equal(ethTxData.Data[:4], unpausePrefix): + msgType = MsgUnpause + case bytes.Equal(ethTxData.Data[:4], createSpendingPoolPrefix): + msgType = MsgCreateSpendingPool + case bytes.Equal(ethTxData.Data[:4], depositSpendingPoolPrefix): + msgType = MsgDepositSpendingPool + case bytes.Equal(ethTxData.Data[:4], registerSpendingPoolBeneficiaryPrefix): + msgType = MsgRegisterSpendingPoolBeneficiary + case bytes.Equal(ethTxData.Data[:4], claimSpendingPoolPrefix): + msgType = MsgClaimSpendingPool + case bytes.Equal(ethTxData.Data[:4], upsertStakingPoolPrefix): + msgType = MsgUpsertStakingPool + case bytes.Equal(ethTxData.Data[:4], claimRewardsPrefix): + msgType = MsgClaimRewards + case bytes.Equal(ethTxData.Data[:4], claimUndelegationPrefix): + msgType = MsgClaimUndelegation + case bytes.Equal(ethTxData.Data[:4], setCompoundInfoPrefix): + msgType = MsgSetCompoundInfo + case bytes.Equal(ethTxData.Data[:4], registerDelegatorPrefix): + msgType = MsgRegisterDelegator + case bytes.Equal(ethTxData.Data[:4], createCustodyPrefix): + msgType = MsgCreateCustody + case bytes.Equal(ethTxData.Data[:4], addToCustodyWhiteListPrefix): + msgType = MsgAddToCustodyWhiteList + case bytes.Equal(ethTxData.Data[:4], addToCustodyCustodiansPrefix): + msgType = MsgAddToCustodyCustodians + case bytes.Equal(ethTxData.Data[:4], removeFromCustodyCustodiansPrefix): + msgType = MsgRemoveFromCustodyCustodians + case bytes.Equal(ethTxData.Data[:4], dropCustodyCustodiansPrefix): + msgType = MsgDropCustodyCustodians + case bytes.Equal(ethTxData.Data[:4], removeFromCustodyWhiteListPrefix): + msgType = MsgRemoveFromCustodyWhiteList + case bytes.Equal(ethTxData.Data[:4], dropCustodyWhiteListPrefix): + msgType = MsgDropCustodyWhiteList + case bytes.Equal(ethTxData.Data[:4], approveCustodyTxPrefix): + msgType = MsgApproveCustodyTx + case bytes.Equal(ethTxData.Data[:4], declineCustodyTxPrefix): + msgType = MsgDeclineCustodyTx + default: + return "", errors.New("no such functions") + } + + txBytes, err = legacySignTx(ethTxData, gwCosmosmux, r, msgType) + + if err != nil { + return "", err + } + + // if ethTxData + + txHash, err := sendCosmosTx(r.Context(), txBytes) + if err != nil { + return "", err + } + + return txHash, nil +} + +func legacyGetStructHash(txType int, valParam string) ethcommon.Hash { + abiPack := abi.ABI{} + var structABIPack []byte + + var funcSig []byte + + switch txType { + case MsgSubmitEvidence: + funcSig = crypto.Keccak256([]byte("submitEvidence(string param)")) + case MsgSubmitProposal: + funcSig = crypto.Keccak256([]byte("submitProposal(string param)")) + case MsgVoteProposal: + funcSig = crypto.Keccak256([]byte("voteProposal(string param)")) + case MsgRegisterIdentityRecords: + funcSig = crypto.Keccak256([]byte("registerIdentityRecords(string param)")) + case MsgDeleteIdentityRecords: + funcSig = crypto.Keccak256([]byte("deleteIdentityRecord(string param)")) + case MsgRequestIdentityRecordsVerify: + funcSig = crypto.Keccak256([]byte("requestIdentityRecordsVerify(string param)")) + case MsgHandleIdentityRecordsVerifyRequest: + funcSig = crypto.Keccak256([]byte("handleIdentityRecordsVerifyRequest(string param)")) + case MsgCancelIdentityRecordsVerifyRequest: + funcSig = crypto.Keccak256([]byte("cancelIdentityRecordsVerifyRequest(string param)")) + case MsgSetNetworkProperties: + funcSig = crypto.Keccak256([]byte("setNetworkProperties(string param)")) + case MsgSetExecutionFee: + funcSig = crypto.Keccak256([]byte("setExecutionFee(string param)")) + case MsgClaimCouncilor: + funcSig = crypto.Keccak256([]byte("claimCouncilor(string param)")) + case MsgWhitelistPermissions: + funcSig = crypto.Keccak256([]byte("whitelistPermissions(string param)")) + case MsgBlacklistPermissions: + funcSig = crypto.Keccak256([]byte("blacklistPermissions(string param)")) + case MsgCreateRole: + funcSig = crypto.Keccak256([]byte("createRole(string param)")) + case MsgAssignRole: + funcSig = crypto.Keccak256([]byte("assignRole(string param)")) + case MsgUnassignRole: + funcSig = crypto.Keccak256([]byte("unassignRole(string param)")) + case MsgWhitelistRolePermission: + funcSig = crypto.Keccak256([]byte("whitelistRolePermission(string param)")) + case MsgBlacklistRolePermission: + funcSig = crypto.Keccak256([]byte("blacklistRolePermission(string param)")) + case MsgRemoveWhitelistRolePermission: + funcSig = crypto.Keccak256([]byte("removeWhitelistRolePermission(string param)")) + case MsgRemoveBlacklistRolePermission: + funcSig = crypto.Keccak256([]byte("removeBlacklistRolePermission(string param)")) + case MsgClaimValidator: + // funcSig = crypto.Keccak256([]byte("delegate(string param)")) + case MsgUpsertTokenAlias: + funcSig = crypto.Keccak256([]byte("upsertTokenAlias(string param)")) + case MsgUpsertTokenRate: + funcSig = crypto.Keccak256([]byte("upsertTokenRate(string param)")) + case MsgActivate: + funcSig = crypto.Keccak256([]byte("activate()")) + case MsgPause: + funcSig = crypto.Keccak256([]byte("pause()")) + case MsgUnpause: + funcSig = crypto.Keccak256([]byte("unpause()")) + case MsgCreateSpendingPool: + funcSig = crypto.Keccak256([]byte("createSpendingPool(string param)")) + case MsgDepositSpendingPool: + funcSig = crypto.Keccak256([]byte("depositSpendingPool(string param)")) + case MsgRegisterSpendingPoolBeneficiary: + funcSig = crypto.Keccak256([]byte("registerSpendingPoolBeneficiary(string param)")) + case MsgClaimSpendingPool: + funcSig = crypto.Keccak256([]byte("claimSpendingPool(string param)")) + case MsgUpsertStakingPool: + funcSig = crypto.Keccak256([]byte("upsertStakingPool(string param)")) + case MsgDelegate: + funcSig = crypto.Keccak256([]byte("delegate(string param)")) + case MsgUndelegate: + funcSig = crypto.Keccak256([]byte("undelegate(string param)")) + case MsgClaimRewards: + funcSig = crypto.Keccak256([]byte("claimRewards()")) + case MsgClaimUndelegation: + funcSig = crypto.Keccak256([]byte("claimUndelegation(string param)")) + case MsgSetCompoundInfo: + funcSig = crypto.Keccak256([]byte("setCompoundInfo(string param)")) + case MsgRegisterDelegator: + funcSig = crypto.Keccak256([]byte("registerDelegator()")) + case MsgCreateCustody: + funcSig = crypto.Keccak256([]byte("createCustody(string param)")) + case MsgAddToCustodyWhiteList: + funcSig = crypto.Keccak256([]byte("addToCustodyWhiteList(string param)")) + case MsgAddToCustodyCustodians: + funcSig = crypto.Keccak256([]byte("addToCustodyCustodians(string param)")) + case MsgRemoveFromCustodyCustodians: + funcSig = crypto.Keccak256([]byte("removeFromCustodyCustodians(string param)")) + case MsgDropCustodyCustodians: + funcSig = crypto.Keccak256([]byte("dropCustodyCustodians(string param)")) + case MsgRemoveFromCustodyWhiteList: + funcSig = crypto.Keccak256([]byte("removeFromCustodyWhiteList(string param)")) + case MsgDropCustodyWhiteList: + funcSig = crypto.Keccak256([]byte("dropCustodyWhiteList(string param)")) + case MsgApproveCustodyTx: + funcSig = crypto.Keccak256([]byte("approveCustodyTransaction(string param)")) + case MsgDeclineCustodyTx: + funcSig = crypto.Keccak256([]byte("declineCustodyTransaction(string param)")) + default: + } + + structJsonData := []byte(`[{"Type":"function","Name":"encode","Inputs":[{"Type":"bytes32","Name":"funcsig"},{"Type":"bytes32","Name":"param"}],"Outputs":[]}]`) + _ = abiPack.UnmarshalJSON(structJsonData) + + var funcSignature [32]byte + copy(funcSignature[:], funcSig) + + structABIPack, _ = PackABIParams(abiPack, + "encode", + convertByteArr2Bytes32(funcSig), + convertByteArr2Bytes32(crypto.Keccak256([]byte(valParam))), + ) + + structHash := crypto.Keccak256Hash(structABIPack) + + return structHash +} + +func legacyValidateEIP712Sign(v, r, s []byte, sender ethcommon.Address, valParam string, txType int) bool { + abiPack := abi.ABI{} + + // get EIP712DomainHash + jsonData := []byte(`[{"Type":"function","Name":"encode","Inputs":[{"Type":"bytes32","Name":"funcsig"},{"Type":"bytes32","Name":"name"},{"Type":"bytes32","Name":"version"},{"Type":"bytes32","Name":"chainId"}],"Outputs":[]}]`) + abiPack.UnmarshalJSON(jsonData) + funcSig := crypto.Keccak256([]byte("EIP712Domain(string name,string version,uint256 chainId)")) + + eip712DomainSeparatorABIPack, _ := PackABIParams(abiPack, + "encode", + convertByteArr2Bytes32(funcSig), + convertByteArr2Bytes32(crypto.Keccak256([]byte("Kira"))), + convertByteArr2Bytes32(crypto.Keccak256([]byte("1"))), + convertByteArr2Bytes32(uint32To32Bytes(config.DefaultChainID)), + ) + eip712DomainSeparator := crypto.Keccak256Hash(eip712DomainSeparatorABIPack) + + // get StructHash + structHash := legacyGetStructHash(txType, valParam) + + // Define the final hash + hash := crypto.Keccak256Hash( + append(append([]byte("\x19\x01"), eip712DomainSeparator.Bytes()...), structHash.Bytes()...), + ) + + signature := getSignature(r, s, v) + + // Recover the public key from the signature + pubKey, err := crypto.SigToPub(hash.Bytes(), signature) + // pbBytes, err := crypto.Ecrecover(hash.Bytes(), signature) + // fmt.Println(string(pbBytes), err) + // pubKey, err := crypto.UnmarshalPubkey(pbBytes) + + if err != nil { + fmt.Println("eip712 err", err) + return false + } + + // Derive the signer's address from the public key + signerAddress := crypto.PubkeyToAddress(*pubKey) + + return signerAddress.Hex() == sender.Hex() +} + +func legacySignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, txType int) ([]byte, error) { + // Create a new TxBuilder. + txBuilder := config.EncodingCg.TxConfig.NewTxBuilder() + + addr1, err := hex2bech32(ethTxData.From, TypeKiraAddr) + if err != nil { + return nil, err + } + cosmosAddr1, err := cosmostypes.AccAddressFromBech32(addr1) + if err != nil { + return nil, err + } + + params := [][]byte(nil) + if txType != MsgBankSend { + params, err = DecodeParam(ethTxData.Data[4:], txType) + if err != nil { + return nil, err + } + valParam := string(params[4]) + + validation := legacyValidateEIP712Sign(params[0][len(params[0])-1:], params[1], params[2], ethcommon.BytesToAddress(params[3][12:]), valParam, txType) + if !validation { + return nil, errors.New("eip712 validation is failed") + } + } + + var msg cosmostypes.Msg + + switch txType { + case MsgBankSend: + addr2, err := hex2bech32(ethTxData.To, TypeKiraAddr) + if err != nil { + return nil, err + } + cosmosAddr2, err := cosmostypes.AccAddressFromBech32(addr2) + if err != nil { + return nil, err + } + + balance := ethTxData.Value.Div(ðTxData.Value, big.NewInt(int64(math.Pow10(12)))) + msg = banktypes.NewMsgSend(cosmosAddr1, cosmosAddr2, + cosmostypes.NewCoins(cosmostypes.NewInt64Coin(config.DefaultKiraDenom, balance.Int64()))) + case MsgSubmitEvidence: + // V, R, S, signer, height, power, time, consensusAddr + from, err := bytes2cosmosAddr(params[3][12:]) + if err != nil { + return nil, err + } + + type Equivocation struct { + Height int64 `json:"height"` + Time time.Time `json:"time"` + Power int64 `json:"power"` + ConsensusAddress string `json:"consensus_address"` + } + + var evidenceJsonParam Equivocation + err = json.Unmarshal(params[4], &evidenceJsonParam) + if err != nil { + return nil, err + } + + evidenceParam := evidencetypes.Equivocation{ + Height: evidenceJsonParam.Height, + Time: evidenceJsonParam.Time, + Power: evidenceJsonParam.Power, + ConsensusAddress: evidenceJsonParam.ConsensusAddress, + } + + msg, err = evidencetypes.NewMsgSubmitEvidence(from, &evidenceParam) + if err != nil { + return nil, err + } + case MsgSubmitProposal: + // from, err := bytes2cosmosAddr(params[3][12:]) + // if err != nil { + // return nil, err + // } + + // type SubmitProposalParam struct { + // Title string `json:"title"` + // Description string `json:"description"` + // Content string `json:"content"` + // } + + // var proposalParam SubmitProposalParam + // err = json.Unmarshal(params[4], &proposalParam) + // if err != nil { + // return nil, err + // } + + // msg, err := customgovtypes.NewMsgSubmitProposal(from) + // if err != nil { + // return nil, err + // } + case MsgVoteProposal: + // V, R, S, signer, param + from, err := bytes2cosmosAddr(params[3][12:]) + if err != nil { + return nil, err + } + + type VoteProposalParam struct { + ProposalID uint64 `json:"proposal_id"` + Option uint64 `json:"option"` + Slash string `json:"slash"` + } + + var proposalParam VoteProposalParam + err = json.Unmarshal(params[4], &proposalParam) + if err != nil { + return nil, err + } + + slash, err := sdkmath.LegacyNewDecFromStr(proposalParam.Slash) + if err != nil { + return nil, err + } + + msg = customgovtypes.NewMsgVoteProposal(proposalParam.ProposalID, from, customgovtypes.VoteOption(proposalParam.Option), slash) + case MsgRegisterIdentityRecords: + // V, R, S, signer, identityInfo, + from, err := bytes2cosmosAddr(params[3][12:]) + if err != nil { + return nil, err + } + + type IdentityRecordParam struct { + Infos []customgovtypes.IdentityInfoEntry `json:"identity_infos"` + } + + var recordParam IdentityRecordParam + err = json.Unmarshal(params[4], &recordParam) + if err != nil { + return nil, err + } + + msg = customgovtypes.NewMsgRegisterIdentityRecords(from, recordParam.Infos) + case MsgDeleteIdentityRecords: + // V, R, S, signer, len, keys, + from, err := bytes2cosmosAddr(params[3][12:]) + if err != nil { + return nil, err + } + + type IdentityRecordParam struct { + Keys []string `json:"keys"` + } + + var recordParam IdentityRecordParam + err = json.Unmarshal(params[4], &recordParam) + if err != nil { + return nil, err + } + + msg = customgovtypes.NewMsgDeleteIdentityRecords(from, recordParam.Keys) + case MsgRequestIdentityRecordsVerify: + // V, R, S, signer, tip, verifier, len, recordIds + from, err := bytes2cosmosAddr(params[3][12:]) + if err != nil { + return nil, err + } + + type IdentityRecordParam struct { + Balance string `json:"balance"` + Verifier string `json:"verifier"` + RecordIds []uint64 `json:"record_ids"` + } + + var recordParam IdentityRecordParam + err = json.Unmarshal(params[4], &recordParam) + if err != nil { + return nil, err + } + + balance, err := cosmostypes.ParseCoinNormalized(recordParam.Balance) + if err != nil { + return nil, err + } + + verifier, err := string2cosmosAddr(recordParam.Verifier) + if err != nil { + return nil, err + } + + msg = customgovtypes.NewMsgRequestIdentityRecordsVerify(from, verifier, recordParam.RecordIds, balance) + case MsgHandleIdentityRecordsVerifyRequest: + // V, R, S, signer, requestId, isApprove + verifier, err := bytes2cosmosAddr(params[3][12:]) + if err != nil { + return nil, err + } + + type IdentityRecordParam struct { + RequestID uint64 `json:"request_id"` + IsApproved bool `json:"is_approved"` + } + + var recordParam IdentityRecordParam + err = json.Unmarshal(params[4], &recordParam) + if err != nil { + return nil, err + } + + msg = customgovtypes.NewMsgHandleIdentityRecordsVerifyRequest(verifier, recordParam.RequestID, recordParam.IsApproved) + case MsgCancelIdentityRecordsVerifyRequest: + // V, R, S, signer, verifyRequestId + executor, err := bytes2cosmosAddr(params[3][12:]) + if err != nil { + return nil, err + } + + type IdentityRecordParam struct { + VerifyRequestId uint64 `json:"verify_request_id"` + } + + var recordParam IdentityRecordParam + err = json.Unmarshal(params[4], &recordParam) + if err != nil { + return nil, err + } + + msg = customgovtypes.NewMsgCancelIdentityRecordsVerifyRequest(executor, recordParam.VerifyRequestId) + case MsgSetNetworkProperties: + // V, R, S, signer, networkProperties + proposer, err := bytes2cosmosAddr(params[3][12:]) + if err != nil { + return nil, err + } + + type NetworkProperties struct { + MinTxFee uint64 `json:"min_tx_fee"` + MaxTxFee uint64 `json:"max_tx_fee"` + VoteQuorum uint64 `json:"vote_quorum"` + MinimumProposalEndTime uint64 `json:"minimum_proposal_end_time"` + ProposalEnactmentTime uint64 `json:"proposal_enactment_time"` + MinProposalEndBlocks uint64 `json:"min_proposal_end_blocks"` + MinProposalEnactmentBlocks uint64 `json:"min_proposal_enactment_blocks"` + EnableForeignFeePayments bool `json:"enable_foreign_fee_payments"` + MischanceRankDecreaseAmount uint64 `json:"mischance_rank_decrease_amount"` + MaxMischance uint64 `json:"max_mischance"` + MischanceConfidence uint64 `json:"mischance_confidence"` + InactiveRankDecreasePercent string `json:"inactive_rank_decrease_percent"` + MinValidators uint64 `json:"min_validators"` + PoorNetworkMaxBankSend uint64 `json:"poor_network_max_bank_send"` + UnjailMaxTime uint64 `json:"unjail_max_time"` + EnableTokenWhitelist bool `json:"enable_token_whitelist"` + EnableTokenBlacklist bool `json:"enable_token_blacklist"` + MinIdentityApprovalTip uint64 `json:"min_identity_approval_tip"` + UniqueIdentityKeys string `json:"unique_identity_keys"` + UbiHardcap uint64 `json:"ubi_hardcap"` + ValidatorsFeeShare string `json:"validators_fee_share"` + InflationRate string `json:"inflation_rate"` + InflationPeriod uint64 `json:"inflation_period"` + UnstakingPeriod uint64 `json:"unstaking_period"` + MaxDelegators uint64 `json:"max_delegators"` + MinDelegationPushout uint64 `json:"min_delegation_pushout"` + SlashingPeriod uint64 `json:"slashing_period"` + MaxJailedPercentage string `json:"max_jailed_percentage"` + MaxSlashingPercentage string `json:"max_slashing_percentage"` + MinCustodyReward uint64 `json:"min_custody_reward"` + MaxCustodyBufferSize uint64 `json:"max_custody_buffer_size"` + MaxCustodyTxSize uint64 `json:"max_custody_tx_size"` + AbstentionRankDecreaseAmount uint64 `json:"abstention_rank_decrease_amount"` + MaxAbstention uint64 `json:"max_abstention"` + MinCollectiveBond uint64 `json:"min_collective_bond"` + MinCollectiveBondingTime uint64 `json:"min_collective_bonding_time"` + MaxCollectiveOutputs uint64 `json:"max_collective_outputs"` + MinCollectiveClaimPeriod uint64 `json:"min_collective_claim_period"` + ValidatorRecoveryBond uint64 `json:"validator_recovery_bond"` + MaxAnnualInflation string `json:"max_annual_inflation"` + MaxProposalTitleSize uint64 `json:"max_proposal_title_size"` + MaxProposalDescriptionSize uint64 `json:"max_proposal_description_size"` + MaxProposalPollOptionSize uint64 `json:"max_proposal_poll_option_size"` + MaxProposalPollOptionCount uint64 `json:"max_proposal_poll_option_count"` + MaxProposalReferenceSize uint64 `json:"max_proposal_reference_size"` + MaxProposalChecksumSize uint64 `json:"max_proposal_checksum_size"` + MinDappBond uint64 `json:"min_dapp_bond"` + MaxDappBond uint64 `json:"max_dapp_bond"` + DappLiquidationThreshold uint64 `json:"dapp_liquidation_threshold"` + DappLiquidationPeriod uint64 `json:"dapp_liquidation_period"` + DappBondDuration uint64 `json:"dapp_bond_duration"` + DappVerifierBond string `json:"dapp_verifier_bond"` + DappAutoDenounceTime uint64 `json:"dapp_auto_denounce_time"` + DappMischanceRankDecreaseAmount uint64 `json:"dapp_mischance_rank_decrease_amount"` + DappMaxMischance uint64 `json:"dapp_max_mischance"` + DappInactiveRankDecreasePercent uint64 `json:"dapp_inactive_rank_decrease_percent"` + DappPoolSlippageDefault string `json:"dapp_pool_slippage_default"` + MintingFtFee uint64 `json:"minting_ft_fee"` + MintingNftFee uint64 `json:"minting_nft_fee"` + VetoThreshold string `json:"veto_threshold"` + } + + var networkProperties NetworkProperties + err = json.Unmarshal(params[4], &networkProperties) + if err != nil { + return nil, err + } + + inActiveRankDecreasePercent, err := cosmostypes.NewDecFromStr(networkProperties.InactiveRankDecreasePercent) + if err != nil { + return nil, err + } + validatorsFeeShare, err := cosmostypes.NewDecFromStr(networkProperties.ValidatorsFeeShare) + if err != nil { + return nil, err + } + inflationRate, err := cosmostypes.NewDecFromStr(networkProperties.InflationRate) + if err != nil { + return nil, err + } + maxJailedPercentage, err := cosmostypes.NewDecFromStr(networkProperties.MaxJailedPercentage) + if err != nil { + return nil, err + } + maxSlashingPercentage, err := cosmostypes.NewDecFromStr(networkProperties.MaxSlashingPercentage) + if err != nil { + return nil, err + } + maxAnnualInflation, err := cosmostypes.NewDecFromStr(networkProperties.MaxAnnualInflation) + if err != nil { + return nil, err + } + dappVerifierBond, err := cosmostypes.NewDecFromStr(networkProperties.DappVerifierBond) + if err != nil { + return nil, err + } + dappPoolSlippageDefault, err := cosmostypes.NewDecFromStr(networkProperties.DappPoolSlippageDefault) + if err != nil { + return nil, err + } + vetoThreshold, err := cosmostypes.NewDecFromStr(networkProperties.VetoThreshold) + if err != nil { + return nil, err + } + + networkPropertiesParam := customgovtypes.NetworkProperties{ + MinTxFee: networkProperties.MinTxFee, + MaxTxFee: networkProperties.MaxTxFee, + VoteQuorum: networkProperties.VoteQuorum, + MinimumProposalEndTime: networkProperties.MinimumProposalEndTime, + ProposalEnactmentTime: networkProperties.ProposalEnactmentTime, + MinProposalEndBlocks: networkProperties.MinProposalEndBlocks, + MinProposalEnactmentBlocks: networkProperties.MinProposalEnactmentBlocks, + EnableForeignFeePayments: networkProperties.EnableForeignFeePayments, + MischanceRankDecreaseAmount: networkProperties.MischanceRankDecreaseAmount, + MaxMischance: networkProperties.MaxMischance, + MischanceConfidence: networkProperties.MischanceConfidence, + InactiveRankDecreasePercent: inActiveRankDecreasePercent, + MinValidators: networkProperties.MinValidators, + PoorNetworkMaxBankSend: networkProperties.PoorNetworkMaxBankSend, + UnjailMaxTime: networkProperties.UnjailMaxTime, + EnableTokenWhitelist: networkProperties.EnableTokenWhitelist, + EnableTokenBlacklist: networkProperties.EnableTokenBlacklist, + MinIdentityApprovalTip: networkProperties.MinIdentityApprovalTip, + UniqueIdentityKeys: networkProperties.UniqueIdentityKeys, + UbiHardcap: networkProperties.UbiHardcap, + ValidatorsFeeShare: validatorsFeeShare, + InflationRate: inflationRate, + InflationPeriod: networkProperties.InflationPeriod, + UnstakingPeriod: networkProperties.UnstakingPeriod, + MaxDelegators: networkProperties.MaxDelegators, + MinDelegationPushout: networkProperties.MinDelegationPushout, + SlashingPeriod: networkProperties.SlashingPeriod, + MaxJailedPercentage: maxJailedPercentage, + MaxSlashingPercentage: maxSlashingPercentage, + MinCustodyReward: networkProperties.MinCustodyReward, + MaxCustodyBufferSize: networkProperties.MaxCustodyBufferSize, + MaxCustodyTxSize: networkProperties.MaxCustodyTxSize, + AbstentionRankDecreaseAmount: networkProperties.AbstentionRankDecreaseAmount, + MaxAbstention: networkProperties.MaxAbstention, + MinCollectiveBond: networkProperties.MinCollectiveBond, + MinCollectiveBondingTime: networkProperties.MinCollectiveBondingTime, + MaxCollectiveOutputs: networkProperties.MaxCollectiveOutputs, + MinCollectiveClaimPeriod: networkProperties.MinCollectiveClaimPeriod, + ValidatorRecoveryBond: networkProperties.ValidatorRecoveryBond, + MaxAnnualInflation: maxAnnualInflation, + MaxProposalTitleSize: networkProperties.MaxProposalTitleSize, + MaxProposalDescriptionSize: networkProperties.MaxProposalDescriptionSize, + MaxProposalPollOptionSize: networkProperties.MaxProposalPollOptionSize, + MaxProposalPollOptionCount: networkProperties.MaxProposalPollOptionCount, + MaxProposalReferenceSize: networkProperties.MaxProposalReferenceSize, + MaxProposalChecksumSize: networkProperties.MaxProposalChecksumSize, + MinDappBond: networkProperties.MinDappBond, + MaxDappBond: networkProperties.MaxDappBond, + DappLiquidationThreshold: networkProperties.DappLiquidationThreshold, + DappLiquidationPeriod: networkProperties.DappLiquidationPeriod, + DappBondDuration: networkProperties.DappBondDuration, + DappVerifierBond: dappVerifierBond, + DappAutoDenounceTime: networkProperties.DappAutoDenounceTime, + DappMischanceRankDecreaseAmount: networkProperties.DappMischanceRankDecreaseAmount, + DappMaxMischance: networkProperties.DappMaxMischance, + DappInactiveRankDecreasePercent: networkProperties.DappInactiveRankDecreasePercent, + DappPoolSlippageDefault: dappPoolSlippageDefault, + MintingFtFee: networkProperties.MintingFtFee, + MintingNftFee: networkProperties.MintingNftFee, + VetoThreshold: vetoThreshold, + } + + msg = customgovtypes.NewMsgSetNetworkProperties(proposer, &networkPropertiesParam) + case MsgSetExecutionFee: + // V, R, S, signer, executionFee, failureFee, timeout, defaultParams + proposer, err := bytes2cosmosAddr(params[3][12:]) + if err != nil { + return nil, err + } + + type ExecutionFeeParam struct { + TransactionType string `json:"transaction_type"` + ExecutionFee uint64 `json:"execution_fee"` + FailureFee uint64 `json:"failure_fee"` + Timeout uint64 `json:"timeout"` + DefaultParams uint64 `json:"default_params"` + } + + var feeParam ExecutionFeeParam + err = json.Unmarshal(params[4], &feeParam) + if err != nil { + return nil, err + } + + msg = customgovtypes.NewMsgSetExecutionFee(feeParam.TransactionType, feeParam.ExecutionFee, feeParam.FailureFee, + feeParam.Timeout, feeParam.DefaultParams, proposer) + case MsgClaimCouncilor: + // V, R, S, signer, moniker string, username string, description string, social string, contact string, avatar string + sender, err := bytes2cosmosAddr(params[3][12:]) + if err != nil { + return nil, err + } + + type ClaimCouncilorParam struct { + Moniker string `json:"moniker"` + Username string `json:"username"` + Description string `json:"description"` + Social string `json:"social"` + Contact string `json:"contact"` + Avatar string `json:"avatar"` + } + + var councilorParam ClaimCouncilorParam + err = json.Unmarshal(params[4], &councilorParam) + if err != nil { + return nil, err + } + + msg = customgovtypes.NewMsgClaimCouncilor(sender, councilorParam.Moniker, councilorParam.Username, councilorParam.Description, + councilorParam.Social, councilorParam.Contact, councilorParam.Avatar) + case MsgWhitelistPermissions: + // V, R, S, signer, permission uint256, controlledAddr string + sender, err := bytes2cosmosAddr(params[3][12:]) + if err != nil { + return nil, err + } + + var permissionParam PermissionsParam + err = json.Unmarshal(params[4], &permissionParam) + if err != nil { + return nil, err + } + + controlledAddr, err := string2cosmosAddr(permissionParam.ControlledAddr) + if err != nil { + return nil, err + } + + msg = customgovtypes.NewMsgWhitelistPermissions(sender, controlledAddr, permissionParam.Permission) + case MsgBlacklistPermissions: + // V, R, S, signer, permission uint256, controlledAddr string + sender, err := bytes2cosmosAddr(params[3][12:]) + if err != nil { + return nil, err + } + + var permissionParam PermissionsParam + err = json.Unmarshal(params[4], &permissionParam) + if err != nil { + return nil, err + } + + controlledAddr, err := string2cosmosAddr(permissionParam.ControlledAddr) + if err != nil { + return nil, err + } + + msg = customgovtypes.NewMsgBlacklistPermissions(sender, controlledAddr, permissionParam.Permission) + case MsgCreateRole: + // V, R, S, signer, sid string, description string + sender, err := bytes2cosmosAddr(params[3][12:]) + if err != nil { + return nil, err + } + + type RoleParam struct { + Sid string `json:"sid"` + Description string `json:"description"` + } + + var roleParam RoleParam + err = json.Unmarshal(params[4], &roleParam) + if err != nil { + return nil, err + } + + msg = customgovtypes.NewMsgCreateRole(sender, roleParam.Sid, roleParam.Description) + case MsgAssignRole: + // V, R, S, signer, roleid uint32, controller string + sender, err := bytes2cosmosAddr(params[3][12:]) + if err != nil { + return nil, err + } + + var roleParam RoleParam + err = json.Unmarshal(params[4], &roleParam) + if err != nil { + return nil, err + } + + controller, err := string2cosmosAddr(roleParam.Controller) + if err != nil { + return nil, err + } + + msg = customgovtypes.NewMsgAssignRole(sender, controller, roleParam.RoleId) + case MsgUnassignRole: + // V, R, S, signer, roleid uint32, controller address + sender, err := bytes2cosmosAddr(params[3][12:]) + if err != nil { + return nil, err + } + + var roleParam RoleParam + err = json.Unmarshal(params[4], &roleParam) + if err != nil { + return nil, err + } + + controller, err := string2cosmosAddr(roleParam.Controller) + if err != nil { + return nil, err + } + + msg = customgovtypes.NewMsgUnassignRole(sender, controller, roleParam.RoleId) + case MsgWhitelistRolePermission: + // V, R, S, signer, permission uint32, roleIdentifier string + sender, err := bytes2cosmosAddr(params[3][12:]) + if err != nil { + return nil, err + } + + var roleParam ListRoleParam + err = json.Unmarshal(params[4], &roleParam) + if err != nil { + return nil, err + } + + msg = customgovtypes.NewMsgWhitelistRolePermission(sender, roleParam.RoleIdentifier, roleParam.Permission) + case MsgBlacklistRolePermission: + // V, R, S, signer, permission uint32, roleIdentifier string + sender, err := bytes2cosmosAddr(params[3][12:]) + if err != nil { + return nil, err + } + + var roleParam ListRoleParam + err = json.Unmarshal(params[4], &roleParam) + if err != nil { + return nil, err + } + + msg = customgovtypes.NewMsgBlacklistRolePermission(sender, roleParam.RoleIdentifier, roleParam.Permission) + case MsgRemoveWhitelistRolePermission: + // V, R, S, signer, permission uint32, roleIdentifier string + sender, err := bytes2cosmosAddr(params[3][12:]) + if err != nil { + return nil, err + } + + var roleParam ListRoleParam + err = json.Unmarshal(params[4], &roleParam) + if err != nil { + return nil, err + } + + msg = customgovtypes.NewMsgRemoveWhitelistRolePermission(sender, roleParam.RoleIdentifier, roleParam.Permission) + case MsgRemoveBlacklistRolePermission: + // V, R, S, signer, permission uint32, roleIdentifier string + sender, err := bytes2cosmosAddr(params[3][12:]) + if err != nil { + return nil, err + } + + var roleParam ListRoleParam + err = json.Unmarshal(params[4], &roleParam) + if err != nil { + return nil, err + } + + msg = customgovtypes.NewMsgRemoveBlacklistRolePermission(sender, roleParam.RoleIdentifier, roleParam.Permission) + case MsgClaimValidator: + // V, R, S, signer, moniker string, valKey cosmostypes.ValAddress, pubKey cryptotypes.PubKey + + // type ClaimParam struct { + // Moniker string `json:"moniker"` + // ValKey string `json:"val_key"` + // PubKey string `json:"pub_key"` + // } + + // var claimParam ClaimParam + // err = json.Unmarshal(params[4], &claimParam) + // if err != nil { + // return nil, err + // } + + // valKey, err := cosmostypes.ValAddressFromBech32(claimParam.ValKey) + // if err != nil { + // return nil, err + // } + + // // how to get pub key from string? + // cryptotypes + + // msg, err = stakingtypes.NewMsgClaimValidator(claimParam.Moniker, valKey, claimParam.PubKey) + // if err != nil { + // return nil, err + // } + case MsgUpsertTokenAlias: + // V, R, S, signer, param + proposer, err := bytes2cosmosAddr(params[3][12:]) + if err != nil { + return nil, err + } + + type UpsertTokenAliasParam struct { + Symbol string `json:"symbol"` + Name string `json:"name"` + Icon string `json:"icon"` + Decimals uint32 `json:"decimals"` + Denoms []string `json:"denoms"` + Invalidated bool `json:"invalidated"` + } + + var upsertTokenAliasParam UpsertTokenAliasParam + err = json.Unmarshal(params[4], &upsertTokenAliasParam) + if err != nil { + return nil, err + } + + msg = tokenstypes.NewMsgUpsertTokenAlias(proposer, upsertTokenAliasParam.Symbol, upsertTokenAliasParam.Name, + upsertTokenAliasParam.Icon, upsertTokenAliasParam.Decimals, upsertTokenAliasParam.Denoms, upsertTokenAliasParam.Invalidated) + case MsgUpsertTokenRate: + // V, R, S, signer, feePayments bool, stakeToken bool, invalidated bool, denom string, rate cosmostypes.Dec, + // stakeCap cosmostypes.Dec, stakeMin cosmostypes.Int + proposer, err := bytes2cosmosAddr(params[3][12:]) + if err != nil { + return nil, err + } + + type UpsertTokenRateParam struct { + Denom string `json:"denom"` + Rate string `json:"rate"` + IsFeePayments bool `json:"is_fee_payments"` + StakeCap string `json:"stake_cap"` + StakeMin string `json:"stake_min"` + IsStakeToken bool `json:"is_stake_token"` + Invalidated bool `json:"invalidated"` + } + + var upsertParam UpsertTokenRateParam + err = json.Unmarshal(params[4], &upsertParam) + if err != nil { + return nil, err + } + + rate, err := cosmostypes.NewDecFromStr(upsertParam.Rate) + if err != nil { + return nil, err + } + stakeCap, err := cosmostypes.NewDecFromStr(upsertParam.StakeCap) + if err != nil { + return nil, err + } + stakeMin, ok := cosmostypes.NewIntFromString(upsertParam.StakeMin) + if !ok { + return nil, errors.New(fmt.Sprintln("StakeMin - decoding from string to Int type is failed:", upsertParam.StakeMin)) + } + + msg = tokenstypes.NewMsgUpsertTokenRate(proposer, upsertParam.Denom, rate, upsertParam.IsFeePayments, + stakeCap, stakeMin, upsertParam.IsStakeToken, upsertParam.Invalidated) + case MsgActivate: + // V, R, S, signer + validator, err := bytes2cosmosValAddr(params[3][12:]) + if err != nil { + return nil, err + } + msg = slashingtypes.NewMsgActivate(validator) + case MsgPause: + // V, R, S, signer + validator, err := bytes2cosmosValAddr(params[3][12:]) + if err != nil { + return nil, err + } + msg = slashingtypes.NewMsgPause(validator) + case MsgUnpause: + // V, R, S, signer + validator, err := bytes2cosmosValAddr(params[3][12:]) + if err != nil { + return nil, err + } + msg = slashingtypes.NewMsgUnpause(validator) + case MsgCreateSpendingPool: + // V, R, S, signer, name string, claimStart uint64, claimEnd uint64, rates cosmostypes.DecCoins, voteQuorum uint64, + // votePeriod uint64, voteEnactment uint64, owners spendingtypes.PermInfo, beneficiaries spendingtypes.WeightedPermInfo, + // sender cosmostypes.AccAddress, dynamicRate bool, dynamicRatePeriod uint64 + sender, err := bytes2cosmosAddr(params[3][12:]) + if err != nil { + return nil, err + } + + type WeightedRole struct { + Role uint64 `json:"role"` + Weight string `json:"weight"` + } + + type WeightedAccount struct { + Account string `json:"account"` + Weight string `json:"weight"` + } + + type WeightedPermInfo struct { + Roles []WeightedRole `json:"roles"` + Accounts []WeightedAccount `json:"accounts"` + } + + type SpendingPoolParam struct { + Name string `json:"name"` + ClaimStart uint64 `json:"claim_start"` + ClaimEnd uint64 `json:"claim_end"` + Rates []string `json:"rates"` + VoteQuorum uint64 `json:"vote_quorum"` + VotePeriod uint64 `json:"vote_period"` + VoteEnactment uint64 `json:"vote_enactment"` + Owners spendingtypes.PermInfo `json:"owners"` + Beneficiaries WeightedPermInfo `json:"beneficiaries"` + IsDynamicRate bool `json:"is_dynamic_rate"` + DynamicRatePeriod uint64 `json:"dynamic_rate_period"` + } + + var poolParam SpendingPoolParam + err = json.Unmarshal(params[4], &poolParam) + if err != nil { + return nil, err + } + + var rates cosmostypes.DecCoins + for _, rate := range poolParam.Rates { + coin, err := cosmostypes.ParseDecCoin(rate) + if err != nil { + return nil, err + } + rates.Add(coin) + } + + var beneficiaries spendingtypes.WeightedPermInfo + for _, account := range poolParam.Beneficiaries.Accounts { + weight, err := cosmostypes.NewDecFromStr(account.Weight) + if err != nil { + return nil, err + } + weightedAccount := spendingtypes.WeightedAccount{ + Account: account.Account, + Weight: weight, + } + beneficiaries.Accounts = append(beneficiaries.Accounts, weightedAccount) + } + for _, role := range poolParam.Beneficiaries.Roles { + weight, err := cosmostypes.NewDecFromStr(role.Weight) + if err != nil { + return nil, err + } + weightedRole := spendingtypes.WeightedRole{ + Role: role.Role, + Weight: weight, + } + beneficiaries.Roles = append(beneficiaries.Roles, weightedRole) + } + + msg = spendingtypes.NewMsgCreateSpendingPool(poolParam.Name, poolParam.ClaimStart, poolParam.ClaimEnd, rates, + poolParam.VoteQuorum, poolParam.VotePeriod, poolParam.VoteEnactment, poolParam.Owners, beneficiaries, + sender, poolParam.IsDynamicRate, poolParam.DynamicRatePeriod) + case MsgDepositSpendingPool: + // V, R, S, signer, amount string, name string + sender, err := bytes2cosmosAddr(params[3][12:]) + if err != nil { + return nil, err + } + + var poolParam SpendingPoolParam + err = json.Unmarshal(params[4], &poolParam) + if err != nil { + return nil, err + } + + amounts, err := cosmostypes.ParseCoinsNormalized(poolParam.Amounts) + if err != nil { + return nil, err + } + + msg = spendingtypes.NewMsgDepositSpendingPool(poolParam.Name, amounts, sender) + case MsgRegisterSpendingPoolBeneficiary: + // V, R, S, signer, name string + sender, err := bytes2cosmosAddr(params[3][12:]) + if err != nil { + return nil, err + } + + var poolParam SpendingPoolParam + err = json.Unmarshal(params[4], &poolParam) + if err != nil { + return nil, err + } + + msg = spendingtypes.NewMsgRegisterSpendingPoolBeneficiary(poolParam.Name, sender) + case MsgClaimSpendingPool: + // V, R, S, signer, name string + sender, err := bytes2cosmosAddr(params[3][12:]) + if err != nil { + return nil, err + } + + var poolParam SpendingPoolParam + err = json.Unmarshal(params[4], &poolParam) + if err != nil { + return nil, err + } + + msg = spendingtypes.NewMsgClaimSpendingPool(poolParam.Name, sender) + case MsgUpsertStakingPool: + // V, R, S, signer, enabled bool, validator string, commission cosmostypes.Dec + from, err := hex2bech32(hex.EncodeToString(params[3][12:]), TypeKiraAddr) + if err != nil { + return nil, err + } + + type StakingPoolParam struct { + Validator string `json:"validator"` + Enabled bool `json:"enabled"` + Commission string `json:"commission"` + } + + var poolParam StakingPoolParam + err = json.Unmarshal(params[4], &poolParam) + if err != nil { + return nil, err + } + + commission, err := cosmostypes.NewDecFromStr(poolParam.Commission) + if err != nil { + return nil, err + } + + msg = multistakingtypes.NewMsgUpsertStakingPool(from, poolParam.Validator, poolParam.Enabled, commission) + case MsgDelegate: + // V, R, S, signer, param + from, err := hex2bech32(hex.EncodeToString(params[3][12:]), TypeKiraAddr) + if err != nil { + return nil, err + } + + var delegateParam DelegateParam + err = json.Unmarshal(params[4], &delegateParam) + if err != nil { + return nil, err + } + + amounts, err := cosmostypes.ParseCoinsNormalized(delegateParam.Amounts) + if err != nil { + return nil, err + } + + msg = multistakingtypes.NewMsgDelegate(from, delegateParam.To, amounts) + case MsgUndelegate: + // V, R, S, signer, amount, validator + from, err := hex2bech32(hex.EncodeToString(params[3][12:]), TypeKiraAddr) + if err != nil { + return nil, err + } + + var delegateParam DelegateParam + err = json.Unmarshal(params[4], &delegateParam) + if err != nil { + return nil, err + } + + amounts, err := cosmostypes.ParseCoinsNormalized(delegateParam.Amounts) + if err != nil { + return nil, err + } + + msg = multistakingtypes.NewMsgUndelegate(from, delegateParam.To, amounts) + case MsgClaimRewards: + // V, R, S, signer + from, err := hex2bech32(hex.EncodeToString(params[3][12:]), TypeKiraAddr) + if err != nil { + return nil, err + } + msg = multistakingtypes.NewMsgClaimRewards(from) + case MsgClaimUndelegation: + // V, R, S, signer, undelegationId uint64 + from, err := hex2bech32(hex.EncodeToString(params[3][12:]), TypeKiraAddr) + if err != nil { + return nil, err + } + + type UndelegationParam struct { + UndelegationId uint64 `json:"undelegation_id"` + } + + var undelegationParam UndelegationParam + err = json.Unmarshal(params[4], &undelegationParam) + if err != nil { + return nil, err + } + + msg = multistakingtypes.NewMsgClaimUndelegation(from, undelegationParam.UndelegationId) + case MsgSetCompoundInfo: + // V, R, S, signer, allDenom bool, len, denoms []string + from, err := hex2bech32(hex.EncodeToString(params[3][12:]), TypeKiraAddr) + if err != nil { + return nil, err + } + + type UndelegationParam struct { + IsAllDenom bool `json:"is_all_denom"` + Denoms []string `json:"denoms"` + } + + var undelegationParam UndelegationParam + err = json.Unmarshal(params[4], &undelegationParam) + if err != nil { + return nil, err + } + + msg = multistakingtypes.NewMsgSetCompoundInfo(from, undelegationParam.IsAllDenom, undelegationParam.Denoms) + case MsgRegisterDelegator: + // V, R, S, signer + from, err := hex2bech32(hex.EncodeToString(params[3][12:]), TypeKiraAddr) + if err != nil { + return nil, err + } + + msg = multistakingtypes.NewMsgRegisterDelegator(from) + case MsgCreateCustody: + // V, R, S, signer, custodyMode uint256, key string, nextController string, len, boolArr, len, strArr + from, err := bytes2cosmosAddr(params[3][12:]) + if err != nil { + return nil, err + } + + type CustodyParam struct { + CustodySettings custodytypes.CustodySettings `json:"custody_settings"` + OldKey string `json:"old_key"` + NewKey string `json:"new_key"` + Next string `json:"next"` + Target string `json:"target"` + } + + var custodyParam CustodyParam + err = json.Unmarshal(params[4], &custodyParam) + if err != nil { + return nil, err + } + + msg = custodytypes.NewMsgCreateCustody(from, custodyParam.CustodySettings, custodyParam.OldKey, custodyParam.NewKey, + custodyParam.Next, custodyParam.Target) + case MsgAddToCustodyWhiteList: + // V, R, S, signer, oldKey string, newKey string, next string, target string + // len, newAddr []string, + from, err := bytes2cosmosAddr(params[3][12:]) + if err != nil { + return nil, err + } + + var custodyParam CustodianParam + err = json.Unmarshal(params[4], &custodyParam) + if err != nil { + return nil, err + } + + var newAddrs []cosmostypes.AccAddress + for _, addrStr := range custodyParam.NewAddrs { + addr, err := cosmostypes.AccAddressFromBech32(addrStr) + if err != nil { + return nil, err + } + newAddrs = append(newAddrs, addr) + } + + msg = custodytypes.NewMsgAddToCustodyWhiteList(from, newAddrs, custodyParam.OldKey, custodyParam.NewKey, + custodyParam.Next, custodyParam.Target) + case MsgAddToCustodyCustodians: + // V, R, S, signer, oldKey string, newKey string, next string, target string + // len, newAddr []string + from, err := bytes2cosmosAddr(params[3][12:]) + if err != nil { + return nil, err + } + + var custodyParam CustodianParam + err = json.Unmarshal(params[4], &custodyParam) + if err != nil { + return nil, err + } + + var newAddrs []cosmostypes.AccAddress + for _, addrStr := range custodyParam.NewAddrs { + addr, err := cosmostypes.AccAddressFromBech32(addrStr) + if err != nil { + return nil, err + } + newAddrs = append(newAddrs, addr) + } + + msg = custodytypes.NewMsgAddToCustodyCustodians(from, newAddrs, custodyParam.OldKey, custodyParam.NewKey, + custodyParam.Next, custodyParam.Target) + case MsgRemoveFromCustodyCustodians: + // V, R, S, signer, newAddr cosmostypes.AccAddress, + // oldKey string, newKey string, next string, target string + from, err := bytes2cosmosAddr(params[3][12:]) + if err != nil { + return nil, err + } + + var custodyParam SingleCustodianParam + err = json.Unmarshal(params[4], &custodyParam) + if err != nil { + return nil, err + } + + newAddr, err := cosmostypes.AccAddressFromBech32(custodyParam.NewAddr) + if err != nil { + return nil, err + } + + msg = custodytypes.NewMsgRemoveFromCustodyCustodians(from, newAddr, custodyParam.OldKey, custodyParam.NewKey, + custodyParam.Next, custodyParam.Target) + case MsgDropCustodyCustodians: + // V, R, S, signer + // oldKey string, newKey string, next string, target string + from, err := bytes2cosmosAddr(params[3][12:]) + if err != nil { + return nil, err + } + + var custodyParam CustodianParam + err = json.Unmarshal(params[4], &custodyParam) + if err != nil { + return nil, err + } + + msg = custodytypes.NewMsgDropCustodyCustodians(from, custodyParam.OldKey, custodyParam.NewKey, + custodyParam.Next, custodyParam.Target) + case MsgRemoveFromCustodyWhiteList: + // V, R, S, signer, newAddr string, + // oldKey string, newKey string, next string, target string + from, err := bytes2cosmosAddr(params[3][12:]) + if err != nil { + return nil, err + } + + var custodyParam SingleCustodianParam + err = json.Unmarshal(params[4], &custodyParam) + if err != nil { + return nil, err + } + + newAddr, err := cosmostypes.AccAddressFromBech32(custodyParam.NewAddr) + if err != nil { + return nil, err + } + + msg = custodytypes.NewMsgRemoveFromCustodyWhiteList(from, newAddr, custodyParam.OldKey, custodyParam.NewKey, + custodyParam.Next, custodyParam.Target) + case MsgDropCustodyWhiteList: + // V, R, S, signer + // oldKey string, newKey string, next string, target string + from, err := bytes2cosmosAddr(params[3][12:]) + if err != nil { + return nil, err + } + + var custodyParam CustodianParam + err = json.Unmarshal(params[4], &custodyParam) + if err != nil { + return nil, err + } + + msg = custodytypes.NewMsgDropCustodyWhiteList(from, custodyParam.OldKey, custodyParam.NewKey, + custodyParam.Next, custodyParam.Target) + case MsgApproveCustodyTx: + // V, R, S, signer, to string, hash string + from, err := bytes2cosmosAddr(params[3][12:]) + if err != nil { + return nil, err + } + + var custodyParam CustodyParam + err = json.Unmarshal(params[4], &custodyParam) + if err != nil { + return nil, err + } + + to, err := cosmostypes.AccAddressFromBech32(custodyParam.To) + if err != nil { + return nil, err + } + + msg = custodytypes.NewMsgApproveCustodyTransaction(from, to, custodyParam.Hash) + case MsgDeclineCustodyTx: + // V, R, S, signer, to string, hash string + from, err := bytes2cosmosAddr(params[3][12:]) + if err != nil { + return nil, err + } + + var custodyParam CustodyParam + err = json.Unmarshal(params[4], &custodyParam) + if err != nil { + return nil, err + } + + to, err := cosmostypes.AccAddressFromBech32(custodyParam.To) + if err != nil { + return nil, err + } + + msg = custodytypes.NewMsgDeclineCustodyTransaction(from, to, custodyParam.Hash) + } + + // fmt.Println(msg) + err = txBuilder.SetMsgs(msg) + if err != nil { + return nil, err + } + txBuilder.SetGasLimit(ethTxData.GasLimit) + // TODO: set fee amount - how can I get the fee amount from eth tx? or fix this? + txBuilder.SetFeeAmount(cosmostypes.NewCoins(cosmostypes.NewInt64Coin(config.DefaultKiraDenom, 200))) + // txBuilder.SetMemo() + // txBuilder.SetTimeoutHeight() + // txHash, err := sendTx(context.Background(), byteData) + + accNum, _ := common.GetAccountNumberSequence(gwCosmosmux, r, addr1) + + privs := []cryptotypes.PrivKey{config.Config.PrivKey} + accNums := []uint64{accNum} // The accounts' account numbers + accSeqs := []uint64{ethTxData.Nonce} // The accounts' sequence numbers + + // First round: gather all the signer infos + var sigsV2 []signing.SignatureV2 + for i, priv := range privs { + sigV2 := signing.SignatureV2{ + PubKey: priv.PubKey(), + Data: &signing.SingleSignatureData{ + SignMode: config.EncodingCg.TxConfig.SignModeHandler().DefaultMode(), + Signature: nil, + }, + Sequence: accSeqs[i], + } + + sigsV2 = append(sigsV2, sigV2) + } + + err = txBuilder.SetSignatures(sigsV2...) + if err != nil { + return nil, err + } + + interxStatus := common.GetInterxStatus("http://127.0.0.1:11000") + + // Second round: all signer infos are set, so each signer can sign. + sigsV2 = []signing.SignatureV2{} + for i, priv := range privs { + signerData := xauthsigning.SignerData{ + ChainID: interxStatus.InterxInfo.ChainID, + AccountNumber: accNums[i], + Sequence: accSeqs[i], + } + sigV2, err := clienttx.SignWithPrivKey( + config.EncodingCg.TxConfig.SignModeHandler().DefaultMode(), signerData, + txBuilder, priv, config.EncodingCg.TxConfig, accSeqs[i]) + if err != nil { + return nil, err + } + + sigsV2 = append(sigsV2, sigV2) + } + err = txBuilder.SetSignatures(sigsV2...) + if err != nil { + return nil, err + } + + txBytes, err := config.EncodingCg.TxConfig.TxEncoder()(txBuilder.GetTx()) + if err != nil { + return nil, err + } + + return txBytes, err +} diff --git a/gateway/kira/metamask/utils.go b/gateway/kira/metamask/utils.go index 228e1f6..abffbb3 100644 --- a/gateway/kira/metamask/utils.go +++ b/gateway/kira/metamask/utils.go @@ -212,3 +212,11 @@ func getSignature(r, s, v []byte) []byte { sig[64] = sig[64] - 27 return sig } + +func getSignatureV2(r, s, v []byte) []byte { + sig := make([]byte, 65) + copy(sig[:32], r) + copy(sig[32:64], s) + copy(sig[64:], v) + return sig +} diff --git a/go.mod b/go.mod index aed68f5..d531693 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module github.com/KiraCore/interx go 1.19 require ( + cosmossdk.io/math v1.2.0 github.com/KeisukeYamashita/go-jsonrpc v1.0.1 github.com/KiraCore/sekai v0.3.38 github.com/btcsuite/btcd v0.22.1 @@ -29,18 +30,12 @@ require ( google.golang.org/protobuf v1.31.0 ) -require ( - github.com/google/uuid v1.3.0 // indirect - github.com/rjeczalik/notify v0.9.1 // indirect -) - require ( cosmossdk.io/api v0.3.1 // indirect cosmossdk.io/core v0.5.1 // indirect cosmossdk.io/depinject v1.0.0-alpha.4 // indirect cosmossdk.io/errors v1.0.0 // indirect cosmossdk.io/log v1.2.1 // indirect - cosmossdk.io/math v1.2.0 // indirect cosmossdk.io/tools/rosetta v0.2.1 // indirect filippo.io/edwards25519 v1.0.0 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect @@ -148,7 +143,6 @@ require ( github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/spf13/viper v1.14.0 // indirect - github.com/storyicon/sigverify v1.1.0 github.com/subosito/gotenv v1.4.1 // indirect github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c // indirect @@ -176,3 +170,5 @@ require ( ) replace github.com/syndtr/goleveldb => github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 +replace github.com/KiraCore/sekai => ../sekai + diff --git a/go.sum b/go.sum index b2a7c11..7fef56c 100644 --- a/go.sum +++ b/go.sum @@ -403,7 +403,6 @@ github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm4 github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= @@ -698,7 +697,6 @@ github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqn github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rjeczalik/notify v0.9.1 h1:CLCKso/QK1snAlnhNR/CNvNiFU2saUtjV0bx3EwNeCE= -github.com/rjeczalik/notify v0.9.1/go.mod h1:rKwnCoCGeuQnwBtTSPL9Dad03Vh2n40ePRrjvIXnJho= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= @@ -761,8 +759,6 @@ github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DM github.com/spf13/viper v1.14.0 h1:Rg7d3Lo706X9tHsJMUjdiwMpHB7W8WnSVOssIY+JElU= github.com/spf13/viper v1.14.0/go.mod h1:WT//axPky3FdvXHzGw33dNdXXXfFQqmEalje+egj8As= github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4 h1:Gb2Tyox57NRNuZ2d3rmvB3pcmbu7O1RS3m8WRx7ilrg= -github.com/storyicon/sigverify v1.1.0 h1:Fz153Jvloz1P0G3TrG7dHGyAlB3mpjmFeu5IszfJWQ0= -github.com/storyicon/sigverify v1.1.0/go.mod h1:q0qxvhdUsMIBAry3h7/IMW7BebRkiT8496TrQP1XW5s= github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= From 57e3dd74aa602cb49d35684f100887e8a0ef1005 Mon Sep 17 00:00:00 2001 From: tj327 Date: Wed, 8 May 2024 10:49:28 -0400 Subject: [PATCH 11/25] revert sekai replace in go.mod --- go.mod | 1 - 1 file changed, 1 deletion(-) diff --git a/go.mod b/go.mod index d531693..d615da3 100644 --- a/go.mod +++ b/go.mod @@ -170,5 +170,4 @@ require ( ) replace github.com/syndtr/goleveldb => github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 -replace github.com/KiraCore/sekai => ../sekai From 6f027ac2ce7f3d6167805462b5e9f7b976e8a721 Mon Sep 17 00:00:00 2001 From: tj327 Date: Thu, 23 May 2024 13:31:20 -0400 Subject: [PATCH 12/25] release --- RELEASE.md | 1 - config/constants.go | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/RELEASE.md b/RELEASE.md index 163a232..d7fa990 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -2,4 +2,3 @@ Features: * Implement KIP-87 : broadcast metamask coin send transaction to sekai * Implement KIP-87 : broadcast eip-712 signed transaction to sekai -* Implement KIP-87 : check validation of eip-712 signed tx diff --git a/config/constants.go b/config/constants.go index e3739ad..bcc7a8f 100755 --- a/config/constants.go +++ b/config/constants.go @@ -1,8 +1,8 @@ package config const ( - InterxVersion = "v0.4.48" - SekaiVersion = "v0.3.42" + InterxVersion = "v0.4.49" + SekaiVersion = "v0.3.45" CosmosVersion = "v0.47.6" DefaultChainID = 8789 From 68a75181eb642744887f1c0c62184be7d2e0f44c Mon Sep 17 00:00:00 2001 From: tj327 Date: Thu, 23 May 2024 13:46:54 -0400 Subject: [PATCH 13/25] sekai version fix --- .../kira/metamask/legacy_cosmostxsender.go | 1585 ----------------- go.mod | 3 +- go.sum | 4 +- 3 files changed, 3 insertions(+), 1589 deletions(-) delete mode 100644 gateway/kira/metamask/legacy_cosmostxsender.go diff --git a/gateway/kira/metamask/legacy_cosmostxsender.go b/gateway/kira/metamask/legacy_cosmostxsender.go deleted file mode 100644 index 513b674..0000000 --- a/gateway/kira/metamask/legacy_cosmostxsender.go +++ /dev/null @@ -1,1585 +0,0 @@ -package metamask - -import ( - "bytes" - "encoding/hex" - "encoding/json" - "errors" - "fmt" - "math" - "math/big" - "net/http" - "time" - - sdkmath "cosmossdk.io/math" - "github.com/KiraCore/interx/common" - "github.com/KiraCore/interx/config" - custodytypes "github.com/KiraCore/sekai/x/custody/types" - evidencetypes "github.com/KiraCore/sekai/x/evidence/types" - customgovtypes "github.com/KiraCore/sekai/x/gov/types" - multistakingtypes "github.com/KiraCore/sekai/x/multistaking/types" - slashingtypes "github.com/KiraCore/sekai/x/slashing/types" - spendingtypes "github.com/KiraCore/sekai/x/spending/types" - tokenstypes "github.com/KiraCore/sekai/x/tokens/types" - clienttx "github.com/cosmos/cosmos-sdk/client/tx" - cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" - cosmostypes "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/tx/signing" - xauthsigning "github.com/cosmos/cosmos-sdk/x/auth/signing" - banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" - "github.com/ethereum/go-ethereum/accounts/abi" - ethcommon "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" -) - -func legacySendTx(txRawData string, gwCosmosmux *runtime.ServeMux, r *http.Request) (string, error) { - byteData, err := hex.DecodeString(txRawData[2:]) - if err != nil { - return "", err - } - - ethTxData, err := GetEthTxInfo(byteData) - - if err != nil { - return "", err - } - - var txBytes []byte - - submitEvidencePrefix, _ := hex.DecodeString("85db2453") - submitProposalPrefix, _ := hex.DecodeString("00000000") - voteProposalPrefix, _ := hex.DecodeString("7f1f06dc") - registerIdentityRecordsPrefix, _ := hex.DecodeString("bc05f106") - deleteIdentityRecordPrefix, _ := hex.DecodeString("25581f17") - requestIdentityRecordsVerifyPrefix, _ := hex.DecodeString("9765358e") - handleIdentityRecordsVerifyRequestPrefix, _ := hex.DecodeString("4335ed0c") - cancelIdentityRecordsVerifyRequestPrefix, _ := hex.DecodeString("eeaa0488") - setNetworkPropertiesPrefix, _ := hex.DecodeString("f8060fb5") - setExecutionFeePrefix, _ := hex.DecodeString("c7586de8") - claimCouncilorPrefix, _ := hex.DecodeString("b7b8ff46") - whitelistPermissionsPrefix, _ := hex.DecodeString("2f313ab8") - blacklistPermissionsPrefix, _ := hex.DecodeString("3864f845") - createRolePrefix, _ := hex.DecodeString("2d8abfdf") - assignRolePrefix, _ := hex.DecodeString("fcc121b5") - unassignRolePrefix, _ := hex.DecodeString("c79ca19d") - whitelistRolePermissionPrefix, _ := hex.DecodeString("59472362") - blacklistRolePermissionPrefix, _ := hex.DecodeString("99c557da") - removeWhitelistRolePermissionPrefix, _ := hex.DecodeString("2a11d702") - removeBlacklistRolePermissionPrefix, _ := hex.DecodeString("f5f865e4") - claimValidatorPrefix, _ := hex.DecodeString("00000000") - upsertTokenAliasPrefix, _ := hex.DecodeString("f69a4787") - upsertTokenRatePrefix, _ := hex.DecodeString("3b30a97a") - activatePrefix, _ := hex.DecodeString("a1374dc2") - pausePrefix, _ := hex.DecodeString("1371cf19") - unpausePrefix, _ := hex.DecodeString("b9179894") - createSpendingPoolPrefix, _ := hex.DecodeString("4ed8a0a2") - depositSpendingPoolPrefix, _ := hex.DecodeString("e10c925c") - registerSpendingPoolBeneficiaryPrefix, _ := hex.DecodeString("7ab7eecf") - claimSpendingPoolPrefix, _ := hex.DecodeString("efeed4a0") - upsertStakingPoolPrefix, _ := hex.DecodeString("fb24f5cc") - delegatePrefix, _ := hex.DecodeString("4b193c09") - undelegatePrefix, _ := hex.DecodeString("94574f0c") - claimRewardsPrefix, _ := hex.DecodeString("9e796524") - claimUndelegationPrefix, _ := hex.DecodeString("2f608d76") - setCompoundInfoPrefix, _ := hex.DecodeString("e2d6a093") - registerDelegatorPrefix, _ := hex.DecodeString("99db185d") - createCustodyPrefix, _ := hex.DecodeString("bebde6d1") - addToCustodyWhiteListPrefix, _ := hex.DecodeString("25a1d834") - addToCustodyCustodiansPrefix, _ := hex.DecodeString("8c7fdb91") - removeFromCustodyCustodiansPrefix, _ := hex.DecodeString("90be51cf") - dropCustodyCustodiansPrefix, _ := hex.DecodeString("0ca697b4") - removeFromCustodyWhiteListPrefix, _ := hex.DecodeString("fa431c3e") - dropCustodyWhiteListPrefix, _ := hex.DecodeString("bc65010a") - approveCustodyTxPrefix, _ := hex.DecodeString("5da292d4") - declineCustodyTxPrefix, _ := hex.DecodeString("dce4399a") - - var msgType int - switch { - case ethTxData.Data == nil: - msgType = MsgBankSend - case len(ethTxData.Data) == 0: - msgType = MsgBankSend - case bytes.Equal(ethTxData.Data[:4], delegatePrefix): - msgType = MsgDelegate - case bytes.Equal(ethTxData.Data[:4], undelegatePrefix): - msgType = MsgUndelegate - case bytes.Equal(ethTxData.Data[:4], submitEvidencePrefix): - msgType = MsgSubmitEvidence - case bytes.Equal(ethTxData.Data[:4], submitProposalPrefix): - msgType = MsgSubmitProposal - case bytes.Equal(ethTxData.Data[:4], voteProposalPrefix): - msgType = MsgVoteProposal - case bytes.Equal(ethTxData.Data[:4], registerIdentityRecordsPrefix): - msgType = MsgRegisterIdentityRecords - case bytes.Equal(ethTxData.Data[:4], deleteIdentityRecordPrefix): - msgType = MsgDeleteIdentityRecords - case bytes.Equal(ethTxData.Data[:4], requestIdentityRecordsVerifyPrefix): - msgType = MsgRequestIdentityRecordsVerify - case bytes.Equal(ethTxData.Data[:4], handleIdentityRecordsVerifyRequestPrefix): - msgType = MsgHandleIdentityRecordsVerifyRequest - case bytes.Equal(ethTxData.Data[:4], cancelIdentityRecordsVerifyRequestPrefix): - msgType = MsgCancelIdentityRecordsVerifyRequest - case bytes.Equal(ethTxData.Data[:4], setNetworkPropertiesPrefix): - msgType = MsgSetNetworkProperties - case bytes.Equal(ethTxData.Data[:4], setExecutionFeePrefix): - msgType = MsgSetExecutionFee - case bytes.Equal(ethTxData.Data[:4], claimCouncilorPrefix): - msgType = MsgClaimCouncilor - case bytes.Equal(ethTxData.Data[:4], whitelistPermissionsPrefix): - msgType = MsgWhitelistPermissions - case bytes.Equal(ethTxData.Data[:4], blacklistPermissionsPrefix): - msgType = MsgBlacklistPermissions - case bytes.Equal(ethTxData.Data[:4], createRolePrefix): - msgType = MsgCreateRole - case bytes.Equal(ethTxData.Data[:4], assignRolePrefix): - msgType = MsgAssignRole - case bytes.Equal(ethTxData.Data[:4], unassignRolePrefix): - msgType = MsgUnassignRole - case bytes.Equal(ethTxData.Data[:4], whitelistRolePermissionPrefix): - msgType = MsgWhitelistRolePermission - case bytes.Equal(ethTxData.Data[:4], blacklistRolePermissionPrefix): - msgType = MsgBlacklistRolePermission - case bytes.Equal(ethTxData.Data[:4], removeWhitelistRolePermissionPrefix): - msgType = MsgRemoveWhitelistRolePermission - case bytes.Equal(ethTxData.Data[:4], removeBlacklistRolePermissionPrefix): - msgType = MsgBlacklistRolePermission - case bytes.Equal(ethTxData.Data[:4], claimValidatorPrefix): - msgType = MsgClaimValidator - case bytes.Equal(ethTxData.Data[:4], upsertTokenAliasPrefix): - msgType = MsgUpsertTokenAlias - case bytes.Equal(ethTxData.Data[:4], upsertTokenRatePrefix): - msgType = MsgUpsertTokenRate - case bytes.Equal(ethTxData.Data[:4], activatePrefix): - msgType = MsgActivate - case bytes.Equal(ethTxData.Data[:4], pausePrefix): - msgType = MsgPause - case bytes.Equal(ethTxData.Data[:4], unpausePrefix): - msgType = MsgUnpause - case bytes.Equal(ethTxData.Data[:4], createSpendingPoolPrefix): - msgType = MsgCreateSpendingPool - case bytes.Equal(ethTxData.Data[:4], depositSpendingPoolPrefix): - msgType = MsgDepositSpendingPool - case bytes.Equal(ethTxData.Data[:4], registerSpendingPoolBeneficiaryPrefix): - msgType = MsgRegisterSpendingPoolBeneficiary - case bytes.Equal(ethTxData.Data[:4], claimSpendingPoolPrefix): - msgType = MsgClaimSpendingPool - case bytes.Equal(ethTxData.Data[:4], upsertStakingPoolPrefix): - msgType = MsgUpsertStakingPool - case bytes.Equal(ethTxData.Data[:4], claimRewardsPrefix): - msgType = MsgClaimRewards - case bytes.Equal(ethTxData.Data[:4], claimUndelegationPrefix): - msgType = MsgClaimUndelegation - case bytes.Equal(ethTxData.Data[:4], setCompoundInfoPrefix): - msgType = MsgSetCompoundInfo - case bytes.Equal(ethTxData.Data[:4], registerDelegatorPrefix): - msgType = MsgRegisterDelegator - case bytes.Equal(ethTxData.Data[:4], createCustodyPrefix): - msgType = MsgCreateCustody - case bytes.Equal(ethTxData.Data[:4], addToCustodyWhiteListPrefix): - msgType = MsgAddToCustodyWhiteList - case bytes.Equal(ethTxData.Data[:4], addToCustodyCustodiansPrefix): - msgType = MsgAddToCustodyCustodians - case bytes.Equal(ethTxData.Data[:4], removeFromCustodyCustodiansPrefix): - msgType = MsgRemoveFromCustodyCustodians - case bytes.Equal(ethTxData.Data[:4], dropCustodyCustodiansPrefix): - msgType = MsgDropCustodyCustodians - case bytes.Equal(ethTxData.Data[:4], removeFromCustodyWhiteListPrefix): - msgType = MsgRemoveFromCustodyWhiteList - case bytes.Equal(ethTxData.Data[:4], dropCustodyWhiteListPrefix): - msgType = MsgDropCustodyWhiteList - case bytes.Equal(ethTxData.Data[:4], approveCustodyTxPrefix): - msgType = MsgApproveCustodyTx - case bytes.Equal(ethTxData.Data[:4], declineCustodyTxPrefix): - msgType = MsgDeclineCustodyTx - default: - return "", errors.New("no such functions") - } - - txBytes, err = legacySignTx(ethTxData, gwCosmosmux, r, msgType) - - if err != nil { - return "", err - } - - // if ethTxData - - txHash, err := sendCosmosTx(r.Context(), txBytes) - if err != nil { - return "", err - } - - return txHash, nil -} - -func legacyGetStructHash(txType int, valParam string) ethcommon.Hash { - abiPack := abi.ABI{} - var structABIPack []byte - - var funcSig []byte - - switch txType { - case MsgSubmitEvidence: - funcSig = crypto.Keccak256([]byte("submitEvidence(string param)")) - case MsgSubmitProposal: - funcSig = crypto.Keccak256([]byte("submitProposal(string param)")) - case MsgVoteProposal: - funcSig = crypto.Keccak256([]byte("voteProposal(string param)")) - case MsgRegisterIdentityRecords: - funcSig = crypto.Keccak256([]byte("registerIdentityRecords(string param)")) - case MsgDeleteIdentityRecords: - funcSig = crypto.Keccak256([]byte("deleteIdentityRecord(string param)")) - case MsgRequestIdentityRecordsVerify: - funcSig = crypto.Keccak256([]byte("requestIdentityRecordsVerify(string param)")) - case MsgHandleIdentityRecordsVerifyRequest: - funcSig = crypto.Keccak256([]byte("handleIdentityRecordsVerifyRequest(string param)")) - case MsgCancelIdentityRecordsVerifyRequest: - funcSig = crypto.Keccak256([]byte("cancelIdentityRecordsVerifyRequest(string param)")) - case MsgSetNetworkProperties: - funcSig = crypto.Keccak256([]byte("setNetworkProperties(string param)")) - case MsgSetExecutionFee: - funcSig = crypto.Keccak256([]byte("setExecutionFee(string param)")) - case MsgClaimCouncilor: - funcSig = crypto.Keccak256([]byte("claimCouncilor(string param)")) - case MsgWhitelistPermissions: - funcSig = crypto.Keccak256([]byte("whitelistPermissions(string param)")) - case MsgBlacklistPermissions: - funcSig = crypto.Keccak256([]byte("blacklistPermissions(string param)")) - case MsgCreateRole: - funcSig = crypto.Keccak256([]byte("createRole(string param)")) - case MsgAssignRole: - funcSig = crypto.Keccak256([]byte("assignRole(string param)")) - case MsgUnassignRole: - funcSig = crypto.Keccak256([]byte("unassignRole(string param)")) - case MsgWhitelistRolePermission: - funcSig = crypto.Keccak256([]byte("whitelistRolePermission(string param)")) - case MsgBlacklistRolePermission: - funcSig = crypto.Keccak256([]byte("blacklistRolePermission(string param)")) - case MsgRemoveWhitelistRolePermission: - funcSig = crypto.Keccak256([]byte("removeWhitelistRolePermission(string param)")) - case MsgRemoveBlacklistRolePermission: - funcSig = crypto.Keccak256([]byte("removeBlacklistRolePermission(string param)")) - case MsgClaimValidator: - // funcSig = crypto.Keccak256([]byte("delegate(string param)")) - case MsgUpsertTokenAlias: - funcSig = crypto.Keccak256([]byte("upsertTokenAlias(string param)")) - case MsgUpsertTokenRate: - funcSig = crypto.Keccak256([]byte("upsertTokenRate(string param)")) - case MsgActivate: - funcSig = crypto.Keccak256([]byte("activate()")) - case MsgPause: - funcSig = crypto.Keccak256([]byte("pause()")) - case MsgUnpause: - funcSig = crypto.Keccak256([]byte("unpause()")) - case MsgCreateSpendingPool: - funcSig = crypto.Keccak256([]byte("createSpendingPool(string param)")) - case MsgDepositSpendingPool: - funcSig = crypto.Keccak256([]byte("depositSpendingPool(string param)")) - case MsgRegisterSpendingPoolBeneficiary: - funcSig = crypto.Keccak256([]byte("registerSpendingPoolBeneficiary(string param)")) - case MsgClaimSpendingPool: - funcSig = crypto.Keccak256([]byte("claimSpendingPool(string param)")) - case MsgUpsertStakingPool: - funcSig = crypto.Keccak256([]byte("upsertStakingPool(string param)")) - case MsgDelegate: - funcSig = crypto.Keccak256([]byte("delegate(string param)")) - case MsgUndelegate: - funcSig = crypto.Keccak256([]byte("undelegate(string param)")) - case MsgClaimRewards: - funcSig = crypto.Keccak256([]byte("claimRewards()")) - case MsgClaimUndelegation: - funcSig = crypto.Keccak256([]byte("claimUndelegation(string param)")) - case MsgSetCompoundInfo: - funcSig = crypto.Keccak256([]byte("setCompoundInfo(string param)")) - case MsgRegisterDelegator: - funcSig = crypto.Keccak256([]byte("registerDelegator()")) - case MsgCreateCustody: - funcSig = crypto.Keccak256([]byte("createCustody(string param)")) - case MsgAddToCustodyWhiteList: - funcSig = crypto.Keccak256([]byte("addToCustodyWhiteList(string param)")) - case MsgAddToCustodyCustodians: - funcSig = crypto.Keccak256([]byte("addToCustodyCustodians(string param)")) - case MsgRemoveFromCustodyCustodians: - funcSig = crypto.Keccak256([]byte("removeFromCustodyCustodians(string param)")) - case MsgDropCustodyCustodians: - funcSig = crypto.Keccak256([]byte("dropCustodyCustodians(string param)")) - case MsgRemoveFromCustodyWhiteList: - funcSig = crypto.Keccak256([]byte("removeFromCustodyWhiteList(string param)")) - case MsgDropCustodyWhiteList: - funcSig = crypto.Keccak256([]byte("dropCustodyWhiteList(string param)")) - case MsgApproveCustodyTx: - funcSig = crypto.Keccak256([]byte("approveCustodyTransaction(string param)")) - case MsgDeclineCustodyTx: - funcSig = crypto.Keccak256([]byte("declineCustodyTransaction(string param)")) - default: - } - - structJsonData := []byte(`[{"Type":"function","Name":"encode","Inputs":[{"Type":"bytes32","Name":"funcsig"},{"Type":"bytes32","Name":"param"}],"Outputs":[]}]`) - _ = abiPack.UnmarshalJSON(structJsonData) - - var funcSignature [32]byte - copy(funcSignature[:], funcSig) - - structABIPack, _ = PackABIParams(abiPack, - "encode", - convertByteArr2Bytes32(funcSig), - convertByteArr2Bytes32(crypto.Keccak256([]byte(valParam))), - ) - - structHash := crypto.Keccak256Hash(structABIPack) - - return structHash -} - -func legacyValidateEIP712Sign(v, r, s []byte, sender ethcommon.Address, valParam string, txType int) bool { - abiPack := abi.ABI{} - - // get EIP712DomainHash - jsonData := []byte(`[{"Type":"function","Name":"encode","Inputs":[{"Type":"bytes32","Name":"funcsig"},{"Type":"bytes32","Name":"name"},{"Type":"bytes32","Name":"version"},{"Type":"bytes32","Name":"chainId"}],"Outputs":[]}]`) - abiPack.UnmarshalJSON(jsonData) - funcSig := crypto.Keccak256([]byte("EIP712Domain(string name,string version,uint256 chainId)")) - - eip712DomainSeparatorABIPack, _ := PackABIParams(abiPack, - "encode", - convertByteArr2Bytes32(funcSig), - convertByteArr2Bytes32(crypto.Keccak256([]byte("Kira"))), - convertByteArr2Bytes32(crypto.Keccak256([]byte("1"))), - convertByteArr2Bytes32(uint32To32Bytes(config.DefaultChainID)), - ) - eip712DomainSeparator := crypto.Keccak256Hash(eip712DomainSeparatorABIPack) - - // get StructHash - structHash := legacyGetStructHash(txType, valParam) - - // Define the final hash - hash := crypto.Keccak256Hash( - append(append([]byte("\x19\x01"), eip712DomainSeparator.Bytes()...), structHash.Bytes()...), - ) - - signature := getSignature(r, s, v) - - // Recover the public key from the signature - pubKey, err := crypto.SigToPub(hash.Bytes(), signature) - // pbBytes, err := crypto.Ecrecover(hash.Bytes(), signature) - // fmt.Println(string(pbBytes), err) - // pubKey, err := crypto.UnmarshalPubkey(pbBytes) - - if err != nil { - fmt.Println("eip712 err", err) - return false - } - - // Derive the signer's address from the public key - signerAddress := crypto.PubkeyToAddress(*pubKey) - - return signerAddress.Hex() == sender.Hex() -} - -func legacySignTx(ethTxData EthTxData, gwCosmosmux *runtime.ServeMux, r *http.Request, txType int) ([]byte, error) { - // Create a new TxBuilder. - txBuilder := config.EncodingCg.TxConfig.NewTxBuilder() - - addr1, err := hex2bech32(ethTxData.From, TypeKiraAddr) - if err != nil { - return nil, err - } - cosmosAddr1, err := cosmostypes.AccAddressFromBech32(addr1) - if err != nil { - return nil, err - } - - params := [][]byte(nil) - if txType != MsgBankSend { - params, err = DecodeParam(ethTxData.Data[4:], txType) - if err != nil { - return nil, err - } - valParam := string(params[4]) - - validation := legacyValidateEIP712Sign(params[0][len(params[0])-1:], params[1], params[2], ethcommon.BytesToAddress(params[3][12:]), valParam, txType) - if !validation { - return nil, errors.New("eip712 validation is failed") - } - } - - var msg cosmostypes.Msg - - switch txType { - case MsgBankSend: - addr2, err := hex2bech32(ethTxData.To, TypeKiraAddr) - if err != nil { - return nil, err - } - cosmosAddr2, err := cosmostypes.AccAddressFromBech32(addr2) - if err != nil { - return nil, err - } - - balance := ethTxData.Value.Div(ðTxData.Value, big.NewInt(int64(math.Pow10(12)))) - msg = banktypes.NewMsgSend(cosmosAddr1, cosmosAddr2, - cosmostypes.NewCoins(cosmostypes.NewInt64Coin(config.DefaultKiraDenom, balance.Int64()))) - case MsgSubmitEvidence: - // V, R, S, signer, height, power, time, consensusAddr - from, err := bytes2cosmosAddr(params[3][12:]) - if err != nil { - return nil, err - } - - type Equivocation struct { - Height int64 `json:"height"` - Time time.Time `json:"time"` - Power int64 `json:"power"` - ConsensusAddress string `json:"consensus_address"` - } - - var evidenceJsonParam Equivocation - err = json.Unmarshal(params[4], &evidenceJsonParam) - if err != nil { - return nil, err - } - - evidenceParam := evidencetypes.Equivocation{ - Height: evidenceJsonParam.Height, - Time: evidenceJsonParam.Time, - Power: evidenceJsonParam.Power, - ConsensusAddress: evidenceJsonParam.ConsensusAddress, - } - - msg, err = evidencetypes.NewMsgSubmitEvidence(from, &evidenceParam) - if err != nil { - return nil, err - } - case MsgSubmitProposal: - // from, err := bytes2cosmosAddr(params[3][12:]) - // if err != nil { - // return nil, err - // } - - // type SubmitProposalParam struct { - // Title string `json:"title"` - // Description string `json:"description"` - // Content string `json:"content"` - // } - - // var proposalParam SubmitProposalParam - // err = json.Unmarshal(params[4], &proposalParam) - // if err != nil { - // return nil, err - // } - - // msg, err := customgovtypes.NewMsgSubmitProposal(from) - // if err != nil { - // return nil, err - // } - case MsgVoteProposal: - // V, R, S, signer, param - from, err := bytes2cosmosAddr(params[3][12:]) - if err != nil { - return nil, err - } - - type VoteProposalParam struct { - ProposalID uint64 `json:"proposal_id"` - Option uint64 `json:"option"` - Slash string `json:"slash"` - } - - var proposalParam VoteProposalParam - err = json.Unmarshal(params[4], &proposalParam) - if err != nil { - return nil, err - } - - slash, err := sdkmath.LegacyNewDecFromStr(proposalParam.Slash) - if err != nil { - return nil, err - } - - msg = customgovtypes.NewMsgVoteProposal(proposalParam.ProposalID, from, customgovtypes.VoteOption(proposalParam.Option), slash) - case MsgRegisterIdentityRecords: - // V, R, S, signer, identityInfo, - from, err := bytes2cosmosAddr(params[3][12:]) - if err != nil { - return nil, err - } - - type IdentityRecordParam struct { - Infos []customgovtypes.IdentityInfoEntry `json:"identity_infos"` - } - - var recordParam IdentityRecordParam - err = json.Unmarshal(params[4], &recordParam) - if err != nil { - return nil, err - } - - msg = customgovtypes.NewMsgRegisterIdentityRecords(from, recordParam.Infos) - case MsgDeleteIdentityRecords: - // V, R, S, signer, len, keys, - from, err := bytes2cosmosAddr(params[3][12:]) - if err != nil { - return nil, err - } - - type IdentityRecordParam struct { - Keys []string `json:"keys"` - } - - var recordParam IdentityRecordParam - err = json.Unmarshal(params[4], &recordParam) - if err != nil { - return nil, err - } - - msg = customgovtypes.NewMsgDeleteIdentityRecords(from, recordParam.Keys) - case MsgRequestIdentityRecordsVerify: - // V, R, S, signer, tip, verifier, len, recordIds - from, err := bytes2cosmosAddr(params[3][12:]) - if err != nil { - return nil, err - } - - type IdentityRecordParam struct { - Balance string `json:"balance"` - Verifier string `json:"verifier"` - RecordIds []uint64 `json:"record_ids"` - } - - var recordParam IdentityRecordParam - err = json.Unmarshal(params[4], &recordParam) - if err != nil { - return nil, err - } - - balance, err := cosmostypes.ParseCoinNormalized(recordParam.Balance) - if err != nil { - return nil, err - } - - verifier, err := string2cosmosAddr(recordParam.Verifier) - if err != nil { - return nil, err - } - - msg = customgovtypes.NewMsgRequestIdentityRecordsVerify(from, verifier, recordParam.RecordIds, balance) - case MsgHandleIdentityRecordsVerifyRequest: - // V, R, S, signer, requestId, isApprove - verifier, err := bytes2cosmosAddr(params[3][12:]) - if err != nil { - return nil, err - } - - type IdentityRecordParam struct { - RequestID uint64 `json:"request_id"` - IsApproved bool `json:"is_approved"` - } - - var recordParam IdentityRecordParam - err = json.Unmarshal(params[4], &recordParam) - if err != nil { - return nil, err - } - - msg = customgovtypes.NewMsgHandleIdentityRecordsVerifyRequest(verifier, recordParam.RequestID, recordParam.IsApproved) - case MsgCancelIdentityRecordsVerifyRequest: - // V, R, S, signer, verifyRequestId - executor, err := bytes2cosmosAddr(params[3][12:]) - if err != nil { - return nil, err - } - - type IdentityRecordParam struct { - VerifyRequestId uint64 `json:"verify_request_id"` - } - - var recordParam IdentityRecordParam - err = json.Unmarshal(params[4], &recordParam) - if err != nil { - return nil, err - } - - msg = customgovtypes.NewMsgCancelIdentityRecordsVerifyRequest(executor, recordParam.VerifyRequestId) - case MsgSetNetworkProperties: - // V, R, S, signer, networkProperties - proposer, err := bytes2cosmosAddr(params[3][12:]) - if err != nil { - return nil, err - } - - type NetworkProperties struct { - MinTxFee uint64 `json:"min_tx_fee"` - MaxTxFee uint64 `json:"max_tx_fee"` - VoteQuorum uint64 `json:"vote_quorum"` - MinimumProposalEndTime uint64 `json:"minimum_proposal_end_time"` - ProposalEnactmentTime uint64 `json:"proposal_enactment_time"` - MinProposalEndBlocks uint64 `json:"min_proposal_end_blocks"` - MinProposalEnactmentBlocks uint64 `json:"min_proposal_enactment_blocks"` - EnableForeignFeePayments bool `json:"enable_foreign_fee_payments"` - MischanceRankDecreaseAmount uint64 `json:"mischance_rank_decrease_amount"` - MaxMischance uint64 `json:"max_mischance"` - MischanceConfidence uint64 `json:"mischance_confidence"` - InactiveRankDecreasePercent string `json:"inactive_rank_decrease_percent"` - MinValidators uint64 `json:"min_validators"` - PoorNetworkMaxBankSend uint64 `json:"poor_network_max_bank_send"` - UnjailMaxTime uint64 `json:"unjail_max_time"` - EnableTokenWhitelist bool `json:"enable_token_whitelist"` - EnableTokenBlacklist bool `json:"enable_token_blacklist"` - MinIdentityApprovalTip uint64 `json:"min_identity_approval_tip"` - UniqueIdentityKeys string `json:"unique_identity_keys"` - UbiHardcap uint64 `json:"ubi_hardcap"` - ValidatorsFeeShare string `json:"validators_fee_share"` - InflationRate string `json:"inflation_rate"` - InflationPeriod uint64 `json:"inflation_period"` - UnstakingPeriod uint64 `json:"unstaking_period"` - MaxDelegators uint64 `json:"max_delegators"` - MinDelegationPushout uint64 `json:"min_delegation_pushout"` - SlashingPeriod uint64 `json:"slashing_period"` - MaxJailedPercentage string `json:"max_jailed_percentage"` - MaxSlashingPercentage string `json:"max_slashing_percentage"` - MinCustodyReward uint64 `json:"min_custody_reward"` - MaxCustodyBufferSize uint64 `json:"max_custody_buffer_size"` - MaxCustodyTxSize uint64 `json:"max_custody_tx_size"` - AbstentionRankDecreaseAmount uint64 `json:"abstention_rank_decrease_amount"` - MaxAbstention uint64 `json:"max_abstention"` - MinCollectiveBond uint64 `json:"min_collective_bond"` - MinCollectiveBondingTime uint64 `json:"min_collective_bonding_time"` - MaxCollectiveOutputs uint64 `json:"max_collective_outputs"` - MinCollectiveClaimPeriod uint64 `json:"min_collective_claim_period"` - ValidatorRecoveryBond uint64 `json:"validator_recovery_bond"` - MaxAnnualInflation string `json:"max_annual_inflation"` - MaxProposalTitleSize uint64 `json:"max_proposal_title_size"` - MaxProposalDescriptionSize uint64 `json:"max_proposal_description_size"` - MaxProposalPollOptionSize uint64 `json:"max_proposal_poll_option_size"` - MaxProposalPollOptionCount uint64 `json:"max_proposal_poll_option_count"` - MaxProposalReferenceSize uint64 `json:"max_proposal_reference_size"` - MaxProposalChecksumSize uint64 `json:"max_proposal_checksum_size"` - MinDappBond uint64 `json:"min_dapp_bond"` - MaxDappBond uint64 `json:"max_dapp_bond"` - DappLiquidationThreshold uint64 `json:"dapp_liquidation_threshold"` - DappLiquidationPeriod uint64 `json:"dapp_liquidation_period"` - DappBondDuration uint64 `json:"dapp_bond_duration"` - DappVerifierBond string `json:"dapp_verifier_bond"` - DappAutoDenounceTime uint64 `json:"dapp_auto_denounce_time"` - DappMischanceRankDecreaseAmount uint64 `json:"dapp_mischance_rank_decrease_amount"` - DappMaxMischance uint64 `json:"dapp_max_mischance"` - DappInactiveRankDecreasePercent uint64 `json:"dapp_inactive_rank_decrease_percent"` - DappPoolSlippageDefault string `json:"dapp_pool_slippage_default"` - MintingFtFee uint64 `json:"minting_ft_fee"` - MintingNftFee uint64 `json:"minting_nft_fee"` - VetoThreshold string `json:"veto_threshold"` - } - - var networkProperties NetworkProperties - err = json.Unmarshal(params[4], &networkProperties) - if err != nil { - return nil, err - } - - inActiveRankDecreasePercent, err := cosmostypes.NewDecFromStr(networkProperties.InactiveRankDecreasePercent) - if err != nil { - return nil, err - } - validatorsFeeShare, err := cosmostypes.NewDecFromStr(networkProperties.ValidatorsFeeShare) - if err != nil { - return nil, err - } - inflationRate, err := cosmostypes.NewDecFromStr(networkProperties.InflationRate) - if err != nil { - return nil, err - } - maxJailedPercentage, err := cosmostypes.NewDecFromStr(networkProperties.MaxJailedPercentage) - if err != nil { - return nil, err - } - maxSlashingPercentage, err := cosmostypes.NewDecFromStr(networkProperties.MaxSlashingPercentage) - if err != nil { - return nil, err - } - maxAnnualInflation, err := cosmostypes.NewDecFromStr(networkProperties.MaxAnnualInflation) - if err != nil { - return nil, err - } - dappVerifierBond, err := cosmostypes.NewDecFromStr(networkProperties.DappVerifierBond) - if err != nil { - return nil, err - } - dappPoolSlippageDefault, err := cosmostypes.NewDecFromStr(networkProperties.DappPoolSlippageDefault) - if err != nil { - return nil, err - } - vetoThreshold, err := cosmostypes.NewDecFromStr(networkProperties.VetoThreshold) - if err != nil { - return nil, err - } - - networkPropertiesParam := customgovtypes.NetworkProperties{ - MinTxFee: networkProperties.MinTxFee, - MaxTxFee: networkProperties.MaxTxFee, - VoteQuorum: networkProperties.VoteQuorum, - MinimumProposalEndTime: networkProperties.MinimumProposalEndTime, - ProposalEnactmentTime: networkProperties.ProposalEnactmentTime, - MinProposalEndBlocks: networkProperties.MinProposalEndBlocks, - MinProposalEnactmentBlocks: networkProperties.MinProposalEnactmentBlocks, - EnableForeignFeePayments: networkProperties.EnableForeignFeePayments, - MischanceRankDecreaseAmount: networkProperties.MischanceRankDecreaseAmount, - MaxMischance: networkProperties.MaxMischance, - MischanceConfidence: networkProperties.MischanceConfidence, - InactiveRankDecreasePercent: inActiveRankDecreasePercent, - MinValidators: networkProperties.MinValidators, - PoorNetworkMaxBankSend: networkProperties.PoorNetworkMaxBankSend, - UnjailMaxTime: networkProperties.UnjailMaxTime, - EnableTokenWhitelist: networkProperties.EnableTokenWhitelist, - EnableTokenBlacklist: networkProperties.EnableTokenBlacklist, - MinIdentityApprovalTip: networkProperties.MinIdentityApprovalTip, - UniqueIdentityKeys: networkProperties.UniqueIdentityKeys, - UbiHardcap: networkProperties.UbiHardcap, - ValidatorsFeeShare: validatorsFeeShare, - InflationRate: inflationRate, - InflationPeriod: networkProperties.InflationPeriod, - UnstakingPeriod: networkProperties.UnstakingPeriod, - MaxDelegators: networkProperties.MaxDelegators, - MinDelegationPushout: networkProperties.MinDelegationPushout, - SlashingPeriod: networkProperties.SlashingPeriod, - MaxJailedPercentage: maxJailedPercentage, - MaxSlashingPercentage: maxSlashingPercentage, - MinCustodyReward: networkProperties.MinCustodyReward, - MaxCustodyBufferSize: networkProperties.MaxCustodyBufferSize, - MaxCustodyTxSize: networkProperties.MaxCustodyTxSize, - AbstentionRankDecreaseAmount: networkProperties.AbstentionRankDecreaseAmount, - MaxAbstention: networkProperties.MaxAbstention, - MinCollectiveBond: networkProperties.MinCollectiveBond, - MinCollectiveBondingTime: networkProperties.MinCollectiveBondingTime, - MaxCollectiveOutputs: networkProperties.MaxCollectiveOutputs, - MinCollectiveClaimPeriod: networkProperties.MinCollectiveClaimPeriod, - ValidatorRecoveryBond: networkProperties.ValidatorRecoveryBond, - MaxAnnualInflation: maxAnnualInflation, - MaxProposalTitleSize: networkProperties.MaxProposalTitleSize, - MaxProposalDescriptionSize: networkProperties.MaxProposalDescriptionSize, - MaxProposalPollOptionSize: networkProperties.MaxProposalPollOptionSize, - MaxProposalPollOptionCount: networkProperties.MaxProposalPollOptionCount, - MaxProposalReferenceSize: networkProperties.MaxProposalReferenceSize, - MaxProposalChecksumSize: networkProperties.MaxProposalChecksumSize, - MinDappBond: networkProperties.MinDappBond, - MaxDappBond: networkProperties.MaxDappBond, - DappLiquidationThreshold: networkProperties.DappLiquidationThreshold, - DappLiquidationPeriod: networkProperties.DappLiquidationPeriod, - DappBondDuration: networkProperties.DappBondDuration, - DappVerifierBond: dappVerifierBond, - DappAutoDenounceTime: networkProperties.DappAutoDenounceTime, - DappMischanceRankDecreaseAmount: networkProperties.DappMischanceRankDecreaseAmount, - DappMaxMischance: networkProperties.DappMaxMischance, - DappInactiveRankDecreasePercent: networkProperties.DappInactiveRankDecreasePercent, - DappPoolSlippageDefault: dappPoolSlippageDefault, - MintingFtFee: networkProperties.MintingFtFee, - MintingNftFee: networkProperties.MintingNftFee, - VetoThreshold: vetoThreshold, - } - - msg = customgovtypes.NewMsgSetNetworkProperties(proposer, &networkPropertiesParam) - case MsgSetExecutionFee: - // V, R, S, signer, executionFee, failureFee, timeout, defaultParams - proposer, err := bytes2cosmosAddr(params[3][12:]) - if err != nil { - return nil, err - } - - type ExecutionFeeParam struct { - TransactionType string `json:"transaction_type"` - ExecutionFee uint64 `json:"execution_fee"` - FailureFee uint64 `json:"failure_fee"` - Timeout uint64 `json:"timeout"` - DefaultParams uint64 `json:"default_params"` - } - - var feeParam ExecutionFeeParam - err = json.Unmarshal(params[4], &feeParam) - if err != nil { - return nil, err - } - - msg = customgovtypes.NewMsgSetExecutionFee(feeParam.TransactionType, feeParam.ExecutionFee, feeParam.FailureFee, - feeParam.Timeout, feeParam.DefaultParams, proposer) - case MsgClaimCouncilor: - // V, R, S, signer, moniker string, username string, description string, social string, contact string, avatar string - sender, err := bytes2cosmosAddr(params[3][12:]) - if err != nil { - return nil, err - } - - type ClaimCouncilorParam struct { - Moniker string `json:"moniker"` - Username string `json:"username"` - Description string `json:"description"` - Social string `json:"social"` - Contact string `json:"contact"` - Avatar string `json:"avatar"` - } - - var councilorParam ClaimCouncilorParam - err = json.Unmarshal(params[4], &councilorParam) - if err != nil { - return nil, err - } - - msg = customgovtypes.NewMsgClaimCouncilor(sender, councilorParam.Moniker, councilorParam.Username, councilorParam.Description, - councilorParam.Social, councilorParam.Contact, councilorParam.Avatar) - case MsgWhitelistPermissions: - // V, R, S, signer, permission uint256, controlledAddr string - sender, err := bytes2cosmosAddr(params[3][12:]) - if err != nil { - return nil, err - } - - var permissionParam PermissionsParam - err = json.Unmarshal(params[4], &permissionParam) - if err != nil { - return nil, err - } - - controlledAddr, err := string2cosmosAddr(permissionParam.ControlledAddr) - if err != nil { - return nil, err - } - - msg = customgovtypes.NewMsgWhitelistPermissions(sender, controlledAddr, permissionParam.Permission) - case MsgBlacklistPermissions: - // V, R, S, signer, permission uint256, controlledAddr string - sender, err := bytes2cosmosAddr(params[3][12:]) - if err != nil { - return nil, err - } - - var permissionParam PermissionsParam - err = json.Unmarshal(params[4], &permissionParam) - if err != nil { - return nil, err - } - - controlledAddr, err := string2cosmosAddr(permissionParam.ControlledAddr) - if err != nil { - return nil, err - } - - msg = customgovtypes.NewMsgBlacklistPermissions(sender, controlledAddr, permissionParam.Permission) - case MsgCreateRole: - // V, R, S, signer, sid string, description string - sender, err := bytes2cosmosAddr(params[3][12:]) - if err != nil { - return nil, err - } - - type RoleParam struct { - Sid string `json:"sid"` - Description string `json:"description"` - } - - var roleParam RoleParam - err = json.Unmarshal(params[4], &roleParam) - if err != nil { - return nil, err - } - - msg = customgovtypes.NewMsgCreateRole(sender, roleParam.Sid, roleParam.Description) - case MsgAssignRole: - // V, R, S, signer, roleid uint32, controller string - sender, err := bytes2cosmosAddr(params[3][12:]) - if err != nil { - return nil, err - } - - var roleParam RoleParam - err = json.Unmarshal(params[4], &roleParam) - if err != nil { - return nil, err - } - - controller, err := string2cosmosAddr(roleParam.Controller) - if err != nil { - return nil, err - } - - msg = customgovtypes.NewMsgAssignRole(sender, controller, roleParam.RoleId) - case MsgUnassignRole: - // V, R, S, signer, roleid uint32, controller address - sender, err := bytes2cosmosAddr(params[3][12:]) - if err != nil { - return nil, err - } - - var roleParam RoleParam - err = json.Unmarshal(params[4], &roleParam) - if err != nil { - return nil, err - } - - controller, err := string2cosmosAddr(roleParam.Controller) - if err != nil { - return nil, err - } - - msg = customgovtypes.NewMsgUnassignRole(sender, controller, roleParam.RoleId) - case MsgWhitelistRolePermission: - // V, R, S, signer, permission uint32, roleIdentifier string - sender, err := bytes2cosmosAddr(params[3][12:]) - if err != nil { - return nil, err - } - - var roleParam ListRoleParam - err = json.Unmarshal(params[4], &roleParam) - if err != nil { - return nil, err - } - - msg = customgovtypes.NewMsgWhitelistRolePermission(sender, roleParam.RoleIdentifier, roleParam.Permission) - case MsgBlacklistRolePermission: - // V, R, S, signer, permission uint32, roleIdentifier string - sender, err := bytes2cosmosAddr(params[3][12:]) - if err != nil { - return nil, err - } - - var roleParam ListRoleParam - err = json.Unmarshal(params[4], &roleParam) - if err != nil { - return nil, err - } - - msg = customgovtypes.NewMsgBlacklistRolePermission(sender, roleParam.RoleIdentifier, roleParam.Permission) - case MsgRemoveWhitelistRolePermission: - // V, R, S, signer, permission uint32, roleIdentifier string - sender, err := bytes2cosmosAddr(params[3][12:]) - if err != nil { - return nil, err - } - - var roleParam ListRoleParam - err = json.Unmarshal(params[4], &roleParam) - if err != nil { - return nil, err - } - - msg = customgovtypes.NewMsgRemoveWhitelistRolePermission(sender, roleParam.RoleIdentifier, roleParam.Permission) - case MsgRemoveBlacklistRolePermission: - // V, R, S, signer, permission uint32, roleIdentifier string - sender, err := bytes2cosmosAddr(params[3][12:]) - if err != nil { - return nil, err - } - - var roleParam ListRoleParam - err = json.Unmarshal(params[4], &roleParam) - if err != nil { - return nil, err - } - - msg = customgovtypes.NewMsgRemoveBlacklistRolePermission(sender, roleParam.RoleIdentifier, roleParam.Permission) - case MsgClaimValidator: - // V, R, S, signer, moniker string, valKey cosmostypes.ValAddress, pubKey cryptotypes.PubKey - - // type ClaimParam struct { - // Moniker string `json:"moniker"` - // ValKey string `json:"val_key"` - // PubKey string `json:"pub_key"` - // } - - // var claimParam ClaimParam - // err = json.Unmarshal(params[4], &claimParam) - // if err != nil { - // return nil, err - // } - - // valKey, err := cosmostypes.ValAddressFromBech32(claimParam.ValKey) - // if err != nil { - // return nil, err - // } - - // // how to get pub key from string? - // cryptotypes - - // msg, err = stakingtypes.NewMsgClaimValidator(claimParam.Moniker, valKey, claimParam.PubKey) - // if err != nil { - // return nil, err - // } - case MsgUpsertTokenAlias: - // V, R, S, signer, param - proposer, err := bytes2cosmosAddr(params[3][12:]) - if err != nil { - return nil, err - } - - type UpsertTokenAliasParam struct { - Symbol string `json:"symbol"` - Name string `json:"name"` - Icon string `json:"icon"` - Decimals uint32 `json:"decimals"` - Denoms []string `json:"denoms"` - Invalidated bool `json:"invalidated"` - } - - var upsertTokenAliasParam UpsertTokenAliasParam - err = json.Unmarshal(params[4], &upsertTokenAliasParam) - if err != nil { - return nil, err - } - - msg = tokenstypes.NewMsgUpsertTokenAlias(proposer, upsertTokenAliasParam.Symbol, upsertTokenAliasParam.Name, - upsertTokenAliasParam.Icon, upsertTokenAliasParam.Decimals, upsertTokenAliasParam.Denoms, upsertTokenAliasParam.Invalidated) - case MsgUpsertTokenRate: - // V, R, S, signer, feePayments bool, stakeToken bool, invalidated bool, denom string, rate cosmostypes.Dec, - // stakeCap cosmostypes.Dec, stakeMin cosmostypes.Int - proposer, err := bytes2cosmosAddr(params[3][12:]) - if err != nil { - return nil, err - } - - type UpsertTokenRateParam struct { - Denom string `json:"denom"` - Rate string `json:"rate"` - IsFeePayments bool `json:"is_fee_payments"` - StakeCap string `json:"stake_cap"` - StakeMin string `json:"stake_min"` - IsStakeToken bool `json:"is_stake_token"` - Invalidated bool `json:"invalidated"` - } - - var upsertParam UpsertTokenRateParam - err = json.Unmarshal(params[4], &upsertParam) - if err != nil { - return nil, err - } - - rate, err := cosmostypes.NewDecFromStr(upsertParam.Rate) - if err != nil { - return nil, err - } - stakeCap, err := cosmostypes.NewDecFromStr(upsertParam.StakeCap) - if err != nil { - return nil, err - } - stakeMin, ok := cosmostypes.NewIntFromString(upsertParam.StakeMin) - if !ok { - return nil, errors.New(fmt.Sprintln("StakeMin - decoding from string to Int type is failed:", upsertParam.StakeMin)) - } - - msg = tokenstypes.NewMsgUpsertTokenRate(proposer, upsertParam.Denom, rate, upsertParam.IsFeePayments, - stakeCap, stakeMin, upsertParam.IsStakeToken, upsertParam.Invalidated) - case MsgActivate: - // V, R, S, signer - validator, err := bytes2cosmosValAddr(params[3][12:]) - if err != nil { - return nil, err - } - msg = slashingtypes.NewMsgActivate(validator) - case MsgPause: - // V, R, S, signer - validator, err := bytes2cosmosValAddr(params[3][12:]) - if err != nil { - return nil, err - } - msg = slashingtypes.NewMsgPause(validator) - case MsgUnpause: - // V, R, S, signer - validator, err := bytes2cosmosValAddr(params[3][12:]) - if err != nil { - return nil, err - } - msg = slashingtypes.NewMsgUnpause(validator) - case MsgCreateSpendingPool: - // V, R, S, signer, name string, claimStart uint64, claimEnd uint64, rates cosmostypes.DecCoins, voteQuorum uint64, - // votePeriod uint64, voteEnactment uint64, owners spendingtypes.PermInfo, beneficiaries spendingtypes.WeightedPermInfo, - // sender cosmostypes.AccAddress, dynamicRate bool, dynamicRatePeriod uint64 - sender, err := bytes2cosmosAddr(params[3][12:]) - if err != nil { - return nil, err - } - - type WeightedRole struct { - Role uint64 `json:"role"` - Weight string `json:"weight"` - } - - type WeightedAccount struct { - Account string `json:"account"` - Weight string `json:"weight"` - } - - type WeightedPermInfo struct { - Roles []WeightedRole `json:"roles"` - Accounts []WeightedAccount `json:"accounts"` - } - - type SpendingPoolParam struct { - Name string `json:"name"` - ClaimStart uint64 `json:"claim_start"` - ClaimEnd uint64 `json:"claim_end"` - Rates []string `json:"rates"` - VoteQuorum uint64 `json:"vote_quorum"` - VotePeriod uint64 `json:"vote_period"` - VoteEnactment uint64 `json:"vote_enactment"` - Owners spendingtypes.PermInfo `json:"owners"` - Beneficiaries WeightedPermInfo `json:"beneficiaries"` - IsDynamicRate bool `json:"is_dynamic_rate"` - DynamicRatePeriod uint64 `json:"dynamic_rate_period"` - } - - var poolParam SpendingPoolParam - err = json.Unmarshal(params[4], &poolParam) - if err != nil { - return nil, err - } - - var rates cosmostypes.DecCoins - for _, rate := range poolParam.Rates { - coin, err := cosmostypes.ParseDecCoin(rate) - if err != nil { - return nil, err - } - rates.Add(coin) - } - - var beneficiaries spendingtypes.WeightedPermInfo - for _, account := range poolParam.Beneficiaries.Accounts { - weight, err := cosmostypes.NewDecFromStr(account.Weight) - if err != nil { - return nil, err - } - weightedAccount := spendingtypes.WeightedAccount{ - Account: account.Account, - Weight: weight, - } - beneficiaries.Accounts = append(beneficiaries.Accounts, weightedAccount) - } - for _, role := range poolParam.Beneficiaries.Roles { - weight, err := cosmostypes.NewDecFromStr(role.Weight) - if err != nil { - return nil, err - } - weightedRole := spendingtypes.WeightedRole{ - Role: role.Role, - Weight: weight, - } - beneficiaries.Roles = append(beneficiaries.Roles, weightedRole) - } - - msg = spendingtypes.NewMsgCreateSpendingPool(poolParam.Name, poolParam.ClaimStart, poolParam.ClaimEnd, rates, - poolParam.VoteQuorum, poolParam.VotePeriod, poolParam.VoteEnactment, poolParam.Owners, beneficiaries, - sender, poolParam.IsDynamicRate, poolParam.DynamicRatePeriod) - case MsgDepositSpendingPool: - // V, R, S, signer, amount string, name string - sender, err := bytes2cosmosAddr(params[3][12:]) - if err != nil { - return nil, err - } - - var poolParam SpendingPoolParam - err = json.Unmarshal(params[4], &poolParam) - if err != nil { - return nil, err - } - - amounts, err := cosmostypes.ParseCoinsNormalized(poolParam.Amounts) - if err != nil { - return nil, err - } - - msg = spendingtypes.NewMsgDepositSpendingPool(poolParam.Name, amounts, sender) - case MsgRegisterSpendingPoolBeneficiary: - // V, R, S, signer, name string - sender, err := bytes2cosmosAddr(params[3][12:]) - if err != nil { - return nil, err - } - - var poolParam SpendingPoolParam - err = json.Unmarshal(params[4], &poolParam) - if err != nil { - return nil, err - } - - msg = spendingtypes.NewMsgRegisterSpendingPoolBeneficiary(poolParam.Name, sender) - case MsgClaimSpendingPool: - // V, R, S, signer, name string - sender, err := bytes2cosmosAddr(params[3][12:]) - if err != nil { - return nil, err - } - - var poolParam SpendingPoolParam - err = json.Unmarshal(params[4], &poolParam) - if err != nil { - return nil, err - } - - msg = spendingtypes.NewMsgClaimSpendingPool(poolParam.Name, sender) - case MsgUpsertStakingPool: - // V, R, S, signer, enabled bool, validator string, commission cosmostypes.Dec - from, err := hex2bech32(hex.EncodeToString(params[3][12:]), TypeKiraAddr) - if err != nil { - return nil, err - } - - type StakingPoolParam struct { - Validator string `json:"validator"` - Enabled bool `json:"enabled"` - Commission string `json:"commission"` - } - - var poolParam StakingPoolParam - err = json.Unmarshal(params[4], &poolParam) - if err != nil { - return nil, err - } - - commission, err := cosmostypes.NewDecFromStr(poolParam.Commission) - if err != nil { - return nil, err - } - - msg = multistakingtypes.NewMsgUpsertStakingPool(from, poolParam.Validator, poolParam.Enabled, commission) - case MsgDelegate: - // V, R, S, signer, param - from, err := hex2bech32(hex.EncodeToString(params[3][12:]), TypeKiraAddr) - if err != nil { - return nil, err - } - - var delegateParam DelegateParam - err = json.Unmarshal(params[4], &delegateParam) - if err != nil { - return nil, err - } - - amounts, err := cosmostypes.ParseCoinsNormalized(delegateParam.Amounts) - if err != nil { - return nil, err - } - - msg = multistakingtypes.NewMsgDelegate(from, delegateParam.To, amounts) - case MsgUndelegate: - // V, R, S, signer, amount, validator - from, err := hex2bech32(hex.EncodeToString(params[3][12:]), TypeKiraAddr) - if err != nil { - return nil, err - } - - var delegateParam DelegateParam - err = json.Unmarshal(params[4], &delegateParam) - if err != nil { - return nil, err - } - - amounts, err := cosmostypes.ParseCoinsNormalized(delegateParam.Amounts) - if err != nil { - return nil, err - } - - msg = multistakingtypes.NewMsgUndelegate(from, delegateParam.To, amounts) - case MsgClaimRewards: - // V, R, S, signer - from, err := hex2bech32(hex.EncodeToString(params[3][12:]), TypeKiraAddr) - if err != nil { - return nil, err - } - msg = multistakingtypes.NewMsgClaimRewards(from) - case MsgClaimUndelegation: - // V, R, S, signer, undelegationId uint64 - from, err := hex2bech32(hex.EncodeToString(params[3][12:]), TypeKiraAddr) - if err != nil { - return nil, err - } - - type UndelegationParam struct { - UndelegationId uint64 `json:"undelegation_id"` - } - - var undelegationParam UndelegationParam - err = json.Unmarshal(params[4], &undelegationParam) - if err != nil { - return nil, err - } - - msg = multistakingtypes.NewMsgClaimUndelegation(from, undelegationParam.UndelegationId) - case MsgSetCompoundInfo: - // V, R, S, signer, allDenom bool, len, denoms []string - from, err := hex2bech32(hex.EncodeToString(params[3][12:]), TypeKiraAddr) - if err != nil { - return nil, err - } - - type UndelegationParam struct { - IsAllDenom bool `json:"is_all_denom"` - Denoms []string `json:"denoms"` - } - - var undelegationParam UndelegationParam - err = json.Unmarshal(params[4], &undelegationParam) - if err != nil { - return nil, err - } - - msg = multistakingtypes.NewMsgSetCompoundInfo(from, undelegationParam.IsAllDenom, undelegationParam.Denoms) - case MsgRegisterDelegator: - // V, R, S, signer - from, err := hex2bech32(hex.EncodeToString(params[3][12:]), TypeKiraAddr) - if err != nil { - return nil, err - } - - msg = multistakingtypes.NewMsgRegisterDelegator(from) - case MsgCreateCustody: - // V, R, S, signer, custodyMode uint256, key string, nextController string, len, boolArr, len, strArr - from, err := bytes2cosmosAddr(params[3][12:]) - if err != nil { - return nil, err - } - - type CustodyParam struct { - CustodySettings custodytypes.CustodySettings `json:"custody_settings"` - OldKey string `json:"old_key"` - NewKey string `json:"new_key"` - Next string `json:"next"` - Target string `json:"target"` - } - - var custodyParam CustodyParam - err = json.Unmarshal(params[4], &custodyParam) - if err != nil { - return nil, err - } - - msg = custodytypes.NewMsgCreateCustody(from, custodyParam.CustodySettings, custodyParam.OldKey, custodyParam.NewKey, - custodyParam.Next, custodyParam.Target) - case MsgAddToCustodyWhiteList: - // V, R, S, signer, oldKey string, newKey string, next string, target string - // len, newAddr []string, - from, err := bytes2cosmosAddr(params[3][12:]) - if err != nil { - return nil, err - } - - var custodyParam CustodianParam - err = json.Unmarshal(params[4], &custodyParam) - if err != nil { - return nil, err - } - - var newAddrs []cosmostypes.AccAddress - for _, addrStr := range custodyParam.NewAddrs { - addr, err := cosmostypes.AccAddressFromBech32(addrStr) - if err != nil { - return nil, err - } - newAddrs = append(newAddrs, addr) - } - - msg = custodytypes.NewMsgAddToCustodyWhiteList(from, newAddrs, custodyParam.OldKey, custodyParam.NewKey, - custodyParam.Next, custodyParam.Target) - case MsgAddToCustodyCustodians: - // V, R, S, signer, oldKey string, newKey string, next string, target string - // len, newAddr []string - from, err := bytes2cosmosAddr(params[3][12:]) - if err != nil { - return nil, err - } - - var custodyParam CustodianParam - err = json.Unmarshal(params[4], &custodyParam) - if err != nil { - return nil, err - } - - var newAddrs []cosmostypes.AccAddress - for _, addrStr := range custodyParam.NewAddrs { - addr, err := cosmostypes.AccAddressFromBech32(addrStr) - if err != nil { - return nil, err - } - newAddrs = append(newAddrs, addr) - } - - msg = custodytypes.NewMsgAddToCustodyCustodians(from, newAddrs, custodyParam.OldKey, custodyParam.NewKey, - custodyParam.Next, custodyParam.Target) - case MsgRemoveFromCustodyCustodians: - // V, R, S, signer, newAddr cosmostypes.AccAddress, - // oldKey string, newKey string, next string, target string - from, err := bytes2cosmosAddr(params[3][12:]) - if err != nil { - return nil, err - } - - var custodyParam SingleCustodianParam - err = json.Unmarshal(params[4], &custodyParam) - if err != nil { - return nil, err - } - - newAddr, err := cosmostypes.AccAddressFromBech32(custodyParam.NewAddr) - if err != nil { - return nil, err - } - - msg = custodytypes.NewMsgRemoveFromCustodyCustodians(from, newAddr, custodyParam.OldKey, custodyParam.NewKey, - custodyParam.Next, custodyParam.Target) - case MsgDropCustodyCustodians: - // V, R, S, signer - // oldKey string, newKey string, next string, target string - from, err := bytes2cosmosAddr(params[3][12:]) - if err != nil { - return nil, err - } - - var custodyParam CustodianParam - err = json.Unmarshal(params[4], &custodyParam) - if err != nil { - return nil, err - } - - msg = custodytypes.NewMsgDropCustodyCustodians(from, custodyParam.OldKey, custodyParam.NewKey, - custodyParam.Next, custodyParam.Target) - case MsgRemoveFromCustodyWhiteList: - // V, R, S, signer, newAddr string, - // oldKey string, newKey string, next string, target string - from, err := bytes2cosmosAddr(params[3][12:]) - if err != nil { - return nil, err - } - - var custodyParam SingleCustodianParam - err = json.Unmarshal(params[4], &custodyParam) - if err != nil { - return nil, err - } - - newAddr, err := cosmostypes.AccAddressFromBech32(custodyParam.NewAddr) - if err != nil { - return nil, err - } - - msg = custodytypes.NewMsgRemoveFromCustodyWhiteList(from, newAddr, custodyParam.OldKey, custodyParam.NewKey, - custodyParam.Next, custodyParam.Target) - case MsgDropCustodyWhiteList: - // V, R, S, signer - // oldKey string, newKey string, next string, target string - from, err := bytes2cosmosAddr(params[3][12:]) - if err != nil { - return nil, err - } - - var custodyParam CustodianParam - err = json.Unmarshal(params[4], &custodyParam) - if err != nil { - return nil, err - } - - msg = custodytypes.NewMsgDropCustodyWhiteList(from, custodyParam.OldKey, custodyParam.NewKey, - custodyParam.Next, custodyParam.Target) - case MsgApproveCustodyTx: - // V, R, S, signer, to string, hash string - from, err := bytes2cosmosAddr(params[3][12:]) - if err != nil { - return nil, err - } - - var custodyParam CustodyParam - err = json.Unmarshal(params[4], &custodyParam) - if err != nil { - return nil, err - } - - to, err := cosmostypes.AccAddressFromBech32(custodyParam.To) - if err != nil { - return nil, err - } - - msg = custodytypes.NewMsgApproveCustodyTransaction(from, to, custodyParam.Hash) - case MsgDeclineCustodyTx: - // V, R, S, signer, to string, hash string - from, err := bytes2cosmosAddr(params[3][12:]) - if err != nil { - return nil, err - } - - var custodyParam CustodyParam - err = json.Unmarshal(params[4], &custodyParam) - if err != nil { - return nil, err - } - - to, err := cosmostypes.AccAddressFromBech32(custodyParam.To) - if err != nil { - return nil, err - } - - msg = custodytypes.NewMsgDeclineCustodyTransaction(from, to, custodyParam.Hash) - } - - // fmt.Println(msg) - err = txBuilder.SetMsgs(msg) - if err != nil { - return nil, err - } - txBuilder.SetGasLimit(ethTxData.GasLimit) - // TODO: set fee amount - how can I get the fee amount from eth tx? or fix this? - txBuilder.SetFeeAmount(cosmostypes.NewCoins(cosmostypes.NewInt64Coin(config.DefaultKiraDenom, 200))) - // txBuilder.SetMemo() - // txBuilder.SetTimeoutHeight() - // txHash, err := sendTx(context.Background(), byteData) - - accNum, _ := common.GetAccountNumberSequence(gwCosmosmux, r, addr1) - - privs := []cryptotypes.PrivKey{config.Config.PrivKey} - accNums := []uint64{accNum} // The accounts' account numbers - accSeqs := []uint64{ethTxData.Nonce} // The accounts' sequence numbers - - // First round: gather all the signer infos - var sigsV2 []signing.SignatureV2 - for i, priv := range privs { - sigV2 := signing.SignatureV2{ - PubKey: priv.PubKey(), - Data: &signing.SingleSignatureData{ - SignMode: config.EncodingCg.TxConfig.SignModeHandler().DefaultMode(), - Signature: nil, - }, - Sequence: accSeqs[i], - } - - sigsV2 = append(sigsV2, sigV2) - } - - err = txBuilder.SetSignatures(sigsV2...) - if err != nil { - return nil, err - } - - interxStatus := common.GetInterxStatus("http://127.0.0.1:11000") - - // Second round: all signer infos are set, so each signer can sign. - sigsV2 = []signing.SignatureV2{} - for i, priv := range privs { - signerData := xauthsigning.SignerData{ - ChainID: interxStatus.InterxInfo.ChainID, - AccountNumber: accNums[i], - Sequence: accSeqs[i], - } - sigV2, err := clienttx.SignWithPrivKey( - config.EncodingCg.TxConfig.SignModeHandler().DefaultMode(), signerData, - txBuilder, priv, config.EncodingCg.TxConfig, accSeqs[i]) - if err != nil { - return nil, err - } - - sigsV2 = append(sigsV2, sigV2) - } - err = txBuilder.SetSignatures(sigsV2...) - if err != nil { - return nil, err - } - - txBytes, err := config.EncodingCg.TxConfig.TxEncoder()(txBuilder.GetTx()) - if err != nil { - return nil, err - } - - return txBytes, err -} diff --git a/go.mod b/go.mod index d615da3..c7bf699 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.19 require ( cosmossdk.io/math v1.2.0 github.com/KeisukeYamashita/go-jsonrpc v1.0.1 - github.com/KiraCore/sekai v0.3.38 + github.com/KiraCore/sekai v0.3.46-0.20240514123010-1b8573dfe96c github.com/btcsuite/btcd v0.22.1 github.com/cometbft/cometbft v0.37.2 github.com/cosmos/cosmos-proto v1.0.0-beta.2 @@ -170,4 +170,3 @@ require ( ) replace github.com/syndtr/goleveldb => github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 - diff --git a/go.sum b/go.sum index 7fef56c..bb25c90 100644 --- a/go.sum +++ b/go.sum @@ -64,8 +64,8 @@ github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d/go.mod h1: github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/KeisukeYamashita/go-jsonrpc v1.0.1 h1:mkg8th2I7C1y3tnAsxroQbmQcXEZ22AkQ5pazRd/KDM= github.com/KeisukeYamashita/go-jsonrpc v1.0.1/go.mod h1:NyiYd1oDwaSsIflCju5dKRvLdG5rZ/I4E07ygRYYmgc= -github.com/KiraCore/sekai v0.3.38 h1:Z0DLYxu4nY9sWnTfQs10bYLq7ZQDhoZmwkUOWSQEWfo= -github.com/KiraCore/sekai v0.3.38/go.mod h1:4lJS3LLWUl+bZwD9Mdl/vsYerMKOJMITx8ftepF80Ug= +github.com/KiraCore/sekai v0.3.46-0.20240514123010-1b8573dfe96c h1:dYb6PmGqa6Ry/xtGCmrLh5XDcPtRlN129CBmbAQQdc4= +github.com/KiraCore/sekai v0.3.46-0.20240514123010-1b8573dfe96c/go.mod h1:SlwwQqlw20qPR35Iuyd3gzv2vOQIawk6RZUrEU/Y8W4= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg= github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw= From 25d3a7f99a9bdf505ea8be75cd7aadb7e0c8dcac Mon Sep 17 00:00:00 2001 From: tj327 Date: Thu, 23 May 2024 20:36:38 -0400 Subject: [PATCH 14/25] fix gov test --- gateway/kira/gov_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gateway/kira/gov_test.go b/gateway/kira/gov_test.go index 2b5471d..bb222a1 100644 --- a/gateway/kira/gov_test.go +++ b/gateway/kira/gov_test.go @@ -12,6 +12,7 @@ import ( "os" "testing" + "cosmossdk.io/math" "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" "github.com/KiraCore/interx/config" @@ -138,7 +139,7 @@ func (s *govServer) NetworkProperties(ctx context.Context, in *govTypes.NetworkP Properties: &govTypes.NetworkProperties{ MinTxFee: 777, MaxTxFee: 888, - VoteQuorum: 999, + VoteQuorum: math.LegacyNewDecWithPrec(33, 2), }, }, nil } From 8c892e69a846021a052368629faa70d21121f205 Mon Sep 17 00:00:00 2001 From: tj327 Date: Thu, 23 May 2024 21:05:37 -0400 Subject: [PATCH 15/25] integration test fix --- scripts/test-local/Proposal/query-proposal-by-id.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/scripts/test-local/Proposal/query-proposal-by-id.sh b/scripts/test-local/Proposal/query-proposal-by-id.sh index 7a91295..ab0d511 100755 --- a/scripts/test-local/Proposal/query-proposal-by-id.sh +++ b/scripts/test-local/Proposal/query-proposal-by-id.sh @@ -15,14 +15,15 @@ sleep 5 INTERX_GATEWAY="127.0.0.1:11000" PROPOSAL_ID_INTERX=$(curl --fail "$INTERX_GATEWAY/api/kira/gov/proposals" | jq '.proposals[0].proposal_id' | tr -d '"' || exit 1) RESULT_INTERX=$(curl --fail $INTERX_GATEWAY/api/kira/gov/proposals/$PROPOSAL_ID_INTERX || exit 1) +echo $RESULT_INTERX DESCRIPTION_INTERX=$(echo $RESULT_INTERX | jq '.proposal.content.messages[0]') QUORUM_INTERX=$(echo $RESULT_INTERX | jq '.proposal.quorum' | tr -d '"') -QUORUM_INTERX=$(printf "%.0f" "$(echo "$QUORUM_INTERX * 100" | bc)") +QUORUM_INTERX=$(printf "%.12f000000" "$(echo "$QUORUM_INTERX" | bc)") DESCRIPTION_CLI=$(showProposal $PROPOSAL_ID_INTERX | jq '.content.messages[0]') QUORUM_CLI=$(showNetworkProperties | jq '.properties.vote_quorum' | tr -d '"' || exit 1) [[ $DESCRIPTION_INTERX != $DESCRIPTION_CLI ]] && echoErr "ERROR: Expected proposal description to be '$DESCRIPTION_CLI', but got '$DESCRIPTION_INTERX'" && exit 1 -[[ $QUORUM_INTERX != $QUORUM_CLI ]] && echoErr "ERROR: Expected proposal description to be '$QUORUM_CLI', but got '$QUORUM_INTERX'" && exit 1 +[[ $QUORUM_INTERX != $QUORUM_CLI ]] && echoErr "ERROR: Expected proposal quorum to be '$QUORUM_CLI', but got '$QUORUM_INTERX'" && exit 1 echoInfo "INFO: $TEST_NAME - Integration Test - END, elapsed: $(prettyTime $(timerSpan $TEST_NAME))" \ No newline at end of file From e3478796998f6ed2e12877235b73e6f497e4160d Mon Sep 17 00:00:00 2001 From: tj327 Date: Thu, 23 May 2024 22:02:05 -0400 Subject: [PATCH 16/25] fix cached quorum calculation --- tasks/proposals.go | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/tasks/proposals.go b/tasks/proposals.go index eb81a5d..0a96a74 100644 --- a/tasks/proposals.go +++ b/tasks/proposals.go @@ -219,12 +219,7 @@ func GetCachedProposals(gwCosmosmux *runtime.ServeMux, gatewayAddr string, rpcAd } if result["properties"] != nil { - quorum, err := strconv.Atoi(result["properties"]["voteQuorum"].(string)) - if err != nil { - return nil, err - } - - quorumStr = fmt.Sprintf("%.2f", float64(quorum)/100) + quorumStr = result["properties"]["voteQuorum"].(string) } } From ba1f0030a989bcfe558d3d534449ced3fd75572f Mon Sep 17 00:00:00 2001 From: tj327 Date: Thu, 23 May 2024 22:21:11 -0400 Subject: [PATCH 17/25] decimal parsing fix --- tasks/proposals.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tasks/proposals.go b/tasks/proposals.go index 0a96a74..57d49fe 100644 --- a/tasks/proposals.go +++ b/tasks/proposals.go @@ -10,6 +10,7 @@ import ( "strings" "time" + "cosmossdk.io/math" "github.com/KiraCore/interx/common" "github.com/KiraCore/interx/config" "github.com/KiraCore/interx/database" @@ -219,7 +220,12 @@ func GetCachedProposals(gwCosmosmux *runtime.ServeMux, gatewayAddr string, rpcAd } if result["properties"] != nil { - quorumStr = result["properties"]["voteQuorum"].(string) + str := result["properties"]["voteQuorum"].(string) + quorumInt, ok := math.NewIntFromString(str) + if !ok { + return nil, fmt.Errorf("Not able to parse: %s", str) + } + quorumStr = math.LegacyNewDecFromIntWithPrec(quorumInt, 18).String() } } From 27794c6cdfcbe4bad44147ca97d25ad5b6ecc41c Mon Sep 17 00:00:00 2001 From: golnar-boosty Date: Tue, 19 Nov 2024 18:11:41 +0000 Subject: [PATCH 18/25] Test commit with GPG signing --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 7d6eaad..305e976 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # INTERX +For test INTERX is an interchain engine, proxy, load balancer & security gateway service for communication between backend and frontend. It will connect to the node using the GRPC endpoint as well as the RPC endpoint ([`Tendermint RPC`](https://docs.tendermint.com/master/rpc/)). @@ -509,4 +510,4 @@ Remember this settings when you set/update manually from `config.json`. ### How to update caching configurations All caching configurations are set in `config.json` file. -`config.json` file includes `rpc_methods` field and there you can set/update caching config of each endpoint. \ No newline at end of file +`config.json` file includes `rpc_methods` field and there you can set/update caching config of each endpoint. From 0811c45531c5d700de14ad64db8c160f10fc4219 Mon Sep 17 00:00:00 2001 From: golnar-boosty Date: Thu, 21 Nov 2024 17:12:54 +0000 Subject: [PATCH 19/25] feat(utils): add utility function to construct tx_search endpoint. Added a function to simplify the creation of tx_search endpoint URLs. This utility takes the RPC address, query, pagination parameters, and order criteria as input, and returns a well-formatted endpoint string. --- common/gateway.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/common/gateway.go b/common/gateway.go index 69c7155..0d7be12 100644 --- a/common/gateway.go +++ b/common/gateway.go @@ -3,6 +3,7 @@ package common import ( "encoding/base64" "encoding/json" + "fmt" "io/ioutil" "net/http" "net/http/httptest" @@ -344,3 +345,9 @@ func RosettaBuildError(code int, message string, description string, retriable b func RosettaServeError(code int, data string, message string, statusCode int) (interface{}, interface{}, int) { return nil, RosettaBuildError(code, message, data, true, nil), statusCode } + +// BuildTxSearchEndpoint creates a tx_search endpoint. +func BuildTxSearchEndpoint(rpcAddr string, query string, page int, limit int, orderBy string) string { + return fmt.Sprintf("%s/tx_search?query=\"%s\"&page=%d&per_page=%d&order_by=\"%s\"", + rpcAddr, query, page, limit, orderBy) +} From 4a6e29a5b00628d96759936c993deef1b6685b83 Mon Sep 17 00:00:00 2001 From: golnar-boosty Date: Thu, 21 Nov 2024 17:18:25 +0000 Subject: [PATCH 20/25] feat(types): add height field to TransactionResponse and TxsResponse struct. - Added a field to the struct to include the block height in transaction details. - Introduced a new struct for wrapping multiple transactions with a total count, enhancing API response consistency. This change improves the API structure by providing more granular transaction information and supporting batch responses effectively. --- types/main.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/types/main.go b/types/main.go index a7490fc..5656f54 100644 --- a/types/main.go +++ b/types/main.go @@ -76,6 +76,7 @@ type ResponseSign struct { type TransactionResponse struct { Time int64 `json:"time"` Hash string `json:"hash"` + Height int64 `json:"height"` Status string `json:"status"` Direction string `json:"direction"` Memo string `json:"memo"` @@ -337,3 +338,8 @@ const ( // POST is a constant to refer POST HTTP Method POST string = "POST" ) + +type TxsResponse struct { + Transactions []TransactionResponse `json:"transactions"` + TotalCount int `json:"total_count"` +} From 2b01ca5413a2b67ed2a61933422050773d9720fc Mon Sep 17 00:00:00 2001 From: golnar-boosty Date: Thu, 21 Nov 2024 17:52:25 +0000 Subject: [PATCH 21/25] chore(dependencies): update cosmossdk.io/math to direct dependency.- Added as a direct dependency in . - Removed its previous listing as an indirect dependency. This change ensures the package is explicitly managed, improving dependency clarity and avoiding potential issues with transitive dependency resolution. --- go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 3664ca9..9754d02 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module github.com/KiraCore/interx go 1.19 require ( + cosmossdk.io/math v1.2.0 github.com/KeisukeYamashita/go-jsonrpc v1.0.1 github.com/KiraCore/sekai v0.3.38 github.com/btcsuite/btcd v0.22.1 @@ -35,7 +36,6 @@ require ( cosmossdk.io/depinject v1.0.0-alpha.4 // indirect cosmossdk.io/errors v1.0.0 // indirect cosmossdk.io/log v1.2.1 // indirect - cosmossdk.io/math v1.2.0 // indirect cosmossdk.io/tools/rosetta v0.2.1 // indirect filippo.io/edwards25519 v1.0.0 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect From e3eeed2ce24e6ccd7301bb311e0704d71f62a0e2 Mon Sep 17 00:00:00 2001 From: golnar-boosty Date: Thu, 21 Nov 2024 17:57:23 +0000 Subject: [PATCH 22/25] feat(tests): enhance transaction test suite and add block height retrieval.Updated interx.tx_test.go to use types.TxsResponse instead of TxsResponse for consistency with the types package. Added getBlockHeight function to retrieve block height for a transaction hash from cache or Tendermint. Improved error handling and logging in getBlockHeight. --- gateway/interx/interx.tx_test.go | 41 ++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/gateway/interx/interx.tx_test.go b/gateway/interx/interx.tx_test.go index b4f32ce..b9cf0b4 100644 --- a/gateway/interx/interx.tx_test.go +++ b/gateway/interx/interx.tx_test.go @@ -2,12 +2,16 @@ package interx import ( "encoding/json" + "errors" + "fmt" + "io/ioutil" "net/http" "net/http/httptest" "os" "testing" "time" + "github.com/KiraCore/interx/common" "github.com/KiraCore/interx/config" "github.com/KiraCore/interx/database" "github.com/KiraCore/interx/test" @@ -96,7 +100,7 @@ func (suite *InterxTxTestSuite) TestBlockTransactionsHandler() { suite.Assert() } - resultTxSearch := TxsResponse{} + resultTxSearch := types.TxsResponse{} err = json.Unmarshal(suite.blockTransactionsQueryResponse.Result, &resultTxSearch) suite.Require().NoError(err) suite.Require().EqualValues(result.TotalCount, resultTxSearch.TotalCount) @@ -140,7 +144,7 @@ func TestInterxTxTestSuite(t *testing.T) { txMsg := make(map[string]interface{}) txMsg["type"] = "send" - resBytes, err = json.Marshal(TxsResponse{ + resBytes, err = json.Marshal(types.TxsResponse{ TotalCount: 1, Transactions: []types.TransactionResponse{ { @@ -229,3 +233,36 @@ func TestInterxTxTestSuite(t *testing.T) { tendermintServer.Close() } + +// Get block height for tx hash from cache or tendermint +func getBlockHeight(rpcAddr string, hash string) (int64, error) { + endpoint := fmt.Sprintf("%s/tx?hash=%s", rpcAddr, hash) + common.GetLogger().Info("[query-block] Entering block query: ", endpoint) + + resp, err := http.Get(endpoint) + if err != nil { + common.GetLogger().Error("[query-block] Unable to connect to ", endpoint) + return 0, err + } + defer resp.Body.Close() + + respBody, _ := ioutil.ReadAll(resp.Body) + response := new(tmJsonRPCTypes.RPCResponse) + + if err := json.Unmarshal(respBody, response); err != nil { + common.GetLogger().Error("[query-block] Unable to decode response: ", err) + return 0, err + } + if response.Error != nil { + common.GetLogger().Error("[query-block] Error response:", response.Error.Message) + return 0, errors.New(response.Error.Message) + } + + result := new(tmRPCTypes.ResultTx) + if err := tmjson.Unmarshal(response.Result, result); err != nil { + common.GetLogger().Error("[query-block] Failed to unmarshal result:", err) + return 0, fmt.Errorf("error unmarshalling result: %w", err) + } + + return result.Height, nil +} From a0ab5728c87b10c6ba7bf20360fe4f12b92146d3 Mon Sep 17 00:00:00 2001 From: golnar-boosty Date: Thu, 21 Nov 2024 18:00:45 +0000 Subject: [PATCH 23/25] refactor(database): enhance transaction file path logic and caching behavior. Refactored GetTransactions to simplify file path construction using basePath and suffix. Added a new resolveFileName helper function to centralize file name determination logic. Updated SaveTransactions to use resolveFileName, improving readability and maintainability. Improved conditional handling in SaveTransactions to append cached transactions only when an address is provided. Enhanced error logging with more descriptive messages in SaveTransactions. --- database/transactions.go | 46 +++++++++++++++++++++++++++++----------- 1 file changed, 34 insertions(+), 12 deletions(-) diff --git a/database/transactions.go b/database/transactions.go index 5b0dbf0..071e0dd 100644 --- a/database/transactions.go +++ b/database/transactions.go @@ -13,9 +13,18 @@ import ( // GetTransactions is a function to get user transactions from cache func GetTransactions(address string, isWithdraw bool) (*tmTypes.ResultTxSearch, error) { - filePath := fmt.Sprintf("%s/transactions/%s", config.GetDbCacheDir(), address) - if !isWithdraw { - filePath = filePath + "-inbound" + var filePath string + + basePath := fmt.Sprintf("%s/transactions", config.GetDbCacheDir()) + suffix := "-inbound" + if isWithdraw { + suffix = "" + } + + if address == "" { + filePath = fmt.Sprintf("%s/all-transactions%s", basePath, suffix) + } else { + filePath = fmt.Sprintf("%s/%s%s", basePath, address, suffix) } data := tmTypes.ResultTxSearch{} @@ -55,10 +64,12 @@ func GetLastBlockFetched(address string, isWithdraw bool) int64 { func SaveTransactions(address string, txsData tmTypes.ResultTxSearch, isWithdraw bool) error { cachedData, _ := GetTransactions(address, isWithdraw) - // Append new txs to the cached txs array - if cachedData.TotalCount > 0 { - txsData.Txs = append(txsData.Txs, cachedData.Txs...) - txsData.TotalCount = txsData.TotalCount + cachedData.TotalCount + if address != "" { + // Append new txs to the cached txs array + if cachedData.TotalCount > 0 { + txsData.Txs = append(txsData.Txs, cachedData.Txs...) + txsData.TotalCount = txsData.TotalCount + cachedData.TotalCount + } } data, err := json.Marshal(txsData) @@ -67,10 +78,8 @@ func SaveTransactions(address string, txsData tmTypes.ResultTxSearch, isWithdraw } folderPath := fmt.Sprintf("%s/transactions", config.GetDbCacheDir()) - filePath := fmt.Sprintf("%s/%s", folderPath, address) - if !isWithdraw { - filePath = filePath + "-inbound" - } + fileName := resolveFileName(address, isWithdraw) + filePath := fmt.Sprintf("%s/%s", folderPath, fileName) global.Mutex.Lock() err = os.MkdirAll(folderPath, os.ModePerm) @@ -85,8 +94,21 @@ func SaveTransactions(address string, txsData tmTypes.ResultTxSearch, isWithdraw global.Mutex.Unlock() if err != nil { - fmt.Println("[cache] Unable to save response: ", filePath) + fmt.Println("[SaveTransactions][cache] Unable to save response: ", filePath) } return err } + +// Helper function to determine the file name +func resolveFileName(address string, isWithdraw bool) string { + if address == "" { + address = "all-transactions" + } + + if !isWithdraw { + return fmt.Sprintf("%s-inbound", address) + } + + return address +} From aaa1a972bc26139426dff9eee7a66e05dcfd0ae0 Mon Sep 17 00:00:00 2001 From: golnar-boosty Date: Thu, 21 Nov 2024 18:04:22 +0000 Subject: [PATCH 24/25] refactor(interx): improve transaction handling and direction processing.Removed the redundant TxsResponse definition and replaced it with types.TxsResponse for consistency.Refactored GetTransactionsWithSync. Consolidated outbound and inbound logic with improved query construction.Eliminated unnecessary checks for empty addresses.Replaced repetitive endpoint construction with BuildTxSearchEndpoint. Simplified GetFilteredTransactions.Introduced processDirection to handle direction-specific logic modularly.Removed redundant loops and conditions for processing inbound and outbound transactions.Added processDirection as a reusable function for transaction direction handling.Enhanced QueryBlockTransactionsHandler.Removed redundant address validation.Updated responses to use types.TxsResponse for consistency.Removed the obsolete getBlockHeight function, as it is no longer needed. --- gateway/interx/interx.tx.go | 122 +++++++++++++++--------------------- 1 file changed, 49 insertions(+), 73 deletions(-) diff --git a/gateway/interx/interx.tx.go b/gateway/interx/interx.tx.go index 7d72a49..5d41296 100644 --- a/gateway/interx/interx.tx.go +++ b/gateway/interx/interx.tx.go @@ -26,11 +26,6 @@ import ( "golang.org/x/exp/slices" ) -type TxsResponse struct { - Transactions []types.TransactionResponse `json:"transactions"` - TotalCount int `json:"total_count"` -} - // RegisterInterxTxRoutes registers tx query routers. func RegisterInterxTxRoutes(r *mux.Router, gwCosmosmux *runtime.ServeMux, rpcAddr string) { r.HandleFunc(config.QueryUnconfirmedTxs, QueryUnconfirmedTxs(rpcAddr)).Methods("GET") @@ -47,10 +42,6 @@ func GetTransactionsWithSync(rpcAddr string, address string, isOutbound bool) (* var limit = 100 var limitPages = 100 - if address == "" { - return &tmTypes.ResultTxSearch{}, nil - } - lastBlock := database.GetLastBlockFetched(address, isOutbound) totalResult := tmTypes.ResultTxSearch{ Txs: []*tmTypes.ResultTx{}, @@ -59,15 +50,23 @@ func GetTransactionsWithSync(rpcAddr string, address string, isOutbound bool) (* for page < limitPages { var events = make([]string, 0, 5) - if isOutbound { - events = append(events, fmt.Sprintf("message.sender='%s'", address)) + if address != "" { + if isOutbound { + events = append(events, fmt.Sprintf("message.sender='%s'", address)) + } else { + events = append(events, fmt.Sprintf("transfer.recipient='%s'", address)) + } + events = append(events, fmt.Sprintf("tx.height>%d", lastBlock)) + } + + var query string + if address == "" { + query = "tx.height>0" } else { - events = append(events, fmt.Sprintf("transfer.recipient='%s'", address)) + query = strings.Join(events, "%20AND%20") } - events = append(events, fmt.Sprintf("tx.height>%d", lastBlock)) - // search transactions - endpoint := fmt.Sprintf("%s/tx_search?query=\"%s\"&page=%d&per_page=%d&order_by=\"desc\"", rpcAddr, strings.Join(events, "%20AND%20"), page, limit) + endpoint := common.BuildTxSearchEndpoint(rpcAddr, query, page, limit, "desc") common.GetLogger().Info("[query-transaction] Entering transaction search: ", endpoint) resp, err := http.Get(endpoint) @@ -131,31 +130,23 @@ func GetFilteredTransactions(rpcAddr string, address string, txtypes []string, d Txs: []*tmTypes.ResultTx{}, TotalCount: 0, } + if len(directions) == 0 { directions = []string{"inbound", "outbound"} } - if slices.Contains(directions, "inbound") { - cachedTxs1, err := GetTransactionsWithSync(rpcAddr, address, false) - for _, cachedTx := range cachedTxs1.Txs { - hashToDirectionMap[cachedTx.Hash.String()] = append(hashToDirectionMap[cachedTx.Hash.String()], "inbound") - } - if err != nil { - return nil, err - } - cachedTxs.TotalCount += cachedTxs1.TotalCount - cachedTxs.Txs = append(cachedTxs.Txs, cachedTxs1.Txs...) - } - if slices.Contains(directions, "outbound") { - cachedTxs2, err := GetTransactionsWithSync(rpcAddr, address, true) - for _, cachedTx := range cachedTxs2.Txs { - hashToDirectionMap[cachedTx.Hash.String()] = append(hashToDirectionMap[cachedTx.Hash.String()], "outbound") - } - if err != nil { - return nil, err + if address != "" { + for _, direction := range directions { + switch direction { + case "inbound": + cachedTxs, _ = processDirection(rpcAddr, address, false, "inbound", hashToDirectionMap, &cachedTxs) + + case "outbound": + cachedTxs, _ = processDirection(rpcAddr, address, true, "outbound", hashToDirectionMap, &cachedTxs) + } } - cachedTxs.TotalCount += cachedTxs2.TotalCount - cachedTxs.Txs = append(cachedTxs.Txs, cachedTxs2.Txs...) + } else { + cachedTxs, _ = processDirection(rpcAddr, address, true, "outbound", hashToDirectionMap, &cachedTxs) } var res []types.TransactionResponse @@ -224,6 +215,7 @@ func GetFilteredTransactions(rpcAddr string, address string, txtypes []string, d Status: hashStatus, Direction: hashToDirectionMap[cachedTx.Hash.String()][0], Hash: fmt.Sprintf("0x%X", cachedTx.Hash), + Height: cachedTx.Height, Txs: txResponses, } if len(hashToDirectionMap[cachedTx.Hash.String()]) > 1 { @@ -306,39 +298,6 @@ func SearchTxHashHandle(rpcAddr string, sender string, recipient string, txType return result, nil } -// Get block height for tx hash from cache or tendermint -func getBlockHeight(rpcAddr string, hash string) (int64, error) { - endpoint := fmt.Sprintf("%s/tx?hash=%s", rpcAddr, hash) - common.GetLogger().Info("[query-block] Entering block query: ", endpoint) - - resp, err := http.Get(endpoint) - if err != nil { - common.GetLogger().Error("[query-block] Unable to connect to ", endpoint) - return 0, err - } - defer resp.Body.Close() - - respBody, _ := ioutil.ReadAll(resp.Body) - response := new(tmJsonRPCTypes.RPCResponse) - - if err := json.Unmarshal(respBody, response); err != nil { - common.GetLogger().Error("[query-block] Unable to decode response: ", err) - return 0, err - } - if response.Error != nil { - common.GetLogger().Error("[query-block] Error response:", response.Error.Message) - return 0, errors.New(response.Error.Message) - } - - result := new(tmTypes.ResultTx) - if err := tmjson.Unmarshal(response.Result, result); err != nil { - common.GetLogger().Error("[query-block] Failed to unmarshal result:", err) - return 0, fmt.Errorf("error unmarshalling result: %w", err) - } - - return result.Height, nil -} - func QueryBlockTransactionsHandler(rpcAddr string, r *http.Request) (interface{}, interface{}, int) { err := r.ParseForm() if err != nil { @@ -371,10 +330,6 @@ func QueryBlockTransactionsHandler(rpcAddr string, r *http.Request) (interface{} //------------ Address ------------ account = r.FormValue("address") - if account == "" { - common.GetLogger().Error("[query-transactions] 'address' is not set") - return common.ServeError(0, "'address' is not set", "", http.StatusBadRequest) - } //------------ Direction ------------ directionsParam := r.FormValue("direction") @@ -509,7 +464,7 @@ func QueryBlockTransactionsHandler(rpcAddr string, r *http.Request) (interface{} } txResults = txResults[offset:int(math.Min(float64(offset+limit), float64(len(txResults))))] - res := TxsResponse{ + res := types.TxsResponse{ TotalCount: totalCount, Transactions: txResults, } @@ -655,3 +610,24 @@ func QueryUnconfirmedTxs(rpcAddr string) http.HandlerFunc { common.WrapResponse(w, request, *response, statusCode, false) } } + +func processDirection( + rpcAddr, address string, + isOutbound bool, + direction string, + hashToDirectionMap map[string][]string, + cachedTxs *tmTypes.ResultTxSearch, +) (tmTypes.ResultTxSearch, error) { + transactions, err := GetTransactionsWithSync(rpcAddr, address, isOutbound) + if err != nil { + return tmTypes.ResultTxSearch{}, err + } + + for _, tx := range transactions.Txs { + hashToDirectionMap[tx.Hash.String()] = append(hashToDirectionMap[tx.Hash.String()], direction) + } + + cachedTxs.TotalCount += transactions.TotalCount + cachedTxs.Txs = append(cachedTxs.Txs, transactions.Txs...) + return *cachedTxs, nil +} From 5a2b775d0562bd9c845e4be9b903e8b8ced1e77c Mon Sep 17 00:00:00 2001 From: mrlutik Date: Fri, 29 Nov 2024 14:13:57 +0100 Subject: [PATCH 25/25] feat(cidi): interx version bump --- config/constants.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/constants.go b/config/constants.go index 96d5828..ee6a213 100755 --- a/config/constants.go +++ b/config/constants.go @@ -1,8 +1,8 @@ package config const ( - InterxVersion = "v0.4.48" - SekaiVersion = "v0.3.42" + InterxVersion = "v0.4.50" + SekaiVersion = "v0.4.1" CosmosVersion = "v0.47.6" QueryDashboard = "/api/dashboard"