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.TrimSpace(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, } }