diff --git a/common/model/Chain.go b/common/model/Chain.go new file mode 100644 index 00000000..8b537907 --- /dev/null +++ b/common/model/Chain.go @@ -0,0 +1 @@ +package model diff --git a/common/model/api_request.go b/common/model/api_request.go new file mode 100644 index 00000000..45ec599a --- /dev/null +++ b/common/model/api_request.go @@ -0,0 +1,11 @@ +package model + +type TryPayUserOpRequest struct { + ForceStrategyId string `json:"strategy_id"` + ForceNetWork string `json:"force_network"` + ForceTokens string `json:"force_tokens"` + ForceEntryPointAddress string `json:"force_entry_point_address"` + UserOperation UserOperationItem `json:"user_operation"` + Apikey string `json:"apikey"` + Extra interface{} `json:"extra"` +} diff --git a/common/model/api_response.go b/common/model/api_response.go new file mode 100644 index 00000000..980f2e7e --- /dev/null +++ b/common/model/api_response.go @@ -0,0 +1,18 @@ +package model + +type TryPayUserOpResponse struct { + StrategyId string `json:"strategy_id"` + EntryPointAddress string `json:"entry_point_address"` + PayMasterAddress string `json:"pay_master_address"` + PayMasterSignature string `json:"pay_master_signature"` + PayReceipt interface{} `json:"pay_receipt"` + GasInfo ComputeGasResponse `json:"gaf_info"` +} + +type ComputeGasResponse struct { + StrategyId string + tokenCost string + network string + token string + UsdCost string +} diff --git a/rpc_server/models/client_credential.go b/common/model/client_credential.go similarity index 81% rename from rpc_server/models/client_credential.go rename to common/model/client_credential.go index 1a048c34..b38ab8ff 100644 --- a/rpc_server/models/client_credential.go +++ b/common/model/client_credential.go @@ -1,4 +1,4 @@ -package models +package model type ClientCredential struct { ApiKey string `json:"apiKey"` diff --git a/rpc_server/models/response.go b/common/model/response.go similarity index 99% rename from rpc_server/models/response.go rename to common/model/response.go index eabb3845..16cb2372 100644 --- a/rpc_server/models/response.go +++ b/common/model/response.go @@ -1,4 +1,4 @@ -package models +package model import ( "github.com/gin-gonic/gin" diff --git a/common/model/strategy.go b/common/model/strategy.go new file mode 100644 index 00000000..e23e5988 --- /dev/null +++ b/common/model/strategy.go @@ -0,0 +1,7 @@ +package model + +type Strategy struct { + Id string + EntryPointAddress string + PayMasterAddress string +} diff --git a/common/model/user_operation.go b/common/model/user_operation.go new file mode 100644 index 00000000..5b7c7e6b --- /dev/null +++ b/common/model/user_operation.go @@ -0,0 +1,14 @@ +package model + +type UserOperationItem struct { + Sender string `json:"sender"` + Nonce string `json:"nonce"` + InitCode string `json:"init_code"` + CallGasLimit string `json:"call_gas_limit"` + VerificationGasList string `json:"verification_gas_list"` + PerVerificationGas string `json:"per_verification_gas"` + MaxFeePerGas string `json:"max_fee_per_gas"` + MaxPriorityFeePerGas string `json:"max_priority_fee_per_gas"` + //paymasterAndData string `json:"paymaster_and_data"` + Signature string `json:"signature"` +} diff --git a/common/types/strategy.go b/common/types/strategy.go deleted file mode 100644 index d0cc8bc2..00000000 --- a/common/types/strategy.go +++ /dev/null @@ -1,4 +0,0 @@ -package types - -type Strategy struct { -} diff --git a/conf/appsettings.yaml b/conf/appsettings.yaml index 65f51631..e86f54a2 100644 --- a/conf/appsettings.yaml +++ b/conf/appsettings.yaml @@ -1,4 +1,4 @@ jwt: - security: hello-eth-paymaster + security: hello-ethereum-paymaster realm: aastar idkey: id diff --git a/go.mod b/go.mod index 2048c10f..410bb62c 100644 --- a/go.mod +++ b/go.mod @@ -49,6 +49,7 @@ require ( golang.org/x/sys v0.17.0 // indirect golang.org/x/text v0.14.0 // indirect golang.org/x/tools v0.18.0 // indirect + golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect google.golang.org/protobuf v1.32.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index eae4b29c..106a0867 100644 --- a/go.sum +++ b/go.sum @@ -151,6 +151,8 @@ golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc golang.org/x/tools v0.18.0 h1:k8NLag8AGHnn+PHbl7g43CtqZAwG60vZkLqgyZgIHgQ= golang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU= +golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/rpc_server/api/health.go b/rpc_server/api/health.go index a2ec82ab..ec543049 100644 --- a/rpc_server/api/health.go +++ b/rpc_server/api/health.go @@ -1,8 +1,8 @@ package api import ( + "AAStarCommunity/EthPaymaster_BackService/common/model" "AAStarCommunity/EthPaymaster_BackService/conf" - "AAStarCommunity/EthPaymaster_BackService/rpc_server/models" "github.com/gin-gonic/gin" "time" ) @@ -16,7 +16,7 @@ import ( // @Router /api/health [post,get,put,delete] // @Success 200 func Healthz(c *gin.Context) { - response := models.GetResponse() + response := model.GetResponse() response.WithDataSuccess(c, gin.H{ "hello": "Eth Paymaster", "environment": conf.Environment.Name, diff --git a/rpc_server/api/v1/get_support_entrypoint.go b/rpc_server/api/v1/get_support_entrypoint.go index 07304541..7ef0b1ff 100644 --- a/rpc_server/api/v1/get_support_entrypoint.go +++ b/rpc_server/api/v1/get_support_entrypoint.go @@ -1,9 +1,9 @@ package v1 import ( + "AAStarCommunity/EthPaymaster_BackService/common/model" "AAStarCommunity/EthPaymaster_BackService/rpc_server/api/utils" - "AAStarCommunity/EthPaymaster_BackService/rpc_server/models" - "AAStarCommunity/EthPaymaster_BackService/service" + "AAStarCommunity/EthPaymaster_BackService/service/executor" "fmt" "github.com/gin-gonic/gin" "net/http" @@ -18,13 +18,13 @@ import ( // @Success 200 // @Security JWT func GetSupportEntrypoint(c *gin.Context) { - response := models.GetResponse() + response := model.GetResponse() if ok, apiKey := utils.CurrentUser(c); ok { _ = apiKey //1.TODO API validate //2. recall service - result, err := service.GetSupportEntrypointExecute() + result, err := executor.GetSupportEntrypointExecute() if err != nil { errStr := fmt.Sprintf("%v", err) response.SetHttpCode(http.StatusInternalServerError).FailCode(c, http.StatusInternalServerError, errStr) diff --git a/rpc_server/api/v1/get_support_strategy.go b/rpc_server/api/v1/get_support_strategy.go index 6143c786..07272918 100644 --- a/rpc_server/api/v1/get_support_strategy.go +++ b/rpc_server/api/v1/get_support_strategy.go @@ -1,8 +1,8 @@ package v1 import ( - "AAStarCommunity/EthPaymaster_BackService/rpc_server/models" - "AAStarCommunity/EthPaymaster_BackService/service" + "AAStarCommunity/EthPaymaster_BackService/common/model" + "AAStarCommunity/EthPaymaster_BackService/service/executor" "fmt" "github.com/gin-gonic/gin" "net/http" @@ -19,8 +19,8 @@ import ( func GetSupportStrategy(c *gin.Context) { //1.TODO API validate //2. recall service - result, err := service.GetSupportStrategyExecute() - response := models.GetResponse() + result, err := executor.GetSupportStrategyExecute() + response := model.GetResponse() if err != nil { errStr := fmt.Sprintf("%v", err) response.SetHttpCode(http.StatusInternalServerError).FailCode(c, http.StatusInternalServerError, errStr) diff --git a/rpc_server/api/v1/try_pay_user_operation.go b/rpc_server/api/v1/try_pay_user_operation.go index cc6caad9..3e7f2c6d 100644 --- a/rpc_server/api/v1/try_pay_user_operation.go +++ b/rpc_server/api/v1/try_pay_user_operation.go @@ -1,8 +1,8 @@ package v1 import ( - "AAStarCommunity/EthPaymaster_BackService/rpc_server/models" - "AAStarCommunity/EthPaymaster_BackService/service" + "AAStarCommunity/EthPaymaster_BackService/common/model" + "AAStarCommunity/EthPaymaster_BackService/service/executor" "fmt" "github.com/gin-gonic/gin" "net/http" @@ -19,10 +19,17 @@ import ( func TryPayUserOperation(c *gin.Context) { //1.TODO API validate //2. recall service - result, err := service.TryPayUserOpExecute() - response := models.GetResponse() + request := model.TryPayUserOpRequest{} + response := model.GetResponse() + + if err := c.ShouldBindJSON(&request); err != nil { + errStr := fmt.Sprintf("Conver Request Error [%v]", err) + response.SetHttpCode(http.StatusBadRequest).FailCode(c, http.StatusBadRequest, errStr) + } + + result, err := executor.TryPayUserOpExecute(request) if err != nil { - errStr := fmt.Sprintf("%v", err) + errStr := fmt.Sprintf("TryPayUserOpExecute ERROR [%v]", err) response.SetHttpCode(http.StatusInternalServerError).FailCode(c, http.StatusInternalServerError, errStr) } response.WithData(result).Success(c) diff --git a/rpc_server/middlewares/recovery.go b/rpc_server/middlewares/recovery.go index 5bb6a889..c6807e03 100644 --- a/rpc_server/middlewares/recovery.go +++ b/rpc_server/middlewares/recovery.go @@ -1,8 +1,8 @@ package middlewares import ( + "AAStarCommunity/EthPaymaster_BackService/common/model" "AAStarCommunity/EthPaymaster_BackService/conf" - "AAStarCommunity/EthPaymaster_BackService/rpc_server/models" "errors" "fmt" "github.com/gin-gonic/gin" @@ -18,7 +18,7 @@ func GenericRecoveryHandler() gin.HandlerFunc { if conf.Environment.Debugger { errStr = fmt.Sprintf("%v", err) } - models.GetResponse().SetHttpCode(http.StatusInternalServerError).FailCode(c, http.StatusInternalServerError, errStr) + model.GetResponse().SetHttpCode(http.StatusInternalServerError).FailCode(c, http.StatusInternalServerError, errStr) }) } diff --git a/rpc_server/models/userOperation.go b/rpc_server/models/userOperation.go deleted file mode 100644 index 2640e7f9..00000000 --- a/rpc_server/models/userOperation.go +++ /dev/null @@ -1 +0,0 @@ -package models diff --git a/rpc_server/routers/boot.go b/rpc_server/routers/boot.go index 94abcdb0..70263d43 100644 --- a/rpc_server/routers/boot.go +++ b/rpc_server/routers/boot.go @@ -1,10 +1,10 @@ package routers import ( + "AAStarCommunity/EthPaymaster_BackService/common/model" "AAStarCommunity/EthPaymaster_BackService/conf" "AAStarCommunity/EthPaymaster_BackService/docs" "AAStarCommunity/EthPaymaster_BackService/rpc_server/middlewares" - "AAStarCommunity/EthPaymaster_BackService/rpc_server/models" "github.com/gin-gonic/gin" swaggerFiles "github.com/swaggo/files" ginSwagger "github.com/swaggo/gin-swagger" @@ -19,7 +19,7 @@ func SetRouters() (routers *gin.Engine) { buildMod(routers) buildRoute(routers) routers.NoRoute(func(ctx *gin.Context) { - models.GetResponse().SetHttpCode(http.StatusNotFound).FailCode(ctx, http.StatusNotFound) + model.GetResponse().SetHttpCode(http.StatusNotFound).FailCode(ctx, http.StatusNotFound) }) return diff --git a/service/dashboard_service/dashboard_service.go b/service/dashboard_service/dashboard_service.go new file mode 100644 index 00000000..a0a2e6e2 --- /dev/null +++ b/service/dashboard_service/dashboard_service.go @@ -0,0 +1,7 @@ +package dashboard_service + +import "AAStarCommunity/EthPaymaster_BackService/common/model" + +func GetStrategyById(strategyId string) model.Strategy { + return model.Strategy{} +} diff --git a/service/dashboard_service/strategy_selector.go b/service/dashboard_service/strategy_selector.go new file mode 100644 index 00000000..c4ac6d48 --- /dev/null +++ b/service/dashboard_service/strategy_selector.go @@ -0,0 +1,11 @@ +package dashboard_service + +import ( + "AAStarCommunity/EthPaymaster_BackService/common/model" +) + +func GetSuitableStrategy(entrypoint string, network string, token string) (model.Strategy, error) { + + return model.Strategy{}, nil + +} diff --git a/service/executor/executor.go b/service/executor/executor.go new file mode 100644 index 00000000..8cd52808 --- /dev/null +++ b/service/executor/executor.go @@ -0,0 +1,12 @@ +package executor + +import ( + "AAStarCommunity/EthPaymaster_BackService/common/model" +) + +func GetSupportEntrypointExecute() (model.Result, error) { + return model.Result{}, nil +} +func GetSupportStrategyExecute() (model.Result, error) { + return model.Result{}, nil +} diff --git a/service/executor/try_pay_user_op_execute.go b/service/executor/try_pay_user_op_execute.go new file mode 100644 index 00000000..445f6d88 --- /dev/null +++ b/service/executor/try_pay_user_op_execute.go @@ -0,0 +1,90 @@ +package executor + +import ( + "AAStarCommunity/EthPaymaster_BackService/common/model" + "AAStarCommunity/EthPaymaster_BackService/service/dashboard_service" + "AAStarCommunity/EthPaymaster_BackService/service/gas_service" + "AAStarCommunity/EthPaymaster_BackService/service/validator_service" + "golang.org/x/xerrors" +) + +func TryPayUserOpExecute(request model.TryPayUserOpRequest) (model.Result, error) { + //validator + if err := paramValidate(request); err != nil { + return model.Result{}, err + } + userOp := request.UserOperation + //getStrategy + strategy, err := strategyGenerate(request) + if err != nil { + return model.Result{}, err + } + if err := validator_service.ValidateStrategy(strategy, userOp); err != nil { + return model.Result{}, err + } + + //base Strategy and UserOp computeGas + gasResponse, gasComputeError := gas_service.ComputeGas(userOp, strategy) + if gasComputeError != nil { + return model.Result{}, gasComputeError + } + + //validate gas + if err := gas_service.ValidateGas(userOp, gasResponse); err != nil { + return model.Result{}, err + } + //pay + payReceipt, payError := executePay(strategy, request.UserOperation, gasResponse) + if payError != nil { + return model.Result{}, payError + } + paymasterSignature := getPayMasterSignature(strategy, request.UserOperation) + var result = model.TryPayUserOpResponse{ + StrategyId: strategy.Id, + EntryPointAddress: strategy.EntryPointAddress, + PayMasterAddress: strategy.EntryPointAddress, + PayReceipt: payReceipt, + PayMasterSignature: paymasterSignature, + GasInfo: gasResponse, + } + + return model.Result{ + Code: 0, + Data: result, + Message: "message", + Cost: "cost", + }, nil +} +func paramValidate(request model.TryPayUserOpRequest) error { + return nil +} + +func executePay(strategy model.Strategy, userOp model.UserOperationItem, gasResponse model.ComputeGasResponse) (interface{}, error) { + //1.Recharge + //2.record account + //3.return Receipt + return nil, nil +} +func getPayMasterSignature(strategy model.Strategy, userOp model.UserOperationItem) string { + return "" +} + +func strategyGenerate(request model.TryPayUserOpRequest) (model.Strategy, error) { + if forceStrategyId := request.ForceStrategyId; forceStrategyId != "" { + //force strategy + strategy := dashboard_service.GetStrategyById(forceStrategyId) + if strategy == (model.Strategy{}) { + return model.Strategy{}, xerrors.Errorf("Not Support Strategy ID: [%w]", forceStrategyId) + } + return strategy, nil + } + + suitableStrategy, err := dashboard_service.GetSuitableStrategy(request.ForceEntryPointAddress, request.ForceNetWork, request.ForceTokens) //TODO + if err != nil { + return model.Strategy{}, err + } + if suitableStrategy == (model.Strategy{}) { + return model.Strategy{}, xerrors.Errorf("Empty Strategies") + } + return suitableStrategy, nil +} diff --git a/service/executor/try_pay_user_op_test.go b/service/executor/try_pay_user_op_test.go new file mode 100644 index 00000000..4a41b057 --- /dev/null +++ b/service/executor/try_pay_user_op_test.go @@ -0,0 +1,28 @@ +package executor + +import ( + "AAStarCommunity/EthPaymaster_BackService/common/model" + + "testing" +) + +func TestTryPayUserOpExecute(t *testing.T) { + request := getMockTryPayUserOpRequest() + TryPayUserOpExecute(request) + +} + +func getMockTryPayUserOpRequest() model.TryPayUserOpRequest { + return model.TryPayUserOpRequest{ + ForceStrategyId: "1", + UserOperation: model.UserOperationItem{ + Sender: "0x123", + Nonce: "", + CallGasLimit: "", + VerificationGasList: "", + PerVerificationGas: "", + MaxFeePerGas: "", + MaxPriorityFeePerGas: "", + }, + } +} diff --git a/service/gasService/gasWeiGenerator.go b/service/gasService/gasWeiGenerator.go deleted file mode 100644 index 457c50b0..00000000 --- a/service/gasService/gasWeiGenerator.go +++ /dev/null @@ -1 +0,0 @@ -package gasService diff --git a/service/gas_service/gasWeiGenerator.go b/service/gas_service/gasWeiGenerator.go new file mode 100644 index 00000000..27fcf074 --- /dev/null +++ b/service/gas_service/gasWeiGenerator.go @@ -0,0 +1 @@ +package gas_service diff --git a/service/gas_service/gas_compotor.go b/service/gas_service/gas_compotor.go new file mode 100644 index 00000000..fcae3d59 --- /dev/null +++ b/service/gas_service/gas_compotor.go @@ -0,0 +1,11 @@ +package gas_service + +import "AAStarCommunity/EthPaymaster_BackService/common/model" + +func ComputeGas(userOp model.UserOperationItem, strategy model.Strategy) (model.ComputeGasResponse, error) { + return model.ComputeGasResponse{}, nil +} + +func ValidateGas(userOp model.UserOperationItem, gasComputeResponse model.ComputeGasResponse) error { + return nil +} diff --git a/service/tryPayUserOperationExecutor.go b/service/tryPayUserOperationExecutor.go deleted file mode 100644 index 62894b27..00000000 --- a/service/tryPayUserOperationExecutor.go +++ /dev/null @@ -1,13 +0,0 @@ -package service - -import "AAStarCommunity/EthPaymaster_BackService/rpc_server/models" - -func TryPayUserOpExecute() (models.Result, error) { - return models.Result{}, nil -} -func GetSupportEntrypointExecute() (models.Result, error) { - return models.Result{}, nil -} -func GetSupportStrategyExecute() (models.Result, error) { - return models.Result{}, nil -} diff --git a/service/validatorService/userOpValidator.go b/service/validatorService/userOpValidator.go deleted file mode 100644 index 0308dbe5..00000000 --- a/service/validatorService/userOpValidator.go +++ /dev/null @@ -1 +0,0 @@ -package validatorService diff --git a/service/validator_service/basic_validator.go b/service/validator_service/basic_validator.go new file mode 100644 index 00000000..f10077c5 --- /dev/null +++ b/service/validator_service/basic_validator.go @@ -0,0 +1,8 @@ +package validator_service + +import "AAStarCommunity/EthPaymaster_BackService/common/model" + +func ValidateStrategy(strategy model.Strategy, userOp model.UserOperationItem) error { + + return nil +} diff --git a/service/validator_service/userOpValidator.go b/service/validator_service/userOpValidator.go new file mode 100644 index 00000000..cb6263b0 --- /dev/null +++ b/service/validator_service/userOpValidator.go @@ -0,0 +1 @@ +package validator_service diff --git a/validator/chain/IChainValidator.go b/validator/chain/IChainValidator.go new file mode 100644 index 00000000..f86f2185 --- /dev/null +++ b/validator/chain/IChainValidator.go @@ -0,0 +1,10 @@ +package chain + +type IChainValidator interface { + PreValidate() (err error) + AfterGasValidate() (err error) + IsSupport() bool +} +type Base struct { + name string +} diff --git a/validator/chain/ethereum/EthereumValidator.go b/validator/chain/ethereum/EthereumValidator.go new file mode 100644 index 00000000..e84d4325 --- /dev/null +++ b/validator/chain/ethereum/EthereumValidator.go @@ -0,0 +1,24 @@ +package ethereum + +import ( + "AAStarCommunity/EthPaymaster_BackService/validator/chain" +) + +type EthValidator struct { + *chain.Base +} + +func (e EthValidator) IsSupport() bool { + //TODO implement me + panic("implement me") +} + +func (e EthValidator) PreValidate() (err error) { + //TODO implement me + panic("implement me") +} + +func (e EthValidator) AfterGasValidate() (err error) { + //TODO implement me + panic("implement me") +} diff --git a/validator/eip/eip_4844/4844Validator.go b/validator/eip/eip_4844/4844Validator.go new file mode 100644 index 00000000..c847b0f8 --- /dev/null +++ b/validator/eip/eip_4844/4844Validator.go @@ -0,0 +1 @@ +package eip_4844 diff --git a/validator/other/eoaEnableValidator.go b/validator/other/eoaEnableValidator.go new file mode 100644 index 00000000..58a9531f --- /dev/null +++ b/validator/other/eoaEnableValidator.go @@ -0,0 +1 @@ +package other