批量空投
This commit is contained in:
@@ -1,10 +1,10 @@
|
|||||||
FROM golang:1.23.4-alpine AS builder
|
FROM golang:1.24.0-alpine AS builder
|
||||||
|
|
||||||
LABEL stage=gobuilder
|
LABEL stage=gobuilder
|
||||||
|
|
||||||
ENV CGO_ENABLED=0
|
ENV CGO_ENABLED=0
|
||||||
ENV GOPROXY=https://goproxy.cn,direct
|
ENV GOPROXY=https://goproxy.cn,direct
|
||||||
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
|
#RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
|
||||||
|
|
||||||
RUN apk update --no-cache && apk add --no-cache tzdata
|
RUN apk update --no-cache && apk add --no-cache tzdata
|
||||||
|
|
||||||
|
|||||||
2
Makefile
2
Makefile
@@ -1,4 +1,4 @@
|
|||||||
host ?= 192.168.2.109:3306
|
host ?= 192.168.2.108:3306
|
||||||
user ?= huangjie
|
user ?= huangjie
|
||||||
pwd ?= jMDqPQM^a6hsAR
|
pwd ?= jMDqPQM^a6hsAR
|
||||||
table ?=
|
table ?=
|
||||||
|
|||||||
@@ -97,3 +97,13 @@ CREATE TABLE `nh_email_reward`
|
|||||||
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
|
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
|
||||||
PRIMARY KEY (`id`)
|
PRIMARY KEY (`id`)
|
||||||
) COMMENT ='需要发放积分的';
|
) COMMENT ='需要发放积分的';
|
||||||
|
|
||||||
|
CREATE TABLE `nh_nft_tarot`
|
||||||
|
(
|
||||||
|
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
|
||||||
|
`token_id` varchar(32) NOT NULL COMMENT 'token id',
|
||||||
|
`tarot_type` tinyint(4) NOT NULL DEFAULT '0' COMMENT '类型:0=小塔罗,1=大塔罗',
|
||||||
|
`tarot_img` varchar(128) NOT NULL COMMENT '塔罗图片',
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
UNIQUE KEY (`token_id`)
|
||||||
|
) COMMENT ='塔罗信息';
|
||||||
@@ -19,7 +19,7 @@ Auth: # js-sdk鉴权相关配置
|
|||||||
AccessSecret: "Mj2G%szYe&$MP@ytNv8JktQN1n5^cPq%" # 鉴权token密钥
|
AccessSecret: "Mj2G%szYe&$MP@ytNv8JktQN1n5^cPq%" # 鉴权token密钥
|
||||||
|
|
||||||
MySql: # mysql相关配置
|
MySql: # mysql相关配置
|
||||||
Addr: "192.168.20.101:3306" # mysql地址
|
Addr: "192.168.2.108:3306" # mysql地址
|
||||||
User: "huangjie" # mysql用户
|
User: "huangjie" # mysql用户
|
||||||
Password: "jMDqPQM^a6hsAR" # mysql密码
|
Password: "jMDqPQM^a6hsAR" # mysql密码
|
||||||
Database: "nova_home" # 数据库名
|
Database: "nova_home" # 数据库名
|
||||||
@@ -41,6 +41,10 @@ Earn:
|
|||||||
ClientSecret: "GJpQ4TmX4p2VMY7U3XtExZQKYfibMv24"
|
ClientSecret: "GJpQ4TmX4p2VMY7U3XtExZQKYfibMv24"
|
||||||
GameId: "c0deda99-bb15-47a2-a3be-f1fe2983cde2"
|
GameId: "c0deda99-bb15-47a2-a3be-f1fe2983cde2"
|
||||||
|
|
||||||
|
AptosConf:
|
||||||
|
PrivateKey: "0xd5ff131abc602f96192d3d23531cf1577394f4997f4bffeb249fe605be688ad0"
|
||||||
|
IsTest: true
|
||||||
|
|
||||||
EarnCorn:
|
EarnCorn:
|
||||||
Spec: "" #"@every 5m"
|
Spec: "" #"@every 5m"
|
||||||
RunOnStart : false
|
RunOnStart : false
|
||||||
|
|||||||
2
go.mod
2
go.mod
@@ -1,6 +1,6 @@
|
|||||||
module nova_task
|
module nova_task
|
||||||
|
|
||||||
go 1.23.4
|
go 1.24
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/aptos-labs/aptos-go-sdk v1.4.1
|
github.com/aptos-labs/aptos-go-sdk v1.4.1
|
||||||
|
|||||||
@@ -30,6 +30,10 @@ type Config struct {
|
|||||||
SettleSpec string
|
SettleSpec string
|
||||||
HolderCheckRunOnStart bool `json:",optional"`
|
HolderCheckRunOnStart bool `json:",optional"`
|
||||||
} `json:",optional"`
|
} `json:",optional"`
|
||||||
|
AptosConf struct {
|
||||||
|
PrivateKey string
|
||||||
|
IsTest bool `json:",default=false"`
|
||||||
|
} `json:",optional"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Cron struct {
|
type Cron struct {
|
||||||
|
|||||||
309
internal/job/airdrop/airdrop.go
Normal file
309
internal/job/airdrop/airdrop.go
Normal file
@@ -0,0 +1,309 @@
|
|||||||
|
package airdrop
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"github.com/aptos-labs/aptos-go-sdk"
|
||||||
|
"github.com/aptos-labs/aptos-go-sdk/bcs"
|
||||||
|
"github.com/aptos-labs/aptos-go-sdk/crypto"
|
||||||
|
"github.com/shopspring/decimal"
|
||||||
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
|
"nova_task/internal/model"
|
||||||
|
"nova_task/internal/svc"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Airdrop struct {
|
||||||
|
ctx context.Context
|
||||||
|
cancel context.CancelFunc
|
||||||
|
svcCtx *svc.ServiceContext
|
||||||
|
client *aptos.Client
|
||||||
|
sender *aptos.Account
|
||||||
|
|
||||||
|
//payloads chan aptos.TransactionBuildPayload
|
||||||
|
//results chan aptos.TransactionSubmissionResponse
|
||||||
|
|
||||||
|
isTest bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewAirdrop(svcCtx *svc.ServiceContext) (*Airdrop, error) {
|
||||||
|
if svcCtx.Config.AptosConf.PrivateKey == "" {
|
||||||
|
return nil, errors.New("aptos private key is empty")
|
||||||
|
}
|
||||||
|
var networkConfig aptos.NetworkConfig
|
||||||
|
if svcCtx.Config.AptosConf.IsTest {
|
||||||
|
networkConfig = aptos.TestnetConfig
|
||||||
|
} else {
|
||||||
|
networkConfig = aptos.MainnetConfig
|
||||||
|
}
|
||||||
|
client, err := aptos.NewClient(networkConfig)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
privateKey := &crypto.Ed25519PrivateKey{}
|
||||||
|
err = privateKey.FromHex(svcCtx.Config.AptosConf.PrivateKey)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
sender, err := aptos.NewAccountFromSigner(privateKey)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
//payloads := make(chan aptos.TransactionBuildPayload, 100)
|
||||||
|
//results := make(chan aptos.TransactionSubmissionResponse, 100)
|
||||||
|
//
|
||||||
|
//threading.GoSafe(func() {
|
||||||
|
// client.BuildSignAndSubmitTransactions(sender, payloads, results)
|
||||||
|
//})
|
||||||
|
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
a := &Airdrop{
|
||||||
|
ctx: ctx,
|
||||||
|
svcCtx: svcCtx,
|
||||||
|
cancel: cancel,
|
||||||
|
client: client,
|
||||||
|
sender: sender,
|
||||||
|
//payloads: payloads,
|
||||||
|
//results: results,
|
||||||
|
isTest: svcCtx.Config.AptosConf.IsTest,
|
||||||
|
}
|
||||||
|
|
||||||
|
//threading.GoSafe(func() {
|
||||||
|
// for result := range results {
|
||||||
|
// a.handleResult(result)
|
||||||
|
// }
|
||||||
|
//})
|
||||||
|
|
||||||
|
return a, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *Airdrop) CoinTransferPayload(toAddress string, amount decimal.Decimal) (*aptos.EntryFunction, error) {
|
||||||
|
receiver := aptos.AccountAddress{}
|
||||||
|
err := receiver.ParseStringRelaxed(toAddress)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
amountUint64 := uint64(amount.Mul(decimal.NewFromInt(1000000)).IntPart())
|
||||||
|
if a.isTest {
|
||||||
|
contractAddress := aptos.AccountAddress{}
|
||||||
|
err = contractAddress.ParseStringRelaxed("0x43417434fd869edee76cca2a4d2301e528a1551b1d719b75c350c3c97d15b8b9")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
coinType := &aptos.TypeTag{
|
||||||
|
Value: &aptos.StructTag{
|
||||||
|
Address: contractAddress,
|
||||||
|
Module: "coins",
|
||||||
|
Name: "USDT",
|
||||||
|
TypeParams: []aptos.TypeTag{}, // USDT 没有额外的类型参数
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return aptos.CoinTransferPayload(coinType, receiver, amountUint64)
|
||||||
|
}
|
||||||
|
|
||||||
|
amountBytes, err := bcs.SerializeU64(amountUint64)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
coinType := aptos.TypeTag{
|
||||||
|
Value: &aptos.StructTag{
|
||||||
|
Address: aptos.AccountOne,
|
||||||
|
Module: "fungible_asset",
|
||||||
|
Name: "Metadata",
|
||||||
|
TypeParams: []aptos.TypeTag{}, // USDT 没有额外的类型参数
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return &aptos.EntryFunction{
|
||||||
|
Module: aptos.ModuleId{
|
||||||
|
Address: aptos.AccountOne,
|
||||||
|
Name: "primary_fungible_store",
|
||||||
|
},
|
||||||
|
Function: "transfer",
|
||||||
|
ArgTypes: []aptos.TypeTag{coinType},
|
||||||
|
Args: [][]byte{
|
||||||
|
receiver[:],
|
||||||
|
amountBytes,
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
//func (a *Airdrop) transferUsdt(id uint64, toAddress string, amount decimal.Decimal) error {
|
||||||
|
// p, err := a.CoinTransferPayload(toAddress, amount)
|
||||||
|
// if err != nil {
|
||||||
|
// return err
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// a.payloads <- aptos.TransactionBuildPayload{
|
||||||
|
// Id: id,
|
||||||
|
// Type: aptos.TransactionSubmissionTypeSingle,
|
||||||
|
// Inner: aptos.TransactionPayload{Payload: p},
|
||||||
|
// }
|
||||||
|
// result := <-a.results
|
||||||
|
// result.Id = id
|
||||||
|
// a.handleResult(result)
|
||||||
|
// return nil
|
||||||
|
//}
|
||||||
|
|
||||||
|
//func (a *Airdrop) handleResult(result aptos.TransactionSubmissionResponse) {
|
||||||
|
// if result.Err != nil {
|
||||||
|
// logx.Errorw("submit transaction error", logx.Field("err", result.Err), logx.Field("id", result.Id))
|
||||||
|
// var txHash string
|
||||||
|
// if result.Response != nil {
|
||||||
|
// txHash = result.Response.Hash
|
||||||
|
// }
|
||||||
|
// a.svcCtx.AirdropModel.SetFailed(a.ctx, uint(result.Id), txHash)
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
// if result.Response != nil {
|
||||||
|
// logx.Infow("submit transaction success", logx.Field("id", result.Id), logx.Field("txHash", result.Response.Hash))
|
||||||
|
// a.svcCtx.AirdropModel.SetTxHash(a.ctx, uint(result.Id), result.Response.Hash)
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
//func (a *Airdrop) processTx(tx *model.NhAirdropLog, isRetry bool) {
|
||||||
|
// if !a.svcCtx.AirdropModel.SetSent(a.ctx, tx.Id, "", isRetry) {
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
// err := a.transferUsdt(uint64(tx.Id), tx.Address, tx.Amount)
|
||||||
|
// if err != nil {
|
||||||
|
// logx.Errorw("transfer usdt error", logx.Field("err", err), logx.Field("id", tx.Id), logx.Field("address", tx.Address), logx.Field("amount", tx.Amount.String()))
|
||||||
|
// a.svcCtx.AirdropModel.SetIllegal(a.ctx, tx.Id)
|
||||||
|
// } else {
|
||||||
|
// logx.Infow("submit transaction success", logx.Field("id", tx.Id), logx.Field("address", tx.Address), logx.Field("amount", tx.Amount.String()))
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
func (a *Airdrop) buildTxs(tx *model.NhAirdropLog, seqNum aptos.SequenceNumber) (*aptos.SignedTransaction, error) {
|
||||||
|
p, err := a.CoinTransferPayload(tx.Address, tx.Amount)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
rx, err := a.client.BuildTransaction(a.sender.AccountAddress(), aptos.TransactionPayload{Payload: p}, seqNum)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return rx.SignedTransaction(a.sender)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *Airdrop) processTxs(txs []*model.NhAirdropLog, isRetry bool) {
|
||||||
|
var signedTransactions []*aptos.SignedTransaction
|
||||||
|
var txIds []uint
|
||||||
|
logx.Debugw("build transactions", logx.Field("count", len(txs)), logx.Field("isRetry", isRetry))
|
||||||
|
ac, err := a.client.Account(a.sender.AccountAddress())
|
||||||
|
if err != nil {
|
||||||
|
logx.Errorw("get account info error", logx.Field("err", err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
seqNo, err := ac.SequenceNumber()
|
||||||
|
if err != nil {
|
||||||
|
logx.Errorw("get account sequence number error", logx.Field("err", err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
seqNo--
|
||||||
|
for _, tx := range txs {
|
||||||
|
seqNo++
|
||||||
|
btx, err := a.buildTxs(tx, aptos.SequenceNumber(seqNo))
|
||||||
|
if err != nil {
|
||||||
|
logx.Errorw("build transaction error", logx.Field("err", err), logx.Field("id", tx.Id), logx.Field("address", tx.Address), logx.Field("amount", tx.Amount.String()))
|
||||||
|
a.svcCtx.AirdropModel.SetIllegal(a.ctx, tx.Id)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
var txHash string
|
||||||
|
if hash, err := btx.Hash(); err == nil {
|
||||||
|
txHash = hash
|
||||||
|
}
|
||||||
|
if !a.svcCtx.AirdropModel.SetSent(a.ctx, tx.Id, txHash, isRetry) {
|
||||||
|
logx.Infow("set sent error", logx.Field("id", tx.Id), logx.Field("address", tx.Address), logx.Field("amount", tx.Amount.String()))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
signedTransactions = append(signedTransactions, btx)
|
||||||
|
txIds = append(txIds, tx.Id)
|
||||||
|
logx.Debugw("build transaction success", logx.Field("id", tx.Id), logx.Field("address", tx.Address), logx.Field("amount", tx.Amount.String()))
|
||||||
|
}
|
||||||
|
faileds, err := a.client.BatchSubmitTransaction(signedTransactions)
|
||||||
|
if err != nil {
|
||||||
|
logx.Errorw("submit transaction error", logx.Field("err", err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tf := range faileds.TransactionFailures {
|
||||||
|
ix := signedTransactions[int(tf.TransactionIndex)]
|
||||||
|
var txHash string
|
||||||
|
if hash, err := ix.Hash(); err == nil {
|
||||||
|
txHash = hash
|
||||||
|
}
|
||||||
|
|
||||||
|
id := txIds[int(tf.TransactionIndex)]
|
||||||
|
|
||||||
|
logx.Errorw("submit transaction error", logx.Field("err", tf.Error), logx.Field("id", id), logx.Field("txHash", txHash))
|
||||||
|
a.svcCtx.AirdropModel.SetFailed(a.ctx, id, txHash)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *Airdrop) checkTx(t *model.NhAirdropLog) {
|
||||||
|
tx, err := a.client.TransactionByHash(t.TxHash)
|
||||||
|
if err != nil {
|
||||||
|
logx.Errorw("get transaction by hash error", logx.Field("err", err), logx.Field("hash", t.TxHash), logx.Field("id", t.Id))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
success := tx.Success()
|
||||||
|
if success != nil && *success {
|
||||||
|
logx.Infow("transaction success", logx.Field("hash", t.TxHash), logx.Field("id", t.Id), logx.Field("address", t.Address), logx.Field("amount", t.Amount.String()))
|
||||||
|
a.svcCtx.AirdropModel.SetSuccess(a.ctx, t.Id)
|
||||||
|
} else {
|
||||||
|
logx.Infow("transaction not success", logx.Field("hash", t.TxHash), logx.Field("id", t.Id))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *Airdrop) Start() {
|
||||||
|
newImportTk := time.NewTicker(time.Second * 10)
|
||||||
|
checkTk := time.NewTicker(time.Second * 13)
|
||||||
|
retryTk := time.NewTicker(time.Second * 17)
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-a.ctx.Done():
|
||||||
|
return
|
||||||
|
case <-newImportTk.C:
|
||||||
|
txs, err := a.svcCtx.AirdropModel.FindAirdropNewImportList(a.ctx, 100)
|
||||||
|
if err != nil {
|
||||||
|
logx.Errorw("find airdrop list error", logx.Field("err", err))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if len(txs) == 0 {
|
||||||
|
logx.Debugw("find airdrop list empty", logx.Field("count", len(txs)))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
a.processTxs(txs, false)
|
||||||
|
case <-checkTk.C:
|
||||||
|
txs, err := a.svcCtx.AirdropModel.FindRequireCheckList(a.ctx, 100)
|
||||||
|
if err != nil {
|
||||||
|
logx.Errorw("find airdrop list error", logx.Field("err", err))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
for _, tx := range txs {
|
||||||
|
a.checkTx(tx)
|
||||||
|
}
|
||||||
|
case <-retryTk.C:
|
||||||
|
txs, err := a.svcCtx.AirdropModel.FindAirdropFailedList(a.ctx, 100)
|
||||||
|
if err != nil {
|
||||||
|
logx.Errorw("find airdrop filed list error", logx.Field("err", err))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if len(txs) == 0 {
|
||||||
|
logx.Debugw("find airdrop filed list empty", logx.Field("count", len(txs)))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
a.processTxs(txs, true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *Airdrop) Stop() {
|
||||||
|
a.cancel()
|
||||||
|
//close(a.payloads)
|
||||||
|
//close(a.results)
|
||||||
|
}
|
||||||
@@ -1,116 +0,0 @@
|
|||||||
package apt
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/aptos-labs/aptos-go-sdk"
|
|
||||||
"github.com/aptos-labs/aptos-go-sdk/crypto"
|
|
||||||
"github.com/zeromicro/go-zero/core/threading"
|
|
||||||
"nova_task/internal/svc"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Apt struct {
|
|
||||||
svcCtx svc.ServiceContext
|
|
||||||
client *aptos.Client
|
|
||||||
sender *aptos.Account
|
|
||||||
|
|
||||||
payloads chan aptos.TransactionBuildPayload
|
|
||||||
results chan aptos.TransactionSubmissionResponse
|
|
||||||
|
|
||||||
isTest bool
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewApt(svcCtx svc.ServiceContext, privateKeyStr string, isTest bool) (*Apt, error) {
|
|
||||||
var networkConfig aptos.NetworkConfig
|
|
||||||
if isTest {
|
|
||||||
networkConfig = aptos.TestnetConfig
|
|
||||||
} else {
|
|
||||||
networkConfig = aptos.MainnetConfig
|
|
||||||
}
|
|
||||||
client, err := aptos.NewClient(networkConfig)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
privateKey := &crypto.Ed25519PrivateKey{}
|
|
||||||
err = privateKey.FromHex(privateKeyStr)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
sender, err := aptos.NewAccountFromSigner(privateKey)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
payloads := make(chan aptos.TransactionBuildPayload, 100)
|
|
||||||
results := make(chan aptos.TransactionSubmissionResponse, 100)
|
|
||||||
|
|
||||||
threading.GoSafe(func() {
|
|
||||||
client.BuildSignAndSubmitTransactions(sender, payloads, results)
|
|
||||||
})
|
|
||||||
|
|
||||||
a := &Apt{
|
|
||||||
client: client,
|
|
||||||
sender: sender,
|
|
||||||
payloads: payloads,
|
|
||||||
results: results,
|
|
||||||
isTest: isTest,
|
|
||||||
}
|
|
||||||
|
|
||||||
threading.GoSafe(func() {
|
|
||||||
for result := range results {
|
|
||||||
a.handleResult(result)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return a, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *Apt) transferUsdt(id uint64, toAddress string, amount uint64) error {
|
|
||||||
receiver := aptos.AccountAddress{}
|
|
||||||
err := receiver.ParseStringRelaxed(toAddress)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// 0x1::primary_fungible_store::transfer
|
|
||||||
// fungible_asset::Metadata
|
|
||||||
contractAddress := aptos.AccountAddress{}
|
|
||||||
err = receiver.ParseStringRelaxed("0x43417434fd869edee76cca2a4d2301e528a1551b1d719b75c350c3c97d15b8b9")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
coinType := &aptos.TypeTag{
|
|
||||||
Value: &aptos.StructTag{
|
|
||||||
Address: contractAddress,
|
|
||||||
Module: "coin",
|
|
||||||
Name: "USDT",
|
|
||||||
TypeParams: []aptos.TypeTag{}, // USDT 没有额外的类型参数
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
p, err := aptos.CoinTransferPayload(coinType, receiver, amount)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
a.payloads <- aptos.TransactionBuildPayload{
|
|
||||||
Id: id,
|
|
||||||
Type: aptos.TransactionSubmissionTypeSingle,
|
|
||||||
Inner: aptos.TransactionPayload{Payload: p},
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *Apt) handleResult(result aptos.TransactionSubmissionResponse) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *Apt) Start() {
|
|
||||||
a.svcCtx.
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *Apt) Stop() {
|
|
||||||
close(a.payloads)
|
|
||||||
close(a.results)
|
|
||||||
}
|
|
||||||
@@ -18,7 +18,7 @@ var cronList = []func(context.Context, *svc.ServiceContext) cron.Job{
|
|||||||
stake_settle.NewCron,
|
stake_settle.NewCron,
|
||||||
}
|
}
|
||||||
|
|
||||||
type Job struct {
|
type Corns struct {
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
cancel context.CancelFunc
|
cancel context.CancelFunc
|
||||||
svcCtx *svc.ServiceContext
|
svcCtx *svc.ServiceContext
|
||||||
@@ -29,8 +29,8 @@ type Spec interface {
|
|||||||
Spec() string
|
Spec() string
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewJob 创建定时器服务
|
// NewCorns 创建定时器服务
|
||||||
func NewJob(svcCtx *svc.ServiceContext) *Job {
|
func newCorns(svcCtx *svc.ServiceContext) *Corns {
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
var err error
|
var err error
|
||||||
c := cron.New(cron.WithSeconds())
|
c := cron.New(cron.WithSeconds())
|
||||||
@@ -39,7 +39,7 @@ func NewJob(svcCtx *svc.ServiceContext) *Job {
|
|||||||
if cs, ok := cr.(Spec); ok {
|
if cs, ok := cr.(Spec); ok {
|
||||||
spec := cs.Spec()
|
spec := cs.Spec()
|
||||||
if spec == "" {
|
if spec == "" {
|
||||||
logx.Errorw("cron job spec is empty")
|
logx.Errorw("cron Corns spec is empty")
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
_, err = c.AddJob(spec, cr)
|
_, err = c.AddJob(spec, cr)
|
||||||
@@ -51,9 +51,9 @@ func NewJob(svcCtx *svc.ServiceContext) *Job {
|
|||||||
c.Schedule(cs, cr)
|
c.Schedule(cs, cr)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
logx.Must(errors.New("cron job must implement either Spec or Schedule interface"))
|
logx.Must(errors.New("cron Corns must implement either Spec or Schedule interface"))
|
||||||
}
|
}
|
||||||
return &Job{
|
return &Corns{
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
cancel: cancel,
|
cancel: cancel,
|
||||||
svcCtx: svcCtx,
|
svcCtx: svcCtx,
|
||||||
@@ -61,14 +61,14 @@ func NewJob(svcCtx *svc.ServiceContext) *Job {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (j *Job) Start() {
|
func (j *Corns) Start() {
|
||||||
logx.Info("start cron job")
|
logx.Info("start cron Corns")
|
||||||
j.c.Start()
|
j.c.Start()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (j *Job) Stop() {
|
func (j *Corns) Stop() {
|
||||||
logx.Info("stop cron job")
|
logx.Info("stop cron Corns")
|
||||||
<-j.c.Stop().Done()
|
<-j.c.Stop().Done()
|
||||||
logx.Info("cron job stopped")
|
logx.Info("cron Corns stopped")
|
||||||
j.cancel()
|
j.cancel()
|
||||||
}
|
}
|
||||||
21
internal/job/jobs.go
Normal file
21
internal/job/jobs.go
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
package job
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
|
"github.com/zeromicro/go-zero/core/service"
|
||||||
|
"nova_task/internal/job/airdrop"
|
||||||
|
"nova_task/internal/svc"
|
||||||
|
)
|
||||||
|
|
||||||
|
func BuildJobs(svcCtx *svc.ServiceContext) []service.Service {
|
||||||
|
ss := []service.Service{
|
||||||
|
newCorns(svcCtx),
|
||||||
|
}
|
||||||
|
airdropService, err := airdrop.NewAirdrop(svcCtx)
|
||||||
|
if err != nil {
|
||||||
|
logx.Errorw("airdrop service init error", logx.Field("err", err))
|
||||||
|
} else {
|
||||||
|
ss = append(ss, airdropService)
|
||||||
|
}
|
||||||
|
return ss
|
||||||
|
}
|
||||||
162
internal/model/nh_airdrop_log_model.go
Executable file
162
internal/model/nh_airdrop_log_model.go
Executable file
@@ -0,0 +1,162 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
|
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ NhAirdropLogModel = (*customNhAirdropLogModel)(nil)
|
||||||
|
|
||||||
|
const (
|
||||||
|
AirdropStatusNewImport StatusType = "新导入"
|
||||||
|
AirdropStatusSent StatusType = "已发送交易"
|
||||||
|
AirdropStatusSuccess StatusType = "交易成功"
|
||||||
|
AirdropStatusFailed StatusType = "交易失败"
|
||||||
|
AirdropStatusReSent StatusType = "已重新发送交易"
|
||||||
|
AirdropStatusIllegal StatusType = "非法交易"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
// NhAirdropLogModel is an interface to be customized, add more methods here,
|
||||||
|
// and implement the added methods in customNhAirdropLogModel.
|
||||||
|
NhAirdropLogModel interface {
|
||||||
|
nhAirdropLogModel
|
||||||
|
withSession(session sqlx.Session) NhAirdropLogModel
|
||||||
|
FindAirdropNewImportList(ctx context.Context, count int) ([]*NhAirdropLog, error)
|
||||||
|
FindAirdropFailedList(ctx context.Context, count int) ([]*NhAirdropLog, error)
|
||||||
|
FindRequireCheckList(ctx context.Context, count int) ([]*NhAirdropLog, error)
|
||||||
|
SetSent(ctx context.Context, id uint, txHash string, isRetry bool) bool
|
||||||
|
SetIllegal(ctx context.Context, id uint) bool
|
||||||
|
SetSuccess(ctx context.Context, id uint) bool
|
||||||
|
SetFailed(ctx context.Context, id uint, txHash string) bool
|
||||||
|
SetTxHash(ctx context.Context, id uint, txHash string)
|
||||||
|
}
|
||||||
|
|
||||||
|
customNhAirdropLogModel struct {
|
||||||
|
*defaultNhAirdropLogModel
|
||||||
|
}
|
||||||
|
StatusType string
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewNhAirdropLogModel returns a model for the database table.
|
||||||
|
func NewNhAirdropLogModel(conn sqlx.SqlConn) NhAirdropLogModel {
|
||||||
|
return &customNhAirdropLogModel{
|
||||||
|
defaultNhAirdropLogModel: newNhAirdropLogModel(conn),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *customNhAirdropLogModel) SetTxHash(ctx context.Context, id uint, txHash string) {
|
||||||
|
update := fmt.Sprintf("update %s set `tx_hash` = ? where `id` = ?", m.table)
|
||||||
|
_, err := m.conn.ExecCtx(ctx, update, txHash, id)
|
||||||
|
if err != nil {
|
||||||
|
logx.Errorw("set txHash error", logx.Field("err", err), logx.Field("id", id))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *customNhAirdropLogModel) SetFailed(ctx context.Context, id uint, txHash string) bool {
|
||||||
|
update := fmt.Sprintf("update %s set `status` = '%s', `tx_hash` = ? where `id` = ? and (`status` = '%s' or `status` = '%s')", m.table, AirdropStatusFailed, AirdropStatusSent, AirdropStatusReSent)
|
||||||
|
result, err := m.conn.ExecCtx(ctx, update, txHash, id)
|
||||||
|
if err != nil {
|
||||||
|
logx.Errorw("set failed error", logx.Field("err", err), logx.Field("id", id))
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
rows, err := result.RowsAffected()
|
||||||
|
if err != nil {
|
||||||
|
logx.Errorw("set failed RowsAffected error", logx.Field("err", err), logx.Field("id", id))
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return rows > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *customNhAirdropLogModel) SetSuccess(ctx context.Context, id uint) bool {
|
||||||
|
update := fmt.Sprintf("update %s set `status` = '%s' where `id` = ? and (`status` = '%s' or `status` = '%s')", m.table, AirdropStatusSuccess, AirdropStatusSent, AirdropStatusReSent)
|
||||||
|
result, err := m.conn.ExecCtx(ctx, update, id)
|
||||||
|
if err != nil {
|
||||||
|
logx.Errorw("set success error", logx.Field("err", err), logx.Field("id", id))
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
rows, err := result.RowsAffected()
|
||||||
|
if err != nil {
|
||||||
|
logx.Errorw("set success RowsAffected error", logx.Field("err", err), logx.Field("id", id))
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return rows > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t StatusType) String() string {
|
||||||
|
return string(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *customNhAirdropLogModel) SetIllegal(ctx context.Context, id uint) bool {
|
||||||
|
update := fmt.Sprintf("update %s set `status` = '%s' where `id` = ? and (`status` = '%s' or `status` = '%s')", m.table, AirdropStatusIllegal, AirdropStatusSent, AirdropStatusReSent)
|
||||||
|
result, err := m.conn.ExecCtx(ctx, update, id)
|
||||||
|
if err != nil {
|
||||||
|
logx.Errorw("set illegal error", logx.Field("err", err), logx.Field("id", id))
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
rows, err := result.RowsAffected()
|
||||||
|
if err != nil {
|
||||||
|
logx.Errorw("set illegal RowsAffected error", logx.Field("err", err), logx.Field("id", id))
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return rows > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *customNhAirdropLogModel) SetSent(ctx context.Context, id uint, txHash string, isRetry bool) bool {
|
||||||
|
var update string
|
||||||
|
if isRetry {
|
||||||
|
update = fmt.Sprintf("update %s set `status` = '%s', `tx_hash` = ?, `submit_at` = ? where `id` = ? and `status` = '%s'", m.table, AirdropStatusReSent, AirdropStatusFailed)
|
||||||
|
} else {
|
||||||
|
update = fmt.Sprintf("update %s set `status` = '%s', `tx_hash` = ?, `submit_at` = ? where `id` = ? and `status` = '%s'", m.table, AirdropStatusSent, AirdropStatusNewImport)
|
||||||
|
}
|
||||||
|
|
||||||
|
result, err := m.conn.ExecCtx(ctx, update, txHash, time.Now(), id)
|
||||||
|
if err != nil {
|
||||||
|
logx.Errorw("set sent error", logx.Field("err", err), logx.Field("id", id))
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
rows, err := result.RowsAffected()
|
||||||
|
if err != nil {
|
||||||
|
logx.Errorw("set sent RowsAffected error", logx.Field("err", err), logx.Field("id", id))
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return rows > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *customNhAirdropLogModel) FindAirdropNewImportList(ctx context.Context, count int) ([]*NhAirdropLog, error) {
|
||||||
|
query := fmt.Sprintf("select %s from %s where `status` = '%s' and `is_del` = 0 limit ?", nhAirdropLogRows, m.table, AirdropStatusNewImport)
|
||||||
|
var tasks []*NhAirdropLog
|
||||||
|
err := m.conn.QueryRowsCtx(ctx, &tasks, query, count)
|
||||||
|
if err != nil && !errors.Is(err, sqlx.ErrNotFound) {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return tasks, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *customNhAirdropLogModel) FindAirdropFailedList(ctx context.Context, count int) ([]*NhAirdropLog, error) {
|
||||||
|
query := fmt.Sprintf("select %s from %s where `status` = '%s' and `is_del` = 0 limit ?", nhAirdropLogRows, m.table, AirdropStatusFailed)
|
||||||
|
var tasks []*NhAirdropLog
|
||||||
|
err := m.conn.QueryRowsCtx(ctx, &tasks, query, count)
|
||||||
|
if err != nil && !errors.Is(err, sqlx.ErrNotFound) {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return tasks, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *customNhAirdropLogModel) FindRequireCheckList(ctx context.Context, count int) ([]*NhAirdropLog, error) {
|
||||||
|
query := fmt.Sprintf("select %s from %s where (`status` = '%s' or `status` = '%s') and `is_del` = 0 limit ?", nhAirdropLogRows, m.table, AirdropStatusSent, AirdropStatusReSent)
|
||||||
|
var tasks []*NhAirdropLog
|
||||||
|
err := m.conn.QueryRowsCtx(ctx, &tasks, query, count)
|
||||||
|
if err != nil && !errors.Is(err, sqlx.ErrNotFound) {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return tasks, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *customNhAirdropLogModel) withSession(session sqlx.Session) NhAirdropLogModel {
|
||||||
|
return NewNhAirdropLogModel(sqlx.NewSqlConnFromSession(session))
|
||||||
|
}
|
||||||
98
internal/model/nh_airdrop_log_model_gen.go
Executable file
98
internal/model/nh_airdrop_log_model_gen.go
Executable file
@@ -0,0 +1,98 @@
|
|||||||
|
// Code generated by goctl. DO NOT EDIT.
|
||||||
|
// versions:
|
||||||
|
// goctl version: 1.7.6
|
||||||
|
|
||||||
|
package model
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"database/sql"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/core/stores/builder"
|
||||||
|
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||||
|
"github.com/zeromicro/go-zero/core/stringx"
|
||||||
|
|
||||||
|
"github.com/shopspring/decimal"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
nhAirdropLogFieldNames = builder.RawFieldNames(&NhAirdropLog{})
|
||||||
|
nhAirdropLogRows = strings.Join(nhAirdropLogFieldNames, ",")
|
||||||
|
nhAirdropLogRowsExpectAutoSet = strings.Join(stringx.Remove(nhAirdropLogFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), ",")
|
||||||
|
nhAirdropLogRowsWithPlaceHolder = strings.Join(stringx.Remove(nhAirdropLogFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), "=?,") + "=?"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
nhAirdropLogModel interface {
|
||||||
|
Insert(ctx context.Context, data *NhAirdropLog) (sql.Result, error)
|
||||||
|
FindOne(ctx context.Context, id uint) (*NhAirdropLog, error)
|
||||||
|
Update(ctx context.Context, data *NhAirdropLog) error
|
||||||
|
Delete(ctx context.Context, id uint) error
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultNhAirdropLogModel struct {
|
||||||
|
conn sqlx.SqlConn
|
||||||
|
table string
|
||||||
|
}
|
||||||
|
|
||||||
|
NhAirdropLog struct {
|
||||||
|
Id uint `db:"id"`
|
||||||
|
Address string `db:"address"` // 用户钱包地址
|
||||||
|
Amount decimal.Decimal `db:"amount"` // 空投数量
|
||||||
|
Status string `db:"status"` // 状态
|
||||||
|
TxHash string `db:"tx_hash"` // 交易hash
|
||||||
|
SubmitAt sql.NullTime `db:"submit_at"` // 提交时间
|
||||||
|
BatchDate sql.NullTime `db:"batch_date"` // 批次-日期
|
||||||
|
BatchNum uint `db:"batch_num"` // 批次-数量
|
||||||
|
AdminId uint `db:"admin_id"` // 管理员ID
|
||||||
|
IsDel int8 `db:"is_del"` // 是否已删除:0否,1是
|
||||||
|
CreatedAt time.Time `db:"created_at"` // 创建时间
|
||||||
|
UpdatedAt time.Time `db:"updated_at"` // 修改时间
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func newNhAirdropLogModel(conn sqlx.SqlConn) *defaultNhAirdropLogModel {
|
||||||
|
return &defaultNhAirdropLogModel{
|
||||||
|
conn: conn,
|
||||||
|
table: "`nh_airdrop_log`",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultNhAirdropLogModel) Delete(ctx context.Context, id uint) error {
|
||||||
|
query := fmt.Sprintf("delete from %s where `id` = ?", m.table)
|
||||||
|
_, err := m.conn.ExecCtx(ctx, query, id)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultNhAirdropLogModel) FindOne(ctx context.Context, id uint) (*NhAirdropLog, error) {
|
||||||
|
query := fmt.Sprintf("select %s from %s where `id` = ? limit 1", nhAirdropLogRows, m.table)
|
||||||
|
var resp NhAirdropLog
|
||||||
|
err := m.conn.QueryRowCtx(ctx, &resp, query, id)
|
||||||
|
switch err {
|
||||||
|
case nil:
|
||||||
|
return &resp, nil
|
||||||
|
case sqlx.ErrNotFound:
|
||||||
|
return nil, ErrNotFound
|
||||||
|
default:
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultNhAirdropLogModel) Insert(ctx context.Context, data *NhAirdropLog) (sql.Result, error) {
|
||||||
|
query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?, ?, ?, ?, ?, ?, ?)", m.table, nhAirdropLogRowsExpectAutoSet)
|
||||||
|
ret, err := m.conn.ExecCtx(ctx, query, data.Address, data.Amount, data.Status, data.TxHash, data.SubmitAt, data.BatchDate, data.BatchNum, data.AdminId, data.IsDel)
|
||||||
|
return ret, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultNhAirdropLogModel) Update(ctx context.Context, data *NhAirdropLog) error {
|
||||||
|
query := fmt.Sprintf("update %s set %s where `id` = ?", m.table, nhAirdropLogRowsWithPlaceHolder)
|
||||||
|
_, err := m.conn.ExecCtx(ctx, query, data.Address, data.Amount, data.Status, data.TxHash, data.SubmitAt, data.BatchDate, data.BatchNum, data.AdminId, data.IsDel, data.Id)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultNhAirdropLogModel) tableName() string {
|
||||||
|
return m.table
|
||||||
|
}
|
||||||
@@ -46,6 +46,7 @@ type ServiceContext struct {
|
|||||||
GameReportModel model.NhGameReportModel
|
GameReportModel model.NhGameReportModel
|
||||||
RoleModel model.NhRoleModel
|
RoleModel model.NhRoleModel
|
||||||
GamesPropertyModel model.NhGamesPropertyLogsModel
|
GamesPropertyModel model.NhGamesPropertyLogsModel
|
||||||
|
AirdropModel model.NhAirdropLogModel
|
||||||
|
|
||||||
ApiKeyCheck rest.Middleware
|
ApiKeyCheck rest.Middleware
|
||||||
AdminSecretCheck rest.Middleware
|
AdminSecretCheck rest.Middleware
|
||||||
@@ -86,6 +87,7 @@ func NewServiceContext(c config.Config) *ServiceContext {
|
|||||||
GameReportModel: model.NewNhGameReportModel(dbConn),
|
GameReportModel: model.NewNhGameReportModel(dbConn),
|
||||||
RoleModel: model.NewNhRoleModel(dbConn),
|
RoleModel: model.NewNhRoleModel(dbConn),
|
||||||
GamesPropertyModel: model.NewNhGamesPropertyLogsModel(dbConn),
|
GamesPropertyModel: model.NewNhGamesPropertyLogsModel(dbConn),
|
||||||
|
AirdropModel: model.NewNhAirdropLogModel(dbConn),
|
||||||
|
|
||||||
ApiKeyCheck: middleware.NewApiKeyCheckMiddleware(configModel).Handle,
|
ApiKeyCheck: middleware.NewApiKeyCheckMiddleware(configModel).Handle,
|
||||||
AdminSecretCheck: middleware.NewAdminSecretCheckMiddleware(configModel).Handle,
|
AdminSecretCheck: middleware.NewAdminSecretCheckMiddleware(configModel).Handle,
|
||||||
|
|||||||
@@ -29,8 +29,10 @@ func main() {
|
|||||||
serviceGroup := service.NewServiceGroup()
|
serviceGroup := service.NewServiceGroup()
|
||||||
defer serviceGroup.Stop()
|
defer serviceGroup.Stop()
|
||||||
|
|
||||||
jb := job.NewJob(ctx)
|
jbs := job.BuildJobs(ctx)
|
||||||
|
for _, jb := range jbs {
|
||||||
serviceGroup.Add(jb)
|
serviceGroup.Add(jb)
|
||||||
|
}
|
||||||
|
|
||||||
httpSvr := rest.MustNewServer(c.RestConf, rest.WithCors(), errs.WithUnauthorizedCallback())
|
httpSvr := rest.MustNewServer(c.RestConf, rest.WithCors(), errs.WithUnauthorizedCallback())
|
||||||
handler.RegisterHandlers(httpSvr, ctx)
|
handler.RegisterHandlers(httpSvr, ctx)
|
||||||
|
|||||||
Reference in New Issue
Block a user