package server import ( "fmt" "sdk_api/constant" apiModel "sdk_api/model/api" "sdk_api/util" "strings" "github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/crypto" "github.com/gin-gonic/gin" "github.com/tidwall/gjson" ) func checkUser(c *gin.Context) { req := &apiModel.CheckUserRequest{} if err := c.ShouldBindJSON(req); err != nil { c.JSON(200, withError(constant.InvalidParam)) return } switch req.Platform { case constant.PlatformTelegram: var ok bool var userId string var botId string for _, token := range conf.TGBot.Tokens { ok, botId, userId = util.VerifyInitData(req.InitData, token) if ok { break } } if !ok { c.JSON(200, withError("invalid initData")) return } dbId := fmt.Sprintf("%s:%s", botId, userId) ok, uid, keystore, err := srv.CheckUser(constant.PlatformTelegram, dbId) if err != nil { c.JSON(200, withError(constant.InternalError)) return } token := util.GenerateJWT(uid, constant.PlatformTelegram, dbId) resp := &apiModel.CheckUserResponse{ IsNewUser: !ok, Keystore: keystore, Token: token, } c.JSON(200, withSuccess(resp)) return case constant.PlatformFingerprint: userId := req.VisitorID ok, uid, keystore, err := srv.CheckUser(constant.PlatformFingerprint, userId) if err != nil { c.JSON(200, withError(constant.InternalError)) return } token := util.GenerateJWT(uid, constant.PlatformFingerprint, userId) resp := &apiModel.CheckUserResponse{ IsNewUser: !ok, Keystore: keystore, Token: token, } c.JSON(200, withSuccess(resp)) default: c.JSON(200, withError(constant.UnsupportedPlatform)) return } } func createUser(c *gin.Context) { req := &apiModel.CreateUserRequest{} if err := c.ShouldBindJSON(req); err != nil { c.JSON(200, withError(constant.InvalidParam)) return } uid := c.GetString("jwt-uid") address := gjson.Get(req.Keystore, "address").String() binSignature, err := hexutil.Decode(req.Signature) if err != nil || len(binSignature) < 65 { c.JSON(200, withError("invalid signature")) return } binSignature[64] -= 27 ecdsaPub, err := crypto.SigToPub(accounts.TextHash([]byte(req.Keystore)), binSignature) if err != nil { c.JSON(200, withError("invalid signature")) return } addr := crypto.PubkeyToAddress(*ecdsaPub) if strings.ToLower(addr.Hex()[2:]) != address { c.JSON(200, withError("invalid signature")) return } ok, err := srv.SetKeystore(uid, strings.ToLower(addr.Hex()), req.Keystore) if err != nil { c.JSON(200, withError(constant.InternalError)) return } if !ok { c.JSON(200, withError("keystore already exist")) return } srv.AONSendGas(addr.Hex()) c.JSON(200, withSuccess("")) } func login(c *gin.Context) { req := &apiModel.LoginRequest{} if err := c.ShouldBindJSON(req); err != nil { c.JSON(200, withError(constant.InvalidParam)) return } var platformId string switch req.Platform { case constant.PlatformTelegram: var ok bool var userId string var botId string for _, token := range conf.TGBot.Tokens { ok, botId, userId = util.VerifyInitData(req.InitData, token) if ok { break } } if !ok { c.JSON(200, withError("invalid initData")) return } platformId = fmt.Sprintf("%s:%s", botId, userId) case constant.PlatformFingerprint: if len(req.VisitorID) <= 10 { c.JSON(200, withError(constant.InvalidParam)) return } platformId = req.VisitorID default: c.JSON(200, withError(constant.UnsupportedPlatform)) return } // 检查签名是否为keystore中的地址 address := gjson.Get(req.Keystore, "address").String() binSignature, err := hexutil.Decode(req.Signature) if err != nil || len(binSignature) < 65 { c.JSON(200, withError("invalid signature")) return } binSignature[64] -= 27 ecdsaPub, err := crypto.SigToPub(accounts.TextHash([]byte(req.Keystore)), binSignature) if err != nil { c.JSON(200, withError("invalid signature")) return } addr := crypto.PubkeyToAddress(*ecdsaPub) if strings.ToLower(addr.Hex()[2:]) != address { c.JSON(200, withError("invalid signature")) return } isExistKeystore, uid, keystore, err := srv.CheckUser(req.Platform, platformId) if err != nil { c.JSON(200, withError(constant.InternalError)) return } token := util.GenerateJWT(uid, req.Platform, platformId) resp := &apiModel.CheckUserResponse{ IsNewUser: !isExistKeystore, Keystore: keystore, Token: token, Uid: uid, } if !isExistKeystore { _, err = srv.SetKeystore(uid, address, req.Keystore) if err != nil { c.JSON(200, withError(constant.InternalError)) return } resp.Keystore = req.Keystore } taskId, err := srv.AONServerLogin(address, req.UserId, req.InviterId) if err != nil { c.JSON(200, withError(constant.InternalError)) return } resp.TaskId = taskId c.JSON(200, withSuccess(resp)) return } func loginV2(c *gin.Context) { req := &apiModel.LoginRequest{} if err := c.ShouldBindJSON(req); err != nil { c.JSON(200, withError(constant.InvalidParam)) return } var platformId string switch req.Platform { case constant.PlatformTelegram: var ok bool var userId string var botId string for _, token := range conf.TGBot.Tokens { ok, botId, userId = util.VerifyInitData(req.InitData, token) if ok { break } } if !ok { c.JSON(200, withError("invalid initData")) return } _ = botId // platformId = fmt.Sprintf("%s:%s", botId, userId) platformId = fmt.Sprintf("v2:%s", userId) case constant.PlatformFingerprint: if len(req.VisitorID) <= 10 { c.JSON(200, withError(constant.InvalidParam)) return } platformId = req.VisitorID default: c.JSON(200, withError(constant.UnsupportedPlatform)) return } // 检查签名是否为keystore中的地址 address := gjson.Get(req.Keystore, "address").String() binSignature, err := hexutil.Decode(req.Signature) if err != nil || len(binSignature) < 65 { c.JSON(200, withError("invalid signature")) return } binSignature[64] -= 27 ecdsaPub, err := crypto.SigToPub(accounts.TextHash([]byte(req.Keystore)), binSignature) if err != nil { c.JSON(200, withError("invalid signature")) return } addr := crypto.PubkeyToAddress(*ecdsaPub) if strings.ToLower(addr.Hex()[2:]) != address { c.JSON(200, withError("invalid signature")) return } isExistKeystore, uid, keystore, err := srv.CheckUser(req.Platform, platformId) if err != nil { c.JSON(200, withError(constant.InternalError)) return } token := util.GenerateJWT(uid, req.Platform, platformId) resp := &apiModel.CheckUserResponse{ IsNewUser: !isExistKeystore, Keystore: keystore, Token: token, Uid: uid, } if !isExistKeystore { _, err = srv.SetKeystore(uid, address, req.Keystore) if err != nil { c.JSON(200, withError(constant.InternalError)) return } resp.Keystore = req.Keystore } taskId, err := srv.AONServerLogin(address, req.UserId, req.InviterId) if err != nil { c.JSON(200, withError(constant.InternalError)) return } resp.TaskId = taskId c.JSON(200, withSuccess(resp)) return }