diff --git a/common/model/api_response.go b/common/model/api_response.go index ef04409b..072e21e5 100644 --- a/common/model/api_response.go +++ b/common/model/api_response.go @@ -20,6 +20,7 @@ type ComputeGasResponse struct { TokenCost string `json:"token_cost"` Network types.Network `json:"network"` Token types.TokenType `json:"token"` + TokenCount string `json:"token_count"` UsdCost string `json:"usd_cost"` BlobEnable bool `json:"blob_enable"` MaxFee big.Int `json:"max_fee"` diff --git a/common/model/gas_price.go b/common/model/gas_price.go index 27081a95..1b384103 100644 --- a/common/model/gas_price.go +++ b/common/model/gas_price.go @@ -4,9 +4,9 @@ import "math/big" type GasPrice struct { MaxBasePriceWei *big.Int `json:"max_base_price_wei"` - MaxBasePriceGwei *big.Float `json:"max_base_price_gwei"` - MaxBasePriceEther *string `json:"max_base_price_ether"` + MaxBasePriceGwei float64 `json:"max_base_price_gwei"` + MaxBasePriceEther *big.Float `json:"max_base_price_ether"` MaxPriorityPriceWei *big.Int `json:"max_priority_price_wei"` - MaxPriorityPriceGwei *big.Float `json:"max_priority_price_gwei"` - MaxPriorityPriceEther *string `json:"max_priority_price_ether"` + MaxPriorityPriceGwei float64 `json:"max_priority_price_gwei"` + MaxPriorityPriceEther *big.Float `json:"max_priority_price_ether"` } diff --git a/common/model/user_operation.go b/common/model/user_operation.go index 6c871eb7..9c63bc2f 100644 --- a/common/model/user_operation.go +++ b/common/model/user_operation.go @@ -49,7 +49,6 @@ type PackUserOperation struct { } func NewUserOp(userOp *map[string]any) (*UserOperation, error) { - var result UserOperation // Convert map to struct decodeConfig := &mapstructure.DecoderConfig{ diff --git a/common/utils/price_util.go b/common/utils/price_util.go index 2d42c857..a385b026 100644 --- a/common/utils/price_util.go +++ b/common/utils/price_util.go @@ -46,5 +46,6 @@ func GetToken(fromToken types.TokenType, toToken types.TokenType) (float64, erro } formTokenPrice, _ := GetPriceUsd(fromToken) toTokenPrice, _ := GetPriceUsd(toToken) + return formTokenPrice / toTokenPrice, nil } diff --git a/service/chain_service/chain_service.go b/service/chain_service/chain_service.go index 287fd4e3..889720d5 100644 --- a/service/chain_service/chain_service.go +++ b/service/chain_service/chain_service.go @@ -5,10 +5,12 @@ import ( "AAStarCommunity/EthPaymaster_BackService/common/types" "context" "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" "github.com/holiman/uint256" "golang.org/x/xerrors" "math/big" + "strings" ) var GweiFactor = new(big.Float).SetInt(big.NewInt(1e9)) @@ -55,19 +57,17 @@ func GetGasPrice(chain types.Network) (*model.GasPrice, error) { gasPriceInGwei.Quo(gasPriceInGwei, GweiFactor) gasPriceInEther := new(big.Float).SetInt(priceWei) gasPriceInEther.Quo(gasPriceInEther, EthWeiFactor) - gasPriceInEtherStr := gasPriceInEther.Text('f', 18) - result.MaxBasePriceGwei = gasPriceInGwei - result.MaxBasePriceEther = &gasPriceInEtherStr + gasPriceInGweiFloat, _ := gasPriceInGwei.Float64() + result.MaxBasePriceGwei = gasPriceInGweiFloat + result.MaxBasePriceEther = gasPriceInEther priorityPriceInGwei := new(big.Float).SetInt(priorityPriceWei) priorityPriceInGwei.Quo(priorityPriceInGwei, GweiFactor) priorityPriceInEther := new(big.Float).SetInt(priorityPriceWei) priorityPriceInEther.Quo(priorityPriceInEther, EthWeiFactor) - priorityPriceInEtherStr := priorityPriceInEther.Text('f', 18) - result.MaxPriorityPriceGwei = priorityPriceInGwei - result.MaxPriorityPriceEther = &priorityPriceInEtherStr - result.MaxPriorityPriceGwei = priorityPriceInGwei - result.MaxPriorityPriceEther = &priorityPriceInEtherStr + priorityPriceInGweiFloat, _ := priorityPriceInGwei.Float64() + result.MaxPriorityPriceGwei = priorityPriceInGweiFloat + result.MaxPriorityPriceEther = gasPriceInEther return &result, nil } @@ -103,3 +103,36 @@ func EstimateGasLimitAndCost(chain types.Network, msg ethereum.CallMsg) (uint64, } return client.EstimateGas(context.Background(), msg) } +func GetAddressTokenBalance(network types.Network, address common.Address, token types.TokenType) ([]interface{}, error) { + client, exist := EthCompatibleNetWorkClientMap[network] + if !exist { + return nil, xerrors.Errorf("chain Client [%s] not exist", network) + } + client.BalanceAt(context.Background(), address, nil) + usdtContractAddress := common.HexToAddress("0xdac17f958d2ee523a2206206994597c13d831ec7") + //address := common.HexToAddress("0xDf7093eF81fa23415bb703A685c6331584D30177") + const bananceABI = `[{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}]` + usdtABI, jsonErr := abi.JSON(strings.NewReader(bananceABI)) + if jsonErr != nil { + return nil, jsonErr + } + data, backErr := usdtABI.Pack("balanceOf", address) + if backErr != nil { + return nil, backErr + + } + //usdtInstance, err := ethclient.NewContract(usdtContractAddress, usdtAbi, client) + result, callErr := client.CallContract(context.Background(), ethereum.CallMsg{ + To: &usdtContractAddress, + Data: data, + }, nil) + if callErr != nil { + return nil, callErr + } + var balanceResult, unpackErr = usdtABI.Unpack("balanceOf", result) + if unpackErr != nil { + return nil, unpackErr + } + //TODO get token balance + return balanceResult, nil +} diff --git a/service/chain_service/chain_test.go b/service/chain_service/chain_test.go index 66beb731..bdc5dbc5 100644 --- a/service/chain_service/chain_test.go +++ b/service/chain_service/chain_test.go @@ -19,6 +19,9 @@ func TestGetGasPrice(t *testing.T) { gasprice, _ := GetGasPrice(types.Ethereum) fmt.Printf("gasprice %d\n", gasprice.MaxBasePriceWei.Uint64()) + fmt.Printf("gaspricegwei %f\n", gasprice.MaxBasePriceGwei) + fmt.Printf("gaspriceeth %s\n", gasprice.MaxBasePriceEther.String()) + } func TestGethClient(t *testing.T) { diff --git a/service/gas_service/gas_computor.go b/service/gas_service/gas_computor.go index 2f4eaf44..ac1d9e56 100644 --- a/service/gas_service/gas_computor.go +++ b/service/gas_service/gas_computor.go @@ -3,6 +3,7 @@ package gas_service import ( "AAStarCommunity/EthPaymaster_BackService/common/model" "AAStarCommunity/EthPaymaster_BackService/common/types" + "AAStarCommunity/EthPaymaster_BackService/common/utils" "AAStarCommunity/EthPaymaster_BackService/service/chain_service" "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/common" @@ -31,13 +32,21 @@ func ComputeGas(userOp *model.UserOperation, strategy *model.Strategy) (*model.C maxGasLimit := big.NewInt(0).Add(userOp.CallGasLimit, userOp.VerificationGasLimit) maxGasLimit = maxGasLimit.Add(maxGasLimit, payMasterPostGasLimit) - maxFee := new(big.Int).Mul(maxGasLimit, gasPrice.MaxBasePriceWei) + maxFeePriceInEther := new(big.Float).SetInt(maxFee) + maxFeePriceInEther.Quo(maxFeePriceInEther, chain_service.EthWeiFactor) + tokenCost, _ := getTokenCost(strategy, maxFeePriceInEther) + if strategy.PayType == types.PayTypeERC20 { + //TODO get ERC20 balance + if err := validateErc20Paymaster(tokenCost, strategy); err != nil { + return nil, err + } + } + // TODO get PaymasterCallGasLimit - tokenCost := GetTokenCost(*maxFee, userOp, *strategy) return &model.ComputeGasResponse{ GasInfo: gasPrice, - TokenCost: tokenCost, + TokenCost: tokenCost.Text('f', 18), Network: strategy.NetWork, Token: strategy.Token, UsdCost: "0.4", @@ -45,11 +54,24 @@ func ComputeGas(userOp *model.UserOperation, strategy *model.Strategy) (*model.C MaxFee: *maxFee, }, nil } -func GetPayMasterGasLimit() *big.Int { +func validateErc20Paymaster(tokenCost *big.Float, strategy *model.Strategy) error { + //useToken := strategy.Token + //// get User address balance + //TODO return nil } -func GetTokenCost(maxFee big.Int, userOp *model.UserOperation, strategy model.Strategy) string { - return "0.0001" +func getTokenCost(strategy *model.Strategy, tokenCount *big.Float) (*big.Float, error) { + formTokenType := chain_service.NetworkInfoMap[strategy.NetWork].GasToken + toTokenType := strategy.Token + toTokenPrice, err := utils.GetToken(formTokenType, toTokenType) + if err != nil { + return nil, err + } + tokenCost := new(big.Float).Mul(tokenCount, big.NewFloat(toTokenPrice)) + return tokenCost, nil +} +func GetPayMasterGasLimit() *big.Int { + return nil } func ValidateGas(userOp *model.UserOperation, gasComputeResponse *model.ComputeGasResponse, strategy *model.Strategy) error {