feat: get support chain api

This commit is contained in:
Ginta
2026-04-14 18:57:38 +08:00
parent 5e68bf8309
commit 1e2282ba2e
11 changed files with 546 additions and 30 deletions
+82 -15
View File
@@ -2,6 +2,7 @@ package telegram
import (
"fmt"
"sort"
"strings"
"sync"
"time"
@@ -14,12 +15,14 @@ import (
)
const (
ReplayAddWallet = "请发给我 TRON(T 开头)或以太坊主网(0x 开头)收款地址"
ReplaySelectNetwork = "请选择要添加的钱包网络"
ReplayAddWallet = "请发送 %s 网络收款地址"
pendingWalletAddressTTL = 5 * time.Minute
)
type pendingWalletAddressState struct {
RequestedAt time.Time
Network string
}
var pendingWalletAddressUsers sync.Map
@@ -36,7 +39,7 @@ func OnTextMessageHandle(c tb.Context) error {
senderID = sender.ID
}
isReplyFlow := msg.ReplyTo != nil && msg.ReplyTo.Text == ReplayAddWallet
isReplyFlow := msg.ReplyTo != nil && strings.HasPrefix(msg.ReplyTo.Text, "请发送 ")
isPendingFlow := isWalletAddressPending(senderID)
if !isReplyFlow && !isPendingFlow {
return nil
@@ -47,22 +50,25 @@ func OnTextMessageHandle(c tb.Context) error {
}
msgText := strings.TrimSpace(msg.Text)
var err error
switch {
case isValidTronAddress(msgText):
_, err = data.AddWalletAddress(msgText)
case isValidEthereumAddress(msgText):
_, err = data.AddWalletAddressWithNetwork(mdb.NetworkEthereum, strings.ToLower(msgText))
default:
_ = c.Send(fmt.Sprintf("钱包 [%s] 添加失败:不是合法的 TRON 或以太坊地址", msgText))
state, _ := getPendingWalletAddressState(senderID)
if state.Network == "" {
_ = c.Send("请先选择网络,再发送地址。")
return nil
}
var err error
if !isValidAddressByNetwork(state.Network, msgText) {
_ = c.Send(fmt.Sprintf("钱包 [%s] 添加失败:不是合法的 %s 地址", msgText, strings.ToUpper(state.Network)))
return nil
}
storeAddress := normalizeWalletAddressByNetwork(state.Network, msgText)
_, err = data.AddWalletAddressWithNetwork(state.Network, storeAddress)
if err != nil {
return c.Send(err.Error())
}
pendingWalletAddressUsers.Delete(senderID)
_ = c.Send(fmt.Sprintf("钱包 [%s] 添加成功", msgText))
_ = c.Send(fmt.Sprintf("钱包 [%s] 添加成功%s", storeAddress, strings.ToUpper(state.Network)))
return WalletList(c)
}
@@ -94,11 +100,26 @@ func WalletList(c tb.Context) error {
addBtn := tb.InlineButton{Text: "添加钱包地址", Unique: "AddWallet"}
bots.Handle(&addBtn, func(c tb.Context) error {
if sender := c.Sender(); sender != nil {
pendingWalletAddressUsers.Store(sender.ID, pendingWalletAddressState{RequestedAt: time.Now()})
chains, err := getEnabledSupportedNetworks()
if err != nil {
return c.Send("读取支持链失败:" + err.Error())
}
return c.Send(ReplayAddWallet, &tb.ReplyMarkup{
ForceReply: true,
if len(chains) == 0 {
return c.Send("当前没有可用链,请先在后台配置 supported-assets。")
}
rows := make([][]tb.InlineButton, 0, len(chains))
for _, network := range chains {
btn := tb.InlineButton{
Text: strings.ToUpper(network),
Unique: "SelectWalletNetwork",
Data: network,
}
bots.Handle(&btn, SelectWalletNetwork)
rows = append(rows, []tb.InlineButton{btn})
}
return c.EditOrSend(ReplaySelectNetwork, &tb.ReplyMarkup{
InlineKeyboard: rows,
})
})
btnList = append(btnList, []tb.InlineButton{addBtn})
@@ -108,6 +129,22 @@ func WalletList(c tb.Context) error {
})
}
func SelectWalletNetwork(c tb.Context) error {
network := strings.ToLower(strings.TrimSpace(c.Data()))
if network == "" {
return c.Send("请选择有效网络")
}
if sender := c.Sender(); sender != nil {
pendingWalletAddressUsers.Store(sender.ID, pendingWalletAddressState{
RequestedAt: time.Now(),
Network: network,
})
}
return c.Send(fmt.Sprintf(ReplayAddWallet, strings.ToUpper(network)), &tb.ReplyMarkup{
ForceReply: true,
})
}
func WalletInfo(c tb.Context) error {
id := mathutil.MustUint(c.Data())
tokenInfo, err := data.GetWalletAddressById(id)
@@ -209,3 +246,33 @@ func isWalletAddressPending(userID int64) bool {
}
return true
}
func getPendingWalletAddressState(userID int64) (pendingWalletAddressState, bool) {
v, ok := pendingWalletAddressUsers.Load(userID)
if !ok {
return pendingWalletAddressState{}, false
}
state, ok := v.(pendingWalletAddressState)
return state, ok
}
func getEnabledSupportedNetworks() ([]string, error) {
assets, err := data.ListEnabledSupportedAssets()
if err != nil {
return nil, err
}
set := make(map[string]struct{})
for _, a := range assets {
n := strings.ToLower(strings.TrimSpace(a.Network))
if n == "" {
continue
}
set[n] = struct{}{}
}
networks := make([]string, 0, len(set))
for n := range set {
networks = append(networks, n)
}
sort.Strings(networks)
return networks, nil
}