package plan import ( "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 != model.RailUnspecified { return override, networkFromEndpoint(endpoint), nil } switch endpoint.Type { case model.EndpointTypeLedger: return model.RailLedger, "", nil case model.EndpointTypeManagedWallet, model.EndpointTypeExternalChain: return model.RailCrypto, networkFromEndpoint(endpoint), nil case model.EndpointTypeCard: return model.RailCardPayout, "", nil default: return model.RailUnspecified, "", merrors.InvalidArgument("plan builder: unsupported payment endpoint") } } func railOverrideFromAttributes(attrs map[string]string, isSource bool) model.Rail { if len(attrs) == 0 { return model.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 != model.RailUnspecified { return rail } } return model.RailUnspecified } func parseRailValue(value string) model.Rail { val := strings.ToUpper(strings.TrimSpace(value)) switch val { 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 gatewayNetworkForRail(rail model.Rail, sourceRail, destRail model.Rail, sourceNetwork, destNetwork string) string { switch rail { case model.RailCrypto: if sourceRail == model.RailCrypto { return strings.ToUpper(strings.TrimSpace(sourceNetwork)) } if destRail == model.RailCrypto { return strings.ToUpper(strings.TrimSpace(destNetwork)) } case model.RailFiatOnRamp: if sourceRail == model.RailFiatOnRamp { return strings.ToUpper(strings.TrimSpace(sourceNetwork)) } if destRail == model.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 "" }