This commit is contained in:
daichao
2025-02-19 09:41:05 +08:00
parent 935fc36b5a
commit 747d8de9b5
4 changed files with 783 additions and 1 deletions

View File

@ -4,6 +4,7 @@ import (
"context"
"errors"
"fmt"
"github.com/bytedance/sonic"
"go-admin/app/admin/models"
"go-admin/app/admin/service"
"go-admin/app/admin/service/dto"
@ -14,6 +15,12 @@ import (
"go-admin/pkg/utility/snowflakehelper"
"go-admin/services/binanceservice"
"go-admin/services/fileservice"
"io"
"net/http"
"os"
"os/exec"
"path/filepath"
"slices"
"strconv"
"strings"
"time"
@ -41,6 +48,9 @@ type AutoPlaceOrder struct {
type LimitOrderTimeoutDuration struct {
}
type ListenSymbol struct {
}
// 初始化合约交易对
func (t InitFuturesSymbol) Exec(arg interface{}) error {
str := time.Now().Format(timeFormat) + " [INFO] JobCore InitFuturesSymbol exec success"
@ -319,3 +329,166 @@ func (t LimitOrderTimeoutDuration) ReFutOrderPlace(db *gorm.DB, order models.Lin
}
return err
}
func (l ListenSymbol) Exec(arg interface{}) error {
str := time.Now().Format(timeFormat) + " [INFO] JobCore ClearLogJob exec success"
defer logger.Info(str)
var db *gorm.DB
for _, item := range sdk.Runtime.GetDb() {
db = item
break
}
set, err := helper.DefaultRedis.GetAllSortSet(rediskey.ListenAveLastSymbol)
if err != nil {
logger.Error("获取监听交易对失败")
return err
}
fmt.Println(set)
//if len(set) == 0 {
// return nil
//}
aveToken, _ := helper.DefaultRedis.GetString(rediskey.AveRequestToken)
if aveToken == "" {
aveToken, err = l.GetAveRequestId()
if err != nil {
logger.Error("获取请求id失败err:", err)
return err
}
}
chainSlice := []string{"solana", "bsc", "eth"}
for _, chain := range chainSlice {
symbols, err := l.GetAveLastSymbol(chain, aveToken)
if err != nil {
continue
}
for _, symbol := range symbols.Data.Data {
if slices.Contains(set, symbol.Token0Symbol+symbol.Token1Symbol) {
// 清除数据
//发送邮箱
l.SendEmailNotice(db, symbol.Pair, symbol.Token0Symbol+symbol.Token1Symbol, chain)
continue
}
}
}
return nil
}
// GetAveRequestId 获取请求id
func (l ListenSymbol) GetAveRequestId() (aveToken string, err error) {
execPath, err := os.Getwd()
// 获取可执行文件所在的目录
execDir := fmt.Sprintf("%s/config/ave.js", filepath.Dir(filepath.Dir(execPath)))
_, err = os.Stat(execDir)
if err != nil {
logger.Error("可执行的js 文件不存在")
return aveToken, err
}
command := exec.Command("node", execDir)
output, err := command.CombinedOutput()
if err != nil {
logger.Error("执行出错:err", err)
return aveToken, err
}
client := &http.Client{}
m := map[string]string{
"request_id": string(output),
}
marshal, _ := sonic.Marshal(m)
var data = strings.NewReader(string(marshal))
req, err := http.NewRequest("POST", "https://febweb002.com/v1api/v1/captcha/requestToken", data)
if err != nil {
return aveToken, err
}
req.Header.Set("accept", "*/*")
req.Header.Set("accept-language", "zh-CN,zh;q=0.9")
req.Header.Set("ave-platform", "web")
req.Header.Set("content-type", "application/json")
req.Header.Set("origin", "https://ave.ai")
req.Header.Set("priority", "u=1, i")
req.Header.Set("referer", "https://ave.ai/")
req.Header.Set("sec-ch-ua", `"Not A(Brand";v="8", "Chromium";v="132", "Google Chrome";v="132"`)
req.Header.Set("sec-ch-ua-mobile", "?0")
req.Header.Set("sec-ch-ua-platform", `"Windows"`)
req.Header.Set("sec-fetch-dest", "empty")
req.Header.Set("sec-fetch-mode", "cors")
req.Header.Set("sec-fetch-site", "cross-site")
req.Header.Set("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36")
resp, err := client.Do(req)
if err != nil {
logger.Error("请求失败err:", err)
return aveToken, err
}
defer resp.Body.Close()
bodyText, err := io.ReadAll(resp.Body)
if err != nil {
logger.Error("读取响应失败err:", err)
return aveToken, err
}
var res RequestId
sonic.Unmarshal(bodyText, &res)
if res.Status == 1 {
aveToken = res.Data.Id
helper.DefaultRedis.SetStringExpire(rediskey.AveRequestToken, res.Data.Id, time.Duration(60*time.Second))
}
return aveToken, err
}
func (l ListenSymbol) GetAveLastSymbol(chain, token string) (aveLastSymbolResp AveLastSymbolResp, err error) {
client := &http.Client{}
url := fmt.Sprintf("https://api.agacve.com/v1api/v4/tokens/treasure/list?chain=%s&sort=created_at&sort_dir=desc&pageNO=1&pageSize=50&category=new&refresh_total=0", chain)
req, err := http.NewRequest("GET", url, nil)
if err != nil {
logger.Error("获取最新交易对列表出错err:", err)
return AveLastSymbolResp{}, err
}
req.Header.Set("accept", "application/json, text/plain, */*")
req.Header.Set("accept-language", "zh-CN,zh;q=0.9")
req.Header.Set("ave-udid", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36--1739784205001--97086a46-bce0-4ca9-8e0e-78f5075be306")
req.Header.Set("cache-control", "no-cache")
req.Header.Set("lang", "en")
req.Header.Set("origin", "https://ave.ai")
req.Header.Set("pragma", "no-cache")
req.Header.Set("priority", "u=1, i")
req.Header.Set("referer", "https://ave.ai/")
req.Header.Set("sec-ch-ua", `"Not A(Brand";v="8", "Chromium";v="132", "Google Chrome";v="132"`)
req.Header.Set("sec-ch-ua-mobile", "?0")
req.Header.Set("sec-ch-ua-platform", `"Windows"`)
req.Header.Set("sec-fetch-dest", "empty")
req.Header.Set("sec-fetch-mode", "cors")
req.Header.Set("sec-fetch-site", "cross-site")
req.Header.Set("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36")
req.Header.Set("x-auth", token)
resp, err := client.Do(req)
if err != nil {
logger.Error("获取最新交易对列表出错1err:", err)
return AveLastSymbolResp{}, err
}
defer resp.Body.Close()
bodyText, err := io.ReadAll(resp.Body)
if err != nil {
logger.Error("获取最新交易对列表出错2err:", err)
return AveLastSymbolResp{}, err
}
var res AveLastSymbolResp
sonic.Unmarshal(bodyText, &res)
return res, nil
}
// SendEmailNotice 发送邮箱通知
// pair 合约地址
// symbol 完整交易对
// chain 链
func (l ListenSymbol) SendEmailNotice(db *gorm.DB, pair string, symbol string, chain string) {
}

View File

@ -1,6 +1,9 @@
package jobs
import "github.com/robfig/cron/v3"
import (
"github.com/robfig/cron/v3"
"time"
)
type Job interface {
Run()
@ -14,3 +17,188 @@ type JobExec interface {
func CallExec(e JobExec, arg interface{}) error {
return e.Exec(arg)
}
type RequestId struct {
Status int `json:"status"`
Msg string `json:"msg"`
Data struct {
Id string `json:"id"`
Image string `json:"image"`
} `json:"data"`
}
// AveLastSymbolResp 最新交易对列表
type AveLastSymbolResp struct {
Status int `json:"status"`
Msg string `json:"msg"`
Data struct {
Total int `json:"total"`
PageNO int `json:"pageNO"`
PageSize int `json:"pageSize"`
Data []struct {
Pair string `json:"pair"`
Chain string `json:"chain"`
Amm string `json:"amm"`
TargetToken string `json:"target_token"`
Token0Address string `json:"token0_address"`
Token0Symbol string `json:"token0_symbol"`
Reserve0 float64 `json:"reserve0"`
Token0LogoUrl string `json:"token0_logo_url"`
Token1Address string `json:"token1_address"`
Token1Symbol string `json:"token1_symbol"`
Reserve1 float64 `json:"reserve1"`
Token1LogoUrl string `json:"token1_logo_url"`
InitReserve0 float64 `json:"init_reserve0"`
InitReserve1 float64 `json:"init_reserve1"`
Tvl float64 `json:"tvl"`
InitTvl float64 `json:"init_tvl"`
TvlRatio float64 `json:"tvl_ratio"`
CurrentPriceUsd float64 `json:"current_price_usd"`
LpHolders int `json:"lp_holders"`
LpLockedPercent int `json:"lp_locked_percent"`
LpLockedTo time.Time `json:"lp_locked_to"`
LpLockPlatform string `json:"lp_lock_platform"`
PriceChange1M float64 `json:"price_change_1m"`
PriceChange5M float64 `json:"price_change_5m"`
PriceChange15M float64 `json:"price_change_15m"`
PriceChange30M float64 `json:"price_change_30m"`
PriceChange1H float64 `json:"price_change_1h"`
PriceChange4H float64 `json:"price_change_4h"`
PriceChange24H float64 `json:"price_change_24h"`
Tx1MCount int `json:"tx_1m_count"`
Tx5MCount int `json:"tx_5m_count"`
Tx15MCount int `json:"tx_15m_count"`
Tx30MCount int `json:"tx_30m_count"`
Tx1HCount int `json:"tx_1h_count"`
Tx4HCount int `json:"tx_4h_count"`
Tx24HCount int `json:"tx_24h_count"`
BuysTx1MCount int `json:"buys_tx_1m_count"`
BuysTx5MCount int `json:"buys_tx_5m_count"`
BuysTx15MCount int `json:"buys_tx_15m_count"`
BuysTx30MCount int `json:"buys_tx_30m_count"`
BuysTx1HCount int `json:"buys_tx_1h_count"`
BuysTx4HCount int `json:"buys_tx_4h_count"`
BuysTx24HCount int `json:"buys_tx_24h_count"`
SellsTx1MCount int `json:"sells_tx_1m_count"`
SellsTx5MCount int `json:"sells_tx_5m_count"`
SellsTx15MCount int `json:"sells_tx_15m_count"`
SellsTx30MCount int `json:"sells_tx_30m_count"`
SellsTx1HCount int `json:"sells_tx_1h_count"`
SellsTx4HCount int `json:"sells_tx_4h_count"`
SellsTx24HCount int `json:"sells_tx_24h_count"`
VolumeU1M float64 `json:"volume_u_1m"`
VolumeU5M float64 `json:"volume_u_5m"`
VolumeU15M float64 `json:"volume_u_15m"`
VolumeU30M float64 `json:"volume_u_30m"`
VolumeU1H float64 `json:"volume_u_1h"`
VolumeU4H float64 `json:"volume_u_4h"`
VolumeU24H float64 `json:"volume_u_24h"`
BuyVolumeU1M float64 `json:"buy_volume_u_1m"`
BuyVolumeU5M float64 `json:"buy_volume_u_5m"`
BuyVolumeU15M float64 `json:"buy_volume_u_15m"`
BuyVolumeU30M float64 `json:"buy_volume_u_30m"`
BuyVolumeU1H float64 `json:"buy_volume_u_1h"`
BuyVolumeU4H float64 `json:"buy_volume_u_4h"`
BuyVolumeU24H float64 `json:"buy_volume_u_24h"`
SellVolumeU1M float64 `json:"sell_volume_u_1m"`
SellVolumeU5M float64 `json:"sell_volume_u_5m"`
SellVolumeU15M float64 `json:"sell_volume_u_15m"`
SellVolumeU30M float64 `json:"sell_volume_u_30m"`
SellVolumeU1H float64 `json:"sell_volume_u_1h"`
SellVolumeU4H float64 `json:"sell_volume_u_4h"`
SellVolumeU24H float64 `json:"sell_volume_u_24h"`
Makers1M int `json:"makers_1m"`
Makers5M int `json:"makers_5m"`
Makers15M int `json:"makers_15m"`
Makers30M int `json:"makers_30m"`
Makers1H int `json:"makers_1h"`
Makers4H int `json:"makers_4h"`
Makers24H int `json:"makers_24h"`
Buyers1M int `json:"buyers_1m"`
Buyers5M int `json:"buyers_5m"`
Buyers15M int `json:"buyers_15m"`
Buyers30M int `json:"buyers_30m"`
Buyers1H int `json:"buyers_1h"`
Buyers4H int `json:"buyers_4h"`
Buyers24H int `json:"buyers_24h"`
Sellers1M int `json:"sellers_1m"`
Sellers5M int `json:"sellers_5m"`
Sellers15M int `json:"sellers_15m"`
Sellers30M int `json:"sellers_30m"`
Sellers1H int `json:"sellers_1h"`
Sellers4H int `json:"sellers_4h"`
Sellers24H int `json:"sellers_24h"`
CreatedAt time.Time `json:"created_at"`
SniperTxCount int `json:"sniper_tx_count"`
RusherTxCount int `json:"rusher_tx_count"`
LastTradeAt time.Time `json:"last_trade_at"`
DynamicTag string `json:"dynamic_tag"`
Tag string `json:"tag"`
MarketCap float64 `json:"market_cap"`
MarketCapDiff int `json:"market_cap_diff"`
Holders int `json:"holders"`
HoldersDiff int `json:"holders_diff"`
RiskScore int `json:"risk_score"`
RiskLevel int `json:"risk_level"`
Appendix string `json:"appendix"`
SmartMoneyBuyCount24H int `json:"smart_money_buy_count_24h"`
SmartMoneySellCount24H int `json:"smart_money_sell_count_24h"`
SmartMoneyBuyVolume24H float64 `json:"smart_money_buy_volume_24h"`
SmartMoneySellVolume24H float64 `json:"smart_money_sell_volume_24h"`
SmartMoneyBuyCount4H int `json:"smart_money_buy_count_4h"`
SmartMoneySellCount4H int `json:"smart_money_sell_count_4h"`
SmartMoneyBuyVolume4H float64 `json:"smart_money_buy_volume_4h"`
SmartMoneySellVolume4H float64 `json:"smart_money_sell_volume_4h"`
SmartMoneyBuyCount1H int `json:"smart_money_buy_count_1h"`
SmartMoneySellCount1H int `json:"smart_money_sell_count_1h"`
SmartMoneyBuyVolume1H float64 `json:"smart_money_buy_volume_1h"`
SmartMoneySellVolume1H float64 `json:"smart_money_sell_volume_1h"`
SmartMoneyBuyCount15M int `json:"smart_money_buy_count_15m"`
SmartMoneySellCount15M int `json:"smart_money_sell_count_15m"`
SmartMoneyBuyVolume15M float64 `json:"smart_money_buy_volume_15m"`
SmartMoneySellVolume15M float64 `json:"smart_money_sell_volume_15m"`
SmartMoneyBuyCount5M int `json:"smart_money_buy_count_5m"`
SmartMoneySellCount5M int `json:"smart_money_sell_count_5m"`
SmartMoneyBuyVolume5M float64 `json:"smart_money_buy_volume_5m"`
SmartMoneySellVolume5M float64 `json:"smart_money_sell_volume_5m"`
HoldersTop10Ratio float64 `json:"holders_top10_ratio"`
DevBalanceRatioCur float64 `json:"dev_balance_ratio_cur"`
InsiderBalanceRatioCur float64 `json:"insider_balance_ratio_cur"`
SniperBalanceRatioCur int `json:"sniper_balance_ratio_cur"`
CtoFlag int `json:"cto_flag"`
ReplyCount int `json:"reply_count"`
Progress int `json:"progress"`
FirstHalfElapsedTime int `json:"first_half_elapsed_time"`
SecondHalfElapsedTime int `json:"second_half_elapsed_time"`
WinnerCount int `json:"winner_count"`
WinnerRatio int `json:"winner_ratio"`
UpCount7D int `json:"up_count_7d"`
UpCount14D int `json:"up_count_14d"`
UpSeq string `json:"up_seq"`
BigorderCnt1H int `json:"bigorder_cnt_1h"`
BigorderBuyCnt1H int `json:"bigorder_buy_cnt_1h"`
BigorderSellCnt1H int `json:"bigorder_sell_cnt_1h"`
HasBrokenIssuePrice bool `json:"has_broken_issue_price"`
ListingAt int `json:"listing_at"`
Holders1440 int `json:"holders_1440"`
BuyCount24H int `json:"buy_count_24h"`
HotRank int `json:"hot_rank"`
FrontShowIndex int `json:"front_show_index"`
PiPriceChange1M float64 `json:"pi_price_change_1m"`
PiPriceChange5M float64 `json:"pi_price_change_5m"`
PiPriceChange15M float64 `json:"pi_price_change_15m"`
PiPriceChange30M float64 `json:"pi_price_change_30m"`
PiPriceChange1H float64 `json:"pi_price_change_1h"`
PiPriceChange4H float64 `json:"pi_price_change_4h"`
PiPriceChange24H float64 `json:"pi_price_change_24h"`
RatRate float64 `json:"rat_rate"`
PhishingRate float64 `json:"phishing_rate"`
ClusterRate float64 `json:"cluster_rate"`
BoulderRate float64 `json:"boulder_rate"`
AllTagRate float64 `json:"all_tag_rate"`
Rugged int `json:"rugged"`
Total int `json:"total"`
RugRate float64 `json:"rug_rate"`
} `json:"data"`
} `json:"data"`
}

View File

@ -52,4 +52,7 @@ const (
//需要清理键值---------END-----------------
JobReOrderTrigger = "job_re_order_trigger" //定时取消限价并下市价锁
ListenAveLastSymbol = "listen_ave_last_symbol" // 监听最新交易对
AveRequestToken = "ave_request_token" // AVE请求token
)

418
config/ave.js Normal file

File diff suppressed because one or more lines are too long