2026-05-15 12:04:52 +08:00

155 lines
4.2 KiB
Go

package redpacket
import (
"context"
"crypto/ecdsa"
"github.com/ethereum/go-ethereum/crypto"
"github.com/openimsdk/open-im-server/v3/internal/rpc/redpacket/chain"
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/controller"
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/database/mgo"
"github.com/openimsdk/open-im-server/v3/pkg/rpcli"
pbredpacket "github.com/openimsdk/protocol/redpacket"
"github.com/openimsdk/tools/db/mongoutil"
"github.com/openimsdk/tools/discovery"
"github.com/openimsdk/tools/log"
"google.golang.org/grpc"
)
type Config struct {
RpcConfig config.RedPacket
MongodbConfig config.Mongo
Share config.Share
Discovery config.Discovery
}
type redPacketServer struct {
pbredpacket.UnimplementedRedPacketServer
config *Config
db controller.RedPacketDatabase
chainClient *chain.ChainClient
tronClient *chain.TronClient
signerKey *ecdsa.PrivateKey
groupClient *rpcli.GroupClient
relationClient *rpcli.RelationClient
}
func Start(ctx context.Context, conf *Config, registry discovery.SvcDiscoveryRegistry, server *grpc.Server) error {
mgoClient, err := mongoutil.NewMongoDB(ctx, conf.MongodbConfig.Build())
if err != nil {
return err
}
db := mgoClient.GetDB()
rpDB, err := mgo.NewRedPacketMongo(db)
if err != nil {
return err
}
claimDB, err := mgo.NewRedPacketClaimMongo(db)
if err != nil {
return err
}
claimAuthDB, err := mgo.NewRedPacketClaimAuthMongo(db)
if err != nil {
return err
}
refundDB, err := mgo.NewRedPacketRefundMongo(db)
if err != nil {
return err
}
challengeDB, err := mgo.NewWalletBindingChallengeMongo(db)
if err != nil {
return err
}
bindingDB, err := mgo.NewWalletBindingMongo(db)
if err != nil {
return err
}
auditLogDB, err := mgo.NewAdminAuditLogMongo(db)
if err != nil {
return err
}
repo := controller.NewRedPacketDatabase(rpDB, claimDB, claimAuthDB, refundDB, challengeDB, bindingDB, auditLogDB)
chainClient, err := chain.NewClient(
conf.RpcConfig.Chain.RPCURL,
conf.RpcConfig.Chain.ContractAddress,
conf.RpcConfig.Chain.ChainID,
conf.RpcConfig.Chain.SignerPrivateKey,
conf.RpcConfig.Chain.ConfigAdminPrivateKey,
)
if err != nil {
log.ZWarn(ctx, "redpacket eth client init failed, continuing without it", err)
chainClient = nil
}
var tronClient *chain.TronClient
if conf.RpcConfig.Tron.FullNodeURL != "" {
abiJSON, abiErr := chain.ExtractABIFromEmbeddedArtifact()
if abiErr != nil {
log.ZWarn(ctx, "redpacket tron load abi failed", abiErr)
} else {
tronClient, err = chain.NewTronClient(
conf.RpcConfig.Tron.FullNodeURL,
conf.RpcConfig.Tron.ContractBase58,
conf.RpcConfig.Tron.OwnerBase58,
conf.RpcConfig.Tron.PrivateKeyHex,
abiJSON,
conf.RpcConfig.Tron.FeeLimit,
)
if err != nil {
log.ZWarn(ctx, "redpacket tron client init failed", err)
tronClient = nil
}
}
}
var signerKey *ecdsa.PrivateKey
if k := conf.RpcConfig.Chain.SignerPrivateKey; k != "" {
sk, parseErr := crypto.HexToECDSA(k)
if parseErr != nil {
log.ZWarn(ctx, "redpacket signer private key parse failed", parseErr)
} else {
signerKey = sk
}
}
groupConn, err := registry.GetConn(ctx, conf.Share.RpcRegisterName.Group)
if err != nil {
return err
}
friendConn, err := registry.GetConn(ctx, conf.Share.RpcRegisterName.Friend)
if err != nil {
return err
}
srv := &redPacketServer{
config: conf,
db: repo,
chainClient: chainClient,
tronClient: tronClient,
signerKey: signerKey,
groupClient: rpcli.NewGroupClient(groupConn),
relationClient: rpcli.NewRelationClient(friendConn),
}
pbredpacket.RegisterRedPacketServer(server, srv)
if conf.RpcConfig.Indexer.PollInterval > 0 {
if chainClient != nil {
ethIndexer := chain.NewIndexer(chainClient, repo, conf.RpcConfig.Indexer.PollInterval, 0, conf.RpcConfig.Indexer.MaxBlocksPerPoll)
ethIndexer.Start(ctx)
}
if tronClient != nil {
tronIndexer := chain.NewTronIndexer(tronClient, repo, conf.RpcConfig.Indexer.PollInterval, 0)
tronIndexer.Start(ctx)
}
} else {
log.ZInfo(ctx, "redpacket indexer disabled by config", "pollInterval", conf.RpcConfig.Indexer.PollInterval)
}
return nil
}