package plan import ( "github.com/tech/sendico/pkg/discovery" "strings" "github.com/tech/sendico/payments/storage/model" "github.com/tech/sendico/pkg/merrors" ) func railFromEndpoint(endpoint model.PaymentEndpoint, attrs map[string]string, isSource bool) (model.Rail, string, error) { override := railOverrideFromAttributes(attrs, isSource) if override != discovery.RailUnspecified { return override, networkFromEndpoint(endpoint), nil } switch endpoint.Type { case model.EndpointTypeLedger: return discovery.RailLedger, "", nil case model.EndpointTypeManagedWallet, model.EndpointTypeExternalChain: return discovery.RailCrypto, networkFromEndpoint(endpoint), nil case model.EndpointTypeCard: return discovery.RailCardPayout, "", nil default: return discovery.RailUnspecified, "", merrors.InvalidArgument("plan builder: unsupported payment endpoint") } } func railOverrideFromAttributes(attrs map[string]string, isSource bool) model.Rail { if len(attrs) == 0 { return discovery.RailUnspecified } keys := []string{"source_rail", "sourceRail"} if !isSource { keys = []string{"destination_rail", "destinationRail"} } lookup := map[string]struct{}{} for _, key := range keys { lookup[strings.ToLower(key)] = struct{}{} } for key, value := range attrs { if _, ok := lookup[strings.ToLower(strings.TrimSpace(key))]; !ok { continue } rail := parseRailValue(value) if rail != discovery.RailUnspecified { return rail } } return discovery.RailUnspecified } func parseRailValue(value string) model.Rail { val := strings.ToUpper(strings.TrimSpace(value)) switch val { case string(discovery.RailCrypto): return discovery.RailCrypto case string(discovery.RailProviderSettlement): return discovery.RailProviderSettlement case string(discovery.RailLedger): return discovery.RailLedger case string(discovery.RailCardPayout): return discovery.RailCardPayout case string(discovery.RailFiatOnRamp): return discovery.RailFiatOnRamp default: return discovery.RailUnspecified } } func gatewayNetworkForRail(rail model.Rail, sourceRail, destRail model.Rail, sourceNetwork, destNetwork string) string { switch rail { case discovery.RailCrypto: if sourceRail == discovery.RailCrypto { return strings.ToUpper(strings.TrimSpace(sourceNetwork)) } if destRail == discovery.RailCrypto { return strings.ToUpper(strings.TrimSpace(destNetwork)) } case discovery.RailFiatOnRamp: if sourceRail == discovery.RailFiatOnRamp { return strings.ToUpper(strings.TrimSpace(sourceNetwork)) } if destRail == discovery.RailFiatOnRamp { return strings.ToUpper(strings.TrimSpace(destNetwork)) } } return "" } func networkFromEndpoint(endpoint model.PaymentEndpoint) string { switch endpoint.Type { case model.EndpointTypeManagedWallet: if endpoint.ManagedWallet != nil && endpoint.ManagedWallet.Asset != nil { return strings.ToUpper(strings.TrimSpace(endpoint.ManagedWallet.Asset.GetChain())) } case model.EndpointTypeExternalChain: if endpoint.ExternalChain != nil && endpoint.ExternalChain.Asset != nil { return strings.ToUpper(strings.TrimSpace(endpoint.ExternalChain.Asset.GetChain())) } } return "" }