Files
sendico/api/gateway/tron/shared/helpers.go
2026-02-05 16:27:43 +01:00

211 lines
5.9 KiB
Go

package shared
import (
"strings"
"github.com/tech/sendico/gateway/tron/storage/model"
chainasset "github.com/tech/sendico/pkg/chain"
pmodel "github.com/tech/sendico/pkg/model"
paymenttypes "github.com/tech/sendico/pkg/payments/types"
moneyv1 "github.com/tech/sendico/pkg/proto/common/money/v1"
connectorv1 "github.com/tech/sendico/pkg/proto/connector/v1"
chainv1 "github.com/tech/sendico/pkg/proto/gateway/chain/v1"
"go.mongodb.org/mongo-driver/v2/bson"
)
// CloneMoney defensively copies a Money proto.
func CloneMoney(m *moneyv1.Money) *moneyv1.Money {
if m == nil {
return nil
}
return &moneyv1.Money{Amount: m.GetAmount(), Currency: m.GetCurrency()}
}
// CloneMetadata defensively copies metadata maps.
func CloneMetadata(input map[string]string) map[string]string {
if len(input) == 0 {
return nil
}
clone := make(map[string]string, len(input))
for k, v := range input {
clone[k] = v
}
return clone
}
// ResolveContractAddress finds a token contract for a symbol in a case-insensitive manner.
func ResolveContractAddress(tokens []TokenContract, symbol string) string {
upper := strings.ToUpper(symbol)
for _, token := range tokens {
if strings.EqualFold(token.Symbol, upper) && token.ContractAddress != "" {
return strings.ToLower(token.ContractAddress)
}
}
return ""
}
func GenerateWalletRef() string {
return bson.NewObjectID().Hex()
}
func GenerateTransferRef() string {
return bson.NewObjectID().Hex()
}
func ChainKeyFromEnum(chain chainv1.ChainNetwork) (string, chainv1.ChainNetwork) {
if name, ok := chainv1.ChainNetwork_name[int32(chain)]; ok {
key := strings.ToLower(strings.TrimPrefix(name, "CHAIN_NETWORK_"))
return key, chain
}
return "", chainv1.ChainNetwork_CHAIN_NETWORK_UNSPECIFIED
}
func ChainEnumFromName(name string) chainv1.ChainNetwork {
return chainasset.NetworkFromString(name)
}
func ManagedWalletStatusToProto(status model.ManagedWalletStatus) chainv1.ManagedWalletStatus {
switch status {
case model.ManagedWalletStatusActive:
return chainv1.ManagedWalletStatus_MANAGED_WALLET_ACTIVE
case model.ManagedWalletStatusSuspended:
return chainv1.ManagedWalletStatus_MANAGED_WALLET_SUSPENDED
case model.ManagedWalletStatusClosed:
return chainv1.ManagedWalletStatus_MANAGED_WALLET_CLOSED
default:
return chainv1.ManagedWalletStatus_MANAGED_WALLET_STATUS_UNSPECIFIED
}
}
func TransferStatusToModel(status chainv1.TransferStatus) model.TransferStatus {
switch status {
case chainv1.TransferStatus_TRANSFER_CREATED:
return model.TransferStatusCreated
case chainv1.TransferStatus_TRANSFER_PROCESSING:
return model.TransferStatusProcessing
case chainv1.TransferStatus_TRANSFER_WAITING:
return model.TransferStatusWaiting
case chainv1.TransferStatus_TRANSFER_SUCCESS:
return model.TransferStatusSuccess
case chainv1.TransferStatus_TRANSFER_FAILED:
return model.TransferStatusFailed
case chainv1.TransferStatus_TRANSFER_CANCELLED:
return model.TransferStatusCancelled
default:
return model.TransferStatus("")
}
}
func TransferStatusToProto(status model.TransferStatus) chainv1.TransferStatus {
switch status {
case model.TransferStatusCreated:
return chainv1.TransferStatus_TRANSFER_CREATED
case model.TransferStatusProcessing:
return chainv1.TransferStatus_TRANSFER_PROCESSING
case model.TransferStatusWaiting:
return chainv1.TransferStatus_TRANSFER_WAITING
case model.TransferStatusSuccess:
return chainv1.TransferStatus_TRANSFER_SUCCESS
case model.TransferStatusFailed:
return chainv1.TransferStatus_TRANSFER_FAILED
case model.TransferStatusCancelled:
return chainv1.TransferStatus_TRANSFER_CANCELLED
default:
return chainv1.TransferStatus_TRANSFER_STATUS_UNSPECIFIED
}
}
func ChainTransferStatusToOperation(status chainv1.TransferStatus) connectorv1.OperationStatus {
switch status {
case chainv1.TransferStatus_TRANSFER_CREATED:
return connectorv1.OperationStatus_OPERATION_CREATED
case chainv1.TransferStatus_TRANSFER_PROCESSING:
return connectorv1.OperationStatus_OPERATION_PROCESSING
case chainv1.TransferStatus_TRANSFER_WAITING:
return connectorv1.OperationStatus_OPERATION_WAITING
case chainv1.TransferStatus_TRANSFER_SUCCESS:
return connectorv1.OperationStatus_OPERATION_SUCCESS
case chainv1.TransferStatus_TRANSFER_FAILED:
return connectorv1.OperationStatus_OPERATION_FAILED
case chainv1.TransferStatus_TRANSFER_CANCELLED:
return connectorv1.OperationStatus_OPERATION_CANCELLED
default:
return connectorv1.OperationStatus_OPERATION_STATUS_UNSPECIFIED
}
}
// NativeCurrency returns the canonical native token symbol for a network.
func NativeCurrency(network Network) string {
currency := strings.ToUpper(strings.TrimSpace(network.NativeToken))
if currency == "" {
currency = strings.ToUpper(network.Name.String())
}
return currency
}
// Network describes a supported blockchain network and known token contracts.
type Network struct {
Name pmodel.ChainNetwork
RPCURL string
GRPCUrl string // Native TRON gRPC endpoint (for transactions)
GRPCToken string // Optional auth token for TRON gRPC (x-token header)
ChainID uint64
NativeToken string
TokenConfigs []TokenContract
GasTopUpPolicy *GasTopUpPolicy
}
// TokenContract captures the metadata needed to work with a specific on-chain token.
type TokenContract struct {
Symbol string
ContractAddress string
}
// ServiceWallet captures the managed service wallet configuration.
type ServiceWallet struct {
Network pmodel.ChainNetwork
Address string
PrivateKey string
}
func ProtoToMoney(money *moneyv1.Money) *paymenttypes.Money {
if money == nil {
return &paymenttypes.Money{}
}
return &paymenttypes.Money{
Amount: money.GetAmount(),
Currency: money.GetCurrency(),
}
}
func MonenyToProto(money *paymenttypes.Money) *moneyv1.Money {
if money == nil {
return &moneyv1.Money{}
}
return &moneyv1.Money{
Amount: money.Amount,
Currency: money.Currency,
}
}