Files
sxchnge/backend/pkg/model/cryptoaddress.go
T

128 lines
3.9 KiB
Go

package model
import (
"encoding/json"
"fmt"
"strings"
"git.sendico.io/tech/sxchnge/bff/pkg/merrors"
"go.mongodb.org/mongo-driver/v2/bson"
)
type CryptoAddressPaymentData struct {
Currency Currency `bson:"currency" json:"currency"`
Address string `bson:"address" json:"address"`
Network string `bson:"network" json:"network"`
DestinationTag *string `bson:"destinationTag,omitempty" json:"destinationTag,omitempty"`
}
type cryptoAddressAssetJSON struct {
Chain string `json:"chain,omitempty"`
TokenSymbol string `json:"token_symbol,omitempty"`
ContractAddress string `json:"contract_address,omitempty"`
}
func (d CryptoAddressPaymentData) MarshalJSON() ([]byte, error) {
var payload struct {
Asset *cryptoAddressAssetJSON `json:"asset,omitempty"`
Address string `json:"address"`
Memo *string `json:"memo,omitempty"`
}
payload.Address = strings.TrimSpace(d.Address)
if strings.TrimSpace(d.Network) != "" || strings.TrimSpace(string(d.Currency)) != "" {
payload.Asset = &cryptoAddressAssetJSON{
Chain: strings.TrimSpace(d.Network),
TokenSymbol: strings.TrimSpace(string(d.Currency)),
}
}
if memo := strings.TrimSpace(strPtr(d.DestinationTag)); memo != "" {
payload.Memo = &memo
}
return json.Marshal(payload)
}
func (d *CryptoAddressPaymentData) UnmarshalJSON(data []byte) error {
var raw struct {
Asset *cryptoAddressAssetJSON `json:"asset"`
Address string `json:"address"`
Memo string `json:"memo"`
Currency string `json:"currency"`
Network string `json:"network"`
DestinationTag *string `json:"destinationTag"`
}
if err := json.Unmarshal(data, &raw); err != nil {
return err
}
currency := strings.TrimSpace(raw.Currency)
network := strings.TrimSpace(raw.Network)
if raw.Asset != nil {
if assetCurrency := strings.TrimSpace(raw.Asset.TokenSymbol); assetCurrency != "" {
currency = assetCurrency
}
if assetNetwork := strings.TrimSpace(raw.Asset.Chain); assetNetwork != "" {
network = assetNetwork
}
}
d.Currency = Currency(strings.ToUpper(currency))
d.Address = strings.TrimSpace(raw.Address)
d.Network = strings.ToUpper(network)
d.DestinationTag = clonePaymentDataStringPtr(raw.Memo)
if d.DestinationTag == nil && raw.DestinationTag != nil {
d.DestinationTag = clonePaymentDataStringPtr(*raw.DestinationTag)
}
return nil
}
func (d *CryptoAddressPaymentData) UnmarshalBSON(data []byte) error {
var raw map[string]any
if err := bson.Unmarshal(data, &raw); err != nil {
return err
}
currency := firstPaymentDataString(raw, "currency")
network := firstPaymentDataString(raw, "network")
if asset := paymentDataDocument(raw["asset"]); asset != nil {
if assetCurrency := firstPaymentDataString(asset, "token_symbol", "tokenSymbol"); assetCurrency != "" {
currency = assetCurrency
}
if assetNetwork := firstPaymentDataString(asset, "chain"); assetNetwork != "" {
network = assetNetwork
}
}
d.Currency = Currency(strings.ToUpper(strings.TrimSpace(currency)))
d.Address = firstPaymentDataString(raw, "address")
d.Network = strings.ToUpper(strings.TrimSpace(network))
d.DestinationTag = clonePaymentDataStringPtr(firstPaymentDataString(raw, "destinationTag", "destination_tag", "memo"))
return nil
}
func (m *PaymentMethod) AsCryptoAddress() (*CryptoAddressPaymentData, error) {
if m.Type != PaymentTypeCryptoAddress {
return nil, merrors.InvalidArgument(fmt.Sprintf("payment method type is %s, not cryptoAddress", m.Type), "type")
}
var d CryptoAddressPaymentData
if err := bson.Unmarshal(m.Data, &d); err != nil {
return nil, err
}
return &d, nil
}
func clonePaymentDataStringPtr(value string) *string {
out := strings.TrimSpace(value)
if out == "" {
return nil
}
return &out
}
func strPtr(value *string) string {
if value == nil {
return ""
}
return *value
}