138 lines
3.5 KiB
Go
138 lines
3.5 KiB
Go
package quotation
|
|
|
|
import (
|
|
"context"
|
|
"sort"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/tech/sendico/payments/storage/model"
|
|
"github.com/tech/sendico/pkg/discovery"
|
|
"github.com/tech/sendico/pkg/mlogger"
|
|
)
|
|
|
|
type discoveryGatewayRegistry struct {
|
|
logger mlogger.Logger
|
|
registry *discovery.Registry
|
|
}
|
|
|
|
func NewDiscoveryGatewayRegistry(logger mlogger.Logger, registry *discovery.Registry) GatewayRegistry {
|
|
if registry == nil {
|
|
return nil
|
|
}
|
|
if logger != nil {
|
|
logger = logger.Named("discovery_gateway_registry")
|
|
}
|
|
return &discoveryGatewayRegistry{
|
|
logger: logger,
|
|
registry: registry,
|
|
}
|
|
}
|
|
|
|
func (r *discoveryGatewayRegistry) List(_ context.Context) ([]*model.GatewayInstanceDescriptor, error) {
|
|
if r == nil || r.registry == nil {
|
|
return nil, nil
|
|
}
|
|
entries := r.registry.List(time.Now(), true)
|
|
items := make([]*model.GatewayInstanceDescriptor, 0, len(entries))
|
|
for _, entry := range entries {
|
|
if entry.Rail == "" {
|
|
continue
|
|
}
|
|
rail := railFromDiscovery(entry.Rail)
|
|
if rail == model.RailUnspecified {
|
|
continue
|
|
}
|
|
items = append(items, &model.GatewayInstanceDescriptor{
|
|
ID: entry.ID,
|
|
InstanceID: entry.InstanceID,
|
|
Rail: rail,
|
|
Network: entry.Network,
|
|
InvokeURI: strings.TrimSpace(entry.InvokeURI),
|
|
Currencies: normalizeCurrencies(entry.Currencies),
|
|
Capabilities: capabilitiesFromOps(entry.Operations),
|
|
Limits: limitsFromDiscovery(entry.Limits),
|
|
Version: entry.Version,
|
|
IsEnabled: entry.Healthy,
|
|
})
|
|
}
|
|
sort.Slice(items, func(i, j int) bool {
|
|
return items[i].ID < items[j].ID
|
|
})
|
|
return items, nil
|
|
}
|
|
|
|
func railFromDiscovery(value string) model.Rail {
|
|
switch strings.ToUpper(strings.TrimSpace(value)) {
|
|
case string(model.RailCrypto):
|
|
return model.RailCrypto
|
|
case string(model.RailProviderSettlement):
|
|
return model.RailProviderSettlement
|
|
case string(model.RailLedger):
|
|
return model.RailLedger
|
|
case string(model.RailCardPayout):
|
|
return model.RailCardPayout
|
|
case string(model.RailFiatOnRamp):
|
|
return model.RailFiatOnRamp
|
|
default:
|
|
return model.RailUnspecified
|
|
}
|
|
}
|
|
|
|
func capabilitiesFromOps(ops []string) model.RailCapabilities {
|
|
var cap model.RailCapabilities
|
|
for _, op := range ops {
|
|
switch strings.ToLower(strings.TrimSpace(op)) {
|
|
case "payin.crypto", "payin.card", "payin.fiat":
|
|
cap.CanPayIn = true
|
|
case "payout.crypto", "payout.card", "payout.fiat":
|
|
cap.CanPayOut = true
|
|
case "balance.read":
|
|
cap.CanReadBalance = true
|
|
case "fee.send":
|
|
cap.CanSendFee = true
|
|
case "observe.confirm", "observe.confirmation":
|
|
cap.RequiresObserveConfirm = true
|
|
case "block", "funds.block", "balance.block", "ledger.block":
|
|
cap.CanBlock = true
|
|
case "release", "funds.release", "balance.release", "ledger.release":
|
|
cap.CanRelease = true
|
|
}
|
|
}
|
|
return cap
|
|
}
|
|
|
|
func limitsFromDiscovery(src *discovery.Limits) model.Limits {
|
|
if src == nil {
|
|
return model.Limits{}
|
|
}
|
|
limits := model.Limits{
|
|
MinAmount: strings.TrimSpace(src.MinAmount),
|
|
MaxAmount: strings.TrimSpace(src.MaxAmount),
|
|
VolumeLimit: map[string]string{},
|
|
VelocityLimit: map[string]int{},
|
|
}
|
|
for key, value := range src.VolumeLimit {
|
|
k := strings.TrimSpace(key)
|
|
v := strings.TrimSpace(value)
|
|
if k == "" || v == "" {
|
|
continue
|
|
}
|
|
limits.VolumeLimit[k] = v
|
|
}
|
|
for key, value := range src.VelocityLimit {
|
|
k := strings.TrimSpace(key)
|
|
if k == "" {
|
|
continue
|
|
}
|
|
limits.VelocityLimit[k] = value
|
|
}
|
|
if len(limits.VolumeLimit) == 0 {
|
|
limits.VolumeLimit = nil
|
|
}
|
|
if len(limits.VelocityLimit) == 0 {
|
|
limits.VelocityLimit = nil
|
|
}
|
|
return limits
|
|
}
|